📌 新手提示:本文结尾提供了一键部署脚本(Windows / macOS / Linux 通用),不想手动逐条敲命令的同学,可以直接拉到文末下载运行,脚本会自动检测网络环境并选择最快的下载源。
引言
如果你用过 Claude Code,一定体验过它在你的项目里读代码、改文件、运行命令的丝滑感。但如果我问你:Claude Code 能不能查你公司内部的 MySQL 数据库?能不能调你团队内部的工单 API?能不能读你私有知识库里的文档?
答案是:能,只要你写一个 MCP Server。
MCP(Model Context Protocol,模型上下文协议) 是 Anthropic 于 2024 年底发布的开源标准,专门用来解决一个问题:AI 助手如何安全、标准化地接入外部数据源和工具。你可以把它理解成 AI 世界的"USB-C 接口"——不管后端是什么(数据库、API、文件系统、第三方服务),只要实现 MCP 协议,AI 就能即插即用。

上图展示了 MCP 的核心架构:Host(宿主进程,比如 Claude Code)通过 Client 与 Server 建立一对一的有状态连接,Server 则暴露 Resources(资源)、Tools(工具)、Prompts(提示词) 三种能力。
本教程会带你从零开始,用 Python 写一个真正能用的 MCP Server——先让它暴露一个简单的计算工具,再接上一个 SQLite 数据库和内部 API 调用,最后部署到云 Agent 沙箱里,让 Claude Code 在生产环境中安全地访问你的私有数据。
读完本文,你将掌握:
- MCP 协议的核心概念:Host、Client、Server 三角色各干什么,为什么这样设计
- 用 Python SDK 手写 MCP Server:从 15 行代码的玩具到能查数据库、调 API 的真实工具
- 接入 Claude Code:配置
.mcp.json,让 AI 在你的项目里直接调用你的 Server - 部署到生产环境:用云 Agent 沙箱实现容器隔离、出站白名单、自动休眠
一、什么是 MCP——给 AI 装一个"万能接口"
1.1 先理解一个痛点
在没有 MCP 之前,如果你想让 AI 助手访问你的私有数据,你只有几条路:
- 把数据贴进聊天框(贴得下吗?贴得完吗?每次都要贴吗?)
- 写一个自定义插件(不同 AI 工具格式不同,写完 Claude Code 的还得写 ChatGPT 的,写完 ChatGPT 的还得写 Cursor 的)
- 自己搭一个 API 网关(认证、鉴权、限流、格式转换……折腾一圈,最后发现每个 AI 工具的接口都不一样)
MCP 就是来解决这个碎片化问题的。 它定义了一套统一的协议,任何 AI 应用(称为 Host)只要支持 MCP,就能通过同一个接口接入任何实现了 MCP 的数据源或工具(称为 Server)。
1.2 一句话讲清楚 MCP 是什么
MCP = 连接 AI 应用与外部系统的开源标准协议。
类比:就像 USB-C 让同一根线能连手机、显示器、硬盘、键盘一样,MCP 让同一个接口能连数据库、API、文件系统、第三方服务。
官方列举了几个典型场景:
| 场景 | 说明 |
|---|---|
| 个人 AI 助手 | AI 访问你的 Google Calendar、Notion,帮你安排日程、整理笔记 |
| 设计稿转代码 | Claude Code 拿 Figma 设计稿,直接生成整站 Web App |
| 企业数据分析 | 聊天框里用自然语言问"上季度华南区销售额 Top 10 是谁",AI 自动查数据库返回结果 |
| 3D 建模 | AI 在 Blender 里创建 3D 设计,再直接送 3D 打印 |
1.3 谁在支持 MCP
目前已有 Claude、ChatGPT、VS Code、Cursor、MCPJam 等主流 AI 工具和平台宣布支持 MCP。这意味着你写一个 MCP Server,可以在多个 AI 应用里复用——真正的"一次编写,到处运行"。
二、MCP 协议架构:三个角色一台戏
MCP 协议底层基于 JSON-RPC(一种用 JSON 格式进行远程过程调用的协议,可以理解为"用 JSON 格式发请求、收结果"),是一个有状态的会话协议。
整个架构由三个角色组成:
2.1 Host(宿主进程)
Host 是"大管家"角色,负责:
- 创建并管理多个 Client 实例
- 控制每个 Client 的连接权限和生命周期
- 强制执行安全策略(比如用户确认后才能访问敏感数据)
- 协调 AI 模型(LLM)与各个 Server 之间的交互
在 Claude Code 里,Claude Code 本身就是一个 Host。 当你输入"帮我查一下数据库里昨天的订单"时,Claude Code(Host)会判断应该调用哪个 MCP Server 的哪个工具,然后把结果拿回来继续推理。
2.2 Client(客户端)
Client 由 Host 创建,与一个 Server 维持 1 对 1 的隔离连接。它的职责是:
- 建立有状态会话(session)
- 与 Server 协商能力(capability exchange)——“你能做什么?你有什么工具?”
- 双向路由协议消息
- 维护 Server 之间的安全边界
简单理解:Client 就是 Host 和 Server 之间的"专属电话线"。Host 可以同时打多个电话(连接多个 Server),但每个电话只连一个 Server。
2.3 Server(服务器)
Server 是真正干活的人,通过 MCP 定义的三种 Primitives(原语,即基本能力单元) 暴露功能:
| Primitive | 作用 | 示例 |
|---|---|---|
| Resources(资源) | 暴露只读数据,类似文件路径 | db://schema(数据库表结构)、docs://readme(文档内容) |
| Tools(工具) | 暴露可执行操作,AI 可以调用并获取结果 | sql_query(sql)(执行 SQL)、create_ticket(title)(创建工单) |
| Prompts(提示词) | 暴露预定义的提示词模板,帮助 AI 更好地使用你的工具 | "分析这张表的最佳实践"提示词 |
Server 还有一个特殊能力:反向请求 Sampling。意思是 Server 可以反过来请求 Host 的 AI 模型帮它生成内容——比如 Server 在处理一个复杂查询时,可以让 AI 先生成一段 SQL,再执行。
2.4 设计原则
MCP 官方明确了四条设计原则:
- Server 应该极其容易构建——这是 MCP 最核心的理念。后面你会看到,15 行 Python 代码就能写完一个 Server。
- Host 负责复杂的编排——把难的事交给平台,简单的事留给开发者。
- Server 专注特定、明确定义的能力——一个 Server 只做一件事,做好。
- 简单至上——能用简单方式解决的问题,绝不搞复杂。
三、环境准备:搭好开发台
在开始写代码之前,先把开发环境搭好。本章每一步都提供国内和海外两条路径,确保你在任何网络环境下都能跑通。
3.1 前置要求
| 要求 | 最低版本 | 检查命令 |
|---|---|---|
| Python | 3.10 及以上 | python3 --version |
| uv(推荐)或 pip | 最新版 | uv --version 或 pip --version |
Python 是一门编程语言,本教程用它来写 MCP Server。uv 是一个超快的 Python 包管理工具(可以理解成"pip 的 Pro Max 版"),官方推荐用来管理 MCP 项目,但 pip 也完全能用。
3.2 安装 Python(如果还没有)
海外用户:直接去 python.org 下载安装。
国内用户:推荐使用华为云镜像(速度更快):
# macOS / Linux
# 海外用户直连 python.org,国内用户用华为云镜像
# 以下以 Ubuntu/Debian 为例,其他系统类似
sudo apt update && sudo apt install python3 python3-pip -y
如果系统没有 apt,也可以直接下载安装包:
- 海外:https://www.python.org/downloads/
- 国内镜像:https://mirrors.huaweicloud.com/python/(选择 3.10 及以上版本)
3.3 安装 uv(推荐)
uv 是官方推荐的 MCP 项目管理工具,安装只需一条命令:
# macOS / Linux
curl -LsSf https://astral.sh/uv/install.sh | sh
# Windows PowerShell
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
如果上述命令因网络问题失败,可以用 pip 替代:
pip install uv。国内用户可加清华镜像:pip install uv -i https://pypi.tuna.tsinghua.edu.cn/simple。
3.4 创建项目目录
mkdir mcp-server-demo && cd mcp-server-demo
如果是用 uv 管理项目,初始化一个项目:
uv init
3.5 安装 MCP Python SDK
# 推荐方式(uv,带 mcp CLI 工具)
uv add "mcp[cli]"
# 或 pip 方式(国内用户加清华镜像加速)
pip install "mcp[cli]" -i https://pypi.tuna.tsinghua.edu.cn/simple
说明:
[cli]是 SDK 的可选扩展,安装后你会获得mcp dev、mcp run、mcp install等命令行工具——这些工具后面会频繁用到。不加[cli]只安装核心库,命令行工具不可用。
关于版本:当前 Python SDK 主分支是 v2(2026 年 7 月重大重构,支持最新 MCP 规范),pip install mcp 默认安装的就是 v2.x。如果你之前用过 v1,注意 v1 和 v2 的 API 有变化,迁移指南见官方文档(海外:https://py.sdk.modelcontextprotocol.io/migration/,国内可用 ghfast.top 镜像访问 GitHub 仓库)。
四、15 行代码写一个 MCP Server
现在进入正题。下面是 MCP 官方文档里的入门示例——一个完整的、能跑的 MCP Server:
# server.py
from mcp.server import MCPServer
# 创建一个 MCP Server 实例,名字叫 "Demo"
mcp = MCPServer("Demo")
@mcp.tool()
def add(a: int, b: int) -> int:
"""Add two numbers."""
return a + b
@mcp.resource("greeting://{name}")
def greeting(name: str) -> str:
"""Greet someone by name."""
return f"Hello, {name}!"
是的,就这么多。15 行代码,包含两个功能。
4.1 逐行解释
第 1 行 from mcp.server import MCPServer
从 MCP 的 Python SDK 里导入 MCPServer 类。这个类就是 MCP Server 的"骨架"。
第 4 行 mcp = MCPServer("Demo")
创建一个 MCP Server 实例,名字叫 "Demo"。这个名字会在 MCP Inspector 和 Claude Code 里显示,方便你识别。
第 6-8 行 @mcp.tool() 装饰器
这是关键。@mcp.tool() 是一个装饰器(Decorator,Python 的一种语法,可以理解为"给函数贴标签")。贴上 @mcp.tool() 标签后,这个函数就变成了一个 MCP Tool(工具)——AI 可以调用它,传入参数,拿到返回值。
第 7 行 def add(a: int, b: int) -> int:
一个普通的 Python 函数,接收两个整数参数 a 和 b,返回它们的和。重点:你不需要手写 JSON Schema,不需要手写请求解析,不需要手写协议处理。 a: int, b: int 这两个类型注解(Type Annotation,告诉 Python 参数是什么类型)会被 SDK 自动转为 JSON Schema,AI 就能"看懂"这个工具需要什么参数。
第 11-12 行 @mcp.resource("greeting://{name}")
这是另一种 MCP 能力:Resource(资源)。与 Tool 不同,Resource 是只读的,类似一个文件路径。"greeting://{name}" 定义了一个 URI 模板,{name} 是占位符——访问 greeting://Alice 会返回 "Hello, Alice!"。
4.2 为什么这个设计好
对比一下没有 MCP SDK 时你需要写什么:
- 手写 JSON-RPC 协议解析(几十行)
- 手写 JSON Schema 定义(每个参数的 type、description、required 都要手写)
- 手写请求路由(哪个方法对应哪个函数)
- 手写错误处理
- 手写 transport 层(stdio / HTTP / SSE)
而现在,两个类型注解函数 + 一个 docstring = 一个完整的 MCP Server。你只需要关注业务逻辑,其余全部由 SDK 处理。
五、用 MCP Inspector 测试你的 Server
写完代码后,不要急着接入 Claude Code——先用 MCP 官方提供的 MCP Inspector(检查器)测试。Inspector 是一个图形化的 MCP 调试工具,让你在浏览器里直接测试 Server 的每个工具和资源。
5.1 启动 Inspector
在 server.py 所在目录执行:
uv run mcp dev server.py
如果你用的是 pip 而不是 uv,可以这样:
mcp dev server.py(前提是 pip 安装时带了[cli]扩展)。
命令执行后,终端会输出类似这样的信息:
MCP Inspector is running on http://localhost:5173
5.2 在浏览器里测试
打开浏览器访问 http://localhost:5173,你会看到一个类似 Postman 的调试界面:
- 左侧面板列出了你的 Server 暴露的所有 Tools 和 Resources
- 点击
add,在输入框里填入a=1, b=2,点击"Call Tool" - 右侧面板会显示返回结果:
{"result": 3} - 再试试
greetingResource,输入name=Alice,返回"Hello, Alice!"
如果一切正常,恭喜你——你的第一个 MCP Server 已经跑通了!
5.3 常见启动失败排查
| 问题 | 原因 | 解决 |
|---|---|---|
command not found: uv | uv 未安装或不在 PATH 中 | 重新安装 uv(见第 3.3 节),或关闭终端重开 |
command not found: mcp | 未安装 [cli] 扩展 | 重新执行 pip install "mcp[cli]" |
ModuleNotFoundError: No module named 'mcp' | 未安装 MCP SDK | 执行 uv add "mcp[cli]" 或 pip install "mcp[cli]" |
Python version not supported | Python 版本低于 3.10 | 升级 Python 到 3.10 或以上 |
| 端口 5173 被占用 | 其他程序占用了 Inspector 端口 | 关闭占用端口的程序,或 MCP 会自动尝试其他端口 |
六、接入 Claude Code:让 AI 真正调用你的工具
MCP Inspector 测试通过后,下一步就是把 Server 接入 Claude Code。这里需要做一些配置。
6.1 Claude Code 的 MCP 配置文件
Claude Code 通过一个 JSON 配置文件来管理 MCP Server。配置文件的位置有两种:
- 项目级配置(推荐):在项目根目录创建
.mcp.json,只对当前项目生效 - 用户级配置:
~/.claude/mcp.json(Linux/macOS)或%USERPROFILE%\.claude\mcp.json(Windows),对所有项目生效
用项目级配置,在 mcp-server-demo 目录下创建 .mcp.json:
{
"mcpServers": {
"demo": {
"command": "uv",
"args": ["run", "mcp", "run", "server.py", "--transport", "stdio"]
}
}
}
解释:
command是启动 Server 的命令,args是命令参数。这里用的是 stdio transport(标准输入输出传输),Server 通过标准输入输出与 Claude Code 通信——这是本地开发最常用的方式。--transport stdio告诉 MCP 用标准输入输出方式通信(而不是 HTTP 网络通信)。
如果你用的是 pip 而不是 uv,配置改成:
{
"mcpServers": {
"demo": {
"command": "python3",
"args": ["-m", "mcp", "run", "server.py", "--transport", "stdio"]
}
}
}
6.2 启动 Claude Code 并测试
在项目目录下启动 Claude Code:
claude
进入会话后,输入:
请帮我用 add 工具计算 123 + 456
如果一切正常,Claude Code 会调用你刚才写的 add 工具,返回 579。你还可以试试:
请用 greeting 资源问候一下 Alice
Claude Code 会调用 greeting Resource,返回 "Hello, Alice!"。
到这里,你已经完成了"从零写一个 MCP Server 并接入 Claude Code"的全流程。工具虽然简单,但整个链路已经打通——接下来我们把能力升级到真实场景。
6.3 关于 Claude Code 的 API 访问
要让 Claude Code 跑起来,你需要一个能调用 Claude 模型的 API Key。官方 API 需要海外信用卡,且对非支持地区用户有封号风险。国内用户推荐使用 云间 API(https://cloudzone-api.cyou/)——一个稳定的 AI API 中转服务,原生支持 Anthropic 兼容接口,一键配置:
export ANTHROPIC_API_KEY="你的云间API-Key"
export ANTHROPIC_BASE_URL="https://cloudzone-api.cyou/v1"
云间 API 的 CC MAX 分组提供 Claude Opus / Sonnet / Haiku 全系列,折扣低至官方 0.5x,21 个模型可选,香港节点直连延迟极低,特别适合国内开发者日常使用。
七、实战:写一个能查数据库的 MCP Server
现在来真的。我们要写一个 MCP Server,包含两个真实功能:
- SQL 查询工具:让 Claude Code 能查本地的 SQLite 数据库
- 内部 API 调用工具:让 Claude Code 能调你公司内部的 HTTP API
7.1 准备测试数据
先创建一个简单的 SQLite 数据库作为示例:
# init_db.py
import sqlite3
conn = sqlite3.connect("company.db")
cursor = conn.cursor()
# 创建员工表
cursor.execute("""
CREATE TABLE IF NOT EXISTS employees (
id INTEGER PRIMARY KEY,
name TEXT NOT NULL,
department TEXT NOT NULL,
salary INTEGER NOT NULL
)
""")
# 插入几条测试数据
employees = [
(1, "张三", "技术部", 25000),
(2, "李四", "市场部", 18000),
(3, "王五", "技术部", 30000),
(4, "赵六", "人事部", 15000),
(5, "钱七", "市场部", 22000),
]
cursor.executemany("INSERT OR REPLACE INTO employees VALUES (?, ?, ?, ?)", employees)
conn.commit()
conn.close()
print("数据库初始化完成:company.db")
运行:
python3 init_db.py
7.2 完整的 MCP Server 代码
# mcp_company_server.py
import sqlite3
import httpx
from mcp.server import MCPServer
mcp = MCPServer("Company Data Server")
# ========== Tool 1: SQL 查询工具 ==========
@mcp.tool()
def sql_query(sql: str) -> str:
"""Execute a SQL query on the company SQLite database.
Use this to query employee information, department stats, etc.
Only SELECT queries are allowed for safety.
"""
# 安全检查:只允许 SELECT 语句
sql_stripped = sql.strip().upper()
if not sql_stripped.startswith("SELECT"):
return "Error: Only SELECT queries are allowed for safety."
try:
conn = sqlite3.connect("company.db")
conn.row_factory = sqlite3.Row # 让结果可以用列名访问
cursor = conn.cursor()
cursor.execute(sql)
rows = cursor.fetchall()
conn.close()
if not rows:
return "Query returned no results."
# 格式化为易读的文本
columns = [desc[0] for desc in cursor.description]
result_lines = [" | ".join(columns)]
result_lines.append("-" * len(result_lines[0]))
for row in rows:
result_lines.append(" | ".join(str(row[col]) for col in columns))
return "\n".join(result_lines)
except Exception as e:
return f"Query error: {str(e)}"
# ========== Tool 2: 内部 API 调用工具 ==========
@mcp.tool()
async def call_internal_api(
endpoint: str,
method: str = "GET",
body: str = "",
) -> str:
"""Call an internal company API endpoint.
endpoint: API path, e.g. '/api/v1/orders/today'
method: HTTP method, 'GET' or 'POST'
body: JSON body for POST requests
"""
BASE_URL = "https://api.internal-company.com"
async with httpx.AsyncClient(timeout=10.0) as client:
try:
if method.upper() == "GET":
response = await client.get(f"{BASE_URL}{endpoint}")
elif method.upper() == "POST":
response = await client.post(
f"{BASE_URL}{endpoint}",
content=body,
headers={"Content-Type": "application/json"},
)
else:
return f"Error: Unsupported method '{method}'. Use GET or POST."
return f"Status: {response.status_code}\n{response.text[:2000]}"
except Exception as e:
return f"API call failed: {str(e)}"
# ========== Resource: 数据库结构 ==========
@mcp.resource("db://schema")
def get_db_schema() -> str:
"""Return the database schema so AI can understand available tables."""
conn = sqlite3.connect("company.db")
cursor = conn.cursor()
cursor.execute(
"SELECT sql FROM sqlite_master WHERE type='table' AND name='employees'"
)
row = cursor.fetchone()
conn.close()
if row:
return f"Table: employees\n{row[0]}"
return "No table found. Run init_db.py first."
7.3 代码解释
sql_query 工具:
- 接收一个 SQL 字符串参数
- 安全检查:只允许
SELECT语句,防止 AI 误删数据(DELETE、DROP等一律拒绝) - 使用
sqlite3.Row让查询结果可以用列名访问,格式化输出为表格文本 - 返回给 AI 的文本会直接显示在 Claude Code 的对话中
call_internal_api 工具:
- 接收三个参数:
endpoint(API 路径)、method(GET/POST)、body(请求体) - 使用
httpx(一个支持异步的 HTTP 客户端库,比 requests 快)发送请求 - 注意这里是
async def——因为 HTTP 请求是 I/O 操作,用异步可以避免阻塞 - 返回 HTTP 状态码和响应内容(最多 2000 字符,避免超长响应)
db://schema Resource:
- 只读资源,返回数据库表结构
- 命名用
db://前缀,表示这是一个数据库相关的资源 - AI 在查询数据之前,可以先读这个 Resource 了解表结构,然后构造正确的 SQL
7.4 安装依赖
# uv 方式
uv add httpx
# pip 方式(国内用户加清华镜像)
pip install httpx -i https://pypi.tuna.tsinghua.edu.cn/simple
7.5 测试
用 MCP Inspector 测试:
uv run mcp dev mcp_company_server.py
在 Inspector 里测试 sql_query 工具,输入:
SELECT * FROM employees WHERE department = '技术部'
应该返回:
id | name | department | salary
------------------------------
1 | 张三 | 技术部 | 25000
3 | 王五 | 技术部 | 30000
7.6 接入 Claude Code
更新 .mcp.json 配置:
{
"mcpServers": {
"company-data": {
"command": "uv",
"args": ["run", "mcp", "run", "mcp_company_server.py", "--transport", "stdio"]
}
}
}
重启 Claude Code,然后试试这些问题:
- “技术部的平均薪资是多少?”
- “查一下公司所有员工,按薪资从高到低排列”
- “市场部有几个人?”
Claude Code 会自动调用你的 sql_query 工具,执行 SQL,然后把结果翻译成自然语言回答你。
这就是 MCP 的真正威力:AI 不需要知道数据库在哪、怎么连——它只需要知道"有一个工具叫 sql_query,可以执行 SQL 查询"。剩下的全部由你的 Server 处理。
八、部署到生产环境:CZ 云 Agent 沙箱
开发时用 mcp dev 和 stdio transport 很方便,但生产环境有几个问题要解决:
- Server 需要持续运行,不能依赖你的本地终端
- 安全隔离:Server 可能访问敏感数据,必须和你的本地环境隔离
- 网络访问控制:Server 只能访问白名单里的外部服务,不能随意出站
- 资源管控:CPU、内存、磁盘需要配额限制
这些问题可以通过 云 Agent 沙箱 来解决。云间 API 平台(https://cloudzone-api.cyou/)提供了一个"云 Agent"功能——一个一键启动的独立容器环境,内置 PicoClaw(轻量级 AI Agent 运行时),支持对话、工具调用与多步骤工作流,你只需要把 MCP Server 代码放进去,就能获得一个生产级的运行环境。
8.1 云 Agent 沙箱的核心能力
| 特性 | 说明 |
|---|---|
| 独立容器 | 每个 Agent 沙箱是独立的容器实例,数据完全隔离,他人无法访问你的工作区 |
| 出站白名单 | 严格限制出站网络访问,只能连接你指定的外部服务,防止数据泄露 |
| 资源配额 | CPU、内存、磁盘有上限,防止异常消耗 |
| 闲置自动暂停 | 一段时间不用后自动暂停,保留期内可恢复,到期自动清理 |
| 独立访问密码 | 专属 WebUI 带独立密码保护 |
| 内置 PicoClaw | 支持对话、工具调用与多步骤工作流,无需额外配置 |
8.2 部署步骤
第一步:在云间 API 面板启动云 Agent
登录 https://cloudzone-api.cyou/,进入「云 Agent」页面,点击启动。约 1 分钟就绪,系统会分配一个专属 WebUI 地址和访问密码。
第二步:上传 MCP Server 代码
通过云 Agent 的 WebUI 或 SSH 终端,将 mcp_company_server.py 和 init_db.py 上传到沙箱内。你也可以直接在沙箱终端里 git clone 你的代码仓库。
第三步:安装依赖
pip install "mcp[cli]" httpx -i https://pypi.tuna.tsinghua.edu.cn/simple
python3 init_db.py
第四步:以 Streamable HTTP 模式启动 Server
生产环境不用 stdio transport,改用 Streamable HTTP(一种基于 HTTP 长连接的传输方式,支持服务端主动推送数据):
mcp run mcp_company_server.py --transport streamable-http --port 8000
第五步:配置出站白名单
在云 Agent 面板的安全设置里,添加你需要访问的外部服务白名单(比如 api.internal-company.com),确保 Server 只能访问你指定的服务。
第六步:连接 Claude Code
在 Claude Code 的 .mcp.json 中改用 HTTP 连接:
{
"mcpServers": {
"company-data": {
"url": "https://your-agent.cloudzone-api.cyou/mcp",
"transport": "streamable-http"
}
}
}
注意:
url替换为云 Agent 分配给你的实际地址。transport设为streamable-http表示通过 HTTP 协议通信。
8.3 生产环境 vs 开发环境对比
| 维度 | 开发环境(stdio) | 生产环境(云 Agent + HTTP) |
|---|---|---|
| 通信方式 | 标准输入输出(本地进程通信) | HTTP(网络通信) |
| 启动方式 | Claude Code 自动启动子进程 | 独立运行,持续监听端口 |
| 隔离性 | 与本地环境共享文件系统 | 独立容器,完全隔离 |
| 网络控制 | 无限制 | 出站白名单 |
| 可用性 | 依赖本地终端 | 7x24 持续运行 |
| 资源管理 | 无限制 | CPU/内存/磁盘配额 |
九、常见问题
Q1:MCP 和 Function Calling 有什么区别?
Function Calling(函数调用)是单个 AI 模型层面的能力——模型在回复中告诉调用方"我想调用这个函数,参数是这些"。但 Function Calling 不定义传输协议、不定义生命周期管理、不定义安全模型。
MCP 是一套完整的协议栈,定义了从传输层(stdio/HTTP/SSE)到能力层(Tools/Resources/Prompts)再到安全层(Host 授权、沙箱隔离)的全部规范。Function Calling 更像是 MCP 内部的一个子机制。
Q2:我的 Server 能同时接 Claude Code 和 ChatGPT 吗?
能。MCP 是标准协议,只要 AI 应用支持 MCP Host 角色,就能接入你的 Server。目前 Claude Code、ChatGPT、Cursor、VS Code 等都已支持。
Q3:Server 需要处理并发请求吗?
取决于你的 transport 选择:
- stdio:单进程通信,天然串行,不需要处理并发
- Streamable HTTP / SSE:可能同时有多个 Client 连接,需要确保代码是线程安全的。
mcp run命令默认会处理基本并发,但如果你的工具代码里用了全局变量或共享状态,需要自己加锁
Q4:如何保护敏感数据(比如数据库密码)?
不要在代码里硬编码密码。 推荐使用环境变量:
import os
DB_PASSWORD = os.environ.get("DB_PASSWORD", "")
if not DB_PASSWORD:
raise RuntimeError("DB_PASSWORD environment variable not set")
在 Claude Code 的 .mcp.json 配置中传入环境变量:
{
"mcpServers": {
"company-data": {
"command": "uv",
"args": ["run", "mcp", "run", "mcp_company_server.py", "--transport", "stdio"],
"env": {
"DB_PASSWORD": "your-secret-password"
}
}
}
}
Q5:pip install mcp 超时怎么办?
国内用户使用清华镜像:
pip install "mcp[cli]" httpx -i https://pypi.tuna.tsinghua.edu.cn/simple
如果清华镜像也超时,可以换阿里云镜像:
pip install "mcp[cli]" httpx -i https://mirrors.aliyun.com/pypi/simple
Q6:uv run mcp dev server.py 报错找不到模块?
确认你在 server.py 所在目录执行命令。如果用的是 pip 安装的 mcp,用 mcp dev server.py 而不是 uv run mcp dev server.py。
Q7:MCP 支持哪些编程语言?
官方 SDK 目前支持 Python 和 TypeScript/JavaScript。社区也有 Go、Rust、Java、Kotlin、C# 等语言的实现。本教程使用 Python 是因为它上手最快、门槛最低。
十、总结
到这里,你已经从零开始,完整走通了 MCP Server 的开发链路:
- 理解了 MCP 协议:Host-Client-Server 三元组架构,基于 JSON-RPC 的有状态会话协议
- 用 Python SDK 写了 Server:从 15 行的玩具到能查数据库、调 API 的真实工具
- 接入 Claude Code:配置
.mcp.json,让 AI 在你的项目里直接调用你的工具 - 部署到生产环境:云 Agent 沙箱提供容器隔离、出站白名单、自动休眠
MCP 的意义在于,它把"AI 接入企业私有数据"这件事从"需要一个团队做半年"变成了"一个开发者一个下午就能搞定"。你不需要理解复杂的协议细节,不需要自己写 JSON-RPC 解析器,不需要操心传输层——Python SDK 帮你做了所有脏活累活,你只需要写好业务逻辑。
当然,这一切的前提是有一个稳定、低价的 API 入口来驱动 Claude Code。如果你还在为官方 API 的高昂费用和封号风险头疼,不妨试试 云间 API(https://cloudzone-api.cyou/)——它提供 GPT 低至 0.05x、DeepSeek 特惠 0.3x、Claude 全系列 0.5x 起的折扣价格,覆盖 90+ 模型,香港核心节点国模延迟低至 30ms,原生支持 Anthropic 和 OpenAI 兼容接口,替换 base_url 即可接入。更有云 Agent 沙箱一键部署,让你的 MCP Server 在生产环境中安全、稳定地运行。
现在就动手吧。 打开终端,创建一个 Python 文件,敲下 @mcp.tool(),然后把你的第一个 MCP Server 接入 Claude Code。你会发现,AI 不再只是聊天工具——它变成了你数据和业务的真正入口。
一键部署脚本
如果你觉得手动配置太繁琐,我们准备了一键部署脚本。脚本会自动完成:检测网络环境 → 安装 Python 依赖 → 初始化示例数据库 → 启动 MCP Server,全程引导式交互,国内国外网络都能用。
下载
| 平台 | 脚本文件 |
|---|---|
| macOS / Linux / WSL | setup-mcp-demo.sh |
| Windows | setup-mcp-demo.ps1 |
不方便下载的同学,可以直接复制文末的完整源码,新建文本文档粘贴后改后缀为 .sh 或 .ps1 运行。
使用说明
macOS / Linux / WSL:
chmod +x setup-mcp-demo.sh
./setup-mcp-demo.sh
Windows:
Windows 默认会阻止运行未签名的 PowerShell 脚本(这是 Windows 的安全策略,不是杀毒软件拦截)。在 PowerShell 中执行以下命令临时放行当前会话的执行策略,再运行脚本:
Set-ExecutionPolicy -Scope Process -ExecutionPolicy Bypass -Force
.\setup-mcp-demo.ps1
🔒 关于"为什么要放行执行策略":Windows 出于安全考虑,默认禁止运行未经数字签名(我们没有购买代码签名证书)的
.ps1脚本。-Scope Process表示仅在当前 PowerShell 窗口生效,关闭窗口后自动恢复原策略,不会永久改变你系统的安全设置。如果你仍不放心,可以先把脚本完整源码复制给任意 AI(包括 Claude、ChatGPT 等),让它帮你判断脚本是否安全,再决定是否运行。这就是我们公开全部源码的原因。
脚本完整源码
macOS / Linux / WSL 版(setup-mcp-demo.sh)
#!/usr/bin/env bash
# ============================================================
# MCP Server 开发实战 一键脚本(macOS / Linux / WSL)
# 公开源码,欢迎审查 —— 不放心可先复制给 AI 判断
# 默认配置:云间 API 中转站(https://cloudzone-api.cyou/)
# 功能:检测网络 → 装 Python 依赖(uv) → 生成示例 server.py → 启动 MCP Inspector
# ============================================================
set -u
CLOUDZONE_URL="https://cloudzone-api.cyou"
CLOUDZONE_API_BASE="https://cloudzone-api.cyou/v1"
GREEN='\033[0;32m'; YELLOW='\033[1;33m'; RED='\033[0;31m'; CYAN='\033[0;36m'; NC='\033[0m'
info() { echo -e "${GREEN}[INFO]${NC} $1"; }
warn() { echo -e "${YELLOW}[WARN]${NC} $1"; }
error() { echo -e "${RED}[ERROR]${NC} $1"; }
step() { echo -e "${CYAN}[STEP]${NC} $1"; }
fail() { error "$1"; error "脚本无法继续。请把以上报错复制给 AI 或贴到 issue 求助。"; exit 1; }
# ---------- 第 0 步:检测网络环境(国内 / 国外)----------
detect_network() {
step "检测网络环境(国内 / 国外)..."
if curl -fsI --max-time 6 "https://pypi.org" >/dev/null 2>&1; then
info "可直连 pypi.org,判定为海外网络"
echo "overseas"
else
warn "无法直连 pypi.org,判定为国内网络环境,将使用清华/阿里 PyPI 镜像"
echo "domestic"
fi
}
# ---------- 第 1 步:检查 Python ≥ 3.10 ----------
check_python() {
step "检查 Python 环境(需 3.10+)..."
if ! command -v python3 >/dev/null 2>&1; then
warn "未检测到 python3。请先安装 Python 3.10+(https://www.python.org/downloads/)"
fail "python3 未安装"
fi
local PY_VER
PY_VER=$(python3 -c 'import sys;print(f"{sys.version_info.major}.{sys.version_info.minor}")' 2>/dev/null || echo "0.0")
local MAJOR MINOR
MAJOR="${PY_VER%%.*}"
MINOR="${PY_VER#*.}"
if [ "$MAJOR" -lt 3 ] || { [ "$MAJOR" -eq 3 ] && [ "$MINOR" -lt 10 ]; }; then
fail "Python 版本 $PY_VER 低于 3.10,请升级(MCP Python SDK 要求 3.10+)"
fi
info "Python $PY_VER 已就绪"
}
# ---------- 第 2 步:安装 uv(推荐方式装 mcp) ----------
install_uv() {
local net="$1"
step "安装 uv(Python 包管理器,推荐)..."
if command -v uv >/dev/null 2>&1; then
info "uv 已安装:$(uv --version 2>/dev/null || echo uv)"
return 0
fi
if [ "$net" = "domestic" ]; then
info "国内网络:用清华 PyPI 镜像装 uv"
pip3 install --user -i https://pypi.tuna.tsinghua.edu.cn/simple uv >/dev/null 2>&1 \
|| pip3 install --user -i https://mirrors.aliyun.com/pypi/simple/ uv >/dev/null 2>&1 \
|| fail "uv 安装失败(pip3 镜像均不通)"
else
info "海外网络:官方脚本装 uv"
curl -LsSf https://astral.sh/uv/install.sh -o /tmp/uv_install.sh 2>/dev/null
[ -s /tmp/uv_install.sh ] && sh /tmp/uv_install.sh >/dev/null 2>&1 || pip3 install --user uv >/dev/null 2>&1 || fail "uv 安装失败"
rm -f /tmp/uv_install.sh
export PATH="$HOME/.local/bin:$HOME/.cargo/bin:$PATH"
fi
command -v uv >/dev/null 2>&1 || fail "uv 安装后仍不在 PATH,请手动装:pip3 install uv"
info "uv 安装完成"
}
# ---------- 第 3 步:创建项目目录 + 示例 server.py ----------
create_server() {
step "创建示例 MCP Server(add + greeting 两个工具)..."
local DIR="$HOME/mcp-demo"
mkdir -p "$DIR"
cd "$DIR" || fail "无法进入 $DIR"
# 初始化项目(国内用镜像源)
if [ ! -f "pyproject.toml" ]; then
info "初始化 uv 项目..."
if [ "${1:-overseas}" = "domestic" ]; then
UV_INDEX_URL="https://pypi.tuna.tsinghua.edu.cn/simple" uv init --no-readme >/dev/null 2>&1 \
|| UV_INDEX_URL="https://mirrors.aliyun.com/pypi/simple/" uv init --no-readme >/dev/null 2>&1
else
uv init --no-readme >/dev/null 2>&1
fi
fi
info "安装 mcp[cli]..."
if [ "${1:-overseas}" = "domestic" ]; then
uv add "mcp[cli]" --index-url https://pypi.tuna.tsinghua.edu.cn/simple >/dev/null 2>&1 \
|| uv add "mcp[cli]" --index-url https://mirrors.aliyun.com/pypi/simple/ >/dev/null 2>&1 \
|| fail "mcp 安装失败(PyPI 镜像均不通)"
else
uv add "mcp[cli]" >/dev/null 2>&1 || fail "mcp 安装失败(pypi.org 不通?)"
fi
cat > server.py <<'PYEOF'
"""示例 MCP Server:add(加法)+ greeting(问候)两个工具。
启动后用 `mcp dev` 打开 Inspector 测试,或在 Claude Code 里把本文件作为 MCP server 接入。
"""
from mcp.server import MCPServer
mcp = MCPServer("Demo")
@mcp.tool()
def add(a: int, b: int) -> int:
"""Add two numbers."""
return a + b
@mcp.resource("greeting://{name}")
def greeting(name: str) -> str:
"""Greet someone by name."""
return f"Hello, {name}!"
if __name__ == "__main__":
mcp.run()
PYEOF
info "示例 server.py 已生成:$DIR/server.py"
echo "$DIR"
}
# ---------- 第 4 步:(可选)引导配置 CZ API Key 接入 Claude Code ----------
setup_api_key() {
echo ""
echo "----------------------------------------"
echo "想让 MCP Server 真正接入 Claude Code 跑起来?"
echo "Claude Code 需调用 Anthropic API。国内直连 anthropic.com 受限,"
echo "推荐用云间 API 中转站:"
echo " · 价格低至官方两折,国内直连无需翻墙"
echo " · 支持 90+ 模型(Claude/GPT/DeepSeek),香港节点延迟低"
echo ""
echo "是否现在跳转注册并获取 API Key?"
echo " Y - 立即跳转至 ${CLOUDZONE_URL}"
echo " N - 我已有 Key,自行输入"
read -r -p "请选择 [Y/N]: " choice
local API_KEY=""
if [ "${choice:-N}" = "Y" ] || [ "${choice:-N}" = "y" ]; then
info "正在打开浏览器..."
if command -v xdg-open >/dev/null 2>&1; then
xdg-open "$CLOUDZONE_URL" >/dev/null 2>&1
elif command -v open >/dev/null 2>&1; then
open "$CLOUDZONE_URL" >/dev/null 2>&1
else
warn "无法自动打开浏览器,请手动访问:$CLOUDZONE_URL"
fi
echo "注册后在「我的 API Key」页面复制 Key(以 sk- 开头)。"
read -r -p "粘贴你的 API Key: " API_KEY
else
# 关闭回显,避免 Key 明文留在终端滚动区
read -r -s -p "请输入你的 API Key (sk-...): " API_KEY
echo
fi
if [ -z "${API_KEY:-}" ]; then
warn "未输入 API Key,跳过 Claude Code 配置。可稍后手动 export ANTHROPIC_API_KEY。"
return 0
fi
# 写入 shell 配置(让 Claude Code 进程能读到)
local RC=""
[ -f "$HOME/.zshrc" ] && RC="$HOME/.zshrc"
[ -f "$HOME/.bashrc" ] && [ -z "$RC" ] && RC="$HOME/.bashrc"
if [ -n "$RC" ]; then
# 去掉旧的 CZ 配置
sed -i '/# CZ API config (cloudzone)/,/^export ANTHROPIC_BASE_URL=/d' "$RC" 2>/dev/null
{
echo "# CZ API config (cloudzone) - added by mcp-demo setup"
echo "export ANTHROPIC_API_KEY=\"${API_KEY}\""
echo "export ANTHROPIC_BASE_URL=\"${CLOUDZONE_API_BASE}\""
} >> "$RC"
info "已写入 $RC:ANTHROPIC_API_KEY + ANTHROPIC_BASE_URL"
warn "新开终端才会生效。当前终端请手动执行:export ANTHROPIC_API_KEY=... ANTHROPIC_BASE_URL=$CLOUDZONE_API_BASE"
else
warn "未找到 .zshrc/.bashrc,请手动设置两个环境变量:ANTHROPIC_API_KEY / ANTHROPIC_BASE_URL"
fi
}
# ---------- 主流程 ----------
main() {
echo "============================================"
echo " MCP Server 开发实战 一键部署"
echo " macOS / Linux / WSL 版"
echo "============================================"
echo ""
local NET
NET=$(detect_network)
check_python
install_uv "$NET"
local DIR
DIR=$(create_server "$NET")
echo ""
step "启动 MCP Inspector 测试..."
echo "示例 server 在:$DIR/server.py"
echo "运行下面命令打开 Inspector(浏览器交互界面):"
echo " cd $DIR && uv run mcp dev server.py"
echo ""
echo "在 Inspector 里调用 add(1, 2) 应得 3,greeting('World') 返回 'Hello, World!'"
echo ""
# 可选:引导 CZ Key 接入 Claude Code
read -r -p "是否现在配置云间 API Key 接入 Claude Code?[Y/N] " want_key
if [ "${want_key:-N}" = "Y" ] || [ "${want_key:-N}" = "y" ]; then
setup_api_key
fi
echo ""
info "全部完成!详细说明见博客:https://cleanresolver.com/tutorials/mcp-server-develop-guide/"
echo "完整脚本源码已在文末公开,也可从 /scripts/setup-mcp-demo.sh 下载"
}
main "$@"
Windows 版(setup-mcp-demo.ps1)
# ============================================================
# MCP Server 开发实战 一键脚本(Windows PowerShell)
# 公开源码,欢迎审查 —— 不放心可先复制给 AI 判断
# 默认配置:云间 API 中转站(https://cloudzone-api.cyou/)
# 功能:检测网络 → 装 Python 依赖(uv) → 生成示例 server.py → 启动 MCP Inspector
# ============================================================
$ErrorActionPreference = "Stop"
$CLOUDZONE_URL = "https://cloudzone-api.cyou"
$CLOUDZONE_API_BASE = "https://cloudzone-api.cyou/v1"
function Write-Info($m) { Write-Host "[INFO] $m" -ForegroundColor Green }
function Write-Warn($m) { Write-Host "[WARN] $m" -ForegroundColor Yellow }
function Write-Err($m) { Write-Host "[ERROR] $m" -ForegroundColor Red }
function Write-Step($m) { Write-Host "[STEP] $m" -ForegroundColor Cyan }
function Fail($m) { Write-Err $m; Write-Err "脚本无法继续。请把以上报错复制给 AI 或贴到 issue 求助。"; exit 1 }
# ---------- 第 0 步:检测网络环境(国内 / 国外)----------
function Detect-Network {
Write-Step "检测网络环境(国内 / 国外)..."
try {
$r = Invoke-WebRequest -Uri "https://pypi.org" -Method Head -TimeoutSec 6 -UseBasicParsing
Write-Info "可直连 pypi.org,判定为海外网络"
return "overseas"
} catch {
Write-Warn "无法直连 pypi.org,判定为国内网络环境,将使用清华/阿里 PyPI 镜像"
return "domestic"
}
}
# ---------- 第 1 步:检查 Python ≥ 3.10 ----------
function Check-Python {
Write-Step "检查 Python 环境(需 3.10+)..."
$py = Get-Command python -ErrorAction SilentlyContinue
if (-not $py) { $py = Get-Command python3 -ErrorAction SilentlyContinue }
if (-not $py) {
Write-Warn "未检测到 python。请先安装 Python 3.10+(https://www.python.org/downloads/)"
Fail "python 未安装"
}
$ver = & $py.Source -c "import sys;print(f'{sys.version_info.major}.{sys.version_info.minor}')" 2>$null
if (-not $ver) { Fail "无法获取 Python 版本" }
$parts = $ver.Split('.')
$major = [int]$parts[0]; $minor = [int]$parts[1]
if ($major -lt 3 -or ($major -eq 3 -and $minor -lt 10)) {
Fail "Python 版本 $ver 低于 3.10,请升级(MCP Python SDK 要求 3.10+)"
}
Write-Info "Python $ver 已就绪"
return $py.Source
}
# ---------- 第 2 步:安装 uv ----------
function Install-Uv($net) {
Write-Step "安装 uv(Python 包管理器,推荐)..."
$uv = Get-Command uv -ErrorAction SilentlyContinue
if ($uv) { Write-Info "uv 已安装:$(uv --version)"; return }
if ($net -eq "domestic") {
Write-Info "国内网络:用清华 PyPI 镜像装 uv"
& python -m pip install --user -i https://pypi.tuna.tsinghua.edu.cn/simple uv 2>$null
if (-not (Get-Command uv -ErrorAction SilentlyContinue)) {
& python -m pip install --user -i https://mirrors.aliyun.com/pypi/simple/ uv 2>$null
}
} else {
Write-Info "海外网络:用官方 PyPI 装 uv"
& python -m pip install --user uv 2>$null
}
if (-not (Get-Command uv -ErrorAction SilentlyContinue)) {
Fail "uv 安装失败。请手动执行:python -m pip install --user uv"
}
Write-Info "uv 安装完成"
}
# ---------- 第 3 步:创建项目目录 + 示例 server.py ----------
function Create-Server($net, $pyExe) {
Write-Step "创建示例 MCP Server(add + greeting 两个工具)..."
$dir = Join-Path $env:USERPROFILE "mcp-demo"
New-Item -ItemType Directory -Force -Path $dir | Out-Null
Set-Location $dir
if (-not (Test-Path "pyproject.toml")) {
Write-Info "初始化 uv 项目..."
if ($net -eq "domestic") {
$env:UV_INDEX_URL = "https://pypi.tuna.tsinghua.edu.cn/simple"
& uv init --no-readme 2>$null
if (-not $?) { $env:UV_INDEX_URL = "https://mirrors.aliyun.com/pypi/simple/"; & uv init --no-readme 2>$null }
} else {
& uv init --no-readme 2>$null
}
}
Write-Info "安装 mcp[cli]..."
if ($net -eq "domestic") {
& uv add "mcp[cli]" --index-url https://pypi.tuna.tsinghua.edu.cn/simple 2>$null
if (-not $?) { & uv add "mcp[cli]" --index-url https://mirrors.aliyun.com/pypi/simple/ 2>$null }
if (-not $?) { Fail "mcp 安装失败(PyPI 镜像均不通)" }
} else {
& uv add "mcp[cli]" 2>$null
if (-not $?) { Fail "mcp 安装失败(pypi.org 不通?)" }
}
$serverPy = @'
"""示例 MCP Server:add(加法)+ greeting(问候)两个工具。
启动后用 `mcp dev` 打开 Inspector 测试,或在 Claude Code 里把本文件作为 MCP server 接入。
"""
from mcp.server import MCPServer
mcp = MCPServer("Demo")
@mcp.tool()
def add(a: int, b: int) -> int:
"""Add two numbers."""
return a + b
@mcp.resource("greeting://{name}")
def greeting(name: str) -> str:
"""Greet someone by name."""
return f"Hello, {name}!"
if __name__ == "__main__":
mcp.run()
'@
Set-Content -Path (Join-Path $dir "server.py") -Value $serverPy -Encoding UTF8
Write-Info "示例 server.py 已生成:$dir\server.py"
return $dir
}
# ---------- 第 4 步:(可选)引导配置 CZ API Key 接入 Claude Code ----------
function Setup-ApiKey {
Write-Host ""
Write-Host "----------------------------------------"
Write-Host "想让 MCP Server 真正接入 Claude Code 跑起来?"
Write-Host "Claude Code 需调用 Anthropic API。国内直连 anthropic.com 受限,"
Write-Host "推荐用云间 API 中转站:"
Write-Host " · 价格低至官方两折,国内直连无需翻墙"
Write-Host " · 支持 90+ 模型(Claude/GPT/DeepSeek),香港节点延迟低"
Write-Host ""
Write-Host "是否现在跳转注册并获取 API Key?"
Write-Host " Y - 立即跳转至 $CLOUDZONE_URL"
Write-Host " N - 我已有 Key,自行输入"
$choice = Read-Host "请选择 [Y/N]"
if ($choice -eq "Y" -or $choice -eq "y") {
Write-Info "正在打开浏览器..."
try { Start-Process $CLOUDZONE_URL } catch { Write-Warn "无法自动打开浏览器,请手动访问:$CLOUDZONE_URL" }
Write-Host "注册后在「我的 API Key」页面复制 Key(以 sk- 开头)。"
$sec = Read-Host "粘贴你的 API Key" -AsSecureString
# SecureString 转明文用于写入配置文件(仅本会话内)
$bstr = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($sec)
$apiKey = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($bstr)
} else {
$sec = Read-Host "请输入你的 API Key (sk-...)" -AsSecureString
$bstr = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($sec)
$apiKey = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($bstr)
}
if ([string]::IsNullOrWhiteSpace($apiKey)) {
Write-Warn "未输入 API Key,跳过 Claude Code 配置。可稍后手动设置。"
return
}
# 写入用户环境变量(永久生效)
[Environment]::SetEnvironmentVariable("ANTHROPIC_API_KEY", $apiKey, "User")
[Environment]::SetEnvironmentVariable("ANTHROPIC_BASE_URL", $CLOUDZONE_API_BASE, "User")
Write-Info "已写入用户环境变量:ANTHROPIC_API_KEY + ANTHROPIC_BASE_URL"
Write-Warn "新开 PowerShell/CMD 窗口才会生效。当前窗口请手动 `$env:ANTHROPIC_API_KEY=... `$env:ANTHROPIC_BASE_URL='$CLOUDZONE_API_BASE'"
}
# ---------- 主流程 ----------
Write-Host "============================================"
Write-Host " MCP Server 开发实战 一键部署"
Write-Host " Windows PowerShell 版"
Write-Host "============================================"
Write-Host ""
$net = Detect-Network
$pyExe = Check-Python
Install-Uv $net
$dir = Create-Server $net $pyExe
Write-Host ""
Write-Step "启动 MCP Inspector 测试..."
Write-Host "示例 server 在:$dir\server.py"
Write-Host "运行下面命令打开 Inspector(浏览器交互界面):"
Write-Host " cd $dir; uv run mcp dev server.py"
Write-Host ""
Write-Host "在 Inspector 里调用 add(1, 2) 应得 3,greeting('World') 返回 'Hello, World!'"
Write-Host ""
$wantKey = Read-Host "是否现在配置云间 API Key 接入 Claude Code?[Y/N]"
if ($wantKey -eq "Y" -or $wantKey -eq "y") {
Setup-ApiKey
}
Write-Host ""
Write-Info "全部完成!详细说明见博客:https://cleanresolver.com/tutorials/mcp-server-develop-guide/"
Write-Host "完整脚本源码已在文末公开,也可从 /scripts/setup-mcp-demo.ps1 下载"

请完成验证后查看评论区