MCP Is the USB-C Port for AI Agents
Understand in one go what the Model Context Protocol is, why you need it, and how to use it.
Preface: Starting from LLM + Tools = Agent
If you have used AI coding assistants (Cursor, Trae, etc.) or built an LLM Agent, you are certainly familiar with the following formula:
LLM + Tools = Agent
A large model itself can only "talk," but when equipped with tools for reading files, writing files, executing commands, etc., it becomes an Agent that can get work done.
Here is where the problems arise:
- Tools are hardcoded into the Agent. Adding a new tool requires code changes and redeployment.
- External teams/third parties wanting to expose their services for AI use have no unified standard, making integration costs extremely high.
- Tools written in different languages (Node calling Python, Java, Rust) are isolated from each other.
- Local tools and remote tools communicate differently, making adaptation painful.
MCP was born to solve this "fragmentation" problem.
A thought: 80% of apps might disappear in the future—because when AI can directly call various services through MCP, users no longer need to open individual apps; they can simply converse with AI to complete all operations.
1. What is MCP?
MCP (Model Context Protocol) is an open protocol proposed by Anthropic at the end of 2024 and contributed to the open-source community in 2025. It is essentially a universal interface standard designed for AI large models.
Let me use an analogy to help you understand:
In the past, if AI needed to call tools from 10 different vendors, it was like needing to carry 10 different chargers when you go out. With MCP, it's like using a "universal charger"—one protocol can connect to all services.
The core idea of MCP is: packaging specific tools and the rules (Schema) for "how to call tools" into an independent server process (Server).
MCP and Tool are not a parallel relationship but a "container" and "content" relationship:
- Before MCP: AI calling Tools was hardcoded; adding a tool required writing glue code.
- After MCP: It becomes dynamic discovery. The Host automatically scans what tools the Server exposes at startup and calls them on demand at runtime.
2. MCP Architecture: The Host / Client / Server Relationship
MCP adopts a classic Client-Server architecture, containing three core roles:
| Role | Description | Example |
|---|---|---|
| MCP Host | The AI application that needs to connect to the outside world; the "brain" that initiates requests | Cursor, Claude Desktop, Trae |
| MCP Client | Runs inside the Host, responsible for establishing a one-to-one connection with the MCP Server | Cursor's built-in MCP Client, reads mcp.json and establishes communication |
| MCP Server | A lightweight program that exposes capabilities externally through a standard protocol | Your own my-mcp-server.mjs |
Each MCP Server can expose three core capabilities:
| Capability | Description | Example |
|---|---|---|
| Tools | Functions that AI can execute | Query users, send emails, read files |
| Resources | Context data that AI can reference | Database records, local files, API response content |
| Prompts | Reusable predefined interaction templates | Conversation templates that guide AI to complete specific tasks |
Summarizing the MCP protocol in one sentence:
Context = Tool + Resource + PromptTemplate
3. MCP Call Flow (7 Steps)
When you say "Help me look up user 002's information" in Cursor, what actually happens behind the scenes?
User inputs prompt
↓
① Host configures mcp.json → Declares which Servers to connect to
↓
② Client sends initialize request → Server returns the list of all tools (dynamic discovery)
↓
③ User inputs task prompt → Host receives it
↓
④ Host analyzes prompt → Retrieves matching items from discovered tools
↓
⑤ Client initiates tool call → Transmitted to MCP Server via stdio / HTTP
↓
⑥ Server executes tool logic → Returns result
↓
⑦ Result injected into LLM context (ToolMessage) → LLM continues reasoning → Generates final reply
Key Step: "Dynamic Discovery" in Step ②
This is the biggest highlight of MCP. The Host does not need to hardcode "what tools are available" in its code; instead, it proactively asks the Server at startup: "What capabilities can you provide?" The Server returns the names, descriptions, and parameter schemas of all its registered tools. Then, when the user sends a task, the Host can automatically match the appropriate tool to execute.
Configuration Example (mcp.json)
{
"mcpServers": {
"my-mcp-server": {
"command": "node",
"args": ["my-mcp-server.mjs"]
}
}
}
4. MCP Communication Methods
MCP supports two communication transport methods, covering both local and remote scenarios:
| Transport Method | Applicable Scenario | Implementation Class |
|---|---|---|
| stdio (Standard Input/Output Stream) | Local child process calls | StdioServerTransport |
| HTTP (Streamable HTTP) | Remote server calls | HttpServerTransport / Streamable HTTP |
This means you can:
- Locally: Call an MCP Server via a child process (even if it's written in Node / Python / Java / Rust)
- Remotely: Call an MCP Server deployed in the cloud via HTTP, enjoying third-party services
One of the greatest significances of MCP: Cross-process, cross-language tool invocation, enabling LLMs to perform more powerful tasks.
5. Writing an MCP Server by Hand (Code in Practice)
Let's look at a complete example: an MCP Server that provides a "query user" capability.
5.1 Dependency Installation
pnpm add @modelcontextprotocol/sdk zod
5.2 Complete Code: my-mcp-server.mjs
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
import { z } from 'zod';
// Mock database
const database = {
users: {
"001": { id: "001", name: "Zhang San", email: "[email protected]", role: "admin" },
"002": { id: "002", name: "Li Si", email: "[email protected]", role: "user" },
"003": { id: "003", name: "Wang Wu", email: "[email protected]", role: "user" },
}
};
// ① Create MCP Server instance
const server = new McpServer({
name: 'my-mcp-server',
version: '1.0.0',
});
// ② Register Tool: Query User
server.registerTool('query-user', {
description: 'Query user information in the database. Input a user ID to return the user\'s detailed information (name, email, role).',
inputSchema: {
userId: z.string().describe("User ID, e.g.: 001, 002, 003"),
},
}, async ({ userId }) => {
const user = database.users[userId];
if (!user) {
return {
content: [{
type: 'text',
text: `User ID ${userId} does not exist. Available IDs: 001, 002, 003`,
}],
};
}
return {
content: [{
type: 'text',
text: `User Information:\n- ID: ${user.id}\n- Name: ${user.name}\n- Email: ${user.email}\n- Role: ${user.role}`,
}],
};
});
// ③ Register Resource: Usage Guide
server.registerResource('Usage Guide', 'docs://guide', {
description: 'MCP Server Usage Documentation',
mimeType: 'text/plain',
}, async () => {
return {
contents: [{
uri: 'docs://guide',
mimeType: 'text/plain',
text: 'MCP Server Usage Guide\nFunctionality: Provides tools such as user query.',
}],
};
});
// ④ Choose communication method and start
const transport = new StdioServerTransport();
await server.connect(transport);
5.3 MCP Development Process Summary
new McpServer() → Create Server instance
server.registerTool() → Register tool (name, description, input schema, execution callback)
server.registerResource() → Register resource (name, URI, description, content callback)
server.registerPrompt() → Register prompt template (optional)
new StdioServerTransport() → Choose communication method
server.connect(transport) → Start Server, wait for Host connection
6. Integrating MCP into Your Own Agent Program
Once the MCP Server is written, it can not only be used in Cursor but also directly embedded into your own Agent programs through frameworks like LangChain, achieving "pluggable" tool integration.
Below is an example using LangChain + MCP Adapters:
import { MultiServerMCPClient } from '@langchain/mcp-adapters';
import { ChatOpenAI } from '@langchain/openai';
import { HumanMessage, ToolMessage } from '@langchain/core/messages';
const model = new ChatOpenAI({
modelName: process.env.MODEL_NAME,
apiKey: process.env.OPENAI_API_KEY,
configuration: { baseURL: process.env.OPENAI_BASE_URL },
});
// ① Create MCP Client, connect to MCP Server
const mcpClient = new MultiServerMCPClient({
mcpServers: {
'my-mcp-server': {
command: 'node',
args: ['/path/to/my-mcp-server.mjs'],
},
},
});
// ② Dynamic discovery + get tools
const tools = await mcpClient.getTools();
// ③ Bind tools to the model
const modelWithTools = model.bindTools(tools);
// ④ Agent loop: Reason → Call tool → Get result → Reason again
async function runAgent(query, maxIterations = 30) {
const messages = [new HumanMessage(query)];
for (let i = 0; i < maxIterations; i++) {
const response = await modelWithTools.invoke(messages);
messages.push(response);
// No tool_calls means reasoning is finished
if (!response.tool_calls || response.tool_calls.length === 0) {
return response.content;
}
// Execute each tool_call, inject result into context
for (const toolCall of response.tool_calls) {
const foundTool = tools.find(t => t.name === toolCall.name);
if (foundTool) {
const toolResult = await foundTool.invoke(toolCall.args);
messages.push(new ToolMessage({
content: toolResult,
tool_call_id: toolCall.id,
}));
}
}
}
return messages[messages.length - 1].content;
}
// ⑤ Use
const result = await runAgent("Look up user 002's information");
console.log(result);
await mcpClient.close();
Key points of this example:
getTools()is "dynamic discovery"—your program doesn't need to hardcode what tools are available.bindTools(tools)injects these dynamically discovered tools into the LLM, letting it "know" what it can call.- In the Agent loop, the LLM decides whether to call a tool, which tool to call, and after execution, the result is fed back to the LLM in the form of
ToolMessage, forming a closed loop.
7. Summary of MCP's Core Value
| Dimension | Traditional Way | MCP Way |
|---|---|---|
| Tool Integration | Hardcoded, one change affects all | Dynamic discovery, plug-and-play |
| Cross-language Calls | Need to write IPC / RPC glue code yourself | Unified protocol, naturally cross-language |
| Third-party Integration | Each defines its own interface, high integration cost | One set of specifications, everyone follows |
| Local vs Remote | Need separate adaptation | stdio / HTTP dual-mode native support |
| Ecosystem Expansion | Closed | Open, large companies can provide services externally via MCP |
8. Final Words
MCP's ambition is far more than just "another tool-calling protocol." It attempts to define the "USB-C interface" of the AI era—a universal, open standard that allows AI to seamlessly connect to various services and data in this world.
Understanding MCP helps you understand why some say "80% of apps will disappear": when AI becomes a super entry point, users no longer need to open individual apps; they just say to AI "help me check my package delivery" or "help me book a ticket," and AI calls the corresponding services behind the scenes through MCP, making everything transparent.
I hope this article helps you build a complete understanding of MCP. Start writing your own MCP Server now—you'll find it's much simpler than you imagine.
References: