MCP distribution qualification
This is the 0.4.5 pre-release contract for
io.github.Alien6-Studio/outerspace-apizr, supplied by outerspace-apizr-mcp.
It covers the official plugin, not generated business servers. Tracking is
#279: the originally
requested number #270 was already occupied by an unrelated merged pull request.
Phase A qualifies local metadata, configuration and distribution mechanisms.
Phase B remains pending separate release authorization and actual external evidence.
Neither a local check nor a prepared bundle means an index has accepted 0.4.5.
Users start at Registry installation. All three explicit inputs remain required, with no defaults: a selected project, reviewed source-analysis grant and installed/activated plugin store. No registry, bundle, schema or ExposurePolicy grants runtime authority.
Current sources and decisions
Inspected 2026-10-11. Ordinary CI consumes the retained schemas in
tests/fixtures/mcp_distribution, verifies their origin hashes and makes no
directory requests. Remote documentation is not a test dependency.
| Primary source | Revision/version inspected | Requirement used |
|---|---|---|
| Official server.json, changelog | Registry 970df037919faa70456dde08c295473002d850e5; published schema 2025-12-11 |
Keep the accepted published schema; do not adopt the unreleased draft. Validate the full descriptor offline. |
| Additional registry requirements, PyPI ownership | Same registry revision | Public PyPI identity, exact namespace and README ownership marker; no alternate package registry. |
| Publisher, validate implementation | v1.8.1 |
Keep the pinned publisher/checksum and GitHub OIDC. validate is non-publishing but calls the registry API; it is not an offline CI step. |
| MCP tools 2025-11-25, 2026-07-28 | Locked Python SDK 2.3.0, both qualified protocols |
Use canonical Tool.title; retain typed schemas and existing annotations. The installed client verifies both modes/protocols. |
| Glama schema, ownership metadata, read API | JSON Schema draft-07; API 1.0.0 |
Keep the existing maintainer-only glama.json. Directory reads need a key. No invented fields or automatic ownership-claim/re-index action. |
| Smithery publication, stdio publication API, download API | API 1.0.0 |
Local stdio publication uses an MCPB upload. There is no documented guarantee of automatic Official Registry ingestion. Prepare a bundle; do not add legacy smithery.yaml. |
| MCPB manifest | 70fe3b34cd6dff1b3bba046638edc72a6467a4fb, manifest 0.4 |
Standard uv runtime with pinned package, explicit user configuration and a delegating entry point. Host support and actual Smithery acceptance must be confirmed in Phase B. |
| MCPfinder | abcdab08862535ab84673edb241209c714a5b748 |
Secondary union of Official Registry, Glama and Smithery. Use its documented digest-bound snapshot; the former HTTP MCP endpoint is deprecated. |
| Is It Trust-Ready? rubric, machine-readable rubric | 0.6.2 |
Apply the ten MCP-axis criteria below. No fabricated score or third-party pass. |
Six-tool review
All descriptions explain purpose and use; the existing delivery descriptions also
identify effects and retry limitations and need no expansion. #268/#269 analysis
descriptions, examples and initialization instructions are retained. Only the
previously undocumented delivery manifest pin gains a field description; its
nested Digest.algorithm and Digest.value were already documented.
| Stable name | Human title | Input contract | Output | Hints: read-only / destructive / idempotent / open-world |
|---|---|---|---|---|
apizr_analyze |
Analyze Python Project | Strict described views/pin | Analysis union | true / false / true / false |
apizr_readiness |
Assess Repository Readiness | Strict described views/pin | Readiness union | true / false / true / false |
apizr_plan_exposure |
Plan Capability Exposure | Strict described policy/pin/paging | ExposurePlan | true / false / true / false |
apizr_delivery_status |
Inspect Delivery Status | Explicit empty object, unknown fields forbidden | BatchResult | true / false / true / false |
apizr_delivery_run |
Run Approved Delivery | Strict described manifest digest object | BatchResult | false / false / false / true |
apizr_delivery_resume |
Resume Approved Delivery | Strict described manifest digest object | BatchResult | false / false / false / true |
Status only reads retained local evidence. Run/resume can write local evidence and remote images/proofs under captured per-operation authority. Their current operations perform no remote deletion or rollback and refuse conflicting observed image identities; registry preflight is not an immutable-tag or compare-and-swap guarantee. Non-idempotent/open-world hints preserve that distinction. Hints are presentation information, never authorization controls.
MCP trust-readiness alignment
Each row is a local assessment, not a claim that an external scanner ran.
Criterion (mcp.cap.*) |
Applicable | Apizr evidence | Test/proof | Remaining external dependency |
|---|---|---|---|---|
tool-descriptions |
Yes, all six | Fixed purpose/use/effect descriptions | mcp_tool_metadata.review, #269 guidance checks |
Directory re-indexing |
param-descriptions |
Yes; status has no parameters | Every input property, including nested digest/policy/view types, described | Recursive live schema review | Directory schema refresh |
output-schemas |
Yes, all six | Canonical output schemas; business failure remains distinct from MCP failure | Actual SDK results validated against advertised schemas | Directory visibility of schemas |
typed-bodies |
Yes | Strict objects and unknown-field rejection; status deliberately takes {} |
Schema and invalid-argument tests | None locally |
titles |
Yes, all six | Standard Tool.title |
Both protocols, both initialization modes, installed wheels | Client/index title support |
annotations-present |
Yes | All four hints present | Live SDK assertions | Directory refresh |
annotations-justified |
Yes | Static analysis; local status; effectful delivery | Existing non-mutation, admission, lifecycle and delivery proofs | None locally |
server-metadata |
Yes | Stable machine name, human title/version/instructions; registry description/homepage/existing icon | SDK discovery, descriptor/schema/package checks | Released descriptor and icon accessibility |
naming |
Yes | Existing consistent apizr_* snake_case |
Exact six-name contract | No vendor-driven rename |
config-ux |
Yes | Three described, required file inputs and documented acquisition | Document-derived new-user fixture and installed registry launch | Actual directory configuration UI |
The rubric's generic “empty properties” heuristic is inapplicable to the
intentionally argument-free status tool: {} with additionalProperties: false
is an exact typed contract. Security-sensitive configuration has no safe default.
Website/domain signing, hosted OAuth and remote server-card checks are outside
this local stdio MCP-axis qualification; no hosted service is invented to score them.
Offline evidence and compatibility
scripts/mcp_schema_proof.py and scripts/mcp_delivery_local_proof.py retain real
SDK discovery and successful structured responses, including valid limited/failed
business outcomes. The #268/#269 fingerprints still constrain schemas, outputs,
errors and annotations. The compatibility projection removes only the six new
tool titles, the human server title and the two delivery pin descriptions. Modern
SDK response metadata may also carry that server title; business content and
digests remain unchanged. Hostile project/result prose cannot change any trusted
metadata. Full raw captures remain in the existing native MCP CI artifacts.
scripts/mcp_registry_proof.py launches uvx with committed descriptor arguments,
candidate wheels outside checkout and no package-index access. Its new-user input
fixture comes from this guide's marked examples, not implementation internals.
It verifies both protocols, titles/annotations, live output schemas, and refused
missing/invalid project, policy and store inputs. The MCPB wrapper undergoes the
same offline installed launch. It cannot enable delivery or bypass plugin admission.
Its runtime is first installed from the unchanged bundle pyproject.toml using
only that target's retained wheels; UV_NO_SYNC=1 then prevents universal
re-resolution across unavailable Python/platform wheels during the offline launch.
The public bundle keeps normal uv run dependency preparation. Its declared
resolution environments match its macOS/Linux support, using the documented
uv project setting
(inspected 2026-10-11, qualification uv 0.12.0). Real directory-host installation
remains a separate Phase B check.
Build the deterministic local bundle without submission:
uv run --locked python scripts/build_mcp_bundle.py --output /tmp/outerspace-apizr-0.4.5.mcpb
This is a separate launcher wrapper, not a new Python publication or a substitute for the governed plugin store. No wheel/sdist version or dependency lock changes.
External verification after authorization
Use the qualified candidate manifest and installed analysis discovery capture:
uv run --locked python scripts/verify_mcp_distribution.py \
--source-sha <QUALIFIED_RELEASE_SHA> \
--candidate <RELEASE_CANDIDATE_DIRECTORY>/candidate.json \
--discovery <MCP_PROOF_DIRECTORY>/discovery-auto.json \
--output /tmp/mcp-distribution.json
This default performs no network access; providers are not_checked.
After release, add --live, optionally --include-mcpfinder,
--smithery-name <NAMESPACE/SERVER> and
--smithery-bundle <QUALIFIED_MCPB_FILE>. The name must be the stable name actually
chosen during authorized Smithery publication, never a guessed temporary ID.
--require-complete exits nonzero while any proof is incomplete. The tool never
publishes, claims ownership, scans a project or triggers indexing.
States distinguish verified, stale, missing, mismatch, not_checked,
authentication_required and temporarily_unavailable. Every non-verified state
also reports verification: not_verified. A timeout, authentication failure,
unsupported response or malformed payload is never reported as absence or success.
No polling loop is needed: maintainers may rerun this explicit read-only step as
propagation progresses, retaining each timestamped report.
- PyPI: require both core and MCP 0.4.5, the exact qualified wheel/sdist hashes, non-yanked files and the MCP namespace marker. Package version alone is insufficient.
- Official Registry: require the exact active name/version, repository, PyPI package, stdio transport and released configuration/metadata. Differences fail distribution qualification.
- Glama: directory reads use
GLAMA_API_KEY. The current API exposes names, descriptions and input schemas, but not titles, output schemas, initialization or package/version. Compare available fields, then review the public schema page for additional exposed fields and retain dated evidence. API-only verification cannot establish a complete 0.4.5 pass. Missing credentials stay unverified. Reports using its data credit and link Glama. Any ownership claim or indexing action requires the separate Phase B authorization. - Smithery: use
SMITHERY_API_KEYto read the actual qualified listing and download its MCPB through the documented API. Compare the exact reproducible bundle (binding version/repository/package), tools and three required configuration inputs. The publication route is a manual MCPB submission, not assumed ingestion. The documentation'suvMCPB support must be confirmed in the real client: Smithery's read API still enumerates older runtime labels. No live compatibility claim is made before that submission/installation test. - MCPfinder: inspect its timestamped, hash-verified snapshot through a bounded read-only SQLite query. Require the expected package/version/transport and all three primary sources, avoiding a stale or single-source confirmation. This is propagation evidence, not another publication target. Its documented 18-hour snapshot freshness bound is enforced.
The prepared Verify MCP distribution after release workflow is manual only,
restricted to master, and bounded to 15 minutes with no polling loop. It first
requires the public release preflight and a successful MCP qualification run at
the exact source SHA, then downloads that run's discovery capture. Directory keys
come only from GitHub Actions secrets in its read-only verification step. The CLI
does not consume these keys outside Actions. Keys are neither printed nor retained
in artifacts. Ordinary CI has no directory keys, queries or propagation waits.
The manual workflow retains incomplete reports and exits nonzero while evidence
is missing; it is not executed during Phase A.
Additional directories
| Directory | Current classification | Decision |
|---|---|---|
| MCPfinder | Automatic upstream aggregation (Tier 2) | Verify propagation only; do not submit. |
| PulseMCP | Official Registry integration plus crawling and manual curation/submission | Optional useful curated reach; first check upstream propagation. A later manual submission is a separate choice. |
| mcp.so | Current self-service paid submission | No submission recommended for this qualification; no evidence it adds required technical coverage. |
PulseMCP's direct page fetch was access-limited during review; its public indexed API documentation describes the maintained integration/submission path. No claim is made that either optional directory has accepted this candidate. No mass directory submission or website/domain work belongs to Phase A.
Publication preflight
The manual Publish MCP Registry workflow remains restricted to master and
retains GitHub OIDC and the verified publisher binary. Before authentication,
both manual workflows admit the requested tag/SHA against the published release
and protected master history in an inline step before checkout. This prevents
an arbitrary candidate from supplying the code that decides its own admission.
scripts/verify_mcp_publication.py requires a clean checkout at the full requested
SHA, a matching existing release tag, published final GitHub Release, source in
protected master history, qualification assets, matching release archive digests,
and the actual public PyPI identities/hashes/ownership marker. It cannot publish.
The publisher's own online validate follows this preflight, then the separately
authorized publish step. Normal Phase A CI exercises guards with offline fixtures;
it does not dispatch that workflow.
Follow the eventual release sequence only after separate authorization. Keep #279 open until the release and all required Phase B external evidence, including any manual Glama/Smithery follow-up, are complete.