publishing to mcp registry#
this document explains how we set up automated publishing to the MCP registry and the lessons learned along the way.
overview#
the MCP registry is Anthropic's official directory of Model Context Protocol servers. publishing makes your server discoverable and installable through Claude Desktop and other MCP clients.
setup#
required files#
-
server.json- registry metadata- must match PyPI package version exactly
- uses namespace format:
io.github.username/server-name - validated against https://static.modelcontextprotocol.io/schemas/2025-09-29/server.schema.json
-
README.md- must containmcp-name:line- format:
mcp-name: io.github.username/server-name - can appear anywhere in the file (we put it at the bottom)
- validation uses simple
strings.Contains()check
- format:
-
.github/workflows/publish-mcp.yml- automation workflow- triggers on version tags (e.g.,
v0.0.6) - publishes to PyPI first, then MCP registry
- uses GitHub OIDC for authentication (no secrets needed)
- triggers on version tags (e.g.,
github secrets#
only one secret required:
PYPI_API_TOKEN- from https://pypi.org/manage/account/token/
workflow#
when you push a version tag:
git tag v0.0.6
git push origin v0.0.6
the workflow automatically:
- runs tests
- builds the package with
uv build - publishes to PyPI with
uv publish - installs
mcp-publisherbinary (v1.2.3) - authenticates using GitHub OIDC
- publishes to MCP registry
cutting a release#
to cut a new release:
-
update server.json version (both fields must match the version you're releasing)
{ "version": "0.0.9", "packages": [{ "version": "0.0.9" }] } -
run pre-commit checks
just check -
commit and push your changes
git add . git commit -m "your commit message" git push origin main -
create and push the version tag
git tag v0.0.9 git push origin v0.0.9 -
verify the release
- workflow: https://github.com/zzstoatzz/tangled-mcp/actions/workflows/publish-mcp.yml
- pypi: https://pypi.org/project/tangled-mcp/
- mcp registry:
https://registry.modelcontextprotocol.io/v0/servers/io.github.zzstoatzz%2Ftangled-mcp/versions/X.Y.Z
key learnings#
mcp-publisher installation#
the official docs suggest using a "latest" URL that doesn't actually work:
# ❌ doesn't work - 404s
curl -L "https://github.com/modelcontextprotocol/registry/releases/download/latest/..."
# ✅ use specific version
curl -L "https://github.com/modelcontextprotocol/registry/releases/download/v1.2.3/mcp-publisher_1.2.3_linux_amd64.tar.gz"
the publisher is a Go binary, not an npm package. don't try npm install.
version synchronization#
server.json version must match the PyPI package version:
{
"version": "0.0.6",
"packages": [{
"version": "0.0.6"
}]
}
if they don't match, registry validation fails with:
PyPI package 'tangled-mcp' not found (status: 404)
readme validation#
the mcp-name: line just needs to exist somewhere in the README content. the validator uses:
strings.Contains(description, "mcp-name: io.github.username/server-name")
so you can place it wherever looks best aesthetically. we put it at the bottom after a horizontal rule.
authentication#
GitHub OIDC is the recommended method for CI/CD:
permissions:
id-token: write
contents: read
steps:
- name: login to mcp registry (github oidc)
run: mcp-publisher login github-oidc
no need for additional tokens or secrets - GitHub handles it automatically.
common errors#
"PyPI package not found (status: 404)"#
cause: version mismatch between server.json and actual PyPI package
fix: ensure server.json versions match the git tag and PyPI will build that version
"ownership validation failed"#
cause: missing or incorrect mcp-name: in README
fix: add mcp-name: io.github.username/server-name anywhere in README.md
"failed to install mcp-publisher"#
cause: wrong download URL or npm package attempt
fix: use specific version binary download from GitHub releases