feat(dist): registry manifests + discoverability for the MCP bridge#7
Conversation
Make the openadapt-agent MCP server easily installable and discoverable, and document the public-capability vs private-bundle boundary. PART 1 (the bridge itself) is already complete on main; this adds the distribution surface. - server.json: official MCP registry manifest (PyPI package, uvx runtime hint, stdio transport, --bundles arg, OPENADAPT_BUNDLE_KEY secret). Validated against the live 2025-12-11 server.schema.json. - smithery.yaml: Smithery stdio startCommand with a bundlesDir/allowRun/ bundleKey configSchema and a commandFunction (verified in node). - llms.txt: link-first summary for AI assistants. - docs/DISTRIBUTION.md: public-vs-private-server distinction, canonical registry metadata, and a founder-action submission plan (PyPI, official registry, Smithery, mcp.so, Glama, PulseMCP, Agent Skills directories). - README: uvx quickstart + "Install as an MCP server (registries)" section; cross-links docs.openadapt.ai. - tests/test_distribution.py: pin version consistency across server.json / pyproject / __version__, assert the registry launch is read-only by default (execution requires operator --allow-run), and guard the smithery wiring. Adds pyyaml to the dev extra. Read-only-by-default is a security invariant: a one-click registry install exposes only inspection tools; run_* requires --allow-run. A user's compiled bundle is their private artifact and is never embedded in the package or any registry listing. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NyCHrzA1psrKMFfroYbzaM
…ecrets) Add a tag/release-gated release pipeline so the founder-action publish plan is as automated as is safely possible, without ever firing a publish from a normal push/PR. .github/workflows/release.yml: - validate job (runs on PRs, workflow_dispatch, and every trigger): builds sdist+wheel, runs the license/package-boundary gate on the BUILT archives, `twine check`, validates server.json against its live schema, and runs the version-consistency guard. No publish -> the pipeline is testable via PR/dispatch. - pypi-publish job (ONLY on a vX.Y.Z tag or a published Release): asserts the tag matches the package version, then uploads via PyPI Trusted Publishing (OIDC) in the `pypi` environment. Token fallback wired behind a repo variable and fails LOUD (naming PYPI_API_TOKEN) if selected-unset. - mcp-registry-publish job (tag/release only): waits for the new version to be live on PyPI (the registry validates package existence), then `mcp-publisher login github-oidc` + publish. PAT fallback wired and fails loud (naming MCP_GITHUB_TOKEN) if selected-unset. - concurrency guard; least-privilege permissions; id-token only where OIDC is used. scripts/check_release_artifacts.py: the license/boundary gate. Inspects the actual wheel+sdist and fails if any member is a bundle (workflow.json), an .enc artifact, run outputs, a key/.env/db, or a non-code wheel payload. Enforces AGENTS.md 4.1/4.2 (never ship a user's bundle or crown-jewel data). Verified to pass on the real archives and to reject an injected bundle. docs/DISTRIBUTION.md: rewrote section 3 into AUTOMATED (fires on release) vs founder one-time actions, with the exact repo config. OIDC path needs ZERO repo secrets: one-time PyPI Trusted Publisher config + a `pypi` GH environment; MCP registry is authorized by the repo's own OIDC identity. Optional token fallbacks name their required secret. Smithery claim / mcp.so / PulseMCP / Agent Skills listings remain one-time manual actions (no publish API); Glama auto-indexes. README: note the automated, secret-free release pipeline. No publish is triggered from this branch. actionlint clean; 35 tests pass; ruff clean. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NyCHrzA1psrKMFfroYbzaM
Update: release automation added (commit 58aef48)Automated the founder-action publish plan as far as is safe — no publish ever fires from a push/PR, only on a deliberate New
New Secrets: NONE in the OIDC path. One-time founder setup: register the PyPI Trusted Publisher ( Still manual (one-time claims, no publish API): Smithery "Add Server" (then it auto-reads
|
Summary
PART 1 of the MCP + Agent Skills bridge (the
openadapt-agent serveMCP server andemit-skillemitter over governed openadapt-flow bundles) is already complete onmain(PR #2) and verified here end-to-end against the real flow CLI: emit-skill produces flow's skill folder + MCP/halt appendix;tools/listexposeslist_workflows/get_workflow/get_run_report+run_<slug>; and a real governedrun_demo_triagereturns a structuredrefused(exit 2, real gate coverage report) — never a fabricated success.This PR adds PART 2: distribution & discoverability, which was the actual gap.
What's added
server.json— official MCP registry manifest (PyPI package,uvxruntime hint, stdio transport, required--bundles, secretOPENADAPT_BUNDLE_KEY). Validated against the live2025-12-11/server.schema.json.smithery.yaml— Smithery stdiostartCommandwith abundlesDir/allowRun/bundleKeyconfig schema and acommandFunction(verified by evaluating it in node).llms.txt— link-first summary for AI assistants (GEO).docs/DISTRIBUTION.md— the public-capability-vs-private-bundle distinction, canonical registry metadata block, and a step-by-step founder-action submission plan (PyPI publish, official registry, Smithery, mcp.so, Glama, PulseMCP, Agent Skills directories). These mint public first-party identities and are deliberately not automated.uvxquickstart + "Install as an MCP server (registries)" section; cross-links docs.openadapt.ai.tests/test_distribution.py— pins version consistency (server.json ↔ pyproject ↔__version__), asserts registry-launch is read-only by default (execution requires operator--allow-run), guards the smithery wiring and theOPENADAPT_BUNDLE_KEY-is-secret invariant. Addspyyamlto thedevextra.Key design decision
Read-only by default; private bundles never shipped. A one-click registry install exposes only inspection tools;
run_*requires the operator to add--allow-run. A user's compiled workflow bundle is their private artifact, supplied at launch via--bundles, and is never embedded in the package,server.json, or any registry listing.Verification
ruff check src testsclean;pytest35 passed (28 existing + 7 new).server.jsonvalidated against the live MCP registry schema.openadapt-flowCLI (emit-skill, MCP tools/list, governed run → structuredrefused).Founder actions (not performed here)
Publishing to PyPI and submitting to each registry are outward-facing founder actions listed in
docs/DISTRIBUTION.md§3. Pick the final release version (e.g.2.0.0rc1) at publish time — the CI guard keeps the three version fields in lockstep.🤖 Generated with Claude Code
https://claude.ai/code/session_01NyCHrzA1psrKMFfroYbzaM