Three fields are required: name, description and version.
Everything else is optional, and most publish failures come from a limit on one of the three rather
than from a missing field.
The one that catches people: description has a maximum length of 100
characters. Not 100 words, and not a soft guideline. It is maxLength: 100 in the
schema, so a sentence that reads well in a README is refused.
| Field | Type and limits | Notes |
|---|---|---|
name | string, 3 to 200, pattern ^[a-zA-Z0-9.-]+/[a-zA-Z0-9._-]+$ | Reverse DNS namespace, exactly one forward slash. Capitals are legal and they change your search rank. |
description | string, 1 to 100 | "Should focus on capabilities, not implementation details." |
version | string, up to 255 | Must be unique per publication. Immutable once published. |
title | string, 1 to 100, optional | Display name. Clients may or may not use it. |
websiteUrl | URI, optional | Homepage or documentation. |
repository | object, optional | url and source both required if present. |
packages | array, optional | Installable forms. |
remotes | array, optional | Hosted endpoints. |
icons | array, optional | See below. |
_meta | object, optional | Reverse-DNS namespaced extension data. |
$schema | URI, optional | Points at the schema version you wrote against. |
A server may declare packages, remotes, both, or neither. Neither is legal
and useless: a survey filed as
registry#1579 on 2026-08-27
counted 387 active servers that declare no package and no remote and therefore cannot be reached by
anything.
Any string up to 255 characters is accepted, but the registry parses it as a semantic version for sorting and to decide which row is marked latest. From the registry's versioning documentation, read 2026-09-09:
^1.2.3, ~1.2.3, >=1.2.3,
1.x, 1.2.* and 1 - 2 are all prohibited.2025.06.18 is a non-semantic date and carries the same risk;
2025-06-18 is fine.registryType, identifier and transport are required on every
entry. registryType is a string such as npm, pypi,
oci, nuget or mcpb. version must be a specific
version; ranges are rejected here too.
fileSha256 is a 64-character lowercase hex string, required for mcpb
packages and optional for the rest. A downloadable bundle with no hash is not publishable,
which is the right way round: the identifier for an mcpb package is a URL, and a URL alone proves
nothing about what arrives.
The remaining fields are runtimeHint, runtimeArguments,
packageArguments, environmentVariables and registryBaseUrl. The
schema carries a warning on the argument types worth reading before you accept user input into one:
arguments build command lines, and a client that runs them through a shell inherits an injection
risk, so the schema tells clients to prefer non-shell execution.
type is streamable-http or sse, and url must
match ^https?://[^\s]+$. Both fields are required. SSE is deprecated and exists for
older clients; a server may publish both at different URLs.
URLs support {curly_brace} template variables with a variables map
carrying description, isRequired, default,
choices and isSecret, which is how a multi-tenant or multi-region service
publishes one entry. headers declares headers the client should send, each with its own
isRequired and isSecret.
One rule is not in the schema and will fail your publish anyway: a remote URL already claimed by a different server name is refused. That is its own trap.
repository needs url and source, and takes an optional
id and subfolder, the latter being the relative path to the server inside a
monorepo.
icons entries need src, an HTTPS URI of at most 255 characters. The
optional mimeType is an enum of png, jpeg, jpg, svg+xml and webp, and sizes
entries must match WxH or the literal any. The schema warns consumers to
treat SVGs carefully, since they can carry script.
Custom data survives publishing under
_meta.io.modelcontextprotocol.registry/publisher-provided. There is a hard 4096-byte
limit on the JSON, and exceeding it fails the publish. The registry writes its own block at
_meta.io.modelcontextprotocol.registry/official carrying status, publishedAt, updatedAt
and isLatest, which is where you read whether a row is active or deprecated.
Sources: https://static.modelcontextprotocol.io/schemas/2025-12-11/server.schema.json,
fetched and parsed 2026-09-09, for every type, limit and pattern quoted; the registry documentation
pages on versioning, remote servers and the FAQ, read the same day, for the version rules and the 4KB
limit. This project publishes its whole catalogue to the registry and has hit the description limit, the
version-range rule and the remote URL rule.
The publish is rejected by schema validation. Write the 100-character version first and treat it as a headline: what the server does, in the words someone would use to look for it. The long explanation belongs in the README and on your website.
No, it is optional. Including it pins the version you wrote against, which is worth doing because the schema is generated from the registry's OpenAPI definition and does change.
Yes, repository is optional. It is recommended for transparency, and directories that build from source have nothing to build without it, so a server with only a remote endpoint and no repository limits where it can be listed.
mcpb, with the identifier set to the download URL and fileSha256 set to the file's hash. That is the only package type where the hash is required.
No. Metadata is immutable per version, so the fix is a new version string. Nothing can be unpublished either, so the version with the typo stays visible in the version list even after a newer one is marked latest.
All MCP servers and prices · All guides · Buy the bundle $39