MCP (Model Context Protocol)
The Universal Connector for AI Tools
What Is MCP?
Model Context Protocol (MCP) is an open standard for connecting AI models to external data and tools. Think of it as the USB-C of AI — a single, universal interface that replaces the mess of one-off integrations.
Without MCP, every AI application builds its own tool-calling layer: custom schemas, custom transports, custom auth. If you want your agent to connect to Slack, your CRM, and a database, you build three separate integrations from scratch.
With MCP, each of those systems exposes a standard MCP server. Your agent connects to them all through one protocol. Build the client once, connect to anything.
MCP Primitives
MCP defines three types of capabilities a server can expose:
| Primitive | What It Does | Example |
|---|---|---|
| Tools | Actions the AI can take (read-write) | `create_ticket`, `send_email`, `update_deal` |
| Resources | Data the AI can read (read-only) | Company knowledge base, product catalog, org chart |
| Prompts | Reusable prompt templates | "Summarize this deal for a QBR", "Draft a cold outreach email" |
Tools are the most common. If you've built tools in Module 1, you already understand the concept — MCP just standardizes how they're described and invoked.
Why MCP Matters for Enterprise
Enterprise AI isn't one model talking to one API. It's dozens of models, hundreds of data sources, and teams that each own different systems. MCP solves three problems:
Server vs Client Architecture
MCP uses a client-server model:
┌─────────────────────────┐
│ Your Agent (MCP Client) │
│ │
│ Discovers tools from │
│ connected servers │
└──────┬───────┬───────────┘
│ │
┌────▼──┐ ┌──▼──────┐
│ CRM │ │ Slack │
│ Server│ │ Server │
└───────┘ └─────────┘Building an MCP Server
Here's a minimal MCP server that exposes a CRM contact search tool:
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { z } from "zod";
const server = new McpServer({
name: "crm-server",
version: "1.0.0",
});
// Register a tool
server.tool(
"search_contacts",
"Search CRM contacts by name, email, or company. Returns matching contacts with deal history.",
{
name: z.string().optional().describe("Contact name (partial match)"),
email: z.string().optional().describe("Contact email"),
company: z.string().optional().describe("Company name"),
},
async ({ name, email, company }) => {
const results = await crmDatabase.search({ name, email, company });
return {
content: [
{ type: "text", text: JSON.stringify(results, null, 2) },
],
};
}
);
// Register a resource
server.resource(
"product-catalog",
"products://catalog",
async () => ({
contents: [
{
uri: "products://catalog",
text: JSON.stringify(await loadProductCatalog()),
mimeType: "application/json",
},
],
})
);
// Start the server
const transport = new StdioServerTransport();
await server.connect(transport);That's it. This server can now be connected to any MCP client. The client discovers search_contacts and product-catalog automatically.
Tool Registration — Mapping Internal Tools to MCP
If you already built tools in Module 1, wrapping them as MCP tools is straightforward. The key mapping:
| Your Tool Property | MCP Equivalent |
|---|---|
| `name` | First argument to `server.tool()` |
| `description` | Second argument to `server.tool()` |
| `parameters` (JSON Schema) | Third argument (Zod schema) |
| `execute` function | Fourth argument (handler function) |
| Return value | `{ content: [{ type: "text", text: "..." }] }` |
The main difference: MCP tool outputs are always wrapped in a content array with typed blocks (text, image, or embedded resource). This is more structured than raw JSON returns but trivial to adapt.
Resources — Exposing Data for AI
Resources are read-only data the AI can access. Unlike tools (which are actions the model *decides* to take), resources are context the client *provides* to the model:
contacts://{id}/profile — parameterized URIs that resolve to specific records.The client reads resources and includes them in the model's context. This is the MCP equivalent of RAG retrieval — but standardized so any client can consume any server's data.
Testing with MCP Inspector
Before wiring your MCP server to an agent, test it standalone using the MCP Inspector:
npx @modelcontextprotocol/inspector your-server.jsThe inspector opens a web UI where you can:
This catches schema mismatches and auth issues before they surface as mysterious agent failures. Always test your MCP server in isolation before connecting it to the agent.
MCP in Your Capstone
In the capstone project, you'll build an MCP server that wraps your Sales Companion's tools — CRM search, deal history, email drafting. This makes your agent's capabilities available to any MCP-compatible client, not just your application. It's the difference between building a feature and building an integration point that scales across the organization.
This is chapter 3 of Production AI Agents.
Get the full hands-on course for $100 and build the complete system. Your projects become your portfolio.
View course details