烂翻译系列之——MCP开发——构建MCP服务

Get started building your own server to use in Claude for Desktop and other clients.

开始构建你自己的服务,用于 Claude Desktop 及其他客户端。

In this tutorial, we’ll build a simple MCP weather server and connect it to a host, Claude for Desktop.

在本教程中,我们将构建一个简单的 MCP 天气服务,并将其连接到主机 Claude for Desktop。

What we’ll be building    我们将要构建的内容

We’ll build a server that exposes two tools: get_alerts and get_forecast. Then we’ll connect the server to an MCP host (in this case, Claude for Desktop):

我们将构建一个提供两个工具的服务:get_alertsget_forecast。然后,我们将该服务连接到一个 MCP 主机(本例中为 Claude for Desktop):

image

Servers can connect to any client. We’ve chosen Claude for Desktop here for simplicity, but we also have guides on building your own client as well as a list of other clients here.

服务可以连接到任何客户端。我们在此选择 Claude for Desktop 是为了简化说明,但我们也有相关指南介绍如何构建你自己的客户端,以及其他客户端的列表,详见此处。

Core MCP Concepts    核心 MCP 概念

MCP servers can provide three main types of capabilities:

MCP服务可提供三大类功能::

  1. Resources: File-like data that can be read by clients (like API responses or file contents)    资源:可供客户端读取的类文件数据(例如API响应或文件内容)

  2. Tools: Functions that can be called by the LLM (with user approval)    工具:可由大语言模型(LLM)调用的函数(需用户批准)

  3. Prompts: Pre-written templates that help users accomplish specific tasks    提示词:预设的模板,帮助用户完成特定任务

This tutorial will primarily focus on tools.

本教程将主要聚焦于“工具”的实现。

Let’s get started with building our weather server! You can find the complete code for what we’ll be building here.

Prerequisite knowledge    前置知识

This quickstart assumes you have familiarity with:

本快速入门教程假设你已具备以下知识:

  • C#

  • LLMs like Claude   像 Claude 这样的大语言模型

  • .NET 8 or higher    .NET 8 或更高版本

Logging in MCP Servers    MCP 服务中的日志记录

When implementing MCP servers, be careful about how you handle logging:

在实现 MCP 服务时,需谨慎处理日志记录:

For STDIO-based servers: Never write to standard output (stdout). This includes:

对于基于 STDIO 的服务:切勿向标准输出(stdout)写入内容。这包括:

  • print() statements in Python    Python 中的 print() 语句

  • console.log() in JavaScript    JavaScript 中的 console.log()

  • fmt.Println() in Go    Go 中的 fmt.Println()

  • Similar stdout functions in other languages    其他语言中类似向 stdout 输出的函数

Writing to stdout will corrupt the JSON-RPC messages and break your server.

向 stdout 写入内容会破坏 JSON-RPC 消息,导致服务无法正常工作。

For HTTP-based servers: Standard output logging is fine since it doesn’t interfere with HTTP responses.

对于基于 HTTP 的服务:可以正常使用标准输出进行日志记录,因为它不会干扰 HTTP 响应。

Best Practices    最佳实践

  1. Use a logging library that writes to stderr or files    使用将日志写入 stderr 或文件的日志记录库

System requirements    系统要求

  • .NET 8 SDK or higher installed.    已安装 .NET 8 SDK 或更高版本。

Set up your environment    设置你的环境

First, let’s install dotnet if you haven’t already. You can download dotnet from official Microsoft .NET website. Verify your dotnet installation:

首先,如果尚未安装 dotnet,请先进行安装。你可以从微软官方 .NET 网站下载 dotnet。安装完成后,请验证你的 dotnet 安装:

dotnet --version

Now, let’s create and set up your project:

现在,让我们创建并配置你的项目:

macOS/Linux Windows
# Create a new directory for our project
mkdir weather
cd weather
# Initialize a new C# project
dotnet new console
# Create a new directory for our project
mkdir weather
cd weather
# Initialize a new C# project
dotnet new console

After running dotnet new console, you will be presented with a new C# project. You can open the project in your favorite IDE, such as Visual Studio or Rider. Alternatively, you can create a C# application using the Visual Studio project wizard. After creating the project, add NuGet package for the Model Context Protocol SDK and hosting: 

运行 dotnet new console 后,系统将为你创建一个新的 C# 项目。你可以使用你喜爱的集成开发环境(IDE)(例如 Visual Studio 或 Rider)打开该项目。或者,你也可以使用 Visual Studio 的项目向导来创建 C# 应用程序。项目创建完成后,添加 Model Context Protocol SDK 及其宿主功能的 NuGet 包:

# Add the Model Context Protocol SDK NuGet package
dotnet add package ModelContextProtocol --prerelease
# Add the .NET Hosting NuGet package
dotnet add package Microsoft.Extensions.Hosting

Now let’s dive into building your server.

现在,让我们开始深入构建你的服务。

Building your server    构建你的服务

Open the Program.cs file in your project and replace its contents with the following code:

在项目中打开 Program.cs 文件,并将其内容替换为以下代码:

using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using ModelContextProtocol;
using System.Net.Http.Headers;

var builder = Host.CreateEmptyApplicationBuilder(settings: null);

builder.Services.AddMcpServer()
    .WithStdioServerTransport()
    .WithToolsFromAssembly();

builder.Services.AddSingleton(_ =>
{
    var client = new HttpClient() { BaseAddress = new Uri("https://api.weather.gov") };
    client.DefaultRequestHeaders.UserAgent.Add(new ProductInfoHeaderValue("weather-tool", "1.0"));
    return client;
});

var app = builder.Build();

await app.RunAsync();

When creating the ApplicationHostBuilder, ensure you use CreateEmptyApplicationBuilder instead of CreateDefaultBuilder. This ensures that the server does not write any additional messages to the console. This is only necessary for servers using STDIO transport.

在创建 ApplicationHostBuilder 时,务必使用 CreateEmptyApplicationBuilder 而不是 CreateDefaultBuilder。这可以确保服务不会向控制台写入任何额外消息。此要求仅适用于使用 STDIO 传输的服务。

This code sets up a basic console application that uses the Model Context Protocol SDK to create an MCP server with standard I/O transport.

这段代码配置了一个基本的控制台应用程序,使用 Model Context Protocol SDK 创建一个采用标准 I/O 传输的 MCP 服务。

Weather API helper functions    天气 API 辅助函数

Create an extension class for HttpClient which helps simplify JSON request handling:

创建一个 HttpClient 的扩展类,以简化 JSON 请求的处理:

using System.Text.Json;

internal static class HttpClientExt
{
    public static async Task<JsonDocument> ReadJsonDocumentAsync(this HttpClient client, string requestUri)
    {
        using var response = await client.GetAsync(requestUri);
        response.EnsureSuccessStatusCode();
        return await JsonDocument.ParseAsync(await response.Content.ReadAsStreamAsync());
    }
}

Next, define a class with the tool execution handlers for querying and converting responses from the National Weather Service API:

接下来,定义一个类,其中包含用于查询和转换美国国家气象局(NWS)API响应的工具执行处理程序:

using ModelContextProtocol.Server;
using System.ComponentModel;
using System.Globalization;
using System.Text.Json;

namespace QuickstartWeatherServer.Tools;

[McpServerToolType]
public static class WeatherTools
{
    [McpServerTool, Description("Get weather alerts for a US state.")]
    public static async Task<string> GetAlerts(
        HttpClient client,
        [Description("The US state to get alerts for.")] string state)
    {
        using var jsonDocument = await client.ReadJsonDocumentAsync($"/alerts/active/area/{state}");
        var jsonElement = jsonDocument.RootElement;
        var alerts = jsonElement.GetProperty("features").EnumerateArray();

        if (!alerts.Any())
        {
            return "No active alerts for this state.";
        }

        return string.Join("\n--\n", alerts.Select(alert =>
        {
            JsonElement properties = alert.GetProperty("properties");
            return $"""
                    Event: {properties.GetProperty("event").GetString()}
                    Area: {properties.GetProperty("areaDesc").GetString()}
                    Severity: {properties.GetProperty("severity").GetString()}
                    Description: {properties.GetProperty("description").GetString()}
                    Instruction: {properties.GetProperty("instruction").GetString()}
                    """;
        }));
    }

    [McpServerTool, Description("Get weather forecast for a location.")]
    public static async Task<string> GetForecast(
        HttpClient client,
        [Description("Latitude of the location.")] double latitude,
        [Description("Longitude of the location.")] double longitude)
    {
        var pointUrl = string.Create(CultureInfo.InvariantCulture, $"/points/{latitude},{longitude}");
        using var jsonDocument = await client.ReadJsonDocumentAsync(pointUrl);
        var forecastUrl = jsonDocument.RootElement.GetProperty("properties").GetProperty("forecast").GetString()
            ?? throw new Exception($"No forecast URL provided by {client.BaseAddress}points/{latitude},{longitude}");

        using var forecastDocument = await client.ReadJsonDocumentAsync(forecastUrl);
        var periods = forecastDocument.RootElement.GetProperty("properties").GetProperty("periods").EnumerateArray();

        return string.Join("\n---\n", periods.Select(period => $"""
                {period.GetProperty("name").GetString()}
                Temperature: {period.GetProperty("temperature").GetInt32()}°F
                Wind: {period.GetProperty("windSpeed").GetString()} {period.GetProperty("windDirection").GetString()}
                Forecast: {period.GetProperty("detailedForecast").GetString()}
                """));
    }
}

Running the server

Finally, run the server using the following command:

最后,使用以下命令运行服务器:

dotnet run

This will start the server and listen for incoming requests on standard input/output.

这将启动服务,并在标准输入/输出上监听传入的请求。

Testing your server with Claude for Desktop    使用 Claude for Desktop 测试你的服务

Claude for Desktop is not yet available on Linux. Linux users can proceed to the Building a client tutorial to build an MCP client that connects to the server we just built.

Claude for Desktop 目前尚未在 Linux 系统上提供。Linux 用户可以前往“构建客户端”教程,创建一个 MCP 客户端,连接到我们刚刚构建的服务。

 First, make sure you have Claude for Desktop installed. You can install the latest version here. If you already have Claude for Desktop, make sure it’s updated to the latest version. We’ll need to configure Claude for Desktop for whichever MCP servers you want to use. To do this, open your Claude for Desktop App configuration at ~/Library/Application Support/Claude/claude_desktop_config.json in a text editor. Make sure to create the file if it doesn’t exist. For example, if you have VS Code installed:

 首先,请确保你已安装 Claude for Desktop。你可以在此处安装最新版本。如果你已安装 Claude for Desktop,请确保其已更新至最新版本。我们需要对 Claude for Desktop 进行配置,以使用你希望连接的 MCP 服务。为此,请在文本编辑器中打开 Claude for Desktop 的应用配置文件:~/Library/Application Support/Claude/claude_desktop_config.json。如果该文件不存在,请先创建它。例如,如果你已安装 VS Code:

macOS/Linux Windows
code ~/Library/Application\ Support/Claude/claude_desktop_config.json
code $env:AppData\Claude\claude_desktop_config.json

You’ll then add your servers in the mcpServers key. The MCP UI elements will only show up in Claude for Desktop if at least one server is properly configured. In this case, we’ll add our single weather server like so: 

然后,你需要在 mcpServers 键中列出你的服务。只有在正确配置了至少一个服务后,Claude for Desktop 中才会显示 MCP 的用户界面元素。在此示例中,我们将添加刚刚创建的天气服务,如下所示:

macOS/Linux Windows
{
  "mcpServers": {
    "weather": {
      "command": "dotnet",
      "args": ["run", "--project", "/ABSOLUTE/PATH/TO/PROJECT", "--no-build"]
    }
  }
}
{
  "mcpServers": {
    "weather": {
      "command": "dotnet",
      "args": [
        "run",
        "--project",
        "C:\\ABSOLUTE\\PATH\\TO\\PROJECT",
        "--no-build"
      ]
    }
  }
}
This tells Claude for Desktop:    这告诉 Claude for Desktop:
  1. There’s an MCP server named “weather”    有一个名为“weather”(天气)的 MCP 服务

  2. Launch it by running dotnet run /ABSOLUTE/PATH/TO/PROJECT     通过运行 dotnet run /ABSOLUTE/PATH/TO/PROJECT 来启动该服务

Save the file, and restart Claude for Desktop.

保存文件,然后重启 Claude for Desktop。

Test with commands    使用命令进行测试

Let’s make sure Claude for Desktop is picking up the two tools we’ve exposed in our weather server. You can do this by looking for the “Search and tools”  icon: 

让我们确认 Claude for Desktop 能够识别我们天气服务提供的两个工具。你可以通过查找“搜索和工具” 图标  来验证:

image

After clicking on the slider icon, you should see two tools listed:

点击  图标后,你应该会看到列出的两个工具:

image

If your server isn’t being picked up by Claude for Desktop, proceed to the Troubleshooting section for debugging tips.

如果 Claude for Desktop 未能识别你的服务,请前往“故障排除”部分获取调试建议。

If the tool settings icon has shown up, you can now test your server by running the following commands in Claude for Desktop:

如果工具设置图标已成功显示,你现在可以在 Claude for Desktop 中运行以下命令来测试你的服务:

  • What’s the weather in Sacramento?    萨克拉门托的天气如何?

  • What are the active weather alerts in Texas?    得克萨斯州当前有哪些天气预警?

image

image

Since this is the US National Weather service, the queries will only work for US locations.

由于这是美国国家气象服务,查询仅对美国境内的地点有效。

What’s happening under the hood    幕后发生了什么

When you ask a question:

当你提出一个问题时,整个流程如下:

  1. The client sends your question to Claude    客户端将你的问题发送给 Claude

  2. Claude analyzes the available tools and decides which one(s) to use    Claude 分析可用的工具,并决定使用哪一个(或多个)

  3. The client executes the chosen tool(s) through the MCP server    客户端通过 MCP 服务执行所选的工具

  4. The results are sent back to Claude    工具执行结果被发送回 Claude

  5. Claude formulates a natural language response    Claude 生成自然语言形式的回复

  6. The response is displayed to you!    回复内容显示给你!

Troubleshooting    故障排除

Claude for Desktop Integration Issues    Claude for Desktop 集成问题

Getting logs from Claude for Desktop    从 Claude for Desktop 获取日志

Claude.app logging related to MCP is written to log files in ~/Library/Logs/Claude:

Claude.app 会将与 MCP 相关的日志写入 ~/Library/Logs/Claude 目录中的日志文件:

  • mcp.log will contain general logging about MCP connections and connection failures.    mcp.log 文件将包含有关 MCP 连接及连接失败的一般日志信息。
  • Files named mcp-server-SERVERNAME.log will contain error (stderr) logging from the named server.    名为 mcp-server-SERVERNAME.log 的文件将包含对应服务输出的错误日志(stderr)。

You can run the following command to list recent logs and follow along with any new ones:

你可以运行以下命令来列出最近的日志,并实时跟踪新生成的日志:

# Check Claude's logs for errors
tail -n 20 -f ~/Library/Logs/Claude/mcp*.log

Server not showing up in Claude    服务未在 Claude 中显示

  1. Check your claude_desktop_config.json file syntax    检查 claude_desktop_config.json 文件的语法是否正确

  2. Make sure the path to your project is absolute and not relative    确保项目路径为绝对路径而非相对路径

  3. Restart Claude for Desktop completely    完全重启 Claude for Desktop

Tool calls failing silently    工具调用静默失败

If Claude attempts to use the tools but they fail:

如果 Claude 尝试使用工具但操作失败:

  1. Check Claude’s logs for errors    检查 Claude 的日志文件是否有错误信息

  2. Verify your server builds and runs without errors    确认服务能够成功构建并正常运行,无任何错误

  3. Try restarting Claude for Desktop    尝试完全重启 Claude for Desktop

None of this is working. What do I do?

以上方法均无效。我该怎么办?

Please refer to our debugging guide for better debugging tools and more detailed guidance. 

请参考我们的调试指南,获取更强大的调试工具和更详细的指导。

Weather API Issues    天气API问题

Error: Failed to retrieve grid point data    错误:无法获取网格点数据

This usually means either:

这通常意味着以下情况之一:

  1. The coordinates are outside the US    坐标位于美国境外

  2. The NWS API is having issues    美国国家气象局(NWS)API 出现问题

  3. You’re being rate limited    你触发了请求频率限制

Fix:

解决方法:

  • Verify you’re using US coordinates    确认你使用的是美国境内的坐标

  • Add a small delay between requests    在请求之间增加短暂延迟

  • Check the NWS API status page    查看 NWS API 的状态页面

Error: No active alerts for [STATE]    错误:[美国的某个州] 无活跃天气预警

This isn’t an error - it just means there are no current weather alerts for that state. Try a different state or check during severe weather.

这并非真正的错误——仅表示该州当前没有天气预警。可以尝试查询其他州,或在恶劣天气期间再次检查。

For more advanced troubleshooting, check out our guide on Debugging MCP

如需更高级的故障排除,请查阅我们的《MCP 调试指南》。

posted @ 2025-09-18 15:39  菜鸟吊思  阅读(8)  评论(0)    收藏  举报