Versioning Published MCP Servers
This article explains how version strings work for MCP servers published to the MCP Registry. It covers the version format requirements, explains why semantic versioning is recommended, and provides best practices for aligning server versions with package and API versions.
MCP servers MUST define a version string in server.json. For example:
{
"$schema": "https://static.modelcontextprotocol.io/schemas/2025-12-11/server.schema.json",
"name": "io.github.username/email-integration-mcp",
"title": "Email Integration",
"description": "Send emails and manage email accounts",
"version": "1.0.0",
"packages": [
{
"registryType": "npm",
"identifier": "@username/email-integration-mcp",
"version": "1.0.0",
"transport": {
"type": "stdio"
}
}
]
}
The version string MUST be unique for each publication of the server. Once published, the version string (and other metadata) cannot be changed.
Version Format
The MCP Registry recommends semantic versioning, but supports any version string format. When a server is published, the MCP Registry will attempt to parse its version as a semantic version string for sorting purposes, and will mark the version as "latest" if appropriate. If parsing fails, the version will always be marked as "latest".
As an error prevention mechanism, the MCP Registry prohibits version strings that appear to refer to ranges of versions.
| Example | Type | Guidance |
|---|---|---|
1.0.0 |
semantic version | Recommended |
2.1.3-alpha |
semantic prerelease | Recommended |
1.0.0-beta.1 |
semantic prerelease | Recommended |
3.0.0-rc.2 |
semantic prerelease | Recommended |
2025.11.25 |
semantic date | Recommended |
2025.6.18 |
semantic date | Recommended (⚠Caution!⚠) |
2025.06.18 |
non-semantic date | Allowed (⚠Caution!⚠) |
2025-06-18 |
non-semantic date | Allowed |
v1.0 |
prefixed version | Allowed |
^1.2.3 |
version range | Prohibited |
~1.2.3 |
version range | Prohibited |
>=1.2.3 |
version range | Prohibited |
<=1.2.3 |
version range | Prohibited |
>1.2.3 |
version range | Prohibited |
<1.2.3 |
version range | Prohibited |
1.x |
version range | Prohibited |
1.2.* |
version range | Prohibited |
1 - 2 |
version range | Prohibited |
1.2 || 1.3 |
version range | Prohibited |
Best Practices
Use Semantic Versioning
Use semantic versioning for version strings.
Align Server Version with Package Version
For local servers, align the server version with the underlying package version in order to prevent confusion:
{
"version": "1.2.3",
"packages": [
{
"registryType": "npm",
"identifier": "@my-username/my-server",
"version": "1.2.3",
"transport": {
"type": "stdio"
}
}
]
}
If there are multiple underlying packages, use the server version to indicate the overall release version:
{
"version": "1.3.0",
"packages": [
{
"registryType": "npm",
"identifier": "@my-username/my-server",
"version": "1.3.0",
"transport": {
"type": "stdio"
}
},
{
"registryType": "nuget",
"identifier": "MyUsername.MyServer",
"version": "1.0.0",
"transport": {
"type": "stdio"
}
}
]
}
Align Server Version with Remote API Version
For remote servers with an API version, the server version should align with the API version:
{
"version": "2.1.0",
"remotes": [
{
"type": "streamable-http",
"url": "https://api.myservice.com/mcp/v2.1"
}
]
}
Use Prerelease Versions for Registry-only Updates
If you anticipate publishing a server multiple times without changing the underlying package or remote URL — for example, to update other parts of the metadata — use semantic prerelease versions:
{
"version": "1.2.3-1",
"packages": [
{
"registryType": "npm",
"identifier": "@my-username/my-server",
"version": "1.2.3",
"transport": {
"type": "stdio"
}
}
]
}
1.2.3-1
are sorted before regular semantic versions such as 1.2.3.
Therefore, if you publish a prerelease version after its corresponding
regular version, the prerelease version will not be marked as "latest".
Aggregator Recommendations
MCP Registry aggregators SHOULD:
- Attempt to interpret versions as semantic versions when possible
- Use the following version comparison rules:
- If one version is marked as "latest", treat it as later
- If both versions are valid semantic versions, use semantic versioning comparison rules
- If neither versions are valid semantic versions, compare published timestamp
- If one version is a valid semantic version and the other is not, treat the semantic version as later
Source: https://modelcontextprotocol.io/registry/versioning.md