DEV Community

Rojan Khadka
Rojan Khadka

Posted on

I built a tool to catch MCP contract drift then found out someone else built almost the same thing

A few months ago I decided I wanted to build something in the MCP ecosystem. It's growing fast, it's early, and I figured if I picked the right problem within it, it'd be worth the bet.

I didn't have a specific painful bug of my own to fix. So instead of guessing, I went looking for evidence real GitHub issues, real breakage reports, real people describing what actually goes wrong when they run MCP servers in production.

A pattern showed up fast: silent contract drift.

Not crashes. Not clean errors. Something upstream a schema, a field type, a version quietly changes shape, and the first sign of it is a confusing failure somewhere downstream that doesn't obviously point back to the real cause.

A few examples I ran into while researching this:

  • An MCP server started throwing ImportError because an SDK bumped from mcp>=1.0.0 to a 2.0.0 release that renamed a core class. Nothing in the dependency range stopped it.
  • A vector-DB-backed MCP tool started returning "palace not found" after a routine upgrade not because data was corrupted, but because a downgrade had silently swapped in an incompatible dependency version. The error message actively pointed at the wrong cause.
  • A single schema change in one tool (a oneOf field) cascaded and broke every other unrelated tool registered in the same MCP session a blast radius way bigger than the actual change.

None of these were caught by anything watching. They were caught by a human noticing something was wrong, sometimes hours or days later.

What I built

ContractWatch polls a live MCP server (or an OpenAPI spec, for REST APIs) on a schedule, diffs the current response shape against the last known-good snapshot, and classifies whatever changed as breaking, warning, or informational so when an alert fires, you know at a glance whether to drop everything or file it for later.

It's deliberately scoped as the complement to CI-based contract testing, not a replacement for it. CI tools catch breaking changes before you merge and deploy your own code. ContractWatch catches the thing CI can't: something changing on a live endpoint you don't control a third-party API, an upstream MCP server, a deploy that bypassed CI entirely.

You can try it here: https://contractwatch-mvp.vercel.app/

The part I want to be upfront about

It's not magic, and it has a real limitation worth naming: right now it needs a spec. You point it at an OpenAPI doc or an MCP server URL, and it diffs against that. If you're consuming a third-party API or an internal endpoint that never got a published spec, ContractWatch can't monitor it yet there's no "learn a baseline from live traffic alone" mode built. That's a real gap, not a hedge.

I found out just how real that gap was in a fairly humbling way: while sourcing potential users for ContractWatch, I ran across a Reddit post from someone who'd independently built almost the exact same category of product FlareCanary except with baseline-learning built in from day one, specifically because they'd hit this exact "no spec" wall themselves in their own enterprise integrations work.

Two people, no contact with each other, arriving at nearly the same problem and nearly the same shape of solution within weeks of each other. If anything, that's made me more confident the problem is real not less. It's just made me more honest about where ContractWatch stands today versus where it needs to go.

Where it's headed

Short term: closing that no-spec gap is the top item on the list. Longer term, I want this to be the thing that tells you (or your agent) before a silent drift causes a real problem not after you've already spent an afternoon tracing a misleading error back to its real cause.

If you're running MCP servers in anything resembling production, I'd genuinely like to know: how do you find out today when something upstream changes shape under you? Alerting? Nothing? You just find out when something breaks?

Feedback, criticism, and "this doesn't solve my actual problem" replies are all welcome that's exactly the kind of thing I'm here to learn from.

Top comments (0)