Supply Chain Security for MCP Servers: SDK Pinning, SBOMs, and the Servers You Did Not Write

Security reviewers have started asking a question that MCP writing mostly ignores: what code is actually running inside your MCP server, and who wrote it. The authorization specification tells you how to validate a token. It says nothing about the forty transitive dependencies that parse the request before your handler sees it, the SDK release you upgraded last Thursday, or the third-party server your gateway now fronts. Those are supply chain questions, and they arrive in the same questionnaire as the OAuth ones.

This is the part of an MCP server that is ordinary software supply chain work, plus three things that are specific to MCP. We will take the ordinary part quickly and spend the time on the specific part.

The ordinary part, stated once

An MCP server is a networked service holding access tokens and reaching into customer data. The baseline is the baseline:

  • A committed lockfile, with builds that fail if the lockfile and manifest disagree.
  • Pinned base images by digest, not by tag.
  • Dependency and image scanning on every build, with a named owner for the output.
  • A CI pipeline that authenticates to your cloud with short-lived federated credentials (OIDC) rather than a stored long-lived key.
  • Signed build artifacts and a recorded provenance attestation, so the image running in production can be traced to a commit.
  • An SBOM generated at build time, in CycloneDX or SPDX, kept for the versions you have deployed.

None of this is novel and none of it is optional once an enterprise reviewer is involved. The SBOM in particular has moved from nice-to-have to requested-by-name, and generating it after the fact for a release you shipped four months ago is unpleasant. Generate it in the pipeline and store it with the release.

Specific part one: the SDK is a spec decision

The MCP SDKs are not passive plumbing. They implement transport framing, session handling, capability negotiation, and in several languages parts of the authorization flow, including metadata discovery and token validation helpers. A minor SDK bump can therefore change security-relevant behavior: which endpoints exist, what an unauthenticated request receives, how a session identifier is generated, whether a new protocol revision is accepted.

Treat SDK upgrades as a reviewed change, not a routine dependency bump:

  • Pin the SDK exactly, and exclude it from automated merge of patch updates.
  • Read the release notes for changes to the protocol revision supported, the authorization helpers, and session handling.
  • Re-run the authorization tests you already have: missing token, wrong audience, expired token, token for another resource, unknown protocol revision.
  • Record the SDK version and the protocol revision your server advertises in the evidence pack. Reviewers ask which revision you implement, and the honest answer comes from the code, not the roadmap.

If a helper in the SDK is doing your token validation, you own its behavior anyway. Read it once. Know whether it checks aud, whether it checks issuer, and what it does with a token it cannot parse. If it is permissive by default, wrap it.

Specific part two: the servers you did not write

Two situations bring foreign code into your perimeter.

The first is a gateway or governed platform fronting several MCP servers, some built by other teams and some pulled in from outside. From your customer's point of view, the gateway is the vendor. Every server behind it inherits your name in the audit log. A server nobody owns, running an unpinned image, with tools that were added last week by someone who has left, is a finding waiting to happen.

The second is installing a published server from a package registry or from the MCP registry ecosystem because it saves a sprint. The risk is not exotic. It is the familiar registry risk: names that resemble a well-known vendor's, a publisher identity that is asserted rather than verified, a version that installs one thing today and another thing tomorrow, and a postinstall script running in your build.

What holds up in review:

  • An inventory. Every MCP server your platform exposes, with an owner, a source repository, a version, and the date of its last security review. If you cannot produce this table, that is the first deliverable.
  • Verified origin, not asserted origin. Prefer servers whose repository you can read and whose releases are signed. Where the registry offers namespace verification tied to a domain or an organization, require it. Treat an unverified publisher claiming to be a large vendor as what it is.
  • Vendoring for anything in the request path. Fork or vendor a pinned version rather than resolving latest at deploy time.
  • No credential handoff by default. A third-party server does not get your IdP tokens because it asked. Downstream identity travels by token exchange (RFC 8693) to an audience you configured, with scopes you chose. See our note on carrying user identity downstream.
  • Network containment. Egress allowlists per server, so a component that starts calling an address you never configured fails loudly instead of quietly succeeding.

Specific part three: tool definitions travel too

In an aggregating platform, the tool list your users see is assembled from the upstream servers at runtime. That makes tool definitions a distribution channel. An upstream server can change a tool description after approval, and a description is read by the model. A changed description is a changed instruction.

The control is boring and effective: snapshot the tool set of every upstream server, compare on every refresh, and fail closed on a mismatch until a human approves the new set. Log the comparison result as an audit event. We covered the mechanics for a server you own in tool definition integrity; for a server you do not own, the same snapshot is the only thing standing between an upstream edit and your users.

Vulnerability response is part of the answer

Questionnaires ask two things about vulnerabilities: how you find out, and how fast you fix. Have real answers.

  • A named intake path for reports, published where a researcher will find it, monitored by a person.
  • Dependency alerts routed to a team, not to a dashboard nobody opens.
  • A stated remediation target by severity, that you have actually met at least once.
  • A way to tell affected customers, which requires knowing which customers run which version.

State targets you can meet. A committed patch window you miss is worse in a second review than a longer one you hit.

What to put in the evidence pack

Four artifacts answer most of this before anyone asks:

  1. A dependency and provenance page: lockfile policy, scanning tools, signing, and where the SBOM lives.
  2. The SDK and protocol revision table, one row per deployed component.
  3. The MCP server inventory, if you run more than one, with owners and review dates.
  4. The vulnerability intake and remediation policy, with the severity targets.

Scope note

If you run a single MCP server you wrote yourself, from one repository, with a lockfile and scanning, the middle sections do not apply yet. Do not build a platform inventory for one server. The parts that still matter are the SDK pinning discipline and the vulnerability intake path, because both cost an afternoon and both get asked about.

If you do run several servers, or front servers other teams built, the inventory is the load-bearing artifact. We build it as part of a governed MCP platform and we check for it during an MCP security audit. If you are not sure how many MCP servers your organization is exposing, that is a short conversation: get in touch.