Versions and rollback
Every time you publish or delete a tool, the platform snapshots the server's whole tool set into a new numbered version, pinned to one exact container image. This page shows you how to list those versions, roll the server back to an earlier one, and retire a version you never want to return to.
Before you begin
-
You need a project member role to list versions, and the project admin role to roll back, yank, or unyank.
-
You need an MCP server with at least two versions. If you do not have one, walk through publish tools and publish twice.
-
For the
platformctltabs: the CLI installed andplatformctl loginrun. Nothing else — the CLI needs no endpoint set. -
For the
curltabs: a token, your project id, and the server name in your shell. The examples also usejq.export CAI_API=https://api.codyhill.devexport CAI_TOKEN=$(curl -s "$CAI_API/v1/auth/login" \-d '{"email":"you@example.com","password":"your-password"}' | jq -r .token)export PROJ=$(curl -s -H "Authorization: Bearer $CAI_TOKEN" "$CAI_API/v1/projects" | jq -r '.projects[0].id')export SERVER=weather-tools -
For the Console tab: a browser is enough. Everything on this page is under Compute → MCP servers.
What a version is
A version is a frozen record of one successful build:
- A number. Versions start at
1and count up. Numbers are never reused. - An image digest. A digest is a fingerprint of the container image's exact contents, written like
sha256:8c1f…. Change one byte of the image and the digest changes completely, so naming a digest names one specific image and no other. Version 2 today is byte-for-byte version 2 forever. - A tool-set snapshot. The tool names, plus every credential key any of those tools declared, as they stood at that moment.
Publishing a tool, updating a tool, and deleting a tool each create a new version, because each one changes the server's tool set as a whole. A version is created only when the build succeeds. A failed build leaves the version history untouched and puts the reason in the server's message field.
List the versions
- platformctl
- curl
- Console
platformctl mcp versions weather-tools
You should see:
VERSION CURRENT YANKED TOOLS CREATED
3 yes no 2 2026-08-12T14:11:07Z
2 no no 1 2026-08-12T13:52:44Z
1 no no 1 2026-08-12T13:40:19Z
Add -o json for the full record — the pinned image digest, the captured tool names, and the version's credential keys, all of which the table leaves out.
curl -s "$CAI_API/v1/projects/$PROJ/mcpservers/$SERVER/versions" \
-H "Authorization: Bearer $CAI_TOKEN" | jq .
You should see:
{
"server": "weather-tools",
"versions": [
{
"version": 3,
"image_digest": "...@sha256:8c1f...",
"credential_keys": ["weather-api-key"],
"tool_names": ["get_alerts", "get_forecast"],
"tool_count": 2,
"current": true,
"created_at": "2026-08-12T14:11:07Z"
},
{
"version": 2,
"image_digest": "...@sha256:41a9...",
"credential_keys": ["weather-api-key"],
"tool_names": ["get_forecast"],
"tool_count": 1,
"current": false,
"created_at": "2026-08-12T13:52:44Z"
},
{
"version": 1,
"image_digest": "...@sha256:07e3...",
"credential_keys": [],
"tool_names": ["get_forecast"],
"tool_count": 1,
"current": false,
"created_at": "2026-08-12T13:40:19Z"
}
]
}
Open Compute → MCP servers and pick a server. The Versions table gives you one row per version, showing its number, its tools, its credential keys, and when it was built. The version the server is running now is marked.
The list is newest first, and it is not split into pages. One request returns the server's whole history.
| Field | Type | Meaning |
|---|---|---|
version | integer | The version number. Starts at 1, never reused. |
image_digest | string | The fingerprint of the exact image this version runs. Omitted if none was recorded. |
credential_keys | array of strings | The project-secret names the tools in this version were allowed to read. Names only, never values. |
tool_names | array of strings | The tools that existed when this version was built. |
tool_count | integer | How many tools that was. |
current | boolean | true for the one version the server is running right now. |
yanked | boolean | Present and true only when the version has been retired. |
yanked_at | string | When it was retired. Present only on yanked versions. |
created_at | string | When the version was built. |
Both timestamps use RFC 3339, the standard format that looks like 2026-08-12T14:11:07Z. The Z means UTC.
Check which version is running
Two places tell you the same thing. The versions list marks it with "current": true, and the server object carries it directly.
- platformctl
- curl
- Console
platformctl mcp get weather-tools
You should see:
created_at 2026-08-12T13:40:19Z
expose -
image ...@sha256:8c1f...
name weather-tools
ready true
state ready
tool_count 2
tool_names get_alerts, get_forecast
url http://<private-hostname>
version 3
visibility internal
curl -s "$CAI_API/v1/projects/$PROJ/mcpservers/$SERVER" \
-H "Authorization: Bearer $CAI_TOKEN" | jq '.mcp_server | {state, ready, version, image}'
You should see:
{
"state": "ready",
"ready": true,
"version": 3,
"image": "...@sha256:8c1f..."
}
The server's page shows its state, version, and endpoint, and the row marked current in the Versions table is the same fact said twice.
Roll back to an earlier version
Version 3 broke something. Point the server back at version 2.
- platformctl
- curl
- Console
platformctl mcp rollback weather-tools 2
You should see:
image ...@sha256:41a9...
note re-pointed the server at version 2's recorded image; no rebuild
rolled_back true
server weather-tools
version 2
curl -s -X POST "$CAI_API/v1/projects/$PROJ/mcpservers/$SERVER/versions/2:rollback" \
-H "Authorization: Bearer $CAI_TOKEN"
You should see:
{"server":"weather-tools","version":2,"image":"...@sha256:41a9...","rolled_back":true,"note":"re-pointed the server at version 2's recorded image; no rebuild"}
In the Versions table, click Roll back on version 2's row and confirm. The button is disabled on the version already running — rolling back to it would do nothing — and on a yanked version, with the reason shown on hover. It is also disabled while a build or rollout is in flight, so a rollback cannot race one.
What just happened, precisely:
- The platform pointed the running server back at version 2's recorded image. Nothing was rebuilt, so a rollback is fast and cannot fail the way a build can.
- The current version moved to 2. No new version number was created, because a rollback is not a publish.
- The server keeps the same bearer token — it is not replaced. Agents and clients already holding it keep working. See connect agents and clients.
- The action is recorded in your project's audit log as
mcpserver.version.rollback.
Rollback changes which image runs. It does not change the editable tool set you see at GET .../mcpservers/{name}/tools, which still holds the newest source you published.
So the moment you publish or delete a tool again, the platform builds a fresh version from that newest source — and the good version you rolled back to stops running. To make a rollback stick, publish the older source again as a new version.
Real error messages:
| Status | Message | Why |
|---|---|---|
400 | version must be a positive integer | The version segment was not a whole number greater than zero. |
404 | no such version | This server has no version with that number. |
409 | version 2 is yanked (retired); unyank it or publish a new version instead | The target was retired. Unyank it first, or move forward instead. |
409 | version 2 has no recorded image to roll back to | The version row exists but carries no image, so there is nothing to run. |
Yank a version
Yanking retires a version. The version stays in the history for the record, but the platform refuses to roll back to it. Use it when you know a version is bad — a leaked credential, or a tool that corrupts data — and you want to be sure nobody restores it by accident.
- platformctl
- curl
- Console
platformctl mcp yank weather-tools 3
You should see:
server weather-tools
version 3
yanked true
curl -s -X POST "$CAI_API/v1/projects/$PROJ/mcpservers/$SERVER/versions/3:yank" \
-H "Authorization: Bearer $CAI_TOKEN"
You should see:
{"server":"weather-tools","version":3,"yanked":true}
Click Yank on version 3's row in the Versions table and confirm. The confirmation spells out what yanking does and does not do: the version stays in the history, it stops being a rollback target, and a server already running that image keeps running.
The version now shows up in the list with "yanked": true and a yanked_at timestamp. Yanking never deletes anything — the row, the digest, and the tool-set snapshot all survive.
You cannot yank the version the server is currently running:
{"error":"version 3 is the one the server currently runs; roll to another version before yanking it","request_id":"..."}
That is a 409. Roll back to a good version first, then yank the bad one.
Unyank a version
Changed your mind, or the "known-bad" turned out to be a misdiagnosis.
- platformctl
- curl
- Console
platformctl mcp unyank weather-tools 3
You should see:
server weather-tools
version 3
yanked false
curl -s -X POST "$CAI_API/v1/projects/$PROJ/mcpservers/$SERVER/versions/3:unyank" \
-H "Authorization: Bearer $CAI_TOKEN"
You should see:
{"server":"weather-tools","version":3,"yanked":false}
A yanked row carries a Restore button in place of Yank. That is the same call — the console names it for what it does to the row.
The version is a valid rollback target again. Yanking an unknown version, in either direction, returns 404 no such version.
Both actions are audited, as mcpserver.version.yank and mcpserver.version.unyank.
How the three actions are written in a URL
Rollback, yank, and unyank do not each get their own path. You name the action by adding a colon and the action's name to the end of the version number in the URL:
POST /v1/projects/{projectID}/mcpservers/{name}/versions/{version}:rollback
POST /v1/projects/{projectID}/mcpservers/{name}/versions/{version}:yank
POST /v1/projects/{projectID}/mcpservers/{name}/versions/{version}:unyank
Anything else after the colon returns 404:
{"error":"unknown method on a version. The custom methods are POST .../versions/{version}:rollback, :yank and :unyank","request_id":"..."}
Summary
| Action | Request | Role | Rebuilds? | New version number? |
|---|---|---|---|---|
| Publish or delete a tool | PUT / DELETE on .../tools/{tool} | admin | Yes | Yes |
| List versions | GET .../versions | member | No | No |
| Roll back | POST .../versions/{version}:rollback | admin | No | No |
| Yank | POST .../versions/{version}:yank | admin | No | No |
| Unyank | POST .../versions/{version}:unyank | admin | No | No |
A quick checklist when something breaks in production, in whichever tab you have been using:
- List the versions and find the last one you know was good.
- Roll back to that number. The server is back within a rollout, with no build.
- Yank the broken version so nobody restores it.
- Fix the source and publish it, which mints a new version on top.
Next steps
- Connect agents and clients — the endpoint URL and the per-server bearer token.
- Publish tools — how each publish mints the versions you just rolled between.
- MCP servers API reference — every field, status code, and error string.
- Tutorial: weather tools over MCP — the end-to-end walkthrough.