Agent infrastructure

Platform integration

What is an MCP server? A deep-dive for engineering teams

What is an MCP server? A deep-dive into Model Context Protocol server architecture, the protocol surface, production requirements, and what MCP doesn't solve.

9 minute read
Decorative imagery showcasing Pontil's brand

If your team is evaluating how to expose tools to agents, you've run into MCP. The question that keeps coming back: what is an MCP server, actually, and how does it differ from the API layer you already run? This piece answers that — not at the marketing-page level, but at the level an engineering team needs to make a real decision.

In one sentence: an MCP server is a process that speaks the Model Context Protocol and exposes a typed catalogue of tools, resources, and prompts to an agent client over a defined transport. It's a contract layer, not a runtime philosophy. The interesting questions are about what belongs on the other side of that contract — and what an MCP server doesn't solve.

The sections below cover the architecture, the protocol surface, what running one in production actually demands, where MCP servers fit relative to APIs and gateways, and the open questions teams should be asking before they commit.

The architecture, without the marketing layer

Model Context Protocol (MCP) is an open specification published by Anthropic in late 2024. It defines how an agent client (a host process running a model) discovers and invokes capabilities provided by a server. The wire format is JSON-RPC 2.0. The transport is either stdio for local processes or Streamable HTTP for remote ones (which replaced the original HTTP+SSE transport in the 2025-03-26 revision). That's the whole shape.

An MCP server is the process on the other end of that connection. It exposes three primitives: tools (functions the agent can call), resources (data the agent can read), and prompts (templated instructions the agent can request). Each primitive has a typed schema. The client lists what's available, the model chooses what to invoke, and the server runs the work and returns a result.

The architecture is deliberately thin. MCP doesn't tell you where the server runs, how it authenticates the underlying systems, how it scales, or how it stays current as the products it fronts change. Those are deployment concerns. The protocol just standardises the conversation between agent and tool surface — which is genuinely useful, because before MCP every agent framework had its own incompatible tool format.

The usual mental model is plugin architecture: the agent is the host, MCP servers are the plugins, and the protocol is the plugin API. That's roughly right, with one caveat. Plugins typically run inside the host. MCP servers run outside it, often on different machines, often owned by different teams. That separation is the whole point — and most of the operational complexity.

The protocol surface, in detail

Three concepts do most of the work. Understanding them clearly is the difference between treating MCP as a black box and treating it as something you can reason about.

Tools are the headline primitive. A tool is a named function with a JSON Schema describing its inputs and a structured output. When the agent decides to call a tool, the client sends a tools/call request with the tool name and arguments. The server runs the work and returns content — text, structured data, or an error. Tools are how agents do things: send the email, create the ticket, run the query.

Resources are read-only data the agent can pull into context. A resource has a URI, a MIME type, and content. The client lists available resources, the agent chooses what to read, and the server returns the bytes. Resources are how agents see things: the file, the document, the database row. The split between tools and resources matters because it lets the model treat reading and acting differently — useful for reasoning about side effects.

Prompts are templated instructions the server suggests to the client, usually surfaced in the agent's UI as slash commands or quick actions. They're the least-used of the three primitives in production, and the easiest to skip on a first pass.

Around these primitives, the protocol defines a handshake (initialize), a capability declaration (which features the server supports), notifications (server-to-client pushes for things like resource updates), and authorisation (OAuth 2.1 for remote servers, since MCP 2025-03-26). The full specification is versioned and documented at modelcontextprotocol.io; the current version at the time of writing is 2025-11-25.

The thing to notice: the protocol describes shapes, not behaviour. It tells you what a tool definition looks like on the wire. It does not tell you what your tool should do, how it should authenticate to the system underneath, or how it should behave when that system rate-limits you. Every MCP server makes its own choices there, and those choices are where production complexity lives.

What running an MCP server in production actually requires

A hello-world MCP server is about thirty lines of code. A production one is a different category of problem.

The first thing the thin protocol surface hides is authentication and identity. MCP defines OAuth 2.1 between the client and the server, but says nothing about how the server then authenticates to the system it fronts. If your MCP server exposes Salesforce as a set of tools, something has to hold a Salesforce session — and the choice between a shared service account and a per-user delegated credential is one of the most consequential decisions in the architecture. Service accounts are simpler and break every audit trail. Per-user auth honours real identity and doubles your auth surface. There's no third option.

The second is observability. JSON-RPC over stdio doesn't log itself. You need request tracing, error attribution, latency tracking per tool, and some way to answer the question "why did this agent call fail at 3am?" without re-running the agent. Most teams underestimate this until they have an incident.

The third is maintenance drift. Tool schemas are contracts. The systems they front change weekly. If the underlying API adds a required field and your tool definition doesn't update, the agent calls keep succeeding at the protocol layer and silently failing at the business layer. Catching that requires the same SDLC discipline you apply to your APIs — tests, CI, versioning — applied to a surface most teams treat as configuration.

The fourth is scope. A small MCP server with five tools is easy to maintain by hand. An MCP server fronting a real B2B SaaS product has hundreds of capabilities, and writing them by hand stops being viable somewhere around tool number forty. This is where the build-vs-buy decision usually lands: not on the protocol, but on the maintenance economics of the catalogue underneath it.

A hello-world MCP server
A production MCP server

Tool count

3–10

50–500+

Auth model

Hardcoded token

OAuth 2.1, per-user delegation, refresh handling

Observability

`console.log`

Distributed tracing, per-tool metrics, error attribution

Schema maintenance

Edited by hand

CI-validated, versioned, drift-detected

Failure handling

Throws on error

Retry policy, rate-limit awareness, circuit breaking

Deployment

Local stdio

Remote Streamable HTTP, horizontally scaled

Where MCP servers fit relative to APIs and gateways

This is where the category confusion gets expensive. An MCP server is not an API gateway. It's not an SDK. It's not an integration platform. It's a tool-catalogue endpoint that speaks a specific protocol to agent clients.

If your product already has a comprehensive REST or GraphQL API, an MCP server is mostly a translation layer: it takes the operations the API exposes and presents them as MCP tools the agent can discover and invoke. The MCP server doesn't add capability; it adds agent-readability. That's a real value, but it's bounded by what the underlying API exposes. If your API only covers a small fraction of what your product does — which is the normal state for B2B SaaS — wrapping it in MCP gives you an agent that can reach the same small fraction. The protocol doesn't widen the surface; it just makes the existing surface legible.

This is also why an MCP server is different from an API gateway like Kong or Apigee. Gateways front APIs that exist — they handle routing, rate limiting, auth at the edge, and policy enforcement. MCP servers front a catalogue of agent-callable operations, which may or may not map cleanly to the API underneath. Some MCP tools wrap a single API call. Others compose several. Others execute logic that has no API equivalent. The relationship between MCP tools and HTTP endpoints is many-to-many.

The layer below an MCP server is also worth being precise about. There are roughly three options for how a tool actually executes:

  1. Wrap an existing API call. Cleanest. Constrained to what the API exposes.
  2. Drive the UI through browser automation. Wider reach, fragile to UI changes, no contract with the underlying system. We've covered the trade-offs in detail elsewhere.
  3. Generate against the codebase directly. Reaches what the UI reaches, holds a real contract, requires tooling that most teams don't have.

The MCP protocol is agnostic to all three. The client cannot tell which one is happening on the other side of the wire. That's a feature for portability and a problem for operational reasoning — because the production characteristics of these three options are nothing alike.

The honest critique: what MCP doesn't solve

MCP is genuinely useful. It's also a protocol, not a strategy. A few things to be clear-eyed about.

It doesn't widen your capability surface. If your product's API covers a fraction of what the UI can do, an MCP server gives agents access to that fraction, formatted nicely. The structural API-behind problem doesn't go away because you put a protocol in front of it.

It doesn't solve maintenance. Tool schemas drift the same way API schemas drift, and the failure mode is worse — an out-of-date tool definition fails silently, mid-agent-run, at runtime. Building an MCP server commits you to maintaining a tool catalogue. That commitment is bigger than it looks on day one.

It doesn't define identity semantics. Whether your agent acts as the user or as a service account is the most important decision in your architecture, and MCP punts on it entirely. You'll make that decision yourself, and you'll live with it.

It's still moving. The spec has revised meaningfully three times since launch (2025-03-26, 2025-06-18, 2025-11-25). The 2025-03-26 revision introduced both OAuth 2.1 authorisation and the Streamable HTTP transport that replaced HTTP+SSE; later revisions made PKCE mandatory (with required S256 support), added OpenID Connect Discovery support, and established JSON Schema 2020-12 as the default dialect. Anything you build today against the current revision will need to track future ones, and the agent framework ecosystem — Claude Desktop, OpenAI (which adopted MCP in March 2025), LangChain, and others — won't all support new versions on the same timeline.

None of this is an argument against MCP. The protocol is the right shape, the ecosystem is forming around it, and not adopting it means writing your own incompatible equivalent. But "adopt MCP" and "solve agent access to your product" are very different projects. The first takes weeks. The second is the actual problem.

How Pontil fits

Most of this article has been about the protocol. The question we spend our time on at Pontil is the layer underneath: where do the tools actually come from, and how do they stay correct as the product changes?

Our view is that for established B2B SaaS companies with hundreds of capabilities to expose, hand-writing and hand-maintaining an MCP server's tool catalogue is the bespoke-connector problem in a new wrapper. The Tools-as-a-Service approach is to generate the catalogue from the existing codebase, run it as a managed runtime that executes as the authenticated user, and keep it current automatically as the product evolves. The output can be served over MCP, over a framework-native tool interface, or over both — protocol is a presentation choice, not the hard part.

If the questions in the previous section sound like the ones you've been trying to answer, a demo is the fastest way to see what that looks like in practice.

So what should your team be asking next?

The right next question isn't "should we adopt MCP?" It's almost certainly yes — the protocol is becoming table stakes for agent-readable products, and the cost of speaking it is low.

The right next question is what sits behind the server. How many tools does your product actually need to expose for the agent use case to be useful? How many of those map cleanly to existing API operations, and how many require something new? Who maintains the catalogue when the product team ships a breaking change on a Tuesday afternoon? What happens to the audit trail when the agent acts on behalf of a user?

MCP gives you a clean answer to one question: how does the agent talk to your tools. The harder questions — what those tools should be, how they execute, who they execute as, and how they stay correct — are the ones that decide whether your agent project ships.

Join our weekly newsletter

Stay up to date on the ever changing agentic landscape.

POSTS

Related content

Agent infrastructure

The agent stack: a map for platform teams

6 minute read

Platform integration

API strategy

Browser automation vs. API-native agent tooling

5 minute read

API strategy

Agent infrastructure

Your APIs expose 2% of what your product can do

4 minute read