Skip to main content
Explainer4 min read

MCP signature verification: the cryptographic floor for trusting servers

Unsigned MCP servers are the npm of 2026. Here is the emerging signature-verification standard, how Sigstore fits, and what to require before installing anything.

Right now, installing an MCP server is `npx -y` and a prayer. By 2027, signature verification will be table stakes — the same way HTTPS became table stakes for the web. Here is what is emerging and what to demand from publishers today.

Why MCP needs signing more than npm did

npm's reputation problem is well-known: typosquatting, dependency confusion, abandoned-package takeovers. MCP inherits all of that and adds new factors:

  • Higher blast radius. An MCP server runs as the user, with access to local files, env vars, and network egress. A backdoored server is closer to a compromised browser extension than a compromised library.
  • Less review surface. MCP servers are configured in JSON, often outside source control. Reviewers do not see them in PRs.
  • AI-driven install. A user can ask a model to "install the MCP server for X" and the model picks one. The friction that protects npm — read the README, check downloads — does not exist.

Signature verification is the only mechanism that scales to this threat model.

The pieces of a signing standard

Three layers, only the first of which exists today:

1. Artefact signing

The compiled or packed MCP server is signed with the publisher's key. Verification confirms: this binary is the one that publisher released.

Today: Sigstore (cosign) is the de-facto choice. Free, OIDC-backed identity, transparency log via Rekor.

# Sign a published Docker image
cosign sign --identity-token "$ID_TOKEN" registry/mcp-server-pg:1.4.2

# Verify before install
cosign verify \
  --certificate-identity 'https://github.com/acme/mcp-server-pg/.github/workflows/release.yml@refs/tags/v1.4.2' \
  --certificate-oidc-issuer https://token.actions.githubusercontent.com \
  registry/mcp-server-pg:1.4.2

2. Manifest signing

The MCP server's declared capabilities (tool list, schemas, resources) are signed separately. This catches the case where the binary is genuine but the runtime exposes more than the publisher claims.

Draft proposal: a manifest.sig file alongside manifest.json, signed with the same key as the artefact. Clients fetch both, verify, and refuse install if they disagree with the live tools/list output.

3. Behaviour attestation

Optional and harder: a record of what the server did in a controlled test run. Compares against runtime behaviour.

Today this is research. Sigstore's slsa-provenance plus a behaviour-trace is the closest practical approximation.

Reading a Sigstore signature in plain English

When cosign verify succeeds for an MCP server, it is saying:

  1. There is a signed entry in the public Rekor transparency log.
  2. The entry was signed by an OIDC identity (a GitHub Actions workflow, a corporate SSO).
  3. The workflow that produced this artefact is the one named in --certificate-identity.

That is enough to defeat: typosquatting (wrong identity), mid-supply-chain swap (binary hash mismatch), maintainer takeover where the attacker cannot also impersonate the build OIDC identity.

It is not enough to defeat: a malicious publisher who legitimately signs malware, a compromised build pipeline, or a vulnerable dependency pulled in at runtime.

What to require before installing

A practical bar today, even before the spec lands:

Tier Requirement When to relax
Untrusted Sigstore-signed by GitHub OIDC never for production
Trusted publisher Pinned version + signed manifest dev only
Internal Org-signed via SSO within zero-trust boundary

Your install tooling — Cursor MCP config, Claude Desktop config, custom installers — should refuse anything that does not meet the tier. See the install hygiene basics in install MCP for Claude Desktop.

Verify in CI

If you commit MCP configs to git (recommended), verify on every PR:

# CI step
for s in $(jq -r '.mcpServers | keys[]' claude_desktop_config.json); do
  pkg=$(jq -r --arg s "$s" '.mcpServers[$s].command + " " + (.mcpServers[$s].args | join(" "))' claude_desktop_config.json)
  cosign verify --certificate-identity-regexp "$ALLOWED" "$pkg" || exit 1
done

A failed verify blocks merge. Same as a failed signed-commit check.

Where the standard lands

The MCP working group has a draft for signatures in the server manifest, mirroring the OCI image-signing model. Expected to land in spec versions through 2026. Once it does, clients (Claude Desktop, Cursor) will surface unsigned servers in red, and corporate policies will flip default-deny.

Until then, lean on Sigstore and cosign — they work today, they will compose with whatever lands later, and they raise the bar from zero to "real attacker has to work."

Limits

Signing is necessary, not sufficient. A signed-but-evil server is still evil. Pair signature verification with:

Defence in depth. No single signature buys you safety.

Loadout

Build your AI agent loadout

Directory
Contact
© 2026 Loadout. Built on Angular 21 SSR.