lastseen-mcp
# lastseen-mcp
<!-- MCP registry ownership -->
mcp-name: dev.lastseen/mortality
[](https://lastseen.dev)
[](https://creativecommons.org/licenses/by/4.0/)
[](LICENSE)
**Is this dependency dead?** Dated observations of whether an npm package, GitHub Action, MCP
server, or Docker image is **alive, dormant, abandoned, archived, or deleted** — published by
[lastseen.dev](https://lastseen.dev). Free, no API key, zero telemetry.
There are two ways in, and they answer the same question from the same dated data:
1. **Call the free HTTP API directly** — the durable, machine-native path (below). An agent that
keeps a dependency list can re-check it on every build.
2. **Run it as an MCP server** — a thin stdio wrapper over that same API, for MCP clients.
---
## 1. The free API (call it directly)
No key. No signup. **60 requests/minute**, anonymous GET. Every response is a **dated
observation with its source** — not a score, not advice. Base URL `https://lastseen.dev`.
```bash
# one component (owner/repo)
curl https://lastseen.dev/api/v1/entity/actions/checkout
# everything held under a GitHub owner/org
curl https://lastseen.dev/api/v1/org/actions
# a whole manifest at once (names-only body)
curl -X POST https://lastseen.dev/api/v1/manifest \
-H 'content-type: application/json' \
-d '{"channel":"api","components":[{"name":"actions/checkout","kind":"github-action"}]}'
# self-describing API docs (JSON)
curl https://lastseen.dev/api/v1/docs
```
A single-component response carries the `latest_state`, the dated `series` behind it, the
`source_of_record`, and interval-censoring notes — enough to re-check any verdict against GitHub
yourself. **This is the recurring path:** wire `GET /api/v1/entity/{owner}/{repo}` into CI and a
dead dependency shows up on the build that introduces it, not months later.
### Contract
- **Lookups, not advice.** Every answer is a dated observation with its source. Never "use X
instead", never a composite score, never a ranking by preference, never urgency language.
- **Fails closed.** An unknown or fabricated subject returns a clean `not_observed` — never a
fabricated result. A network/store error *degrades* (try later); it is never read as "dead".
- **Absence ≠ gone.** No record means "not checked", never "deleted". Only an authoritative
HTTP 404 is a deletion.
### States
`alive` (≤180d since last commit) · `dormant` (180–365d) · `abandoned` (>365d) ·
`archived` (repo archived) · `deleted` (authoritative HTTP 404) · `eol` (declared end-of-life) ·
`unknown-stale` (the observation the verdict rests on is older than the 180-day threshold and was
not re-verified — no state asserted; **not** a death) · `not_observed` (403 / 429 / timeout / not
held — **not** dead).
---
## 2. Run it as an MCP server
A **pure-standard-library** stdio wrapper over the API above — no `mcp` package, no `requests`,
no FastAPI/Starlette, nothing that can conflict with a host app. It speaks JSON-RPC 2.0 over
stdio and calls the free API over `urllib`.
### Install
```bash
pipx install lastseen-mcp
# or run without installing:
uvx lastseen-mcp
```
Requires Python ≥ 3.10. No dependencies.
### Add to an MCP client
```json
{
"mcpServers": {
"lastseen": { "command": "lastseen-mcp" }
}
}
```
(If you use `uvx`, set `"command": "uvx", "args": ["lastseen-mcp"]`.)
### Tools
| Tool | What it does |
| --- | --- |
| `check_entity(slug, live?)` | Dated survival series for one `owner/repo` (e.g. `actions/checkout`). `live=true` attaches a live GitHub read (absence ≠ gone). |
| `check_org(name)` | Dated states for every held component under a GitHub owner/org. |
| `check_manifest(paste)` | Paste a GitHub Actions workflow (`uses:` refs) or `owner/repo` lines; get the dated state per component. Unheld components are `not_observed`. |
| `survival_profile(category)` | Category ranking — **not available over the free API**; returns an honest not-supported result pointing to the per-entity/org/manifest lookups and the CC-BY dumps. |
`check_manifest` looks up at most 30 parsed components per call (free-tier rate bound); any
remainder is reported as `n_truncated`.
---
## Privacy
Zero telemetry. The client and the API store nothing and transmit no identifier about you, your
org, or the subjects you look up — anonymous GETs only.
## Licensing
- **Code:** MIT (see `LICENSE`).
- **Data:** the mortality/survival observations are published by lastseen.dev under
**CC-BY-4.0** (attribution required). The two licenses are independent.
## Links
- Service & data: <https://lastseen.dev>
- API docs (self-describing JSON): <https://lastseen.dev/api/v1/docs>
- MCP registry entry: `dev.lastseen/mortality`
TDQS
Scored across 4 tools
Each tool targets a distinct input scope: single owner/repo, org slug, pasted manifest, and category profile. The scopes are clearly described, and the batch manifest tool is unlikely to be confused with the single-entity or org-level lookups.
Three of the four tools follow the consistent check_<scope> pattern (check_entity, check_org, check_manifest). survival_profile breaks the verb_noun pattern, but it is a single recognizable exception rather than a systemic inconsistency.
Four tools is a reasonable size for a narrow read-only lookup service. However, survival_profile is effectively an unsupported stub that always returns not_supported, so it pads the count without adding a working capability.
The core lookup workflows are covered: single entity, org-wide, and manifest-based batch checks. The main gap is category-level ranking, which survival_profile cannot provide, though the description points to alternative lookups and external dumps as workarounds.