Back to blog

Building Production-Grade AI Agents · Part 3 of 15

MCP: A Shared Capability Layer for Agents

Model Context Protocol is most useful when capabilities need to be reusable across agents, clients, and frameworks.

Chris Eberl

Chris Eberl

Founder • Engineering Leader, GenAI, Data, ML

Production AI AgentsSep 14, 20268 min read
MCP: A Shared Capability Layer for Agents

MCP is easy to overhype because it sits at an exciting intersection: models, tools, enterprise systems, and interoperability. The useful way to think about it is much simpler. An MCP server is a standardized capability provider. An agent runtime is a consumer of those capabilities.

That means MCP is not an orchestration strategy. It does not decide how your agent plans, whether a workflow is sequential, when to ask a human, or whether a financial action is permitted. It standardizes how a client discovers and invokes capabilities such as tools, resources, and prompts.

System flow
1Agent runtime / MCP client2        ↓3connect + discover4        ↓5MCP server6    ├── tools7    ├── resources8    └── prompts9        ↓10real backend services

When MCP is the right abstraction

If one application has three internal functions, direct function tools are often simpler. MCP becomes compelling when the same capability surface needs to be consumed by multiple agents, development environments, or model stacks—or when you want a stable agent-facing facade over a complicated enterprise API.

Salesforce is a good example. Instead of every agent implementing Salesforce integration separately, a shared MCP server can expose semantic tools such as get_opportunity(), add_note(), and update_stage(). Different agents can reuse the same capability layer while authenticating with different identities and receiving different effective permissions.

What an MCP server and client actually look like

On the server, an MCP tool is the same three-part contract as a direct tool — a name the model can select, a validated input schema, and an execute function — just declared on the capability provider instead of inside the agent. Here is a trimmed version of the add_note() tool from the facade above:

Exposing a semantic tool from an MCP server
1import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";2import { z } from "zod";3 4const server = new McpServer({ name: "crm", version: "1.0.0" });5 6server.registerTool(7  "add_opportunity_note",8  {9    description: "Append a note to a CRM opportunity.",10    inputSchema: {11      opportunityId: z.string(),12      note: z.string().max(2000),13    },14  },15  async ({ opportunityId, note }) => {16    // Runs against the connecting client's identity and permissions,17    // never with the MCP server's own privileges.18    const actor = await authorizeRequest(requestContext);19    await crm.addNote(opportunityId, note, { actor });20    return { content: [{ type: "text", text: "Note added." }] };21  },22);

On the client, the agent runtime connects to the server, discovers its capability list, and bridges those tools into its own tool map. With the AI SDK, the bridge is a few lines:

Consuming the MCP server from an agent
1import { generateText, stepCountIs } from "ai";2import { experimental_createMCPClient as createMCPClient } from "ai/mcp-stdio";3 4// Connect and discover what the server offers.5const crm = await createMCPClient({6  transport: { command: "node", args: ["dist/crm-server.js"] },7});8 9const result = await generateText({10  model,11  system: SUPPORT_AGENT_INSTRUCTIONS,12  messages,13  // Discovered MCP tools merge into the agent's action space14  // alongside any direct tools.15  tools: { ...directTools, ...(await crm.tools()) },16  stopWhen: stepCountIs(50),17});

Notice what stayed the same and what moved. The tool map is still the agent's entire action space — discovery only changes where its entries come from. And the authorization model inverts: with a direct tool, the runtime enforces permissions; with MCP, the server enforces them per connected identity. That inversion is exactly what lets a shared capability layer stay safe when multiple agents, clients, and frameworks reuse it.

Shared integration does not mean shared authority

A shared MCP server should never imply that every connected agent can use every capability. Authorization remains a server-side concern. One agent might only have read access and add_note(); another privileged automation agent might additionally receive update_stage(). The server or underlying service should enforce those permissions even if a tool is accidentally exposed to the wrong model.

MCP can be a semantic facade

Many enterprise APIs are optimized for application developers, not models. An MCP layer can trim, combine, normalize, and rename those APIs into a smaller semantic surface. That is not obfuscation; it is interface design. It gives the model fewer ways to be wrong while preserving the backend system of record.

The protocol keeps evolving

The MCP specification continues to evolve quickly. The July 2026 specification introduced a stateless protocol core, cacheable capability-list results, authorization hardening, and a formal extensions framework. That reinforces the architectural direction: MCP is maturing into infrastructure that can sit behind gateways, rate limiters, and enterprise authorization systems rather than remaining a local-tool novelty.

PFPLabs takeaways

  • MCP is an interoperability protocol, not an orchestration strategy.
  • Use direct tools when they are simpler. Reach for MCP when reuse, standardization, or cross-client interoperability matters.
  • Keep authorization server-side. Shared integration logic must not become shared privilege.
  • Design the MCP surface semantically. Expose business capabilities, not arbitrary backend plumbing.

Further reading

Model Context Protocol: July 2026 specification releaseModel Context Protocol blog

Read next

Newsletter

New posts, straight from Chris

A short note from me whenever a new article goes live — product engineering, AI workflows, IoT, indie apps, and engineering leadership. No spam, unsubscribe anytime.

By subscribing, you agree to our Privacy Policy. We do not share your email.