MCP客户端入门
客户端是与 MCP 服务器直接通信以请求资源、工具和提示的自定义应用程序或脚本。与使用提供图形界面的检查工具不同,编写自己的客户端可以实现编程和自动化交互。这使开发人员能够将 MCP 功能集成到自己的工作流程中,自动化任务,并构建针对特定需求量身定制的解决方案。
本课程介绍了 Model Context Protocol (MCP) 生态系统中的客户端概念。您将学习如何编写自己的客户端并将其连接到 MCP 服务器。
完成本课程后,您将能够:
- 了解客户端的功能。
- 编写自己的客户端。
- 连接并测试客户端与 MCP 服务器,以确保服务器正常工作。
要编写客户端,您需要完成以下步骤:
- 导入正确的库。您将使用之前相同的库,但需要不同的构造。
- 实例化客户端。这包括创建客户端实例并将其连接到选定的传输方法。
- 决定要列出的资源。您的 MCP 服务器提供资源、工具和提示,您需要决定列出哪些内容。
- 将客户端集成到主机应用程序中。一旦了解了服务器的功能,您需要将其集成到主机应用程序中,以便用户输入提示或其他命令时,调用相应的服务器功能。
现在我们已经了解了即将进行的操作的总体概况,接下来让我们看一个示例。
让我们看一个示例客户端:
TypeScript
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js";
const transport = new StdioClientTransport({
command: "node",
args: ["server.js"]
});
const client = new Client(
{
name: "example-client",
version: "1.0.0"
}
);
await client.connect(transport);
// List prompts
const prompts = await client.listPrompts();
// Get a prompt
const prompt = await client.getPrompt({
name: "example-prompt",
arguments: {
arg1: "value"
}
});
// List resources
const resources = await client.listResources();
// Read a resource
const resource = await client.readResource({
uri: "file:///example.txt"
});
// Call a tool
const result = await client.callTool({
name: "example-tool",
arguments: {
arg1: "value"
}
});
在上述代码中,我们:
- 导入了库。
- 创建了一个客户端实例,并使用 stdio 作为传输方式进行连接。
- 列出了提示、资源和工具,并调用了它们。
就是这样,一个可以与 MCP 服务器通信的客户端。
接下来,我们将在练习部分逐步分解每段代码并解释其作用。
如上所述,我们将逐步解释代码,当然,如果您愿意,可以跟着一起编写代码。
让我们导入所需的库,我们需要引用客户端和选定的传输协议 stdio。stdio 是一种用于本地运行的协议。SSE 是另一种传输协议,我们将在后续章节中展示,但这是您的另一个选择。现在,让我们继续使用 stdio。
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;
using ModelContextProtocol.Client;
using ModelContextProtocol.Protocol;
接下来是实例化。
我们需要创建传输实例以及客户端实例:
.NET
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;
using ModelContextProtocol.Client;
using ModelContextProtocol.Protocol;
var builder = Host.CreateApplicationBuilder(args);
builder.Configuration.AddEnvironmentVariables().AddUserSecrets<Program>();
var clientTransport = new StdioClientTransport(new()
{
Name = "Demo Server",
Command = "dotnet",
Arguments = ["run", "--project", @"F:\dht\SLM\Source\McpCalculatorServer\McpCalculatorServer.csproj"],
});
await using var mcpClient = await McpClientFactory.CreateAsync(clientTransport);
在上述代码中,我们:
- 导入了所需的库。
- 创建了一个 stdio 传输,并创建了一个客户端
mcpClient
。后者是我们用来列出和调用 MCP 服务器功能的工具。
注意,在 "Arguments" 中,您可以指向 .csproj 或可执行文件。
现在,我们有一个可以连接的客户端,但程序运行时它实际上并没有列出其功能,因此接下来让我们完成这一部分:
.NET
foreach(var tool in await mcpClient.ListToolsAsync())
{
Console.WriteLine($"{tool.Name} ({tool.Description})");
}
以上是一个列出服务器工具的示例。对于每个工具,我们打印出其名称。
要调用功能,我们需要确保指定正确的参数,有时还需要指定我们尝试调用的名称。
- 添加一些代码以调用工具:
var result = await mcpClient.CallToolAsync("add", new Dictionary<string, object?>() { ["a"] = 1, ["b"] = 3 }, cancellationToken: CancellationToken.None);
- 打印结果,以下是处理结果的代码:
var res = result.Content.First(c => c.Type == "text"); if (res is TextContentBlock textContentBlock) { Console.WriteLine(textContentBlock.Text); }
要运行客户端,请在终端中输入以下命令:
.NET
dotnet run
在本次作业中,您将使用所学内容创建自己的客户端。
以下是您可以使用的服务器,您需要通过客户端代码调用它,看看是否可以为服务器添加更多功能,使其更有趣。
.NET
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using ModelContextProtocol.Server;
using System.ComponentModel;
var builder = Host.CreateApplicationBuilder(args);
builder.Logging.AddConsole(consoleLogOptions =>
{
// Configure all logs to go to stderr
consoleLogOptions.LogToStandardErrorThreshold = LogLevel.Trace;
});
builder.Services
.AddMcpServer()
.WithStdioServerTransport()
.WithToolsFromAssembly();
await builder.Build().RunAsync();
[McpServerToolType]
public static class CalculatorTool
{
[McpServerTool, Description("Adds two numbers")]
public static string Add(int a, int b) => $"Sum {a + b}";
}
查看此项目以了解如何 添加提示和资源。
同时,查看此链接以了解如何调用 提示和资源。
解决方案文件夹包含完整的、可运行的客户端实现,展示了本教程中涵盖的所有概念。每个解决方案包括客户端和服务器代码,组织为独立的项目。
解决方案目录按编程语言组织:
solution/
├── typescript/ # TypeScript client with npm/Node.js setup
│ ├── package.json # Dependencies and scripts
│ ├── tsconfig.json # TypeScript configuration
│ └── src/ # Source code
├── java/ # Java Spring Boot client project
│ ├── pom.xml # Maven configuration
│ ├── src/ # Java source files
│ └── mvnw # Maven wrapper
├── python/ # Python client implementation
│ ├── client.py # Main client code
│ ├── server.py # Compatible server
│ └── README.md # Python-specific instructions
├── dotnet/ # .NET client project
│ ├── dotnet.csproj # Project configuration
│ ├── Program.cs # Main client code
│ └── dotnet.sln # Solution file
├── rust/ # Rust client implementation
| ├── Cargo.lock # Cargo lock file
| ├── Cargo.toml # Project configuration and dependencies
| ├── src # Source code
| │ └── main.rs # Main client code
└── server/ # Additional .NET server implementation
├── Program.cs # Server code
└── server.csproj # Server project file
每个语言特定的解决方案提供:
- 完整的客户端实现,包含本教程中的所有功能。
- 工作项目结构,具有适当的依赖项和配置。
- 构建和运行脚本,便于设置和执行。
- 详细的 README,提供语言特定的说明。
- 错误处理和结果处理示例。
-
导航到您选择的语言文件夹:
cd solution/typescript/ # For TypeScript cd solution/java/ # For Java cd solution/python/ # For Python cd solution/dotnet/ # For .NET
-
按照每个文件夹中的 README 说明:
- 安装依赖项
- 构建项目
- 运行客户端
-
您应该看到的示例输出:
Prompt: Please review this code: console.log("hello"); Resource template: file Tool result: { content: [ { type: 'text', text: '9' } ] }
有关完整文档和逐步说明,请参阅:📖 解决方案文档
我们提供了所有编程语言的完整、可运行的客户端实现。这些示例展示了上述功能的全部内容,可用作参考实现或您自己项目的起点。
语言 | 文件 | 描述 |
---|---|---|
Java | client_example_java.java |
使用 SSE 传输的完整 Java 客户端,包含全面的错误处理 |
C# | client_example_csharp.cs |
使用 stdio 传输的完整 C# 客户端,支持自动服务器启动 |
TypeScript | client_example_typescript.ts |
完整的 TypeScript 客户端,支持所有 MCP 协议功能 |
Python | client_example_python.py |
使用 async/await 模式的完整 Python 客户端 |
Rust | client_example_rust.rs |
使用 Tokio 进行异步操作的完整 Rust 客户端 |
每个完整示例包括: |
- ✅ 连接建立和错误处理
- ✅ 服务器发现(工具、资源、提示等,视情况而定)
- ✅ 计算器操作(加、减、乘、除、帮助)
- ✅ 结果处理和格式化输出
- ✅ 全面的错误处理
- ✅ 清晰、带注释的代码,包含逐步说明
- 从上表中选择您偏好的语言
- 查看完整示例文件,以了解完整实现
- 按照
complete_examples.md
中的说明运行示例 - 根据您的具体用例修改和扩展示例
有关运行和自定义这些示例的详细文档,请参阅:📖 完整示例文档
解决方案文件夹 | 完整示例 |
---|---|
包含构建文件的完整项目结构 | 单文件实现 |
带依赖项的即用型项目 | 专注于代码示例 |
类生产环境的设置 | 教学参考 |
语言特定的工具链 | 跨语言对比 |
这两种方法各有价值——对于完整项目,请使用解决方案文件夹;对于学习和参考,请使用完整示例。
本章的关键要点如下,关于客户端的内容:
- 客户端既可以用于发现服务器功能,也可以调用服务器功能。
- 客户端可以在自身启动时启动服务器(如本章所述),但也可以连接到已运行的服务器。
- 客户端是测试服务器功能的绝佳方式,与上一章提到的Inspector等替代方案相比,具有独特优势。
