Toolpin

API and MCP server

Everything Toolpin observes is readable two ways: an MCP server your agent can call while it is picking a dependency, and a JSON API for everything else. Both are open without an account. Both return the same facts, because both read the same data.

MCP server

Point any MCP client at:

https://toolpin.dev/mcp

Streamable HTTP, stateless, no sign-up. Configuration differs between clients, but most take a shape like this:

{
  "mcpServers": {
    "toolpin": {
      "url": "https://toolpin.dev/mcp"
    }
  }
}

To raise your limits or use watch_server, add an API key as an Authorization: Bearer header. Never put a key in a URL.

The 6 tools it publishes, read from the running server:

ToolWhat it answers
search_servers Find MCP servers in the public registry by name or title.
get_server Everything Toolpin has observed about one MCP server: reachability of each remote endpoint and when each was last checked and last verified, repository activity, the current tool-definition hash, and how many changes it has recorded in the last 90 days.
get_server_tools The tool definitions one MCP server advertised when Toolpin last read them, each with a SHA-256 hash of the fields the MCP specification defines.
get_server_changes Changes Toolpin recorded for one MCP server: tool definitions changing, and endpoints going down or coming back.
get_spec_status The current MCP specification revision, which of its proposals Toolpin checks for, and how much of the catalog has migrated.
watch_server Start monitoring an MCP server on the caller's Toolpin account, so they are emailed when it changes or stops answering.

JSON API

Base path /v1. The machine-readable schema is at /openapi.json.

EndpointReturns
GET /v1/servers/{name} Everything known about one server: every endpoint's reachability, when it was last checked and last verified, repository activity, the current tool-definition hash, and recorded changes.
GET /v1/tools?server= The tool definitions as last read, each with its SHA-256 hash.
GET /v1/changes?server= What changed and when: which tools moved, which fields differed, and the hash either side.
GET /v1/search?q= Find a server's canonical name.
GET /v1/spec The current specification revision, what we check for, and how far the catalog has migrated.
GET /v1/catalog/stats Catalog counters and the drift base rate.
/v1/watches List, add, and remove the servers you monitor. Needs a key.

Two things in every response

How old the facts are.

Every reply carries as_of, the point at which all of our daily jobs had last succeeded, and stale when they have not run recently. We would rather tell you the data is old than quietly serve it as current.

The number that makes a count mean something.

Every per-server change count arrives with the catalog-wide drift rate beside it. Changes are heavily concentrated in servers nobody depends on, so "two changes in ninety days" tells you almost nothing until you know what a normal day looks like. This matters most when the reader is a language model, which will otherwise turn a bare number into a verdict we did not make.

Keys and limits

No key needed to read. A key raises the daily limit and is required for anything that touches your account. Create one on your dashboard.

CallerServers per day
Anonymous25
Signed in, free200
Any paid planUnmetered

The limit counts distinct servers, not requests. Checking the same servers all day costs one against your limit each, however often you ask, so watching your own dependencies never runs out.

Feed API

Everything above answers a question about one server you already know about. The Feed API is the other shape: a cursored, catalog-wide stream of every recorded event, plus the full snapshot history behind any server.

Built for the gateways, registries, and platforms rebuilding this dataset internally. Priced by contract rather than from this page, because the shape depends on what you are doing with it.

Email us about the feed

Clients

There is no Toolpin SDK, on purpose. Every read is a GET with one header, and /openapi.json describes every response, so a typed client in your language is one generator run away and will never be a version behind ours.

The one piece worth copying is the feed loop. Resume from the cursor, and check whether retention removed anything behind you:

let cursor = loadCursor();          // whatever you persisted last run

while (true) {
  const url = new URL("https://toolpin.dev/v1/feed/events");
  url.searchParams.set("limit", "500");
  if (cursor !== null) url.searchParams.set("cursor", String(cursor));

  const res = await fetch(url, { headers: { Authorization: `Bearer ${KEY}` } });
  if (res.status === 429) { await sleep(60_000); continue; }   // burst limit
  if (!res.ok) throw new Error(await res.text());

  const { data } = await res.json();

  // Retention is 180 days. If you were away longer, say so loudly rather than
  // resuming as though nothing was missed.
  if (data.retention.gap_before_cursor) {
    console.warn("gap: events were pruned between your cursor and", data.retention.oldest_event_id);
  }

  for (const event of data.events) handle(event);

  cursor = data.next_cursor;   // unchanged on an empty page, so this is safe
  saveCursor(cursor);
  if (!data.has_more) break;   // caught up; poll again later
}

What it will never return

No score, no grade, no rating, no safety judgment. Toolpin publishes what it observed and when it observed it, and the judgment stays with you. That is a deliberate limit on the product, not an omission. Read how we monitor for exactly what is measured and how.