Model Context ProtocolEnterprise IntegrationsupgradedEnterprise Autonomy

Connecting Legacy APIs with MCP

MW
Mark Weber · Chief Enterprise Architect
December 3, 2025

Any competent engineer can put a thirty-year-old system behind a modern protocol in an afternoon. The hard part is refusing to let the wrapper make promises the system underneath has never kept.

A team decides to make its order management system available to AI. The system is old — a mainframe-era core with a SOAP façade bolted on sometime in the previous decade — but the façade is documented, and the documentation is enough to produce a clean tool definition in an afternoon. The tool is called create_order. It takes a customer identifier, a SKU, and a quantity. It returns an order identifier. It works on the first try in the test environment, and everyone in the room feels the specific pleasure of having made something ugly look simple.

What the tool definition does not say is that the SOAP endpoint is not the system. It is a receipt printer sitting in front of a batch queue. The call returns promptly with an identifier, and that identifier is real in the sense that it has been allocated, but the order it names does not exist in any queryable way until a downstream job picks it up, which happens on a cadence that varies with load. If you call get_order with the identifier you were just handed, the system will tell you, truthfully by its own lights, that no such order exists. Occasionally the downstream job rejects the record outright — a customer credit hold, a discontinued SKU, a field that passed the façade's validation and failed the core's — and nothing reverses the acknowledgment the caller already received. And if the same call goes out twice, because a timeout was ambiguous and a client retried, the system will happily create two orders, because it has no notion of an idempotency key and never has.

None of this is secret. Every one of these behaviors is known to the four people who have integrated with this system before, and it is written down, more or less, in a runbook that says things like "wait, then poll" and "always check the reject file the next morning" and "never retry a create without checking first." The knowledge exists. What just happened is that a protocol layer was placed over the system, and the protocol layer carried the function signature forward and left the runbook behind.

The wrapper inherits the semantics whether it admits them or not

The Model Context Protocol is an open standard for exposing tools and context to AI systems in a uniform way, and its value is precisely that it collapses the integration surface: a model that speaks the protocol can reach anything that speaks it back, without a bespoke connector per system. That uniformity is the point, and it is also the trap, because uniformity of interface invites an assumption of uniformity of behavior. A tool that returns an identifier looks, from the caller's side, exactly like every other tool that returns an identifier. The protocol does not distinguish between a create that is durable when it returns and a create that is a promise to try later, and it was never supposed to — that distinction is not the protocol's job. It is the wrapper author's job, and it is the job most often skipped.

Skipping it feels harmless because the wrapper does not lie in any way that shows up in testing. Under light load, in a clean environment, with well-formed inputs, the eventually consistent create looks synchronous, the non-idempotent create is never retried, and the silent rejection path never fires. The wrapper passes every test anyone thinks to write, ships, and then behaves differently in production not because it is broken but because production is where the system's actual semantics live. What has been built is an abstraction whose error is invisible exactly in the conditions where abstractions are validated and glaring exactly in the conditions where they are used.

It is worth being precise about what kind of failure this is, because it is not the familiar one. The classic integration bug is a call that fails and reports failure; that is annoying and entirely recoverable, because everything downstream can see what happened. The failure introduced by an honest-looking wrapper over a dishonest interface is a call that succeeds, reports success, and is wrong — and the wrongness is discovered somewhere else, later, by someone who has no way to trace it back. Legacy enterprise systems are full of this shape. There are updates that return acknowledgment before any write is durable, deletes that mark a row and leave it visible to a different read path, batch endpoints that accept twenty records and process seventeen while returning a single cheerful status, and interfaces whose only reliable notion of "did it work" is a report you read tomorrow.

Agents amplify exactly the assumptions a wrapper encodes

Human integrators absorb this kind of thing by developing suspicion. An engineer who has been burned by the order system twice does not trust its acknowledgment; they build a wait, a re-query, and a reconciliation step, and they do it on instinct rather than because the interface asked them to. The interface was always a partial description of the system, and the missing half lived in the operator's judgment. That arrangement was never good, but it was survivable, because the human in the loop was a semantic shock absorber standing between an optimistic API and the real world.

An agent has no such instinct, and this is the part that changes the stakes rather than merely raising them. A reasoning system planning across a set of tools treats each tool description as the authoritative account of what that tool does, because that is the only account it has. If the description implies the write is durable on return, the agent will confidently sequence the next step against a state that does not exist yet, get an empty read, and conclude — reasonably, from its evidence — that the write must have failed. Then it will do the single most destructive thing available: retry a non-idempotent operation. What a human would have hesitated over, an agent executes cleanly and quickly, and it will keep executing cleanly and quickly across every branch of a plan that touches that tool. The wrapper's optimism does not stay contained in one call. It propagates into every plan built on top of it, and it does so at machine speed and machine scale.

This is a large part of why so many agentic programs stall in ways their sponsors find hard to diagnose. When Gartner predicted that over forty percent of agentic AI projects will be canceled by the end of 2027, it named inadequate risk controls alongside cost and unclear value. Inadequate risk controls, in practice, usually does not mean the absence of a governance committee. It means an agent was handed a description of an enterprise system that was cleaner than the system, made decisions that were correct given the description and wrong given reality, and produced a class of mistake nobody could explain afterward. The reasoning was sound. The map was wrong.

Fidelity about failure is the whole value of the abstraction

The corrective is not to keep agents away from legacy systems, which is neither possible nor desirable, since the legacy systems are where the enterprise's actual state lives. It is to treat the wrapper as a semantic artifact rather than a syntactic one, and to accept that generating the transport is the easy tenth of the work. A faithful tool for the order system does not present a create that returns an identifier. It presents a create that returns an identifier and an explicit statement that the record is not yet observable, an expected settlement window, the name of the read that confirms it, an idempotency key the caller is required to supply, and a plain declaration that a duplicate call without one will produce a duplicate order. It exposes the reject path as a first-class outcome rather than a surprise in tomorrow's file. It says, in the one place the agent will actually read, everything the runbook said.

That is a heavier lift than it sounds, and the reason it usually goes undone is that it requires the tribal knowledge of the people who have integrated with the system before, which is rarely written anywhere a code generator can find it. The productive way to think about capabilities that make protocol servers fast to stand up — StudioX's Instant MCP among them — is that they remove the excuse rather than the obligation. When the transport, the schema, and the plumbing take minutes instead of a quarter, the remaining work is the semantic interrogation nobody had budget for before: which of these operations are safe to repeat, which return before they are true, which fail quietly, which have a read that actually confirms them. Specialist Agents built on top of the result behave well not because they are careful by nature but because the ground they are standing on is described accurately, and their caution can be earned from the interface rather than bolted on by a prompt begging them to double-check. It is the same discipline that the wider literature on building an autonomous enterprise keeps arriving at from other directions: autonomy scales with the accuracy of the system's self-description, not with the sophistication of the model.

So the mental model worth carrying is that an integration layer is not a translator but a witness. A translator's job is to make the old system speak the new language as fluently as possible, and fluency is precisely what causes the damage, because it smooths over the stutters that were load-bearing. A witness's job is to say what is true, including the parts that make the system look bad — that this call is a promise rather than a fact, that this one must never be repeated, that this one lies. The teams that get real work out of agents against thirty-year-old infrastructure will be the ones who understood that the honest wrapper is not a degraded version of the clean one. It is the only one that was ever worth building, because an agent can plan around a limitation it has been told about and cannot plan around a limitation it has been protected from.

Discussion

No comments yet — start the conversation.

Join the discussion

See StudioX run.

Put autonomous AI workers to work on your own systems and knowledge.