Documentation

Install the gate. Or call the network.

The wedge is the in-path drift gate: one command pins every MCP tool’s contract and HOLDs a call the moment that contract silently changes, before your agent acts. No key, zero credential custody. Start at §3b — Install the gate.

The rest of this page documents the advisory directory the gate queries: an MCP-native API (free, no key, low-latency) that returns a verdict (REVIEW or UNVERIFIED today; ALLOW / DENY are reserved in the contract) on a tool and a recommendation endpoint for discovery — direct HTTP, drop-in MCP server, or embedded.

The shape

Five components in the request path; a refresh job keeps the catalog current.

01Agent clientWhere your agent runsCALLS02Discovery adapterClient-side bridge to the APICALLS03Recommendation APINatural-language task → ranked picksREADS04Ranking engineComposite scoring across signalsREADS05Indexed catalogThousands of MCP servers · refreshed daily06Refresh workerDaily catalog rebuild · integrity-gatedWRITES← UPSTREAM SOURCEREQUEST FLOW
Fig. 01 · Architecture, top-down. Request flow synchronous; refresh async, daily.

Top-down: a request originates in your agent client and passes through an adapter into the API. The trust path returns a verdict for a given tool (does it do what its description claims); the discovery path ranks an indexed catalog of MCP servers and returns picks with install commands. The catalog is rebuilt daily from an upstream source.

What you don’t need to care about as a caller: which storage layer backs the catalog, where the refresh worker runs, what compute hosts the API. The contracts are the verdict endpoint (trust) and the recommendation endpoint (discovery); everything else is internal.

Ways to use it

Pick the shape that matches where the agent lives.

A

Direct HTTP API

For server-side agents, custom orchestrators, anything outside an MCP client.

# trust: does this tool do what it claims? (per-server or per-tool)
curl "https://mcpindex.ai/api/v1/trust/server/<slug>"

# screen: paste a description, get a live verdict (POST)
curl -X POST "https://mcpindex.ai/api/v1/screen" \
  -H "content-type: application/json" \
  -d '{"description":"Reads a file and returns its contents."}'

# discovery: find a tool for a task
curl "https://mcpindex.ai/api/v1/recommend?task=read+pdf+to+s3"

# pre-flight: discovery + the rank-1 server's verdict in one call
curl "https://mcpindex.ai/api/v1/preflight?task=read+pdf+to+s3"

# search: full-text registry search (?q= required; &category= &limit= optional)
curl "https://mcpindex.ai/api/v1/search?q=postgres&limit=10"

# diff: what changed in the registry since a date
curl "https://mcpindex.ai/api/v1/diff?since=2026-06-01"

# server: the full record for one server by slug
curl "https://mcpindex.ai/api/v1/server/<slug>"

# fleet drift query: has this tool's contract drifted? (crawler-corroborated)
curl "https://mcpindex.ai/api/v1/drift/any?fp=<tool_fingerprint>"

# drift ledger: contract changes the crawler observed (fingerprint-only)
curl "https://mcpindex.ai/api/v1/ledger"

trust returns a stored verdict (REVIEW or UNVERIFIED today; ALLOW / DENY are reserved in the contract); screen runs the live LLM judge on a pasted description and returns a fresh PARTIAL verdict; recommend returns ranked picks; preflight composes the two - the top servers plus the rank-1 server's advisory verdict in one round trip (verdict is null when that server is not yet screened - treat as not-cleared); search and diff query the registry; server returns one full record; drift/any answers whether a tool's contract drifted (crawler-corroborated; powers warns-you-on-call-1) and ledger lists the public drift record. All JSON, same shapes an MCP client gets.

B

Drop-in MCP server

For Claude Desktop, Cursor, Cline, Zed. Install once, the agent finds the rest from inside the loop.

npm install -g mcp-server-mcpindex

The package is a thin client to the same API. Zero config in most clients - see the wiring step below.

C

Embedded in your platform

For platforms (Composio, Mastra, Toolhouse, IDE plays) that want MCP discovery as a feature.

// Server-side, your code:
const res = await fetch("https://mcpindex.ai/api/v1/recommend?task=" +
  encodeURIComponent(userTask));
const { recommendations } = await res.json();

Attribution appreciated. Email hello@mcpindex.ai if you want a higher rate limit.

D

Embeddable verdict badge

For READMEs and server listings - a live SVG that always agrees with the verdict page.

<!-- Markdown (GitHub-style; extension-less, keys off Content-Type) -->
[![mcpindex](https://mcpindex.ai/api/v1/badge/<slug>)](https://mcpindex.ai/server/<slug>)

The badge reads the same verdict the site pages and the trust API use, so the three never disagree. States are screened / flagged / review / re-check due, and a fail-closed gray not screened for an unknown slug - never green, never a fake pass, never a broken image.

Wire it to your client

The server is identical across clients. Only the config-file location and shape differ. Restart the client after editing.

Claude Desktop

~/Library/Application Support/Claude/claude_desktop_config.json

{
  "mcpServers": {
    "mcpindex": {
      "command": "npx",
      "args": ["-y", "mcp-server-mcpindex@latest"]
    }
  }
}

Cursor

.cursor/mcp.json (project) or ~/.cursor/mcp.json (global)

{
  "mcpServers": {
    "mcpindex": {
      "command": "npx",
      "args": ["-y", "mcp-server-mcpindex@latest"]
    }
  }
}

Cline (VS Code)

Cline settings panel → MCP Servers → Add

Command:  npx
Args:     -y mcp-server-mcpindex@latest

Zed

~/.config/zed/settings.json

{
  "context_servers": {
    "mcpindex": {
      "command": "npx",
      "args": ["-y", "mcp-server-mcpindex@latest"]
    }
  }
}

Once installed, the six tools are available in any agent loop: recommend_mcp_for_task, search_mcp_servers, get_install_command, compare_servers, check_tool_trust, assess_server. Ask your agent something like “find me an MCP server that can read PDFs and write to S3” and watch it call recommend_mcp_for_task automatically.

Install the gate

The directory tools above answer “which tool, and is it screened” before you wire it. The drift gate is the live, in-path check during use: it pins each MCP tool’s contract on first sight and HOLDs a call the moment that contract silently changes, before your agent acts. It is a contract-diff, not a safety verdict (see /methodology), and it never receives your credentials.

Install (Claude Desktop / Cursor / Cline / Zed)

The auditable path: install the package, then let the wizard rewrite your host config so each MCP server launches behind the gate. The curl | shone-liner does the same thing in one step — inspect it first if you prefer:

# auditable path — install the package, then run the wiring wizard
uv tool install mcpindex-preflight

# convenience: the same install + host-config rewrite in one command.
# inspect it before you run it — it only rewrites your MCP host config,
# and uninstall.sh restores it:
curl -fsSL https://mcpindex.ai/install.sh | less   # read it first
curl -fsSL https://mcpindex.ai/install.sh | sh     # then run it

# Windows (PowerShell): https://mcpindex.ai/install.ps1

Prefer to wire it by hand? Rewrite each MCP server entry so the agent launches that server behindthe gate: keep the server’s original command as the gate’s argument. The example below wraps a stdio server (before after); the same shape works in Cursor (.cursor/mcp.json) and Zed (~/.config/zed/settings.json). Restart the client after editing.

# claude_desktop_config.json — route an existing server through the gate

// before: the agent talks to the server directly
"filesystem": {
  "command": "npx",
  "args": ["-y", "@modelcontextprotocol/server-filesystem", "/data"]
}

// after: the gate launches the server and checks each tool's contract in-path.
// The original command becomes --upstream-command; each original arg becomes a
// separate --upstream-arg=VALUE (the =VALUE form is required — a dash-leading
// arg like -y does not survive a bare passthrough).
"filesystem": {
  "command": "uvx",
  "args": ["--from", "mcpindex-preflight", "python", "-m", "tooling.cse.proxy",
           "--mcpindex-stdio",
           "--upstream-command", "npx",
           "--upstream-arg=-y",
           "--upstream-arg=@modelcontextprotocol/server-filesystem",
           "--upstream-arg=/data"]
}

Easier: let the one-click installer write this for you — it rewrites every server entry, which is fiddly to do by hand. The gate forwards to your original server and checks the contract on every call. Zero credentials change hands: a stdio server’s original env and an http server’s original headersride through to your server untouched — the gate reads only the public tool contracts, never your tokens. The one-click installer (install.sh / install.ps1) does this rewrite for you across every detected host.

Remote / HTTP MCP servers

The example above wraps a stdio server. An http / url entry (a remote server like a hosted GitHub MCP) is routed through a local gateway instead: the gate rewrites the entry to point your client at a loopback gateway, and the gateway forwards to the upstream with your original headersthreaded through untouched — same zero-custody posture, just over HTTP.

One boundary to know: today the gateway gates only HTTPS upstreams that resolve to a public IP. A plain-http, localhost, or LAN upstream is rejected (ssrf_blocked), not silently passed through — gating those is on the roadmap. So a remote HTTPS server is gated like any stdio one; a local HTTP server is not yet covered.

SDK: wrap an already-authenticated session

For a server-side agent or custom orchestrator, wrap the MCP client session you already authenticated. One line; no per-server config, no token handling — the wrapper reuses the session’s own transport. list_tools / call_tool stay drop-in.

// TypeScript — npm i @mcp-index/sdk
import { wrap, PreflightPin } from "@mcp-index/sdk";

const guarded = wrap(session, { pin: new PreflightPin(), serverId: "your-server" });
// use guarded.list_tools() / guarded.call_tool(...) exactly as before

# Python
from tooling.cse.preflight_intercept import wrap
from tooling.cse.preflight import PreflightPin

session = wrap(session, pin=PreflightPin(), server_id="your-server")

Pass PreflightPin(path=…) to persist the baseline across restarts (so drift while the agent is offline is still caught on the next call). On a hold the wrapper raises (or calls your on_hold handler) with the structured verdict; the wrapped session is never called on a hold.

Postures and what a HOLD does

  • Monitor— notify and proceed (awareness, no friction).
  • Guard(default) — hold the unambiguously breaking and dangerous changes; auto-accept a proven-benign drift (added optional param, byte-identical description) and re-pin so cosmetic churn never raises a false alarm.
  • Strict— hold on any drift.

A HOLD stops the call before your agent acts and surfaces what changed (the exact ChangeKind, the before/after on a description change). It is fail-closed: a tool the gate cannot verify holds rather than proceeds. You review, then re-pin if the change is expected. On an ambiguous change, the third-door behavioral verifier — a built in-path seam that is held off by default and requires explicit opt-in — can exercise the changed tool to clear or refute the change. It clears or refutes; it does not prove a tool safe.

Blast-radius grade (on by default)

Alongside the contract-diff, the gate labels what each call would do before your agent acts — action_type (read, write, delete, send), whether it can be undone (reversibility), and whether it leaves the machine (egress) — plus a static autonomy ceiling. A read and an irreversible delete look identical to an agent until something labels them; this is that label. It is on by default in @mcp-index/sdk and mcpindex-preflight.

The grade is read statically from the tool’s declared contract — it never runs the tool — so it is deterministic, needs no network, and carries no argument values (every field is a typed enum or hash). It is advisory and fail-closed: when the contract is ambiguous it grades toward the more dangerous class. It says what a call would do, not whether the contract is safe; your orchestrator owns whether to allow, pause, or require approval.

Ambient presence (on by default)

The clients leave a quiet trace that mcpindex is working: the first time each tool is used in a session, one dim line on stderr mcpindex · noted github/delete_repo — delete, irreversible— then silence on every repeat call, plus a one-line session summary. It is local-only: no network, nothing persisted, and it never touches stdout or changes a gate decision.

The first line shows how to turn it off (silence: MCPINDEX_AMBIENT_NOTICE=off); the cadence tunes via MCPINDEX_AMBIENT_NOTICE_MODE (first_touch / summary / every / off), and it stays quiet in CI and under DO_NOT_TRACK. To render it in your own UI instead, pass an on_invocation callback (Python) / onInvocation (TS) to wrap().

Drift network (opt-in, off by default)

mcpindex crawls the public MCP registry every day and records which tool contracts silently change. Turn the network on with MCPINDEX_DRIFT_TELEMETRY=detection(off by default) and the gate asks it, on each pin, whether the crawler already caught this contract drifting — warning you on the first call. A contract-diff advisory: it rides alongside the verdict and never moves PROCEED or HOLD. Surfaced by renderVerdict and the fleetAdvisory field on the verdict.

Under the same flag the gate emits one one-way salted-fingerprint signal on a pin or a drift and queries /api/v1/drift/any; it never sends a schema, argument, description, URL, or server/tool name, and fails open (never blocks a call). Every drift the crawler catches is public in the /ledger. Full disclosure on privacy.

Anatomy of a response

The trust endpoints (/api/v1/trust/server/… and /api/v1/trust/tool/…) return the free-tier verdict: a decision (ALLOW / DENY / REVIEW, or UNVERIFIED when a tool has not been screened), the dimensions behind it with severity, the screen granularity (description-level today, tool-level for a few), a freshness window, and the honest limits shipped on every verdict. See one rendered on a server page or in the methodology.

{
  "verdict_contract_version": "1.0.0",
  "subject": { "server_id": "community/quickpay-mcp", "tool_name": null },
  "status": "PARTIAL",              // EVALUATED | PARTIAL | STALE | ERROR
  "directive": "REVIEW",            // ALLOW | DENY | REVIEW
  "granularity": "description-level",   // what was screened: "description-level" | "tool-level"
  "dimensions": [
    { "id": "mcpindex.integrity.description", "verdict": "PASS", "severity": "INFO" }
  ],
  "expires_at": "2026-06-07T00:00:00Z",   // re-screen after this; trust decays
  "honest_limits": [
    "conformance_monitored_not_enforced",
    "calibrated_false_v1",
    "advisory_deployment"
  ]
}

A server that has not been screened returns the same shape, fail-closed: status: "ERROR", directive: "UNVERIFIED", empty dimensions, and an added no_verdict_data_in_v1_advisory honest limit. An agent must treat UNVERIFIED as fail-closed - never as permission to proceed.

At v1 the screen produces only REVIEW (a semantic-only read) or UNVERIFIED (not yet on file). ALLOW and DENY are in the contract and the response shape, but a real ALLOW requires the behavioral conformance probe, which is gated to the D3 labeled-corpus milestone and has not run on the public corpus yet. Treat the example above as the illustrative shape, not the common case today.

The recommendation endpoint (discovery) returns a tight JSON envelope. Three picks ranked by composite score, each with reasoning, install commands per registry type, and the live MCP Quality Score.

{
  "task": "read pdf and save to s3",
  "recommendations": [
    {
      "rank": 1,                                  // composite-rank position (1-3)
      "slug": "io-github-foo-pdf-mcp",            // url-safe ident, used in the per-server page
      "name": "io.github.foo/pdf-mcp",            // canonical registry name
      "title": "PDF Tools MCP Server",            // display name
      "description": "Generate PDF from HTML…",   // one-line description from the registry
      "category": "docs",                         // inferred category (28 total)
      "qualityScore": 95,                         // 0-100, see /methodology
      "reasoning": "Matches \"pdf\" in docs-category server.",  // why it ranked
      "installs": {
        "npm": "@foo/pdf-mcp",                    // present if registry has an npm package
        "pypi": null,
        "docker": null,
        "remote": null                            // present if registry has a remote URL
      },
      "url": "https://mcpindex.ai/server/io-github-foo-pdf-mcp"
    },
    /* … 2 more ranked picks … */
  ],
  "note": "v0 ranker - heuristic score blends keyword match (70%) with MCP Quality Score (30%). See /methodology."
}

Limits + API guarantees

  • Rate

    60 requests / minute / IP across /api/v1/* on the free tier. The live screen endpoint (/api/v1/screen) is tighter - 10 / minute / IP plus a global daily ceiling, since each call runs an LLM. No key required. 429 with Retry-After when exceeded. Email hello@mcpindex.ai for higher limits or for a Pro key.

  • Schema stability

    /api/v1/* is versioned. Breaking changes ship behind /api/v2; v1 stays available for at least 6 months after v2 lands. Field additions are not breaking and ship to v1.

  • Cache

    Responses are cached at the edge with stale-while-revalidate fallback. Repeat queries within minutes are essentially free; the first call after a cache miss adds modest latency.

  • Fallback

    If the API is unreachable, fall back to /llms.txt and /llms-full.txt for static reference data. The MCP server package surfaces a clear error to the agent rather than fabricating results.

  • Data freshness

    Catalog rebuilt nightly. Integrity checks reject obviously partial refreshes before they go live. Worst-case staleness: 24 hours.

  • Authentication

    None on free tier - public endpoints. CORS open. The Pro tier uses bearer tokens for higher limits and multi-tenant/enterprise use; existing free endpoints stay open.

How this compares

Five common ways an agent (or developer) finds an MCP server today. mcpindex.ai is the only one that hits all four traits an agent at inference time actually needs.

MethodAgent-callableRanked picksInstall-readyStays current
mcpindex.ai
recommendation API + drop-in MCP server
yes
yes
composite score
yes
per-client config
daily
Anthropic official registry
registry.modelcontextprotocol.io
yes
raw HTTP
no
paginated list
partial
in payload
live
Human directories
PulseMCP · Smithery · Glama · MCP.so
no
browsing UX
partial
hand-curated
partial
daily
awesome-mcp-servers (GitHub)
punkpeye/awesome-mcp-servers
no
no
flat list
varies
weekly
PR-driven
Ask the LLM directly
e.g. "Claude, what MCP servers exist for X?"
yes
no
hallucination-prone
no
training cutoff

The honest framing: the table above is the discovery axis. mcpindex.ai sits on top of the Anthropic registry for discovery, not as a replacement; the registry is the canonical source of truth. The reason mcpindex exists is the second axis these tools don’t have at all: a trust verdict on whether a tool does what it claims, before your agent acts on it.

Footnote on “ranked picks”: the registry returns servers in publication order; PulseMCP and Smithery offer hand-curated featured collections but no programmatic per-task ranking. mcpindex.ai computes a composite score (search match × MCP Quality Score) per request - see /methodology for the algorithm.

Where to next

Found a gap, a typo, or a wiring question that isn’t answered here? hello@mcpindex.ai.