Three failed publishes, and how to publish
Publishing an MCP server in the official registry looks like one API call. It is not: it is a three-step protocol with two traps that do not surface as validation errors and a byte limit that cuts you halfway. We published ours (dev.theboomer/ai-tasker) on 21 October 2026, and this is the log of the three attempts it took.
Reviewed · Published
Why the official registry goes first
The official registry is the canonical directory of the protocol: MCP clients and aggregators query it, and the other indexes drink from it. A server listed in the registry shows up in other directories without anyone asking: the Glama listing of AI Tasker exists that way, with nobody submitting it by hand. That is why publication order is not a whim: official registry first, directories afterwards.
The uncomfortable part is that the registry does not require you to publish the code. Authentication is a DNS challenge on your domain, so an MCP server can live in a private repository and still be discoverable by any client. That changes the conversation with the directories: you do not have to open the repository for the server to be installable.
Attempt 1: 403 over a misunderstood namespace
The first publish returned a 403 that did not look like a permissions problem:
Registry response (403).
You do not have permission to publish this server.
You have permission to publish: dev.theboomer/*, dev.theboomer.* The name of a server in the registry is reverse-DNS: the domain backwards, like io.github.user/repo. Authenticating the domain theboomer.dev grants the namespace dev.theboomer, not theboomer.dev. What we did was authenticate one domain and publish to another: that is why the permission was dev.theboomer/* while we asked for theboomer.dev/ai-tasker.
The fix was not about permissions but about the name: the server became dev.theboomer/ai-tasker, with the product domain (ai-tasker.theboomer.dev) as websiteUrl and the authenticated domain as theboomer.dev. The endpoint and the code did not change; the label did.
Attempt 2: 400 over a 4 KB extension
With the name fixed, the registry returned another 400, this time about the _meta extension a publisher can attach to the manifest:
Registry response (400).
_meta.io.modelcontextprotocol.registry/publisher-provided extension
exceeds 4KB limit (4835 bytes) The _meta extension is limited to 4 KB, and with the description of all 40 tools of the MCP server the block came to 4.835 bytes. The fix was not to drop tools but to decide what belongs in the manifest and what does not: the extension carries only the names of the tools (2.004 bytes) and the descriptions stay in the machine-readable catalogue (/llms-full.txt) and on the tools page of the site.
The lesson: the official manifest is an index, not a manual. The bigger the extension, the fewer times you can republish without breaking the limit, because every new tool adds bytes.
Attempt 3: 200
With the right namespace and the extension inside the limit, the publish returned 200 and the server went live with its version:
Publication (200).
{"server":{"name":"dev.theboomer/ai-tasker","version":"1.1.8", ...}} Two traps that are not validation errors
What cost the most time was not the errors: it was the responses that looked right and were not.
- The token comes in `registry_token`, not `access_token`. Looking for
access_tokenin the body is the easiest mistake to make and the most confusing, because the response says 200 and carries a token that is not the one you expected. - `GET /v0/servers?search=…` takes more than 25 seconds and exhausts the timeout of any serious client. To check that the publication exists, use the version endpoint, which answers in under a second:
/v0/servers/<name>%2F<server>/versions/<version>. - The JWT expires after 5 minutes. DNS authentication and the publish have to happen in the same run: you cannot authenticate in the morning and publish in the afternoon.
The DNS challenge, in detail
The domain proof has three steps and none of them needs a third-party account. You generate an Ed25519 key pair; the private key lives outside the repository (in a file with 600 permissions) and the public key is published as a TXT record at the apex of the domain:
TXT record at the apex of the domain.
v=MCPv1; k=ed25519; p=<public key in standard base64> Once the TXT has propagated, an RFC3339 timestamp is signed with the private key and sent to the authentication endpoint, which returns a one-time token:
Authentication and publication.
POST /v0/auth/dns
{"domain":"theboomer.dev","timestamp":"...","signed_timestamp":"<hex>"}
-> {"registry_token":"<JWT>","expires_at":...}
POST /v0/publish Authorization: Bearer <JWT> Rotating the key means deleting the TXT and publishing a new one with the script: the old signature stops being valid. Removing the entry from the registry is a DELETE on /v0/servers/<name> with the same token.
What to take from this
- The name of the server is the reverse-DNS of the domain you authenticate, not the one you would prefer. Check it before signing anything.
- The publisher extension
_metahas a 4 KB limit: put indexes in it, not content. - Authenticate and publish in the same run (the JWT lasts 5 minutes).
- Verify against the version endpoint, not against the search: the search takes more than 25 seconds.
- The manifest is generated at runtime from the real version and tool catalogue, so it cannot drift from what is deployed.
All of this is automated in the project repository: the publish script writes the TXT, waits for propagation, signs, authenticates, publishes and verifies; and it exits with a non-zero code if the manifest does not satisfy the current schema, if the extension goes over 4 KB, or if the registry rejects the publication. The part that cannot be automated is the TXT: somebody has to publish it in the domain panel.
Publishing an MCP server in the official registry
The four real steps, with what to check at each one and which response you get.
- Generate the key pair and the TXT
The script creates an Ed25519 key outside the repository (mode 600) and prints the TXT record to publish at the apex of the domain: v=MCPv1; k=ed25519; p=<public key>. DNS is published by a human: there is no API for that.
- Wait for propagation and authenticate
With the TXT visible, the script signs the RFC3339 timestamp with the private key and calls POST /v0/auth/dns. The response carries registry_token (not access_token) and expires after 5 minutes.
- Publish the manifest
POST /v0/publish with the JWT in Authorization. The manifest is validated against the current registry schema: if the _meta extension goes over 4 KB, the registry answers 400 and does not publish.
- Verify against the version endpoint
GET /v0/servers/<name>%2F<server>/versions/<version> answers in under a second. Do not use the search: GET /v0/servers?search=… takes more than 25 seconds and exhausts the timeout.
Frequently asked questions
Do I need a GitHub account or a public repository to publish in the registry?
No. Authentication is a DNS challenge on the domain: you publish a TXT with a public key and sign a timestamp. The MCP server repository can stay private. AI Tasker is published as dev.theboomer/ai-tasker with the code in a private repository.
What is the limit on the _meta extension of the manifest?
4 KB. The extension the publisher adds cannot exceed that size. With the descriptions of the 40 tools it came to 4.835 bytes and the registry answered 400; the fix was to include only the names of the tools (2.004 bytes) and leave the descriptions in the machine-readable catalogue.
Why does my publication return 403 even though the domain is authenticated?
Because the name of the server is reverse-DNS and has to match the granted namespace. Authenticating theboomer.dev grants the dev.theboomer namespace, so the server must be called dev.theboomer/<name> and not theboomer.dev/<name>.
Sources
- MCP Registry — API documentation
https://registry.modelcontextprotocol.io/docs - Manifest schema (2025-12-11)
https://static.modelcontextprotocol.io/schemas/2025-12-11/server.schema.json - Published AI Tasker entry
https://registry.modelcontextprotocol.io/v0/servers/dev.theboomer%2Fai-tasker/versions/1.1.8 - Live AI Tasker manifest
https://ai-tasker.theboomer.dev/server.json - Internal publishing runbook
https://git.dev.theboomer.dev/boomerdev/ai-tasker
Figures verified against the live API and each product’s official page on 21 October 2026. Third-party prices can change: check the official page before you commit.
Related guides
- All posts — Technical notes from the team: what does not fit in the documentation.
- MCP for task management: guide and comparison — What a task-management MCP server is, which tools each one exposes and how to choose. A table with the real price of every server.
- Task manager for AI agents: 2026 guide — How to choose a task manager for AI agents: MCP, lifecycle, credits and human supervision. A comparison and a checklist.
- MCP or HTTP API: when to use which — MCP or the HTTP API: what each access solves, when to use each one and how to decide without duplicating integrations. Copyable config and real cost.
- Pricing — Real prices: free plan and a 2.00 €/month billable unit.
- MCP integration —
https://mcp.ai-tasker.theboomer.dev/mcp - /llms.txt — Machine-readable contract.
This guide exists to be indexed and cited. It is deliberately not in the menu.