Skip to content

The passmcp ecosystem

What exists, what each piece is for, and what is only planned. 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.

Shipping

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.
satellion.com GPL-3.0-only no 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-action Apache-2.0 yes The GitHub Action wrapping the published image by digest, and a GitLab CI template.

Planned

These do not exist yet. They are recorded so the layout cannot drift silently once they do, and so nobody goes looking for them. Every row states the boundary that forces a separate repository and the criterion for archiving it.

passmcp-lsp

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.

  • Licence Apache-2.0 · go · Lockstep no
  • Why separate Editor embedding. It ships inside editors and extension marketplaces whose licensing and release cadence are not passmcp's; the extensions live in its own editors/ directory rather than a repository each.
  • Archive when The guidance hover goes unused. Scoped so that cutting it costs one repository and no capability.

passmcp-census

The published reliability census: the dataset, the methodology, the disclosure log and the reproduction command.

  • Licence CC-BY-4.0 · data · Lockstep no
  • Why separate Licence and cadence. A GPL repository cannot cleanly carry a CC-BY dataset, and a quarterly data release has no business sharing a version with a fortnightly tool release.
  • Archive when The census is not repeated on schedule. Delete it rather than leave a stale dataset presented as current.

The ssg surfaces

Both web surfaces are 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-registry Contested by the official registry, the container catalogue and four directories, two of which already publish a score. Supply the signal they display instead.
passmcp-wasm CORS blocks a browser build against most servers. A build target, not a repository.

Two names in that table are still open questions, recorded here rather than settled quietly:

  • 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.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. The original objection is kept because a reversed decision with its history intact is worth more than a tidy page.

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 automatic. A release fires repository_dispatch at each satellite, which writes the version, pins the image by digest, tags itself and deploys.
  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: the first satellites exist. Two facts about them are worth stating. passmcp-action and passmcp-server follow passmcp's release exactly as rule 2 describes: the release fires repository_dispatch at them, each pins the new image by digest, and 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. The dispatch reaches it too, as the signal that the release it tagged for has shipped.

The rule binds every repository whose Lockstep column says yes. Two rows are deliberately outside it. passmcp-census publishes a dataset, and a census edition is not a build of the tool — binding them would force a no-op tool release every quarter. passmcp-lsp follows editor and marketplace cadences that are not this project's. Anything that embeds or reports a passmcp version stays in lockstep, because that is the ambiguity the rule exists to remove.

Where to go next