Back to Browse

Endoflife MCP Server

Developer ToolsLow Risk8.0MCP RegistryRemote
Free

Server data from the Official MCP Registry

EOL dates, risk scores, CISA KEV exposure, SBOM audits and edge-device EOS for 700+ products.

About

EOL dates, risk scores, CISA KEV exposure, SBOM audits and edge-device EOS for 700+ products.

Remote endpoints: streamable-http: https://mcp.endoflife.ai

Security Report

8.0
Low Risk8.0Low Risk

Valid MCP server (1 strong, 1 medium validity signals). 2 known CVEs in dependencies (0 critical, 2 high severity) Imported from the Official MCP Registry.

10 tools verified · Open access · 2 issues found

Security scores are indicators to help you make informed decisions, not guarantees. Always review permissions before connecting any MCP server.

Permissions Found in Source Code

Found by scanning the linked source code. This listing connects to a hosted endpoint, so none of this runs on your machine: it describes what the server software does where it is hosted.

HTTP Network Access

Connects to external APIs or services over the internet.

env_vars

Applies to the server that hosts this plugin, not to your machine.

How to Connect

Remote Plugin

No local installation needed. Your AI client connects to the remote endpoint directly.

Add this to your MCP configuration to connect:

{
  "mcpServers": {
    "io-github-endoflife-ai-endoflife-mcp": {
      "url": "https://mcp.endoflife.ai"
    }
  }
}

Documentation

View on GitHub

From the project's GitHub README.

endoflife.ai — MCP Server

Node.js EOL status EOL data: endoflife.ai

Exposes endoflife.ai's lifecycle intelligence to AI agents over the Model Context Protocol (MCP, Streamable HTTP transport). A dependency-free Cloudflare Worker that wraps the public api.endoflife.ai/v1 endpoints and the site's published feeds — no data duplicated, every answer carries a source URL.

Current version: 1.4.1 (SERVER_INFO.version in src/index.js, server.json, package.json, the Dockerfile ARG VERSION, and the site's endoflife/.well-known/mcp/server-card.json — keep them in step; the registry and Glama read server.json).

1.4.1: description and tool text carry the current build-computed counts (700+ products, 15,000+ versions) for the registry and npm listings; no behaviour change.

1.4.0: check_sbom is a thin proxy to the API's POST /v1/sbom (one resolver for every surface; versions keep their release family, e.g. python 3.12, ubuntu 20.04). Above the tier cap it returns the scored subset plus limit_note and not_scored_count; scan_stack scores the first N the tier allows and lists the rest in not_checked. Until 1.4.0 check_sbom cut every version to its major number and a keyless SBOM with more than 5 matched components returned nothing.

Tools (all read-only)

ToolWhat it doesBacked by
check_eolIs product X version Y end-of-life?GET /v1/status/:slug/:version
get_risk_scoreEOL Risk Score (0–100) + factor breakdownGET /v1/score/:slug[/:version]
scan_stackScore a whole stack at oncePOST /v1/batch
list_productsSearch the 700+ tracked products → resolve slugsGET /v1/products
get_product_lifecycleFull version history + dates for one productGET /v1/product/:slug
get_kev_exposureEvery CISA KEV entry attributed to a product (date added, due date, required action verbatim) + Exploited & Unpatchable entriesendoflife.ai/kev-products.json, exploited-and-unpatchable.json
get_upcoming_eolEverything reaching EOL in the next N days (catalog-wide or a product list)endoflife.ai/scanner-db.json
get_edge_device_statusEOS Edge Device feed with BOD 26-02 statuses, filter by platform / status / modelendoflife.ai/eos-edge-devices.json
get_upgrade_pathSupported targets, the site's recommendation, vendor-stated successorGET /v1/product/:slug, checker-db.json, edge feed
check_sbomCycloneDX / SPDX JSON → components resolved by package URL (exact, purl-map.json) or by name when no purl → scored up to the tier cap, the rest counted in a note; unmatched listed with a reason, never guessedPOST /v1/sbom

Every tool advertises annotations (readOnlyHint, idempotentHint) and a permissive outputSchema; results are returned both as JSON text and as structuredContent. Lookup misses return "did you mean" slug suggestions (prefix / substring / edit-distance ≤ 2 against the live product list).

Resources (resources/list / resources/read): llms.txt, the EOS Edge Device feed, Exploited & Unpatchable, KEV by product, the edge change log.

Prompts (prompts/list / prompts/get): audit_stack, eol_calendar, edge_device_review.

Endpoints: POST / (JSON-RPC), GET / (info page), GET /health (liveness JSON), GET /.well-known/mcp/server-card.json (discovery card).

Usage telemetry

With the USAGE Analytics Engine binding (see wrangler.toml, dataset endoflife_mcp_usage) each method / tool call writes one data point: tool name, client user agent, ok/error, keyed/anon, latency in ms. No request bodies. Query via the Cloudflare Analytics Engine SQL API, e.g.

SELECT blob1 AS tool, count() AS calls, sum(_sample_interval) AS weighted
FROM endoflife_mcp_usage WHERE timestamp > NOW() - INTERVAL '7' DAY
GROUP BY tool ORDER BY calls DESC

The binding is optional; the code no-ops without it.

Deploy

Production deploys run from GitHub Actions, never a local wrangler:

gh workflow run mcp-server-deploy.yml

(.github/workflows/mcp-server-deploy.yml, pinned wrangler; needs the CLOUDFLARE_API_TOKEN / CLOUDFLARE_ACCOUNT_ID repository secrets.) Local wrangler dev still works for development; the API service binding and the USAGE dataset are declared for both the default and production environments.

Custom domain (mcp.endoflife.ai)

The route in wrangler.toml needs mcp.endoflife.ai to resolve through Cloudflare: an AAAA record, name mcp, IPv6 100::, proxied. Already in place.

Test before deploying

A Node harness exercises every method against the live API and feeds (the module runs unchanged in Node with env.API = { fetch }):

node scratch/mcp_test.mjs   # see the session scratchpad; 22 RPC calls, expects 0 failures

Offline unit tests (fetch mocked, no network): npm test in mcp-server/ (node --test test/).

Run as a container (Red Hat UBI)

server.mjs runs the same handler that serves mcp.endoflife.ai inside a plain Node.js process, and Dockerfile packages it on registry.access.redhat.com/ubi9/nodejs-22-minimal for cluster deploys (the form the OpenShift AI MCP catalog expects). No build step, no dependencies; the container talks to https://api.endoflife.ai over HTTPS and runs as the unprivileged UBI user (uid 1001).

docker build -t endoflife-mcp mcp-server/
docker run --rm -p 8080:8080 endoflife-mcp
curl -s localhost:8080/health

Endpoints are the Worker's own: POST / (Streamable HTTP JSON-RPC), GET /health (readiness), GET /.well-known/mcp/server-card.json. Set ENDOFLIFE_API_KEY (docker run -e ENDOFLIFE_API_KEY=...) and the server sends it as X-API-Key on every call that carries no key of its own. A self-hosted server needs it from November 16, 2026 at 00:00 UTC, when the API stops answering data requests without a key; only the hosted endpoint at mcp.endoflife.ai stays keyless. A free key is emailed at once from https://endoflife.ai/api#free-key (150 requests a day, no expiry; higher volume is on a paid key). Validated on RHEL 9 and 10 with Node 20 and 22 by .github/workflows/rhel-validation.yml (evidence in docs/company/redhat-validation-evidence.md).

Connect from an MCP client

Claude Desktop / Cursor / VS Code (mcpServers):

{
  "mcpServers": {
    "endoflife": { "command": "npx", "args": ["mcp-remote", "https://mcp.endoflife.ai"] }
  }
}

Clients with native remote-MCP support can use the URL directly:

{ "mcpServers": { "endoflife": { "url": "https://mcp.endoflife.ai" } } }

Test without a client

# tools/list
curl -s https://mcp.endoflife.ai -X POST -H 'Content-Type: application/json' \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}' | jq

# KEV exposure for a product
curl -s https://mcp.endoflife.ai -X POST -H 'Content-Type: application/json' \
  -d '{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"get_kev_exposure","arguments":{"product":"ivanti-connect-secure"}}}' | jq

# health + discovery card
curl -s https://mcp.endoflife.ai/health | jq
curl -s https://mcp.endoflife.ai/.well-known/mcp/server-card.json | jq

Auth & tiers

The read tools work with no key for individual use and evaluation through the hosted endpoint mcp.endoflife.ai (each agent gets 2,000 a day and 5 per call). Calling the API directly, or running this server yourself, works without a key only until November 16, 2026 at 00:00 UTC (anonymous tier: 50 requests a day, 3 components per SBOM or batch call); from then every data request needs a key (set ENDOFLIFE_API_KEY on a self-hosted server; free key at https://endoflife.ai/api#free-key). Agents that run inside a company's tooling, check inventories or call on a schedule are production use and belong on a paid key: Starter ($89/month, 10,000 requests a day, 25 per call) or Pro ($299/month, 100,000 requests a day under fair use, 50 per call), issued at checkout from https://endoflife.ai/api?utm_source=mcp#get-key. Forward it as an X-API-Key header; the Worker passes it straight through to api.endoflife.ai.

Notes

  • Same-zone trap: api.endoflife.ai is a Worker on this zone; a plain fetch() to it goes to origin and fails. The API service binding is mandatory in prod.
  • Static feeds are fetched from the site origin with cf.cacheTtl = 600 and memoised in the isolate for 10 minutes.
  • Per-client rate limits: relies on the upstream API's limits. If MCP traffic grows, add a KV rate-limiter keyed on CF-Connecting-IP before the upstream call.
  • Discovery card is also served from the main site at https://endoflife.ai/.well-known/mcp/server-card.json.

Reviews

No reviews yet

Be the first to review this server!