MCP Server Architecture for Coding Agents
MCP collapses the combinatorial chaos of wiring agents to tools into one standard interface.

Before any of this makes sense, you need to understand the problem MCP was built to solve.
Picture a world where every coding agent had to be hand-wired to every tool it used. GitHub connector: custom. Postgres connector: custom. Terminal access: custom. Each one built by a different team, each one brittle in its own special way. Every time the tool's API changed, or the agent's architecture changed, someone had to go fix the glue in between. It was like trying to fill an ocean with a teaspoon — technically possible, but the math never works in your favor.
Anthropic described this as a combinatorial problem: N tools multiplied by M clients. Every new agent makes every integration problem worse. Every new tool makes every agent more expensive to maintain. The matrix just keeps growing.
That's the trap. And it scaled terribly as agents got more capable, because more capable agents needed more tools.
MCP's answer was to stop negotiating the matrix and collapse it. One standard interface. Any compliant agent connects to any compliant server, regardless of who built either side. The USB-C analogy is almost too clean, but it holds: you stopped caring which laptop made the charger. You just plugged it in.
The integration burden shifted from "every agent team builds every connector" to "every server maintainer builds once, for everyone." That's a fundamentally different problem. And it's solvable.
One governance note worth flagging: Anthropic released MCP in November 2024, then donated it to the Linux Foundation's Agentic AI Foundation in December 2025, alongside founding projects from Block and OpenAI. This isn't a vendor feature that gets deprecated when priorities shift. It's infrastructure. The whole ecosystem is converging on it.
The Three Primitives That Define What an MCP Server Can Do
MCP is built on JSON-RPC 2.0. Its entire expressive surface comes down to exactly three primitives. Not a dozen feature flags, not a sprawling API surface. Three things.
Anything a coding agent needs to do maps onto one of three categories, and designing a good MCP server is mostly a question of deciding which category something belongs in.
Here are the three:
- Tools are actions. Verbs. Run a test suite, create a file, open a pull request, trigger a deployment. These are the things an agent does.
- Resources are data. Nouns. Files, database records, API responses, log streams. The raw material an agent reads before it reasons or plans.
- Prompts are reusable templates that a server can expose to the client. Less glamorous than the other two, but meaningful in multi-step workflows where framing the task correctly is half the battle.
The primitives are intentionally minimal. They're not a feature list. They're a grammar. And grammars are powerful precisely because they're constrained — as one engineer put it: "Why did the API go on a diet? Because it had too many endpoints."
One thing they deliberately leave out: how any of this actually travels between components. That's transport, which is its own layer. The primitives define what gets exchanged. Transport defines how it moves. Keeping those concerns separate is one of the smarter design choices in the spec.
The practical implication for builders: your main design decision isn't "what does MCP support?" It's "is this thing a Tool or a Resource?" The protocol doesn't make that call for you. A schema inspection capability could live as either. Getting that distinction right shapes how agents interact with your server downstream.
How the Host-Client-Server Topology Actually Works at Runtime
There are three distinct roles in every MCP interaction. They sound similar until you understand what each one is responsible for, and then they're very different.
- The Host is the application the developer is actually working in. A Cursor session. A CLI runner. A CI pipeline. The host orchestrates the agent and holds the overall context for what's happening.
- The Client lives inside the host. It's the component that speaks MCP. It connects to one or more servers, issues requests, and pipes results back to the model.
- The Server is a process that exposes Tools, Resources, or Prompts to any compliant client. Servers are deliberately narrow. A Postgres MCP server knows about database operations. It knows nothing about the GitHub pull request the agent is working toward.
That narrowness isn't a limitation. It's the point.
Composability comes from the host assembling multiple servers into one coherent session. Consider an agent tasked with "add rate limiting to the API gateway." That agent might simultaneously hold open connections to a filesystem server, a terminal server, a GitHub server, and a test-runner server. The host coordinates all four. The model reasons across all four as if they were one unified surface.
That raises a question worth thinking through: what happens when one of those servers fails?
In the old custom-integration model, the failure domain was the whole agent. Everything was wired together, so a break anywhere broke everything. In the MCP topology, failure domains are scoped to individual servers. If the test-runner server goes down, the filesystem server keeps working. The host can retry, swap, or skip without tearing down the entire session.
That's not a small difference in a production environment. That's the difference between an incident and a hiccup.
Transport Layer Choices and What Each One Is Actually For
MCP is transport-agnostic by design. The protocol spec defines what messages mean. It deliberately says nothing about how those messages move. That separation lets the same protocol work across very different deployment contexts.
As of the June 2025 spec revision, two transports are in active use:
- stdio communicates over standard input/output. It's for local tool servers running on the same machine as the host. Low latency, no network stack, trivial to spin up. This is the right choice when the server lives next to the agent.
- Streamable HTTP is the transport for remote or hosted servers. It supports long-running connections, works across network boundaries, and is the foundation for cloud-deployed MCP infrastructure.
There's a third name you'll see in older documentation: SSE (Server-Sent Events). This was an earlier remote transport that the ecosystem is actively moving away from. Building new servers on SSE today means inheriting technical debt you'll eventually have to unwind. It's not a disaster, but it's an unnecessary tax on future you.
The practical decision rule is almost embarrassingly simple: local tools get stdio, hosted or shared tools get Streamable HTTP. The choice is rarely ambiguous once you know where the server actually lives.
But here's where teams get caught out. They treat the two transports as roughly equivalent and don't think through the downstream differences. Latency differs. Security surface differs substantially. Operational complexity differs. A local stdio server running in a dev environment and a remote Streamable HTTP server deployed to shared infrastructure are not the same operational animal, even if they expose the same Tools. Teams that discover this in production, rather than in architecture review, have a harder day than necessary.
How the November 2025 Spec Update Changed MCP's Enterprise Readiness
Through most of 2025, enterprise adoption was slower than the ecosystem's momentum suggested it should be. The protocol was architecturally sound. The developer enthusiasm was real. But the governance layer was missing.
Security teams kept asking the same questions, and the spec couldn't answer them.
The November 2025 update addressed this directly with three additions:
- Asynchronous operations. Agents can now initiate long-running tasks and retrieve results later, rather than holding a blocking connection open. This matters enormously for CI pipelines and deployment workflows, where the task is measured in minutes and a blocking connection is not a viable pattern.
- Formal server identity verification. Servers can now prove what they are before an agent trusts them with tool calls. This closes a gap where a malicious or misconfigured server could impersonate a legitimate one. Before this, trust was essentially implicit.
- Structured audit trails. Every tool invocation can be logged in a standardized format. Security and compliance teams get the observability they need without every team building a bespoke logging layer from scratch.
Each of these maps directly to a question that shows up in enterprise security reviews. This update wasn't a feature addition. It was a prerequisite for institutional sign-off.
What changed in practice: teams that had been prototyping and waiting now had the primitives to write internal security reviews and pass procurement. The underlying architecture had always been capable of supporting serious workflows. The governance layer just had to catch up to where the engineering had already gone.
The Security Risks Specific to MCP's Architecture and How They Arise
Here's the tension at the heart of MCP's design: the openness that makes it powerful is exactly what makes its attack surface different from a traditional API.
Any compliant server can expose any Tools and Resources. That's the whole point. And it means the agent is, by default, trusting the server's description of itself. The agent cannot independently verify that a server actually does what it says it does.
OWASP maintains an MCP-specific Top 10. The risks most consequential for coding agents:
- Tool poisoning. A malicious or compromised server describes itself as doing one thing and does another. The agent has no independent way to verify the description. It just trusts it.
- Prompt injection via Resources. A file an agent reads, a database record, a log entry. Any of these can contain instructions that redirect the agent's behavior. The agent often cannot cleanly distinguish data from instruction. That's a structural problem, not a bug that gets patched.
- Excessive tool permissions. A server that exposes write access to the entire filesystem, or unrestricted terminal execution, amplifies the blast radius of any agent error or adversarial input. The tool isn't the problem. The scope of the tool is.
- Rug pulls and supply chain risk. A publicly listed MCP server can change its behavior after an organization has reviewed and deployed it. There is no stable versioning guarantee across the ecosystem today. Approval at time T doesn't mean safety at time T+6.
It's also worth being direct about why these risks are more acute for coding agents specifically. An agent that can write and execute code, open pull requests, and trigger CI pipelines has real system access. This isn't an agent answering questions. It's an agent taking actions in systems you care about. A compromised or misbehaving server has a path to production.
These aren't theoretical vulnerabilities. They're architectural properties of an open protocol applied to systems with real execution capability. Treating them as theoretical is one of the more expensive mistakes a team can make.
Defense-First Practices for MCP Server Deployments in Development Environments
The mitigation mindset that actually works here is defense-first architecture. Not bolt-on security reviewed after an incident. The decisions that matter most happen when you're selecting and configuring servers, not when you're writing the post-mortem.
A few practices that hold up in real deployments:
Least privilege, applied specifically to MCP. Every server should expose the narrowest Tools needed for its job. A GitHub server a coding agent uses only to open pull requests should not also have push-to-main access. The principle isn't new. Applying it to tool scope specifically takes intention.
Input validation at the server boundary. Servers should treat all inputs, including agent-generated inputs, as untrusted. Data retrieved via Resources should never flow directly into tool execution paths without inspection. The agent isn't adversarial, but the data it reads might be.
Server identity and version pinning. Use only servers with formal identity verification (available since the November 2025 spec). Pin specific server versions in production environments. Have a defined process for reviewing updates before they reach agent-accessible infrastructure. An unreviewed update to a production-accessible server is a supply chain event.
Audit log review as routine, not reactive. The structured audit trails added in November 2025 are only useful if someone is actually reading them. Platform teams should treat MCP logs the way they treat application logs: monitored, with anomaly alerts. Saving logs nobody looks at is not a security practice. It's comfort theater.
Sandboxed execution environments. Agents that can run terminal commands or execute code should do so in isolated environments with defined egress rules. The MCP server enables the capability. The surrounding infrastructure constrains its reach. Both matter.
Human-in-the-loop checkpoints for high-stakes categories. File writes, deployments, pull request merges. These are candidates for an approval step even in otherwise autonomous workflows. The autonomy dial should be set by the risk profile of the tool, not by what's most convenient to configure.
MCP's Relationship to A2A and Where Multi-Agent Architectures Are Heading
When Google announced A2A (Agent-to-Agent protocol) in April 2025, a common reaction was to frame it as competition for MCP. That framing is wrong, and it leads to architectural decisions that don't hold up.
The cleaner picture is layers:
- MCP is vertical. It connects an agent to tools, data sources, and services. It handles the agent-to-infrastructure relationship.
- A2A is horizontal. It connects agents to other agents. It handles task delegation between autonomous systems.
These aren't alternatives. They're complements operating at different levels of the stack.
In a multi-agent coding workflow, they compose naturally. A coordinating agent uses A2A to assign a subtask ("write the test suite for this module") to a specialist agent. That specialist agent then uses MCP to call the filesystem, test runner, and repository servers it needs to actually do the work. The protocols don't compete. They each handle the layer they were designed for.
One governance development worth noting: both protocols are now housed under the Linux Foundation's AAIF, alongside IBM's ACP (which merged into A2A in mid-2025). That consolidation matters. The layer boundaries are being standardized across organizations, not fragmented across competing vendor ecosystems. That's a meaningful signal about durability.
For teams building multi-agent coding systems, the architecture is not speculative. The protocol stack is defined, it's governable, and it's already running in production systems. The design question isn't whether to use it. It's how to layer it correctly.
What the Ecosystem of Available MCP Servers Actually Gives a Coding Agent Today
The number of publicly listed MCP servers has grown substantially since the November 2024 release. The scale matters for one practical reason: most teams won't need to build from scratch for common integrations. The connectors already exist.
The categories most immediately useful to coding agents:
- Version control and code review. GitHub and GitLab servers let agents open pull requests, query issue history, and read review comments without the developer copying and pasting context by hand. The agent works with the repository directly.
- Database access. Postgres, SQLite, and similar database servers expose schema and query capabilities as Tools. An agent writing a migration can read the actual schema first, rather than inferring it.
- Documentation and library reference. Servers like Context7 surface version-correct library documentation. This addresses a real and underappreciated problem: models are trained on data from months or years ago. An agent calling a current-docs server gets the actual API signatures, not whatever the training snapshot captured.
- Browser automation. Servers that give agents a headless browser for testing UI flows, verifying that a deployed change renders correctly, or extracting structured data from pages.
- CI/CD and observability. Servers that surface build logs, test results, and deployment status as Resources. An agent can read a failing CI run and propose a fix in the same session, without the developer manually pulling that information and feeding it in.
The cumulative effect of this ecosystem is that an agent can move from "here's the issue" to "here's a tested, submitted pull request" within a single MCP-connected session. The developer doesn't construct any glue between tools. It's already there.
But. Ecosystem breadth does not guarantee ecosystem quality. Server reliability, maintenance, and security posture vary widely across public listings. A list of available servers is a starting point. A vetting process is the actual work.
How Coding Agents Use MCP's Code Execution Capability to Scale Beyond Direct Tool Calls
The naive pattern is intuitive: agent gets a task, calls each tool directly, accumulates results in context, repeats until done. It works fine for simple tasks. It breaks down as tasks get more complex.
Why? Context window. Every tool definition and every result takes up space. In a complex coding task with dozens of tool interactions, the agent can exhaust its available context before the work is finished.
Anthropic's own engineering documentation describes a better pattern. Instead of calling tools directly, agents write code that calls tools. The code runs outside the context window. Only the result comes back. The context stays clean.
MCP is what makes this pattern scale. Because MCP is a universal protocol, an agent that has implemented MCP once can write code against any MCP-compliant server without learning a new interface. The ecosystem of servers becomes the agent's callable library. Write code once that knows how to speak MCP; it now has access to everything that speaks MCP back.
What this enables is agents that can sustain long, multi-step workflows. Analyze a codebase, run targeted tests, iterate on a fix, verify the result, open the pull request. Without the context budget collapsing somewhere in the middle because the agent accumulated too many raw tool results.
One thing worth challenging here: is this pattern actually that different from just being careful about context management? It is. The difference is structural, not just disciplinary. Writing code that runs externally isn't "be more efficient with your context window." It's moving the work outside the window entirely. The ceiling disappears rather than being managed.
The practical implication for teams: designing agents to write and execute code rather than accumulate direct tool results is an architectural decision. It should happen early. Retrofitting it into an existing agent system is harder than designing for it from the start.
That's really the through-line of everything here. MCP's architecture, the primitives, the topology, the transport choices, the security posture, the multi-agent layer. None of it is especially complicated in isolation. The complexity is in how the pieces compose, and in making the right choices about how they compose before you're in production and regretting the ones you made at 2am during a prototype sprint.
The protocol gives you a grammar. What you build with it is still up to you.


