A human integrating with your order API reads the docs once, writes the call, handles the one error they actually hit in testing, and ships. They make that call a few times a minute at peak. When something breaks, they read the stack trace, swear, and fix it.
An agent does none of that. It reads your tool’s schema at runtime, calls it forty times in a loop because a retry policy told it to, fans out to three other tools while it waits, and when your endpoint returns a shape it didn’t expect, it doesn’t swear. It improvises. Sometimes that improvisation is a hallucinated field name. Sometimes it’s a second call you didn’t budget for. Either way, nobody is reading the stack trace, because the caller is a model and the trace is gone by the time you notice the bill.
This is the shift behind all the noise about the Model Context Protocol. The interesting thing about MCP isn’t the protocol. It’s that the caller changed. Once agents are the ones calling your APIs, the integration layer stops being a human convenience and becomes a machine contract. Most platforms were built for the convenience. They are about to meet the contract.
Why this is happening now
For twenty years the integration layer optimized for the person in front of it. Drag a connector onto a canvas. Map a field. Click save. The whole industry trained itself to make integration feel like configuration, because the consumer of that work was a human who wanted to ship a workflow by Friday.
MCP is the moment that assumption breaks. It gives a model a standard way to discover the tools available to it, read their input and output contracts, and call them — without a human in the loop deciding which endpoint to hit or what the payload should look like. The agent asks the server what it can do, the server answers in a machine-readable schema, and the agent decides.
That inversion sounds small. It is not. A person used to supply a lot of judgment for free: they knew which endpoint to hit, they noticed when a response looked wrong, they paced themselves, they remembered last week’s outage. Take the person out and that judgment has to live somewhere. It ends up being the integration layer’s problem — discovery, tracing, access control, version discipline — and most integration layers were never asked to carry it before.

Discovery has to be machine-readable, or the agent guesses
A human learns your API once and remembers it. An agent learns it on every run, from whatever you hand it. If the only description of a tool is a name and a free-text blurb, the agent fills the gaps with plausible nonsense — inventing a customer_id field because most APIs have one, assuming a date format because the example happened to use it.
The fix is not better docs. It’s a machine-readable contract the agent reads instead of guessing. This is why OpenAPI specs and JSON Schema stopped being nice-to-haves the day agents started calling tools. A tool that exposes a typed schema — these fields, these types, this is required, this is an enum with exactly these values — gives the agent a contract to obey instead of a vibe to approximate. The schema becomes a guardrail, not documentation.
The platforms that will struggle here are the ones where the integration’s real behavior lives in a UI and the published contract is an afterthought. The agent can’t see the canvas. It can only see what you exported. If those two things have drifted apart, the agent is calling a tool that doesn’t exist the way it thinks it does.
You lose observability exactly where you start needing it most
Here is the failure mode nobody demos. Your agent calls a tool. The tool calls a downstream service. That service is slow today. The agent, waiting on a response that’s taking 800ms instead of the 100ms it expected, hits its timeout, retries, calls a second tool to compensate, and produces an answer that’s subtly wrong. Your user files a ticket. You go to investigate.
What can you actually see?
If your integration platform logs into its own proprietary console with a UI-only view and a short retention window, the honest answer is: not much. You can see that the workflow ran. You cannot see the span where the 800ms came from, you cannot correlate the agent’s retry with the downstream slowdown, and you cannot replay the decision. The agent made a judgment call inside a black box and the box already closed.

This is the part of the agent story the category is least ready for. Agents make integration calls opaque by default — they decide, retry, and compose faster than any human would, and they do it without narration. The only thing that makes that legible is real tracing. OpenTelemetry is the standard for this: spans that cross from the agent’s decision through the tool call to the downstream service, in a format your own observability stack already understands. Notably, almost no integration platform exports agent-layer traces in an open format. They keep them, briefly, in a place you can’t query. You find out where the latency came from by guessing, which is the same thing the agent was doing, which is the whole problem.
When the caller is a model, the trace is the only witness. If you can’t query it in your own stack, you don’t have one.
Governance was built for users. Agents don’t have users.
Every access model you’ve ever shipped assumes a user. OAuth scopes, RBAC, audit logs — all of it answers the question “who is allowed to do this,” where “who” is a person or a service account standing in for one.
An agent breaks that question. There’s no user. There’s a task, a context, and a set of tools the agent might reach for. The governance surface is no longer “which endpoints can this user hit.” It’s a harder set of questions:
- Which tools does this agent even see? Tool visibility is the new permission boundary. An agent can’t misuse a tool that was never offered to it.
- Which fields can it read or write? Field-level scope matters more when the caller will happily pass along whatever it’s given.
- Can it call tool B after tool A? Sequencing and side-effect classification — is this call a read, a write, or something destructive — let you gate the dangerous ones.
- On whose behalf is it acting? The same agent serving two different customers must not see across the boundary, which turns multi-tenant isolation from a deployment detail into a per-call requirement.

The old playbook for that last one was to stand up a separate integration instance per customer. That’s fine at ten customers and a slow-motion outage at a hundred. The agent-era pattern is a single surface that binds tenant identity per request — but that only works if your platform can carry that identity through the call instead of assuming one instance equals one tenant.
Tool definitions are now a reliability surface
The last thing that changes is the most boring and the most expensive. When a human owns a brittle integration, they baby it. When an agent owns it, it leans on it — hard, in loops, under retry policies that assume the tool behaves the way its contract says.
So the contract has to be true, and it has to stay true across changes. If you tweak a tool’s behavior and the agents calling it don’t find out, they burn their token budgets and timeouts recovering from a surprise. Tool definitions need the same discipline as the services behind them: versioning, review, the ability to roll back. The teams that treat an agent-callable tool as a real artifact — something that lives in git, gets reviewed before it changes, and can be pinned to a known-good version — will spend their on-call hours on actual incidents. The teams that treat it as a setting someone clicked will spend them explaining why the agent started doing something new at 2 a.m. and nobody changed anything.
The honest part
You don’t need any of this on day one. If you’re wiring a single internal agent to two read-only tools for a prototype, a static config and a log file are completely fine. MCP and the discipline around it earn their keep when agents start calling tools you didn’t write, on behalf of customers who aren’t you, often enough that the bill and the blast radius both matter. Reach for the heavy machinery when you cross that line — not before.
But most teams shipping agents into production are already across it and haven’t noticed, because the workflow still runs and the demo still works. The gap only shows up the first time something is wrong and you go looking for the trace that isn’t there.
What to actually check
The question to take back to your own stack isn’t “should we adopt MCP.” It’s whether the integration layer underneath your agents can hold up once a model is the one calling. Can an agent discover your tools from a real schema, or is it guessing? When something’s slow, can you trace it in the observability stack you already run, or does the trail end in someone’s console? Do you control which tools an agent sees and whose data it touches? And when a tool definition changes, does that go through review, or does it just change?
This is the bet we made with Koodisi: that an agent calling your APIs is the normal case, not the exotic one. So the things this post argues for — tools an agent can read from an OpenAPI schema, OpenTelemetry traces you can pull into your own stack on every tier including the free one, integrations versioned in git like the rest of your code — are the floor, not a tier you upgrade into. The free Community tier is enough to see what an agent-callable tool looks like when the platform assumes the caller is a model.
The protocol is the easy part. The contract is the work.