my-remote-mcp-py
by ervin-zhang
README.md
# Python 远程 MCP Server Demo
基于官方 [MCP Python SDK](https://github.com/modelcontextprotocol/python-sdk) 的 `FastMCP`,
使用 **Streamable HTTP** 传输实现的远程 MCP Server,可被任意 MCP 客户端(如 Cursor)远程连接。
## 目录结构
```
.
├── server.py # 远程 MCP Server(工具 / 资源 / 提示 / 进度 / 补全)
├── client.py # 基础测试客户端
├── client_advanced.py # 进阶客户端(进度 + 日志 + 自动补全)
├── curl_test.sh # 用 curl 测试的脚本
├── requirements.txt # 依赖
└── README.md
```
## 环境要求
- Python 3.10+(本项目使用 3.11)
## 安装
```bash
python3.11 -m venv venv
source venv/bin/activate
pip install -r requirements.txt
```
## 启动 Server
```bash
venv/bin/python server.py
```
默认监听 `http://0.0.0.0:8000/mcp`。可用环境变量调整:
```bash
MCP_HOST=0.0.0.0 MCP_PORT=9000 venv/bin/python server.py
```
## 运行测试客户端
另开一个终端:
```bash
venv/bin/python client.py # 基础:工具 / 资源 / 提示
venv/bin/python client_advanced.py # 进阶:进度 + 日志 + 自动补全
venv/bin/python client.py http://127.0.0.1:9000/mcp
```
也可以用 curl 脚本(依赖 `curl`、`jq`):
```bash
./curl_test.sh # 默认 http://127.0.0.1:8000/mcp
./curl_test.sh http://127.0.0.1:9000/mcp
```
## Server 能力
| 类型 | 名称 | 说明 |
| --- | --- | --- |
| 工具 | `add(a, b)` | 求和 |
| 工具 | `now(tz_offset_hours=8)` | 返回当前时间(默认东八区) |
| 工具 | `fetch_url_title(url)` | 抓取网页标题(异步示例) |
| 工具 | `long_task(steps)` | 长任务,实时上报**进度(progress)**与**日志(logging)** |
| 资源 | `config://app` | 静态配置 |
| 资源 | `greeting://{name}` | 动态参数资源 |
| 提示 | `summarize(text)` | 生成总结提示 |
| 补全 | `greeting://{name}` 的 `name` | 按前缀返回候选名字(**completion**) |
### 进度 + 日志(long_task)
`long_task` 通过 `ctx: Context` 在执行中实时推送进度和日志。客户端注册回调即可接收:
```python
async def on_log(params): # 接收 ctx.info/debug 的日志
print(params.level, params.data)
async def on_progress(progress, total, message): # 接收进度
print(f"{progress}/{total} {message}")
async with ClientSession(read, write, logging_callback=on_log) as session:
await session.call_tool("long_task", {"steps": 5}, progress_callback=on_progress)
```
> **stateless_http 注意**:无状态模式下不能直接用 `ctx.report_progress()`,
> 因为它未携带 `related_request_id`,进度通知无法关联到当前请求的 SSE 流而被丢弃。
> 本 demo 在 `_report_progress()` 中改为直接调用 `session.send_progress_notification(...)`
> 并显式传入 `related_request_id=ctx.request_id`。日志 `ctx.info/debug` 不受影响(SDK 已自动携带)。
### 自动补全(completion)
用 `@mcp.completion()` 注册全局补全处理器,为资源模板/提示的参数提供候选:
```python
comp = await session.complete(
ResourceTemplateReference(type="ref/resource", uri="greeting://{name}"),
argument={"name": "name", "value": "小"},
)
print(comp.completion.values) # => ['小明', '小红']
```
## 在 Cursor 中连接
在 `~/.cursor/mcp.json`(或项目 `.cursor/mcp.json`)中添加:
```json
{
"mcpServers": {
"demo-remote": {
"url": "http://127.0.0.1:8000/mcp"
}
}
}
```
## 说明
- `stateless_http=True`:每个请求独立、无会话状态,便于远程部署和水平扩展。
- 生产部署可放在 Nginx/网关之后,并自行实现鉴权(如校验 `Authorization` 头)。
This server cannot be deployed
Maintenance
ActivityStale
ResponsivenessNo issues