Building agents inside an MCP-only architecture
What happens when every tool the agent uses is exposed via MCP, every memory access is via MCP, every observability hook is via MCP. The architecture gets cleaner, the lock-in shrinks, and a few specific design decisions become obvious.
A useful architectural exercise for late 2025: what does an agent platform look like if every interaction with the outside world goes through MCP? Every tool is an MCP server. Every memory access is an MCP server. Every observability hook is an MCP server. Every audit trail flows through MCP. The agent runtime itself is the only non-MCP component, and it talks exclusively in MCP-shaped requests.
The exercise is worth doing because the architecture that emerges is cleaner than the typical patchwork, the vendor lock-in surface shrinks meaningfully, and a few specific design decisions become obvious that aren't obvious in mixed-protocol architectures. Worth being explicit about what works and where the rough edges are.
What "MCP-only" actually means
The constraint, in concrete shape:
- Tool access via MCP servers. No direct API calls from the agent code. Every external action is a tool call against an MCP-exposed surface.
- Memory via MCP servers. Conversation memory, user preferences, persona definitions, all exposed via MCP-memory primitives. The agent doesn't directly access state stores.
- Observability via MCP. Audit logs, metrics, traces, emitted into MCP servers that capture them. The agent doesn't directly log to a backend.
- Policy decisions via MCP. OPA-style policy evaluation exposed as an MCP server. The agent calls "is this allowed" via MCP rather than embedding policy logic.
- Configuration via MCP. Even the agent's own configuration (which models it can use, what its scope is, what tools it can reach) is queried via MCP.
The MCP-only constraint means the agent runtime is small and protocol-shaped. Everything that varies between deployments lives behind MCP servers. The runtime ports across deployments cleanly because the deployment-specific stuff is on the other side of the protocol.
What gets cleaner
A few specific architectural simplifications that emerge:
The agent runtime becomes minimal. Without direct integrations to specific tools, memory backends, observability platforms, the runtime is essentially "talk MCP, decide what to call, integrate the responses." A few hundred lines of well-designed code, not the typical thousands of lines of integrations.
Tools become genuinely portable. A tool exposed as an MCP server in one deployment runs in another deployment with no code change. The "MCP-as-the-tool-portability-layer" promise actually delivers when there's no fallback to direct integration.
Memory becomes vendor-neutral. When memory access is MCP-shaped, swapping memory backends (from a vendor's saved-memories surface to a local Postgres-backed memory server to a custom Redis-backed implementation) requires no agent-code changes.
Observability is uniform. Every action the agent takes flows through MCP and into the observability servers. The shape of the audit trail is consistent across actions; queries against it are uniform; tooling that reads the audit trail works the same regardless of what the underlying action was.
Policy enforcement is uniform. Every action checks against the policy server before executing. The policy logic is centralized; the enforcement is consistent; there's no class of action that bypasses policy because it took a non-MCP path.
The vendor lock-in surface shrinks dramatically. The agent runtime is the only thing that's potentially vendor-specific. Everything else is protocol-shaped and portable. Switching agent runtimes (between vendor SDKs, or to a custom one) is a smaller migration than the typical mixed-protocol case.
These are real wins. The architecture is cleaner, the lock-in is smaller, the operational story is more coherent.
What gets harder
Worth being honest about the trade-offs:
Latency tax on everything. Every external interaction is an MCP call. Even the cheapest local actions pay a small protocol-overhead cost. For most workloads this is noise; for very high-throughput workloads it adds up.
Tool authoring is more deliberate. When a quick experimental tool needs to be MCP-shaped before the agent can use it, the activation energy for a new tool is higher than the "just call this function from the agent code" alternative. The discipline pays back; the friction is real.
Schema standardization matters more. The MCP protocol is stable but the schemas inside it (what an "agent identity" looks like, what a "memory item" looks like) aren't fully standardized. The MCP-only architecture is exposed to whichever schema choices the deployment makes; portability suffers if the schemas drift from emerging conventions.
Some integrations don't fit. A few external systems are awkward to wrap in MCP, long-running streaming connections, push-notification surfaces, anything where the request-response shape doesn't fit cleanly. These need adapter MCP servers that do the impedance matching.
The MCP server population grows. A serious deployment ends up with dozens of MCP servers, one per tool surface, one for memory, one for policy, one for audit, several for various integrations. The routing layer I wrote about becomes more important; without it, the server population is hard to operate.
These aren't dealbreakers. They're the normal trade-offs of any standardization choice, you give up some flexibility for substantial uniformity gain.
What an MCP-only agent looks like in practice
A concrete sketch of an MCP-only agent platform:
The agent runtime. A small service that takes a user request, plans, calls tools (all via MCP), accumulates results, produces output. Talks to the model layer directly (because the model layer isn't reasonably MCP-shaped) and to everything else via MCP.
A small set of "core" MCP servers that every agent uses: - A memory server for conversation state and user preferences. - A policy server for allow/deny decisions. - An audit server that captures every action. - A configuration server for runtime config and feature flags. - A metrics server for observability emission.
A larger set of "tool" MCP servers for the specific external interactions the agents need: - Per-domain tool servers (CRM, email, calendar, code repo, etc.). - Wrapped third-party services (Slack, Notion, GitHub, etc.). - Wrapped internal systems (ticketing, monitoring, deployment).
A routing layer (MetaMCP-class) that combines the MCP server population into a coherent surface for the agent. Handles per-agent scoping, capability resolution, observability spans across servers.
A small operations surface for managing the MCP server population, registration, health checks, configuration, version management.
That's the architecture. It's recognizable to anyone who's built an agent platform; the discipline is in keeping the MCP-only constraint rather than letting direct integrations creep in for "just this once."
Why the discipline is hard to keep
The temptation to break the MCP-only constraint shows up regularly:
Performance pressure. A direct integration would be faster than going through MCP. The temptation is to bypass MCP "just for this one critical path." Once allowed once, the direct-integration class of code grows; the architectural simplicity erodes.
Existing code that already works. When migrating to MCP-only from a mixed-protocol architecture, the existing direct integrations work. The activation energy to wrap them in MCP is real. The pragmatic path is to leave them and migrate gradually; the disciplined path is to wrap them now and avoid the long-tail mixed state.
Vendor SDKs that don't speak MCP. Some vendor SDKs (particularly the model-vendor agent SDKs) don't have MCP-shaped interfaces for everything. The temptation is to call vendor-SDK functions directly for the cases the SDK handles natively. The discipline is to wrap those in MCP servers anyway.
Time pressure. New features ship faster with direct integration than with the MCP wrapping discipline. Teams under release pressure often skip the wrapping. The technical debt accumulates.
The MCP-only architecture works when the team commits to it; it works less well when it's "MCP-mostly" with a long tail of direct integrations. The discipline is the hard part.
Where this fits in the broader pattern
The MCP-only architecture is the natural endpoint of the agent design patterns discipline. The patterns work best when there's a uniform foundation beneath them; MCP-only provides that uniformity. The patterns work less well when the foundation is patchwork; MCP-only addresses that.
It also extends the vendor-lock-in mitigation pattern, the lock-in dimension that survives is the agent-runtime choice, which is the smallest piece of the architecture. The other dimensions (tools, memory, policy, observability, audit) are all portable.
For teams building new agent platforms in late 2025: starting from MCP-only is easier than retrofitting it. For teams with existing agent platforms: the gradual migration path is real and worth doing, with the explicit recognition that "we'll be MCP-only by Q3 2026" is a reasonable plan.
The honest summary
MCP-only agent architecture is cleaner, more portable, and more disciplined than the typical mixed-protocol pattern. It costs some flexibility and adds some friction. The trade-offs favor MCP-only for serious production deployments; less so for prototype or experimental work.
The pattern is the right architectural endpoint for the next two years of agent platform work. The teams that adopt it deliberately get the clean architecture and the lock-in protection. The teams that drift into mixed-protocol patterns get the typical patchwork, works fine for a while, accumulates rough edges, eventually requires the same migration just in worse circumstances.
Worth being deliberate about. The MCP standardization made this architecture possible; the engineering discipline to commit to it is what makes it worthwhile.