客户端开发(Node)
系统要求
在开始之前,请确保您的系统满足以下要求:
- Mac或Windows电脑 安装Node.js 16或更高版本
- 安装最新版本的npm Anthropic API密钥(Claude)
设置您的环境
首先,让我们创建并设置我们的项目:
bash
# Create project directory
mkdir mcp-client-typescript
cd mcp-client-typescript
# Initialize npm project
npm init -y
# Install dependencies
npm install @anthropic-ai/sdk @modelcontextprotocol/sdk dotenv
# Install dev dependencies
npm install -D @types/node typescript
# Create source file
touch index.ts
bash
# Create project directory
md mcp-client-typescript
cd mcp-client-typescript
# Initialize npm project
npm init -y
# Install dependencies
npm install @anthropic-ai/sdk @modelcontextprotocol/sdk dotenv
# Install dev dependencies
npm install -D @types/node typescript
# Create source file
new-item index.ts
更新你的 package.json 文件,将 type 设置为 'module' 并添加一个构建脚本:
json
{
"type": "module",
"scripts": {
"build": "tsc && chmod 755 build/index.js"
}
}
Create a tsconfig.json in the root of your project:
json
{
"compilerOptions": {
"target": "ES2022",
"module": "Node16",
"moduleResolution": "Node16",
"outDir": "./build",
"rootDir": "./",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true
},
"include": ["index.ts"],
"exclude": ["node_modules"]
}
设置您的API密钥
您需要从Anthropic控制台获取一个Anthropic API密钥。
创建一个.env文件来存储它:
bash
echo "ANTHROPIC_API_KEY=<your key here>" > .env
Add .env to your .gitignore:
bash
echo ".env" >> .gitignore
注意
确保您的 ANTHROPIC_API_KEY 安全!
创建客户端
基本客户端结构
首先,让我们设置导入并在index.ts中创建基本的客户端类:
typescript
import { Anthropic } from "@anthropic-ai/sdk";
import {
MessageParam,
Tool,
} from "@anthropic-ai/sdk/resources/messages/messages.mjs";
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js";
import readline from "readline/promises";
import dotenv from "dotenv";
dotenv.config();
const ANTHROPIC_API_KEY = process.env.ANTHROPIC_API_KEY;
if (!ANTHROPIC_API_KEY) {
throw new Error("ANTHROPIC_API_KEY is not set");
}
class MCPClient {
private mcp: Client;
private anthropic: Anthropic;
private transport: StdioClientTransport | null = null;
private tools: Tool[] = [];
constructor() {
this.anthropic = new Anthropic({
apiKey: ANTHROPIC_API_KEY,
});
this.mcp = new Client({ name: "mcp-client-cli", version: "1.0.0" });
}
// methods will go here
}
服务器连接管理
接下来,我们将实现连接到MCP服务器的方法:
typescript
async connectToServer(serverScriptPath: string) {
try {
const isJs = serverScriptPath.endsWith(".js");
const isPy = serverScriptPath.endsWith(".py");
if (!isJs && !isPy) {
throw new Error("Server script must be a .js or .py file");
}
const command = isPy
? process.platform === "win32"
? "python"
: "python3"
: process.execPath;
this.transport = new StdioClientTransport({
command,
args: [serverScriptPath],
});
this.mcp.connect(this.transport);
const toolsResult = await this.mcp.listTools();
this.tools = toolsResult.tools.map((tool) => {
return {
name: tool.name,
description: tool.description,
input_schema: tool.inputSchema,
};
});
console.log(
"Connected to server with tools:",
this.tools.map(({ name }) => name)
);
} catch (e) {
console.log("Failed to connect to MCP server: ", e);
throw e;
}
}
查询处理逻辑
现在让我们添加用于处理查询和工具调用的核心功能:
typescript
async processQuery(query: string) {
const messages: MessageParam[] = [
{
role: "user",
content: query,
},
];
const response = await this.anthropic.messages.create({
model: "claude-3-5-sonnet-20241022",
max_tokens: 1000,
messages,
tools: this.tools,
});
const finalText = [];
const toolResults = [];
for (const content of response.content) {
if (content.type === "text") {
finalText.push(content.text);
} else if (content.type === "tool_use") {
const toolName = content.name;
const toolArgs = content.input as { [x: string]: unknown } | undefined;
const result = await this.mcp.callTool({
name: toolName,
arguments: toolArgs,
});
toolResults.push(result);
finalText.push(
`[Calling tool ${toolName} with args ${JSON.stringify(toolArgs)}]`
);
messages.push({
role: "user",
content: result.content as string,
});
const response = await this.anthropic.messages.create({
model: "claude-3-5-sonnet-20241022",
max_tokens: 1000,
messages,
});
finalText.push(
response.content[0].type === "text" ? response.content[0].text : ""
);
}
}
return finalText.join("\n");
}
交互式聊天界面
现在我们将添加聊天循环和清理功能:
typescript
async chatLoop() {
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
});
try {
console.log("\nMCP Client Started!");
console.log("Type your queries or 'quit' to exit.");
while (true) {
const message = await rl.question("\nQuery: ");
if (message.toLowerCase() === "quit") {
break;
}
const response = await this.processQuery(message);
console.log("\n" + response);
}
} finally {
rl.close();
}
}
async cleanup() {
await this.mcp.close();
}
主入口点
最后,我们将添加主执行逻辑:
typescript
async function main() {
if (process.argv.length < 3) {
console.log("Usage: node index.ts <path_to_server_script>");
return;
}
const mcpClient = new MCPClient();
try {
await mcpClient.connectToServer(process.argv[2]);
await mcpClient.chatLoop();
} finally {
await mcpClient.cleanup();
process.exit(0);
}
}
main();
运行客户端
要使用任何MCP服务器运行您的客户端:
bash
# Build TypeScript
npm run build
# Run the client
node build/index.js path/to/server.py # python server
node build/index.js path/to/build/index.js # node server
注意
如果您正在继续服务器快速入门中的天气示例,您的命令可能看起来像这样:node build/index.js .../quickstart-resources/weather-server-typescript/build/index.js
客户端将会:
- 连接到指定的服务器
- 列出可用工具
- 启动交互式聊天会话,您可以:
- 输入查询
- 查看工具执行情况
- 获取来自Claude的响应
它是如何工作的
当您提交查询时:
- 客户端从服务器获取可用工具列表
- 您的查询与工具描述一起发送到Claude
- Claude决定使用哪些工具(如果有的话)
- 客户端通过服务器执行任何请求的工具调用
- 结果被发送回Claude
- Claude提供自然语言响应
- 响应显示给您
最佳实践
1.错误处理
- 使用TypeScript的类型系统以获得更好的错误检测
- 将工具调用包装在try-catch块中
- 提供有意义的错误消息
- 优雅地处理连接问题
2.安全性
- 在.env中安全地存储API密钥
- 验证服务器响应
- 谨慎处理工具权限
故障排除
服务器路径问题
- 仔细检查服务器脚本的路径是否正确
- 如果相对路径不起作用,请使用绝对路径
- 对于Windows用户,确保在路径中使用正斜杠(/)或转义的反斜杠()
- 验证服务器文件具有正确的扩展名(Node.js用.js,Python用.py)
正确路径使用示例:
bash
# Relative path
node build/index.js ./server/build/index.js
# Absolute path
node build/index.js /Users/username/projects/mcp-server/build/index.js
# Windows path (either format works)
node build/index.js C:/projects/mcp-server/build/index.js
node build/index.js C:\\projects\\mcp-server\\build\\index.js
Response Timing
- 第一次响应可能需要长达30秒的时间
- 这是正常的,发生在:
- 服务器初始化时
- Claude处理查询时
- 工具执行时
- 后续响应通常更快
- 在初始等待期间不要中断进程
常见错误消息
如果您看到:
- Error: Cannot find module:检查您的build文件夹并确保TypeScript编译成功
- Connection refused:确保服务器正在运行且路径正确
- Tool execution failed:验证工具所需的环境变量已设置
- ANTHROPIC_API_KEY is not set:检查您的.env文件和环境变量
- TypeError:确保您使用了正确的工具参数类型