MCP协议简单拆解
一、什么是MCP?
-
模型上下文协议(Model Context Protocol,MCP),是由 Anthropic推出的开源协议,旨在实现大语言模型与外部数据源和工具的集成,用来在大模型和数据源之间建立安全双向的连接。
-
模型上下文协议协议是专为高效获得模型所需要上下文信息而设计的通用接口,可以将推动大语言模型应用的标准化和去中心化。该协议是提供了类似于 OpenAPI 的开放标准,定义了一套通用的通信协议、数据格式和规则,可以有简化开发、灵活、实时响应、安全合规、可扩展的特点,它通过相同的协议同时处理本地资源(例如数据库、文件、服务等)和远程资源(例如Slack或GitHub等API) 。
-
MCP 是一个开放协议,它标准化了应用程序向 LLM 提供上下文的方式。可以将 MCP 视为 AI 应用的 USB-C 端口。正如 USB-C 提供了一种标准化的方式将您的设备连接到各种外围设备和配件一样,MCP 提供了一种标准化的方式将 AI 模型连接到不同的数据源和工具。
-
大模型与外部工具交互的方案目前有两种:对话上下文、FunctionCall,而MCP则是通过对 工具接入与执行流程的标准化 以实现对 FunctionCall能力的扩展,来增强大模型与外部工具交互的能力,模型上下文的标准化+与外部工具交互的标准化的一套数据通用协议。
二、拆解MCP
1. MCP的构成
- MCP Client(用户搭建的本地应用、平台、工作流、Agent等)
- MCP Server (基于MCP解析搭建的标准化工具、能力、服务)
- Origin Service(原始服务: HTTP接口、可执行文件、Figma编辑器、三方服务)
2. McpServer的类型
- 运行本地命令行
- 访问外部接口/API
- 连接三方应用(Figma、模拟器、浏览器)
- 连接三方平台(coze、lbs、百度)
3. MCP的工作流程
4. MCP的执行流程
三、执行案例
下面以浏览器自动化MCP服务@executeautomation/playwright-mcp-server
演示案例
1. 安装依赖
// 安装MCP包
npm i @executeautomation/playwright-mcp-server --save
// 安装MCP标准SDK
npm i @modelcontextprotocol/sdk --save
// 安装langchain作为模型执行器
npm i langchain --save
2. 执行代码
const { Client } = require('@modelcontextprotocol/sdk/client/index.js');
const { StdioClientTransport } = require('@modelcontextprotocol/sdk/client/stdio.js');
const { ChatOpenAI } = require('@langchain/openai');
const { ChatPromptTemplate } = require('@langchain/core/prompts');
const { AgentExecutor, createOpenAIToolsAgent } = require('langchain/agents');
const { DynamicStructuredTool } = require('langchain/tools');/*** 创建OpenAI实例* @returns*/
const createOpenAiInstance = () => {const chat = new ChatOpenAI({model: `gpt4o`,temperature: 0,apiKey: '',configuration: {baseURL: `/`},streaming: false,});return chat;
};/*** 创建浏览器Mcp客户端* 备注:sever必须运行在client下,这样才可以获取标准输出*/
const createPlaywrightMcpClient = async () => {// 创建链接const transport = new StdioClientTransport({command: 'npx',args: ['-y', '@executeautomation/playwright-mcp-server'],});const client = new Client({name: 'ai-agent-mcp-client',version: '0.0.1',});// 连接Mcp-Serverawait client.connect(transport);return client;
};/*** Main Process*/
(async () => {// 客户端const mcpClient = await createPlaywrightMcpClient();// 工具列表const { tools: mcpTools } = await mcpClient.listTools();// 解析工具集const tools = mcpTools.map(({ name, description, inputSchema }) =>new DynamicStructuredTool({name,description,schema: inputSchema,func: async (toolArgs) => {const result = await mcpClient.callTool({ name: name, arguments: toolArgs });return `${JSON.stringify(result)}`;},}));// 对话实例const chatInstance = createOpenAiInstance();// 创建会话const prompt = ChatPromptTemplate.fromMessages([['system', 'You are a helpful assistant'],['placeholder', '{chat_history}'],['human', '{input}'],['placeholder', '{agent_scratchpad}'],]);// 创建智能体const agent = await createOpenAIToolsAgent({llm: chatInstance,tools: tools,prompt,streamRunnable: false,});// 创建执行器const agentExecutor = new AgentExecutor({agent,tools: tools,});const result = await agentExecutor.invoke({input: `# 问题你好,1. 帮我截取一张图片,地址是:http://www.baidu.com,请在页面加载完成后再截图2. 帮我提取这个站点页面上所有的文字,并在下文输出给我`,});console.log('result', result);
})();