Skip to content
verify mcp Beta VerifyMCP is currently in beta. If you notice any issues, email [email protected] and we’ll put it right.

Keep your MCP tool surface stable

What we checked

We compare two captures of your server’s surface and look for destabilising changes. For a hosted endpoint that is a rolling 30-day window of daily snapshots. For a package it is the versions we captured inside that same window, because a published version cannot change once released, so what matters is what changes between them:

No destabilizing schema changes in the last 30 days.
Destabilising schema changes within the observed window (tool removals, breaking changes, auth or transport breaks)
Destabilising changes to the tool surface between two published versions (tool removals, breaking changes)
Stability credit is still accruing: it ramps linearly over the first 30 days of clean observed history
Stability not yet verified: not enough scan history yet (needs a 30-day window).
Stability not yet verified: we do not have a sandbox capture of the MCP schema this version of the package serves yet.
Stability not yet verified: our sandbox run of this package did not complete, so we have no schema to compare.
Stability not yet verified: the captured schema was too large for us to store in full, and comparing a partial copy would report our own trimming as a change.
Stability not yet verified: two runs of the same published version returned different tool surfaces, so we cannot tell a change in the package from a difference in our own sandbox run.

Why it matters

Agents bind to your tools by name and argument shape. When a tool disappears or its parameters change incompatibly, every agent and saved workflow that depended on it breaks, usually silently, mid-task. An MCP server is a contract with everyone using it, whether they connect to it or install it, so your tool surface should be treated like a public API, where a backwards-incompatible change is the kind that warrants a major version bump under semantic versioning: changes are cheap to make and expensive for everyone downstream.

Additive changes are safe; mutations and removals are not. The distinction is the whole game.

How to fix it

This is mostly process. Add new capabilities rather than mutating existing ones, and when something truly must go, deprecate it with a migration path before removing it. The example below contrasts a safe additive change with a breaking one.

// SAFE (additive): add a NEW optional parameter. Existing callers keep working.
inputSchema: {
city: z.string().describe("City name."),
units: z
  .enum(["metric", "imperial"])
  .optional()
  .describe("Optional. Defaults to metric."),
}

// BREAKING: renaming or removing a parameter invalidates every existing call.
//   city  ->  location   // every caller passing 'city' now fails

// BREAKING: removing a whole tool. Prefer a new tool + a deprecation period.
//   server.registerTool("get_weather_v2", ...)   // add
//   // keep get_weather working, mark it deprecated in its description, then
//   // remove only after consumers have migrated.

What counts as a breaking change?

Anything that invalidates a call an existing agent already makes: renaming or removing a tool, renaming a parameter, adding a required parameter, changing a parameter’s type, or tightening a constraint such as narrowing an enum. Additive changes are safe, so a new tool, a new optional parameter, a loosened constraint, or a clearer description all read as a steady surface. Only the breaking kind counts as churn.

On a package, only a change between versions can count as churn. If we capture the same version twice and the two disagree, we report that we could not tell what changed rather than counting it against you: either our sandbox is unreliable for your package (usually a tool list that varies with a secret or a native dependency), or you publish under a coordinate that can be re-pointed, such as an OCI tag. Two captures of one version that agree are simply stable.

How we re-check

We keep capturing your surface: on each crawl for a hosted endpoint, and on a regular refresh plus every time you publish a new version for a package. Every clean observed day adds credit on the next score refresh, and once the window contains no destabilising changes the check records a fully stable surface.

Give this to your AI

Paste this into Claude Code (or any coding agent) from inside your server's repository. It states the failing signal, the outcome we re-check for, and the format the fix has to take.

Prompt
Context: this repository publishes an MCP server, either as a hosted
endpoint or as a package on a registry such as npm or PyPI.
VerifyMCP's stability check failed, which means a comparison of two
captures of your tool surface found a destabilising change: a tool was
renamed or removed, a parameter was renamed, a new required parameter
appeared, a parameter's type changed, or a constraint (e.g. an enum) was
tightened. For a hosted endpoint the two captures are 30 days apart. For
a package they are two different published versions, so the change is
what a consumer meets when they upgrade.

Goal: the tool surface stays steady across the rolling 30-day window
(only additive changes), so the next crawl records it as stable.

Do this:
1. Find the change that caused the churn (compare the current tool
   definitions against the version from before the change, e.g. via
   git history or a diff of the registered tools).
2. If the change genuinely must happen, add it as a NEW tool or a NEW
   optional parameter alongside the existing one, rather than mutating
   what is already there.
3. Mark the old tool or parameter as deprecated in its `description`,
   naming the replacement, and keep it working.
4. Only remove the deprecated tool or parameter after a real migration
   window has passed and you have confirmed existing consumers no
   longer call it.

Rules:
- A breaking change (rename, removal, new required parameter, narrowed
  type or enum) is a product decision, not a formatting one: ask the
  human before shipping it, and check whether existing clients depend
  on the current shape first.
- Do not "fix" churn by reverting the change and reintroducing it later
  under a different name; that still breaks callers mid-window.

Report back: which changes were additive versus which you held back to
ask about, and the current state of the deprecated tool's description.

Reference: https://verifymcp.io/docs/remote/stability

Written by Stuart Blackler · Last reviewed 31 July 2026.