agent开发-mcp02

5 阅读1分钟

mcp底层通信的原理

下面是一个自己实现的mcp server,采用进程通信。

当这个server被父进程的程序运行起来后,操作系统就会创建两个管道,server自身进程和它的父进程之间的通信桥梁。一个是父亲到儿子传输。一个儿子给父亲传输。

然后 await server.connect(transport);这个代码一旦执行,就会:

  • server进程开始持续监听 父亲-儿子 这个管道的消息,一旦有消息到子进程,server就可以获取到
  • 如果子进程中的代码执行了向父进程传输数据的功能,就会通过另外一个管道 写到父进程中。但是这个写入能力 需要在这个代码执行的时候 激活。
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
import { z } from 'zod';

// 数据库
const database = {
    users: {
        '001': { id: '001', name: '张三', email: 'zhangsan@example.com', role: 'admin' },
        '002': { id: '002', name: '李四', email: 'lisi@example.com', role: 'user' },
        '003': { id: '003', name: '王五', email: 'wangwu@example.com', role: 'user' },
    }
};

const server = new McpServer({
    name: 'my-mcp-server',
    version: '1.0.0',
});


// 注册工具:查询用户信息
server.registerTool('query_user', {
    description: '查询数据库中的用户信息。输入用户 ID,返回该用户的详细信息(姓名、邮箱、角色)。',
    inputSchema: {
        userId: z.string().describe('用户 ID,例如: 001, 002, 003'),
    },
}, async ({ userId }) => {
    const user = database.users[userId];

    if (!user) {
        return {
            content: [
                {
                    type: 'text',
                    text: `用户 ID ${userId} 不存在。可用的 ID: 001, 002, 003`,
                },
            ],
        };
    }

    return {
        content: [
            {
                type: 'text',
                text: `用户信息:\n- ID: ${user.id}\n- 姓名: ${user.name}\n- 邮箱: ${user.email}\n- 角色: ${user.role}`,
            },
        ],
    };
});


server.registerResource('使用指南', 'docs://guide', {
    description: 'MCP Server 使用文档',
    mimeType: 'text/plain',
}, async () => {
    return {
        contents: [
            {
                uri: 'docs://guide',
                mimeType: 'text/plain',
                text: `MCP Server 使用指南

功能:提供用户查询等工具。

使用:在 Cursor 等 MCP Client 中通过自然语言对话,Cursor 会自动调用相应工具。`,
            },
        ],
    };
});


const transport = new StdioServerTransport();
await server.connect(transport);