通过0到1实现MCP Tool浅析Agent基础构件

135 阅读5分钟

在当今的大模型(LLM)应用开发中,只要涉及“智能体(Agent)”,我们面临的最大痛点往往不是模型不够聪明,而是模型与世界的连接过于脆弱。我们要么把大量上下文硬塞进 Prompt(导致 Token 爆炸),要么为每个工具(数据库、API、文件系统)单独写一套复杂的 Function Calling 适配层。直到 MCP(Model Context Protocol,模型上下文协议) 的出现,我们终于看到了“AI 时代的 USB 标准”。

什么是MCP?

MCP(Model Context Protocol,模型上下文协议)是一个用于将 AI 应用连接到外部系统的开源标准。通过 MCP,像 Cursor、Claude 或 ChatGPT 这样的 AI 应用可以连接到数据源(例如本地文件、数据库)、工具(例如搜索引擎、计算器)以及工作流(例如特定用途的提示)——从而让它们能够访问关键数据并执行任务。

可以把 MCP 想象成 AI 应用的 USB-C 接口。正如 USB-C 提供了一种连接电子设备的标准化方式,MCP 也提供了一种将 AI 应用接入外部系统的标准化方式。

image.png

为什么要用MCP?

解决传统的 M × N 集成噩梦

在 MCP 出现之前,AI Agent 连接外部工具,基本就是“硬编码”一对一手工对接。比如说,你有 M 个 AI 应用,N 个工具(数据库、文件系统啥的),那就得写 M × N 个集成模块。每对接一个新工具,都要从头适配一遍,费时费力。MCP 怎么解决的?引入一个通用协议,就像 USB-C 标准一样。

有了 MCP,M 个 AI 应用只需实现一次 MCP 客户端,N 个工具只需实现一次 MCP 服务器。一次对接,解锁整个生态——这才是真正的效率提升!

292D6E5E-E4BE-4F1A-B5B5-AB034262BE87.jpg

MCP概念

MCP架构的关键参与者

  • MCP Host:用于协调和管理一个或多个 MCP 客户端的 AI 应用程序
  • MCP Client:一个维护与 MCP 服务器连接并从 MCP 服务器获取上下文以供 MCP 主机使用的组件。
  • MCP Server:一个为 MCP 客户端提供上下文信息的程序

image.png

MCP由两层组成

数据层:定义了基于 JSON-RPC 2.0的客户端-服务器通信协议,包括生命周期管理和核心原语,如工具、资源、提示和通知

  • Request Object

    { "jsonrpc": "2.0", "id": 1, "method": "", "params": {} }

  • Response Object

    { "jsonrpc": "2.0", "id": 1, "result": {}, "error": {} }

传输层:传输层管理客户端和服务器之间的通信通道和身份验证。它处理连接建立、消息帧构建以及MCP参与者之间的安全通信

MCP支持两种传输机制:

  • Stdio :使用标准输入/输出流在同一台机器上的本地进程之间进行直接进程通信,提供最佳性能,且无网络开销。

    • Node.js / TypeScript
    • Python
    • Go
    • Rust
    • Java
    • C / C++
    • PHP
    • Ruby
    • .NET / C#
  • HTTP

    • Streamable HTTP:双向传输
    • SSE:单向流式传输,需要http post辅助
  • Websocket:双向传输

MCP基本元素

  • Tools

    • tools/list
    • tools/call
  • Resources

    • resources/list
    • resources/read
    • resources/query
    • resources/subscribe
  • Prompts

    • prompts/list
    • prompts/get
    • prompts/execute

MCP服务类型

  • Local MCP

    • 基于Stdio,主要通过Node.js / Python实现
  • Remote MCP

    • 基于HTTP,任何服务器端语言都能实现

如何实现本地MCP Server?

需要实现的几个核心方法(以tools为例)

  • initialize

    • request body

      {
        "jsonrpc": "2.0",
        "id": 1,
        "method": "initialize",
        "params": {}
      }
      
    • response body

      {
        "jsonrpc": "2.0",
        "id": 1,
        "result": {
          "protocolVersion": "2025-06-18",
          "capabilities": {
            "tools": {},
            "resources": {}
          },
          "serverInfo": {
            "name": "example-server",
            "version": "1.0.0"
          }
        }
      }
      
  • tools/list

  • tools/call

实现一个可以在Cursor上使用的MCP Server

技术栈

Nodejs + Stdio + @modelcontextprotocol/sdk

核心代码

import { Server } from '@modelcontextprotocol/sdk/server/index.js';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
import {
  CallToolRequestSchema,
  ListToolsRequestSchema,
} from '@modelcontextprotocol/sdk/types.js';
import { z } from 'zod';

// Define the tools
const TOOLS = {
  get_events_and_meetings_list: {
    name: 'get_events_and_meetings_list',
    description: 'Get the list of events and meetings',
    inputSchema: z.object({
      start_date: z.string(),
      end_date: z.string(),
    }),
    resultSchema: z.array(
      z.object({
        summary: z.string(),
        start: z.object({
          dateTime: z.string(),
          timeZone: z.string(),
        }),
        end: z.object({
          dateTime: z.string(),
          timeZone: z.string(),
        }),
        description: z.string().nullable().optional(),
        location: z.string().nullable().optional(),
      })
    ),
  },
};

// Create the server
const server = new Server(
  {
    name: 'calendar-mcp-server',
    version: '1.0.0',
  },
  {
    capabilities: {
      tools: {},
    },
  }
);

// Handle tool listing
server.setRequestHandler(ListToolsRequestSchema, async () => {
  return {
    tools: [
      {
        name: TOOLS.get_events_and_meetings_list.name,
        description: TOOLS.get_events_and_meetings_list.description,
        inputSchema: {
          type: 'object',
          properties: {
            start_date: { type: 'string', description: 'Start date' },
            end_date: { type: 'string', description: 'End date' },
          },
          required: ['start_date', 'end_date'],
        },
      },
    ],
  };
});

// Handle tool execution
server.setRequestHandler(CallToolRequestSchema, async (request) => {
  const { name, arguments: args } = request.params;

  try {
    if (name === 'get_events_and_meetings_list') {
      return {
        content: [
          {
            type: 'text',
            text: JSON.stringify({}, null, 2),
          },
        ],
      };
    }

    throw new Error(`Unknown tool: ${name}`);
  } catch (error) {}
});

// Start the server
async function run() {
  const transport = new StdioServerTransport();
  await server.connect(transport);
  console.error('MCP Server running on stdio');
}

run().catch((error) => {
  console.error('Fatal error running server:', error);
  process.exit(1);
});

Cursor上配置MCP Server

{
  "mcpServers": {
    "calendar-mcp-server": {
      "command": "node",
      "args": [{{ mcp server path }}]
    }
  }
}

查看启动状态:

image.png

从AI Tool输入Prompt到响应发生了什么?

Cursor是AI Agent吗?

智能体需要的四个核心能力:

1. 规划&推理(Planning)

智能体的大脑负责:

  • 理解目标与上下文
  • 分解任务
  • 制定行动步骤
  • 决定调用哪些工具
  • 动态调整计划(基于执行结果)

规划 ≈ “Agent 决定下一步做什么”。

2. 工具(Tools)

智能体与外界交互的动作接口,例如:

  • 查询数据库
  • 调用 API
  • 控制流程(文件、搜索、业务系统)
  • 运行脚本、数学、外部插件

工具 = 动作能力,是 Agent 的“手和脚”。

在 MCP 中,Tool 是最核心的“行动模块”。

3. 记忆(Memory)

用于保持智能体的状态,包括:

短期记忆(Working Memory)

  • 当前对话
  • 当前任务步骤
  • 工具执行返回的数据

长期记忆(Long-term Memory)

  • 用户偏好
  • 业务规则
  • 总结过的知识

记忆 = Agent 的“认知连续性”。

4. 执行(Execution)

执行是规划后的实际动作,包括:

  • 调用工具
  • 根据结果调整策略
  • 继续下一步
  • 确认任务成功或失败
  • 触发新的计划

执行 = 将 Planning 转化为 Actions。