The MCP tool sprawl is already breaking teams: how to pick one agent runtime instead of 10 incompatible tools
I’m Denis Shokhirev, an Agentic AI Systems Architect based in Freiburg im Breisgau, Germany, and at DennisCraft AI Studio I ship production AI systems on Claude, Supabase, n8n, Doppler, and self-hosted Postgres. The failure mode I keep seeing is painfully specific: a team connects MCP servers, workflow tools, local scripts, and model SDKs, gets a clean demo, then spends the next month debugging permissions, schema mismatches, retries, and missing audit trails once real users touch the system. M
I’m Denis Shokhirev, an Agentic AI Systems Architect based in Freiburg im Breisgau, Germany, and at DennisCraft AI Studio I ship production AI systems on Claude, Supabase, n8n, Doppler, and self-hosted Postgres. The failure mode I keep seeing is painfully specific: a team connects MCP servers, workflow tools, local scripts, and model SDKs, gets a clean demo, then spends the next month debugging permissions, schema mismatches, retries, and missing audit trails once real users touch the system.
MCP is not the problem. Tool sprawl is. Once every part of the stack introduces its own execution model, error format, auth path, and state store, the agent stops being a system and becomes a pile of adapters. In regulated environments, that breaks faster than most teams expect.
Why MCP sprawl hurts before model quality does
Most teams assume the weak point is reasoning quality. In production, I more often see failures in the execution layer: the model selects the right action, but the tool wrapper returns inconsistent JSON, a workflow times out, a secret is rotated in one place but not another, or the side effect executes without a policy check.
Anthropic’s documentation on tool use and Model Context Protocol is useful precisely because it pushes teams toward standardized tool definitions and predictable context exchange. Source: Anthropic Docs, 2025, https://docs.anthropic.com/. That matters more than adding yet another connector. On three recent deployments I reviewed, the highest-cost incidents came from runtime inconsistency, not from the model “thinking wrong.”
What tool sprawl looks like in practice
| Pattern | What teams do | What breaks |
|---|---|---|
| Duplicate tool registries | The same operation exists in Claude Code, n8n, and a custom service | Schema drift and permission drift |
| Mixed error contracts | One tool returns HTTP JSON, another plain text, another silent timeout | Recovery logic becomes unreliable |
| Fragmented secrets | Some secrets in Doppler, some in env files, some inside workflows | Rotation and audit become manual |
| Scattered state | Conversation memory, database state, and workflow state all differ | You lose reproducibility |
What an agent runtime actually is
I use “runtime” very narrowly. It is not just an SDK and not just a protocol. An agent runtime is the execution layer that accepts a tool decision, validates it, applies policy, handles retries and timeouts, records state transitions, and logs enough data for later review. If you do not have that layer, you do not have an agent runtime. You have integrations.
In my stack, Claude or the Anthropic SDK usually handles model-side tool selection. Postgres or Supabase stores state and audit records. n8n handles business workflows that benefit from visible orchestration. Doppler manages secrets. The important part is that the model sees one stable execution contract, not five unrelated subsystems.
A minimal tool contract with a real SDK
from anthropic import Anthropic
import os, json
client = Anthropic(api_key=os.environ["ANTHROPIC_API_KEY"])
tools = [{
"name": "create_invoice",
"description": "Create invoice in ERP",
"input_schema": {
"type": "object",
"properties": {
"customer_id": {"type": "string"},
"amount": {"type": "number"}
},
"required": ["customer_id", "amount"]
}
}]
response = client.messages.create(
model="claude-sonnet-4-5",
max_tokens=800,
tools=tools,
messages=[{"role": "user", "content": "Create invoice for C-102 with 1200 EUR"}]
)
print(json.dumps(response.model_dump(), indent=2))This does not solve orchestration by itself. It does show the baseline I care about: explicit schema, explicit model call, no prompt-parsed fake API. Once that exists, you can enforce policy and observability around it.
How to pick one runtime instead of 10 tools
Ignore catalog size for a moment. I would evaluate five harder criteria.
1. One tool definition standard
If one part of your system defines tools with JSON Schema and another relies on prompt conventions, drift is inevitable. Inputs, outputs, and failure modes need one contract.
2. Action-level observability
I need to know which agent invoked which tool, with which arguments, from which state, under which policy decision, and what side effect happened. If I cannot replay the chain, I cannot trust it in production.
3. State outside the model
Critical state cannot live only in context windows. Put it in Postgres or Supabase with versioned records and clear ownership. Otherwise, retry behavior and recovery become guesswork.
4. Policy before side effects
The model should not decide on its own whether it may update payouts, send customer emails, or access PII. That decision belongs outside the model.
type ToolCall = { name: string; input: Record<string, unknown> };
export function allowTool(call: ToolCall, role: string): boolean {
const restricted = ["send_email", "update_payout", "delete_record"];
if (restricted.includes(call.name) && role !== "approved_operator") {
return false;
}
if (call.name === "update_payout" && typeof call.input["amount"] === "number") {
return Number(call.input["amount"]) <= 1000;
}
return true;
}5. Pre-release scanning for generated code and workflows
If agents generate code, SQL, or workflow definitions, scan them. OWASP’s LLM and GenAI guidance is useful here, especially around excessive agency and insecure output handling. Source: OWASP GenAI Security Project, 2025, https://genai.owasp.org/. For Python and repo hygiene, I usually wire in semgrep, bandit, and gitleaks.
semgrep --config=p/owasp-top-ten .
bandit -r app/ -f json -o bandit-report.json
gitleaks detect --source . --report-format json --report-path gitleaks.jsonWhere n8n, Supabase, and Postgres help — and where they become the problem
n8n is useful when you need visible orchestration across many external systems. It becomes a liability when half the agent logic is hidden in nodes, undocumented branches, and mutable credentials. Supabase is a good managed layer for state, auth, and internal tools, but I still want one clear system of record. For higher-sensitivity cases, that is often self-hosted Postgres.
A healthy architecture lets you swap the model or add another tool provider without rebuilding your policy layer, state model, and audit trail. An unhealthy one couples everything so tightly that replacing one connector rewrites the whole stack.
A practical runtime pattern for regulated teams
My default pattern is conservative. The model decides, but does not execute side effects directly. Every tool call passes through a policy layer. State transitions and tool outcomes are written to Postgres. Secrets are centralized. Workflows that need business-facing visibility live in n8n. Generated artifacts go through static analysis and, where money, customer data, or external messaging is involved, human review.
There is a related source worth keeping close: the OpenAI Cookbook repeatedly demonstrates structured tool calling and controlled execution patterns instead of free-form action generation. Source: OpenAI Cookbook, 2024–2025, https://cookbook.openai.com/. Different vendor, same lesson: standardize execution before you scale tool count.
FAQ
Is MCP enough to standardize the full stack?
No. MCP helps standardize how tools are described and invoked. It does not replace state management, policy enforcement, audit logging, or recovery strategy.
Should I keep orchestration inside n8n?
Only where that improves visibility and speed. If your main decision logic and failure handling live only inside workflow nodes, maintenance gets expensive quickly.
Can I do this without self-hosted Postgres?
Yes, if your managed setup meets your requirements for logging, backups, access control, and auditability. The critical point is having one source of truth, not three partial ones.
What matters more in production: the model or the runtime?
Usually the runtime. You can change models in days; untangling a bad execution layer can cost months of rework.
How do I audit tool sprawl first?
Map every tool call, secret source, state store, and side effect. If your team cannot explain in 30 minutes where a decision is made and where it is executed, sprawl is already present.
Which layer in your agent stack causes the most production pain right now: tool execution, policy checks, state recovery, or observability? I’d genuinely like to know, because that answer predicts architecture debt faster than benchmark scores ever will.
I run a free 30-min stack audit for DACH founders building AI in regulated markets. DM me on LinkedIn or write to @ger_dennis_ai.
Turn your process into an AI system
Production quality. DACH B2B focus.