> For the complete documentation index, see [llms.txt](https://yeasy.gitbook.io/claude_guide/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://yeasy.gitbook.io/claude_guide/di-er-bu-fen-gong-ju-pian/04_mcp/4.5_custom.md).

# 4.5 从零开发自定义 MCP Server

虽然社区提供了很多现成的 Server，但在企业应用中，往往需要让 Claude 连接 **内部 API**、**私有数据库** 或者 **自研系统**。

本节将介绍如何用 Python 和 TypeScript 两种语言，快速开发一个自定义的 MCP Server。

## 4.5.1 极速入门：FastMCP

如果是 Python 开发者，Anthropic 官方提供了一个名为 `fastmcp`（包含在 `mcp` 库中）的高级封装，它可以像写 FastAPI 一样简单地写 MCP Server。

### 环境准备

```bash
# 安装 mcp 库
pip install mcp
```

### 编写代码：`weather_server.py`

下面做一个简单的“虚拟天气服务”。

```python
from mcp.server.fastmcp import FastMCP

# 1. 创建 Server 实例
mcp = FastMCP("My Weather Server")

# 2. 定义工具 (使用装饰器)
# docstring 会自动变成工具的 description
# 类型注解会自动变成 input_schema
@mcp.tool()
def get_weather(city: str) -> str:
    """获取指定城市的当前天气情况。"""
    # 这里可以填写真实的 API 调用逻辑
    # 例如: requests.get(f"https://api.weather.com/{city}")
    return f"{city} 今天晴朗，气温 25度。"

# 3. 定义资源
# 让 Claude 可以直接读取这种格式的数据: weather://beijing
@mcp.resource("weather://{city}")
def get_weather_resource(city: str) -> str:
    """以资源形式获取天气数据"""
    return f"Latest weather report for {city}: Sunny, 25C, Humidity 40%."

if __name__ == "__main__":
    # 启动 Server
    mcp.run()
```

### 本地测试

可以使用 MCP Inspector 直接运行它：

```bash
npx @modelcontextprotocol/inspector python weather_server.py
```

这会弹出一个网页，可以在上面看到 `get_weather` 工具，点击运行，还能看到 JSON 交互日志。

## 4.5.2 企业级开发：TypeScript SDK

如果是 Node.js 开发者，可以使用官方的 TypeScript SDK。这通常用于构建生产环境级别、基于 Docker 的 Server。

### 初始化项目

```bash
mkdir my-mcp-server
cd my-mcp-server
npm init -y
npm pkg set type=module   # 必须：示例使用顶层 await，CommonJS 下 tsx 会直接报错
npm install @modelcontextprotocol/sdk zod
npm install -D typescript tsx @types/node
```

### 编写代码：`index.ts`

```typescript
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { CallToolRequestSchema, ListToolsRequestSchema } from "@modelcontextprotocol/sdk/types.js";

// 1. 初始化 Server
const server = new Server(
  {
    name: "my-ts-server",
    version: "1.0.0",
  },
  {
    capabilities: {
      tools: {}, // 声明支持 Tools 能力
    },
  }
);

// 2. 实现 Tools 列表
server.setRequestHandler(ListToolsRequestSchema, async () => {
  return {
    tools: [
      {
        name: "calculate_sum",
        description: "计算两个数字的和",
        inputSchema: {
          type: "object",
          properties: {
            a: { type: "number" },
            b: { type: "number" },
          },
          required: ["a", "b"],
        },
      },
    ],
  };
});

// 3. 实现工具调用逻辑
server.setRequestHandler(CallToolRequestSchema, async (request) => {
  if (request.params.name === "calculate_sum") {
    const args = request.params.arguments as { a: number; b: number };
    const sum = args.a + args.b;

    return {
      content: [
        {
          type: "text",
          text: `Result is ${sum}`,
        },
      ],
    };
  }
  throw new Error("Tool not found");
});

// 4. 连接 Transport
const transport = new StdioServerTransport();
await server.connect(transport);
```

开发时可直接运行：

```bash
npx tsx index.ts
```

## 4.5.3 设计原则与最佳实践

开发 MCP Server 时，请遵循以下原则：

### 保持原子性

不要做一个名为 `do_everything` 的工具。

* *Bad*: `manage_user(action="create", ...)`
* *Good*: `create_user(...)`, `delete_user(...)`, `update_user(...)` 工具越小，模型越容易组合使用。

### 丰富的描述

`docstring` 或 `description` 字段非常重要。 告诉 Claude：

* 这个工具是干嘛的？
* 参数的单位是什么？（秒？毫秒？）
* 返回值的格式是什么？

### 错误处理

如果 API 调用失败，**不要抛出异常让进程崩溃**。 应该捕获异常，并返回一个包含错误信息的文本结果，或者使用 `isError: true` 标志（如果 SDK 支持）。这样 Claude 可以读取错误信息，并尝试自我修正（比如换个参数重试）。

## 4.5.4 部署与分发

当写好 Server 后，如何分享给团队？

* **NPM 发布**: 将 TypeScript Server 发布为 npm 包。
  * 配置 command: `npx -y my-mcp-server`
* **Docker 部署**: 封装为 Docker 镜像，通过 Streamable HTTP 暴露远程 MCP 端点。
  * 适用于云端部署，供远程 Client 连接；如果必须兼容旧客户端，可同时保留旧 HTTP+SSE 传输。
* **Git 仓库**: 直接分享源码。
  * 配置 command: `python /path/to/repo/main.py`

***

Claude 现在已经连接上了数据。接下来，将介绍更强大的功能——让 Claude 自己看屏幕，像人一样操作电脑。

➡️ [第五章：Computer Use 计算机操控](/claude_guide/di-er-bu-fen-gong-ju-pian/05_computer_use.md)
