Skip to content

The passmcp ecosystem

What exists, what each piece is for, and what is not yet released. Nothing on this page is aspirational unless it says so: a map that lists things which do not exist is worse than no map, because it costs a reader the trip.

The family

Every repository around passmcp, generated from internal/ecosystem so that this table and the manifest cannot disagree. make ecosystem-verify fails the build when they do.

Released

Repository Licence Lockstep What it owns
passmcp GPL-3.0-only yes The engine, every check, and the three peer surfaces: CLI, TUI and the embedded local web UI.
passmcp-reporting Apache-2.0 yes The attestation predicate, its JSON Schema and the offline verifier, as a module with no dependencies; the report schema, the renderers and the rubric as data follow when a consumer needs them.
passmcp-server GPL-3.0-only yes An MCP server exposing passmcp's diagnostics as read-only tools, so an agent can evaluate a server, or check an attestation about one, from inside the editor.
passmcp-action Apache-2.0 yes The GitHub Action wrapping the published image by digest, and a GitLab CI template.
passmcp-graph GPL-3.0-only yes A local graph of which agents use which MCP servers, which tools those servers expose and which identities reach them, built from passmcp's attestations, reports and MCP client configurations, queried offline and gated by policy in CI.
passmcp-registry AGPL-3.0-only AND CC-BY-4.0 yes The tooling for a signed public scorecard of the remote servers in the MCP Registry: each checked read-only and without credentials by a pinned passmcp release, every result an offline-verifiable attestation, and anything that would expose a vulnerability withheld for its owner first. No run has been published yet.
passmcp-lsp Apache-2.0 yes A language server over MCP artefacts — server.json, tool schemas, client configuration, passmcp policy and attestation files — with check-id hover from the guidance catalogue.
passmcp-census CC-BY-4.0 yes The reliability census of the MCP Registry's remote servers: the methodology, the disclosure log and the command that reproduces the figures. No edition has been published yet.
satellion.com GPL-3.0-only yes The public site at satellion.com, built with SSG against passmcp's latest release: the home page, the manual and a sample report passmcp generates.
passmcp-sdk-go Apache-2.0 yes MCP client and server SDK for Go covering revisions 2025-06-18 through 2026-07-28 (stdio and Streamable HTTP, OAuth 2.1 with PKCE, SEP-2164, SEP-2549, stateless server/discover, read-only defaults) and offline passmcp attestation verification.
passmcp-sdk-python Apache-2.0 yes MCP client and server SDK for Python covering revisions 2025-06-18 through 2026-07-28 (stdio and Streamable HTTP, OAuth 2.1 with PKCE, SEP-2164, SEP-2549, stateless server/discover, read-only defaults) and offline passmcp attestation verification.
passmcp-sdk-java Apache-2.0 yes MCP client and server SDK for Java covering revisions 2025-06-18 through 2026-07-28 (stdio and Streamable HTTP, OAuth 2.1 with PKCE, SEP-2164, SEP-2549, stateless server/discover, read-only defaults) and offline passmcp attestation verification.
passmcp-sdk-cpp Apache-2.0 yes MCP client and server SDK for C++20 covering revisions 2025-06-18 through 2026-07-28 (stdio and Streamable HTTP, OAuth 2.1 with PKCE, SEP-2164, SEP-2549, stateless server/discover, read-only defaults) and offline passmcp attestation verification.
passmcp-sdk-typescript Apache-2.0 yes MCP client and server SDK for TypeScript covering revisions 2025-06-18 through 2026-07-28 (stdio and Streamable HTTP, OAuth 2.1 with PKCE, SEP-2164, SEP-2549, stateless server/discover, read-only defaults) and offline passmcp attestation verification.
passmcp-sdk-rust Apache-2.0 yes MCP client and server SDK for Rust covering revisions 2025-06-18 through 2026-07-28 (stdio and Streamable HTTP, OAuth 2.1 with PKCE, SEP-2164, SEP-2549, stateless server/discover, read-only defaults) and offline passmcp attestation verification.

The ssg surfaces

Every web surface built here is generated by ssg from a theme in the SSG theme suite. That is an invariant, not a habit: make ssg-check fails the build when a page appears outside a layout, when a configuration stops matching this table, or when CI would install an ssg older than the theme requires.

Surface Theme Vendored from Layouts Output Embedded
web-shell passmcp e32f60c (min ssg 0.0.56) web/_layouts internal/web/dist yes

The layouts are vendored so the site builds in CI with nothing but the ssg binary. 9 file(s) deliberately differ from the theme, each with a recorded reason — a declared delta is a patch on its way upstream, and an undeclared one is a fork nobody decided to make. The list is in internal/ecosystem/sites.go.

Considered and rejected

Repository Why not
passmcp-gateway Fourteen incumbents, two of them free and open source, one of them AWS. Being in the data path would also convert passmcp from a tool that touches nothing into a production dependency trusted with traffic.
passmcp-wasm CORS blocks a browser build against most servers. A build target, not a repository.
passmcp-proxy The gateway again under another name: in the data path is in the data path whether it only watches or also rewrites (ADR 0007). A rewriting shield would also judge by classifier rather than cite the request that showed the property (ADR 0002). Live inspection is the official MCP Inspector's job.
passmcp-fuzz An adversarial mode in its own repository, which ADR 0008 rules out behind a flag and behind a verb alike: the read-only posture is what lets a security team approve passmcp. Resilience is already a phase of the check, and passmcp fuzzes its own parsers.

Decisions in that table that were once made the other way, recorded here rather than reversed quietly — a reversed decision with its history intact is worth more than a tidy page:

  • passmcp-server was previously reserved for the public site and hosted diagnostic. It is listed above as an MCP server instead, because a repository with that name containing no MCP server misleads everyone who finds it. The public site moved to its own repository, satellion.github.io, which serves satellion.com, on 26 Sep 2026. The drift that kept it here is closed from that side: its build reads the check count, score, ledger and evidence from the passmcp release it builds against and fails when the page disagrees. The embedded shell stays here, go:embeded, under the same count gate.
  • passmcp-lsp was considered and deliberately deferred, on the grounds that a language server is a large permanent surface with no demand behind it. That reasoning holds for a language server over MCP server source and not for one over MCP artefacts — server.json, tool schemas, client configuration, and passmcp's own policy and attestation files, where hovering a check id can return the guidance catalogue's remediation. It is listed above at that narrower scope.
  • passmcp-registry was once rejected as an index of MCP servers: contested by the official registry, the container catalogue and four directories, two of which already publish a score, with the advice to "supply the signal they display instead". The repository that now carries the name is that advice taken: not an index but a signed, per-server scorecard of the official registry's remote servers, each result an attestation anyone can verify offline. The objection to an index stands.
  • passmcp-lsp and passmcp-census were outside the lockstep. The census was held out because a census edition is not a build of the tool and binding it would force a no-op tool release every quarter; the language server because editor marketplaces keep their own cadence. The owner decided on 29 Sep 2026 that the whole family carries one version, including both: a reader should never have to ask which version of which piece they are looking at. The cost that argument named is accepted, as it already was for the site (see the version rule). Neither had been tagged, so on the same day the owner decided both skip 0.0.1 and first ship at the family's next version, 0.0.2: an untagged changelog section is not a release, and a member joining the lockstep joins at the family's version.
  • passmcp-graph and passmcp-registry have no recorded archive criterion. Every other satellite states when it should be archived; for these two the owner has not yet said, and their rows say so rather than carry a guess.

Today: three surfaces, one engine

Everything below ships from passmcp itself.

Surface Entry point What it is
CLI passmcp check The diagnostic as a command. Text, JSON, NDJSON, Markdown or HTML.
TUI passmcp tui The same run, driven interactively, for picking a tool and watching a phase.
Web passmcp serve The same run in a browser, on the operator's own machine.

The three are not three implementations. internal/engine owns a run: RunSpec carries the intent, Run executes it, a Sink receives events. Each surface builds a spec and presents the events.

That is enforced rather than intended. cmd/parity_test.go fails the build when a flag configures a run but carries no RunSpec field, because a capability reachable only through a flag is one the TUI and the web UI can never have. See ADR 0005 for how the hosted surface inherits the same guarantee.

Published artefacts

Every release produces the same set, from one tag.

Artefact Where Provenance
Binaries GitHub Releases SHA256SUMS, keyless cosign signature, SLSA provenance
Container image ghcr.io/sebastienrousseau/passmcp Multi-arch, cosign-signed, digest-addressable
SBOM Attached to each release CycloneDX, generated by Syft
Packages deb, rpm, AUR, Homebrew cask, Nix Built from the release archives — see pkg/

Verification instructions, including the cosign certificate identity, are in pkg/VERIFY.md. There is no KEYS.asc: signing is keyless, so there is no long-lived key to publish, and the thing to check is the workflow identity in the certificate rather than a key fingerprint.

The version rule

Every repository in the ecosystem always carries the same version.

This is a hard rule, not a convention, and it exists because ambiguity about which build of the tool is behind a hosted service is the expensive kind of ambiguity for a security diagnostic.

  1. One source. passmcp's tag is the only place a version is authored. Satellites never choose their own.
  2. Propagation is automated up to the tag. A release fires repository_dispatch at a satellite, which writes the version and pins the image by digest on its feat/vX.Y.Z branch. A person reviews and merges that pull request and pushes the signed tag.
  3. Drift is a red check. Each satellite carries a required Version Lockstep status check comparing its version to the latest published passmcp release. Disagreement blocks the merge.

The cost is real and accepted: a typo on the site cannot ship as a site-only patch. It bumps the whole ecosystem, including a passmcp release in which nothing changed. A no-op release is cheap and automated; not knowing what is deployed is not.

All three rules are in force. How each repository meets them differs, and is stated here as it is, not as it will be. passmcp-action and passmcp-server follow passmcp's release as rule 2 describes: the release fires repository_dispatch at them, and each one's sync workflow commits the version and the image digest onto its feat/vX.Y.Z branch, or opens sync/vX.Y.Z when that branch does not exist. It does not merge or tag; the owner does, after the pull request's checks are restarted (commits made with the workflow's own token start no workflows). Each one's Version Lockstep check refuses a version that is not passmcp's latest. passmcp-reporting runs the other way, because passmcp imports it: it tags first, so that passmcp's go.mod can name the version, and its lockstep check allows it to be exactly one release ahead of passmcp's latest and nothing else. It has no dispatch workflow: nothing in it reacts to passmcp's release.

The rule binds every repository in the family: every row above says yes in its Lockstep column, and internal/ecosystem refuses a row that does not. The dispatch in release.yml reaches the three repositories named above today. passmcp-graph, passmcp-registry, passmcp-lsp, passmcp-census and the website carry the version in their own CHANGELOG.md; the dispatch does not reach them yet, and adding them needs the dispatch token's scope widened to them, which is a repository setting rather than a change here.

Where to go next