HonestHook

Sign in

Blog ·

Publishing a remote MCP server to the official registry

If you run a hosted API and you want AI agents to find it, the official Model Context Protocol registry is the shortest path, and almost nothing written about it covers the case that most SaaS products are actually in: a remote server, closed source, no public repository.

I published one on 24 September 2026. It took a working afternoon, and four of those hours were spent on things the documentation does not warn you about. Here is the whole path.

The thing that decides whether this is even for you

The community lists are the obvious place to go first. The largest of them, awesome-mcp-servers, asks contributions to point at a public GitHub repository. A remote-only server doesn't have one. There is nothing to link, so there is nothing to submit.

The official registry has a different requirement, and it is the one that matters here: what has to be publicly accessible is the server, not the source. A streamable-http remote with a reachable URL qualifies. My entry has no repository field at all.

That inversion is the whole reason this path exists for commercial APIs, and I have not seen it stated anywhere.

Claiming the namespace

Server names in the registry are namespaced by a domain you control: mine is com.honesthook/social-data. You prove control with an ed25519 keypair and either a DNS record or an HTTP file. I used the file, because I already control the deploy.

It lives at /.well-known/mcp-registry-auth and its entire contents are one line:

v=MCPv1; k=ed25519; p=<your base64 public key>

The first thing that failed. The p= value is the raw 32-byte public key, base64-encoded. What openssl hands you by default is DER, which is 44 bytes — 12 bytes of structure followed by the key. Base64 the whole 44 and the registry rejects the proof with an error that does not tell you which part is wrong. Take the last 32 bytes:

openssl pkey -in key.pem -pubout -outform DER | tail -c 32 | base64

Publishing

The CLI is mcp-publisher (I used 1.8.1). Two commands: login, then publish.

The second thing that failed. --private-key does not take your PEM file. It takes the raw key material as a hex string. The documented way to produce it pulls the priv: block out of openssl pkey -text and strips the separators:

openssl pkey -in key.pem -noout -text | grep -A3 "priv:" | tail -n +2 | tr -d ' :\n'

Point the flag at key.pem and you get an authentication failure, not a format error.

The third thing that failed. The token login returns expires in minutes. If you log in, then go read the schema docs, then come back and publish, you will be publishing with a dead token — and the error you get back talks about authorization, which sends you to re-check the DNS or the well-known file you just got right. Run the two commands adjacently. If publish fails, log in again before retrying.

The schema URL is the version number

The fourth thing that failed, and the one worth the whole post.

Your server.json starts with a $schema key. It looks like documentation. It is not: the registry reads the version out of that URL. A $schema pointing at .../draft/server.schema.json is rejected, because "draft" is not a version.

Here is the part that will cost someone an afternoon. As of today, three different schema versions are in circulation at the same time:

Where Version in the URL
The publishing guide in the registry repo 2025-07-09
My published entry 2025-10-17
The newest entries the registry serves back 2025-12-11

All three are live right now. Copy the $schema line out of the guide and you are pinning a version from July. My own entry is two versions behind the current one and is still active with isLatest: true, so this is not an emergency — but it does mean the documentation is not the source of truth for this field. Read what the registry is actually serving:

GET https://registry.modelcontextprotocol.io/v0/servers?limit=1

and take the $schema from a recent entry.

What a minimal entry looks like

Mine is five keys. There is no repository, no packages array, no install instructions, because there is nothing to install:

{
  "$schema": "https://static.modelcontextprotocol.io/schemas/2025-10-17/server.schema.json",
  "name": "com.honesthook/social-data",
  "description": "Instagram, TikTok, Threads, Bluesky and 6 more: one API, one key, one JSON shape",
  "version": "1.0.0",
  "websiteUrl": "https://honesthook.com",
  "remotes": [
    { "type": "streamable-http", "url": "https://honesthook.com/api/mcp" }
  ]
}

You can check any published entry, including this one, without credentials:

GET https://registry.modelcontextprotocol.io/v0/servers?search=honesthook

The response carries a _meta block with status, publishedAt and isLatest. That is how you confirm a publish actually landed, rather than trusting the CLI's exit code.

One thing I would decide earlier

A remote MCP server has to answer two different "no key" situations, and they are not the same:

Collapsing those into one message is tempting and wrong — the first person needs a signup link; the second needs the API's own error, not a reclassified one. I split mine, and I'd get that right before publishing rather than after, because the tool list is the first thing an agent reads and the error text is the only documentation it gets.

Related: my balance-reading tool costs zero credits. Charging to check a balance means the number changes because you looked at it.

Method, and what would make this wrong

Everything above is from one publish, on one day, against the registry as it stood on 24–25 September 2026:

The vendor paragraph

I build HonestHook, so read this as the ad it partly is.

The server that came out of the above exposes ten platforms — Instagram, TikTok, Threads, Bluesky, Mastodon, Pinterest, SoundCloud, GitHub, Linktree and Medium — as MCP tools an agent can call directly. Five of the eight tools answer with no key at all — the discovery ones; every platform read needs a key. Every key gets 1,000 credits a month free, no card.

Pricing is here, generated from the same catalogue that serves the requests.


Registry behaviour, schema versions and the published entry were read from the live MCP registry on 25 September 2026. The publish itself was performed on 24 September 2026 with mcp-publisher 1.8.1.

Trend data with a memory

Every social API answers what’s trending now, then throws it away. HonestHook keeps the hourly archive, so you can ask what gained traction.

Free key, 1,000 credits a month, no card →