Skip to main content

mcpindex-gate

The in-path drift gate for agent tool calls — the open-core client of mcpindex.ai, the drift-monitored MCP server index. It runs on your host with zero egress and checks every MCP tool definition against your own pinned baseline before a call goes out.

Renamed: previously published as mcpindex-preflight. That name remains a deprecated alias that depends on this package. New installs should use mcpindex-gate.

What it does

mcpindex-gate produces a drift decisionPROCEED / HOLD / INCONCLUSIVE — by diffing the live tool contract against the contract you pinned. If a server silently changes a tool's schema, description, or surface, the gate can HOLD the call and surface why.

from mcpindex_gate import wrap, PreflightPin, PreflightHold

session = wrap(your_mcp_client_session, pin=PreflightPin(path="~/.mcpindex/pin.json"))

try:
    result = await session.call_tool("transfer_funds", {...})
except PreflightHold as hold:
    # The tool contract drifted from your pin — inspect `hold` and decide.
    print(hold)

wrap() accepts any duck-typed client session; this package does not depend on the mcp SDK.

What it is — and is not

  • It is a contract diff, not a safety oracle. It detects that a tool changed; it does not judge whether the change is malicious.
  • A HOLD means "this drifted from your pin — look before you act." It is advisory. It does not block attacks, guarantee safety, or make a server tamper-proof.
  • It mints no clearance verdict. The offline client can detect drift and HOLD; it can never publish a "SAFE" verdict.

What status tells you (0.11.0)

mcpindex-config-wire status reports enforcement, not merely that our proxy is in the launch line:

  • [x] requires that nothing is un-wired, unreadable, or non-enforcing. Before 0.11.0 the mark appeared as soon as one server was wired and could never turn off.
  • [!] means real coverage gaps, and names them by host.
  • notify-only counts servers launched with --posture monitor, which never blocks. It is a legitimate choice, but it is not protection, so it is never counted as such.
  • hosts scanned: N is stated because project-scoped configs (a repo's own .mcp.json, .cursor/mcp.json, .vscode/mcp.json, …) are not scanned yet. The total is a floor, not a census.

If the gate HOLDs on your baseline

A HOLD whose reason names the baseline rather than a tool contract means the pin store for that server was present but unreadable, or was deleted after having been pinned. The gate refuses to proceed rather than silently re-learning the contract from whatever the server is serving right now. This holds in every posture and regardless of fail_open, because neither is consent to trust a baseline that may have been rewritten.

To recover deliberately, delete that server's file under ~/.mcpindex/pins/ and restart the host. That re-pins from the current contract — a fresh trust-on-first-use — so do it only when you know why the store was unreadable (an interrupted write, a restored backup, a machine migration).

Honest limit: this is tamper-evident, never tamper-proof. A process running as you that replaces the store with a well-formed one carrying its own baseline is still trusted. No same-user control prevents that: any secret the gate can read, a process running as you can read too.

Install

uv tool install mcpindex-gate

One-click host wiring + a resident auto-onboard watcher are available via the installer at https://mcpindex.ai/install.sh.

Call receipts (on by default)

After each gated call the gate emits a compact, credential-blind receipt: a hash of the tool identity, the gate verdict, and the action class (read / write / execute). It never includes tool arguments, result content, server names, or URLs. Receipts are linked by a random per-install token stored in ~/.mcpindex/install_id -- pseudonymous, not derived from you or your machine. Keyless installs have no account link; if you sign in on mcpindex.ai and configure an api_key, receipts from that install are associated with your key.

From gate v0.9.0, the first run on a machine prints a one-line disclosure of exactly this behavior to stderr and sends nothing that session -- emission starts on run 2, so no receipt ever leaves before the notice and the opt-out were visible. Earlier versions emit without the runtime notice, per this README.

After 10 gated calls the ambient notifier fires a one-line message on stderr:

mcpindex - 10 tool calls noted - mcpindex.ai/receipts?id=<your-install-id>

That link shows your per-install call log. To suppress receipt egress entirely:

export MCPINDEX_RECEIPT_INGEST_ENABLED=0

Weekly summary line (local, zero egress)

At most once per ISO week the gate prints one line summarizing what it did last week -- calls gated, tools and servers watched, drift seen, holds issued:

mcpindex · week 2026-W29: 240 call(s) gated across 12 tool(s) / 3 server(s), 0 drift - your baseline is holding · mcpindex.ai/receipts?id=<your-install-id>

The counters live only in ~/.mcpindex/weekly_stats.json; nothing about this line is sent anywhere. To silence it:

export MCPINDEX_WEEKLY_SUMMARY=0

Drift telemetry (opt-in, OFF by default)

The gate can report that a tool's contract drifted — so mcpindex can track drift on servers it can't crawl itself (private / auth-gated). It is off by default and sends nothing unless you turn it on:

export MCPINDEX_DRIFT_TELEMETRY=detection   # off (default) | detection | contribute

When enabled, each tool you pin and each contract drift sends one one-way signal. See https://mcpindex.ai/privacy and https://mcpindex.ai/docs.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distributions

No source distribution files available for this release.See tutorial on generating distribution archives.

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

mcpindex_gate-0.11.1-py3-none-any.whl (521.4 kB view details)

Uploaded Python 3

File details

Details for the file mcpindex_gate-0.11.1-py3-none-any.whl.

File metadata

  • Download URL: mcpindex_gate-0.11.1-py3-none-any.whl
  • Upload date:
  • Size: 521.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for mcpindex_gate-0.11.1-py3-none-any.whl
Algorithm Hash digest
SHA256 f9c9c2f331ad4c7fc87f6156afd761aec9ab8f9a74cf8f2e30beebb465014abc
MD5 89eff3ec33e0f5bac58a5ca411a69005
BLAKE2b-256 f4d018e5942dde4f3a717358db4037fc9bdc738ac17286f95422061558f34e69

See more details on using hashes here.

Provenance

The following attestation bundles were made for mcpindex_gate-0.11.1-py3-none-any.whl:

Publisher: release-preflight.yml on mcpindex-ai/mcpindex-trust

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

0.14.0

1 file

0.13.5

1 file

0.13.4

1 file

0.13.3

1 file

0.13.2

1 file

0.13.1

1 file

0.13.0

1 file

0.12.2

1 file

0.12.1

1 file

0.12.0

1 file

0.11.2

1 file

This release

0.11.1 This release

1 file

0.11.0

1 file

0.10.0

1 file

0.9.2

1 file

0.9.1

1 file

0.9.0

1 file

0.8.0

1 file

0.7.0

1 file

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page