mcp的使用
mcp的使用
模型上下文协议(mcp)允许应用程序以标准化方式为 LLM 提供上下文,从而将提供上下文的关注点与实际的 LLM 交互分开。此 TypeScript SDK 实现了完整的 MCP 规范,使其易于:
- Build MCP clients that can connect to any MCP server 构建可连接到任何 MCP 服务器的 MCP 客户端
- Create MCP servers that expose resources, prompts and tools 创建公开资源、提示和工具的 MCP 服务器
- Use standard transports like stdio and Streamable HTTP 使用标准传输方式,如 stdio 和 Streamable HTTP
- Handle all MCP protocol messages and lifecycle events 处理所有 MCP 协议消息和生命周期事件
McpServer
MCP 协议的核心接口。它处理连接管理、协议合规性和消息路由。
const server = new McpServer({
name: "My App",
version: "1.0.0"
});
Resources 资源
资源是向 LLM 公开数据的方式。它们类似于 REST API 中的 GET 端点 - 它们提供数据,但不应执行大量计算或具有副作用:
入参:
- 资源类型标识符
- url 相当于请求路径
- callback 返回体
// Static resource
server.resource(
"config",
"config://app",
async (uri) => ({
contents: [{
uri: uri.href,
text: "App configuration here"
}]
})
);
// 动态url
server.resource(
"user-profile",
new ResourceTemplate("users://{userId}/profile", { list: undefined }),
async (uri, { userId }) => ({
contents: [{
uri: uri.href,
text: `Profile data for user ${userId}`
}]
})
);
ResourceTemplate
动态url
import { Server, ResourceTemplate } from '@modelcontextprotocol/sdk/server/index.js';
const server = new Server(/*...*/);
// 方式1: 简单字符串URI(静态)
server.resource(
"config",
"config://app", // 固定URI
async (uri) => ({
contents: [{ uri: uri.href, text: "Static config" }]
})
);
// 方式2: ResourceTemplate(动态)
server.resource(
"user-profile",
new ResourceTemplate(
"users://{userId}/profile", // 动态URI模板
{
list: undefined // 不支持列表
}
),
async (uri, { userId }) => { // 注意:回调函数多了第二个参数
// 模拟用户数据
const users = {
'123': { name: 'Alice', email: '[email protected]', role: 'admin' },
'456': { name: 'Bob', email: '[email protected]', role: 'user' },
'789': { name: 'Charlie', email: '[email protected]', role: 'user' }
};
const user = users[userId];
if (!user) {
throw new Error(`用户不存在: ${userId}`);
}
return {
contents: [{
uri: uri.href,
mimeType: "application/json",
text: JSON.stringify({
userId: userId,
profile: user,
lastUpdated: new Date().toISOString()
}, null, 2)
}]
};
}
);
// 方式3: ResourceTemplate 支持列表
server.resource(
"user-posts",
new ResourceTemplate(
"users://{userId}/posts",
{
list: async () => {
// 返回所有可用的用户ID
return [
{ uri: "users://123/posts", name: "Alice的文章" },
{ uri: "users://456/posts", name: "Bob的文章" },
{ uri: "users://789/posts", name: "Charlie的文章" }
];
}
}
),
async (uri, { userId }) => {
const posts = {
'123': [
{ id: 1, title: 'Hello World', content: 'My first post' },
{ id: 2, title: 'Learning MCP', content: 'MCP is awesome!' }
],
'456': [
{ id: 3, title: 'JavaScript Tips', content: 'Some useful tips' }
],
'789': []
};
return {
contents: [{
uri: uri.href,
mimeType: "application/json",
text: JSON.stringify({
userId: userId,
posts: posts[userId] || [],
totalCount: (posts[userId] || []).length
}, null, 2)
}]
};
}
);
// 更复杂的多参数模板
server.resource(
"file-content",
new ResourceTemplate(
"files://{projectId}/{fileName}",
{ list: undefined }
),
async (uri, { projectId, fileName }) => {
console.log(`请求项目 ${projectId} 中的文件 ${fileName}`);
// 模拟文件内容
const fileContent = `
// 项目: ${projectId}
// 文件: ${fileName}
export default function ${fileName.replace('.js', '')}() {
console.log('Hello from ${fileName}');
}
`;
return {
contents: [{
uri: uri.href,
mimeType: "text/javascript",
text: fileContent.trim()
}]
};
}
);
Tools 工具
工具允许 LLM 通过服务器执行操作。与资源不同,工具需要执行计算并具有副作用:
入参:
- 资源类型标识符
- callback函数入参的类型约束
- callback 返回体
server.tool(
"calculate-bmi",
{
weightKg: z.number(),
heightM: z.number()
},
async ({ weightKg, heightM }) => ({
content: [{
type: "text",
text: String(weightKg / (heightM * heightM))
}]
})
);
// Async tool with external API call
server.tool(
"fetch-weather",
{ city: z.string() },
async ({ city }) => {
const response = await fetch(`https://api.weather.com/${city}`);
const data = await response.text();
return {
content: [{ type: "text", text: data }]
};
}
);
Prompts 提示
提示是可重用的模板,可帮助 LLM 有效地与服务器交互:
入参:
- 资源类型标识符
- callback函数入参的类型约束
- callback 返回体
server.prompt(
"review-code",
{ code: z.string() },
({ code }) => ({
messages: [{
role: "user",
content: {
type: "text",
text: `Please review this code:\n\n${code}`
}
}]
})
);
运行服务器
StdioServerTransport
是MCP服务器的标准输入输出传输层,它负责:
- 建立通信通道:通过stdin/stdout与MCP客户端进行双向通信
- 消息序列化:将JavaScript对象转换为JSON消息格式
- 协议处理:处理MCP协议的消息交换
工作流程:
- 客户端发送JSON消息到服务器的stdin
- StdioServerTransport接收并解析消息
- 服务器处理请求并返回响应
- StdioServerTransport将响应写入stdout发送给客户端
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
const server = new McpServer({
name: "example-server",
version: "1.0.0"
});
// ... set up server resources, tools, and prompts ...
const transport = new StdioServerTransport();
await server.connect(transport);
评论
其他文章