# https://github.com/sparfenyuk/mcp-proxy 项目说明书

生成时间：2026-06-14 03:24:34 UTC

## 目录

- [概览与系统架构](#page-1)
- [客户端模式（SSE/StreamableHTTP → stdio）](#page-2)
- [客户端模式（stdio → SSE/StreamableHTTP）](#page-3)
- [安装、部署、扩展与常见故障](#page-4)

<a id='page-1'></a>

## 概览与系统架构

### 相关页面

相关主题：[客户端模式（SSE/StreamableHTTP → stdio）](#page-2), [客户端模式（stdio → SSE/StreamableHTTP）](#page-3)

<details>
<summary>相关源码文件</summary>

以下源码文件用于生成本页说明：

- [README.md](https://github.com/sparfenyuk/mcp-proxy/blob/main/README.md)
- [codecov.yml](https://github.com/sparfenyuk/mcp-proxy/blob/main/codecov.yml)
- [src/mcp_proxy/__init__.py](https://github.com/sparfenyuk/mcp-proxy/blob/main/src/mcp_proxy/__init__.py)
- [src/mcp_proxy/__main__.py](https://github.com/sparfenyuk/mcp-proxy/blob/main/src/mcp_proxy/__main__.py)
- [src/mcp_proxy/config_loader.py](https://github.com/sparfenyuk/mcp-proxy/blob/main/src/mcp_proxy/config_loader.py)
- [src/mcp_proxy/mcp_server.py](https://github.com/sparfenyuk/mcp-proxy/blob/main/src/mcp_proxy/mcp_server.py)
- [src/mcp_proxy/proxy_server.py](https://github.com/sparfenyuk/mcp-proxy/blob/main/src/mcp_proxy/proxy_server.py)
- [src/mcp_proxy/sse_client.py](https://github.com/sparfenyuk/mcp-proxy/blob/main/src/mcp_proxy/sse_client.py)
- [src/mcp_proxy/streamablehttp_client.py](https://github.com/sparfenyuk/mcp-proxy/blob/main/src/mcp_proxy/streamablehttp_client.py)
- [src/mcp_proxy/httpx_client.py](https://github.com/sparfenyuk/mcp-proxy/blob/main/src/mcp_proxy/httpx_client.py)
</details>

# 概览与系统架构

## 一、项目定位与核心能力

`mcp-proxy` 是一个基于 [MCP Python SDK](https://github.com/modelcontextprotocol/python-sdk) 构建的传输桥接工具，主要解决 [Model Context Protocol (MCP)](https://modelcontextprotocol.io) 客户端与服务端之间的传输协议不匹配问题。根据 `README.md` 的描述，工具支持两大基础模式：**stdio → SSE/StreamableHTTP** 与 **SSE → stdio**，外加自 v0.8.0 起引入的「命名服务器」（Named Servers）能力，允许单实例同时代理多个 stdio 后端。

资料来源：[README.md:1-50]()

其典型使用场景包括：
- 让仅支持 stdio 的客户端（如 Claude Desktop）访问远程 SSE/StreamableHTTP 服务。
- 将远程 SSE/StreamableHTTP 服务桥接到本地 stdio 工作流。
- 在同一端口下通过 `/servers/<name>/` 路径前缀代理多个 stdio 子进程（Named Servers）。

## 二、整体系统架构

下图展示了 `mcp-proxy` 在三种典型部署形态下的组件交互关系。

```mermaid
graph LR
    A["MCP 客户端<br/>(stdio / SSE / StreamableHTTP)"] --> B["mcp-proxy 入口<br/>(__main__.py)"]
    B --> C{"模式选择"}
    C -->|stdio→SSE/HTTP| D["mcp_server.py<br/>本地 HTTP/SSE 服务"]
    C -->|SSE/StreamableHTTP→stdio| E["sse_client.py<br/>或 streamablehttp_client.py"]
    D --> F["proxy_server.py<br/>create_proxy_server()"]
    E --> F
    F --> G["远程或本地 MCP 后端"]
    F --> H["配置加载<br/>config_loader.py"]
    H --> D
```

入口层负责解析命令行参数与读取 JSON 配置；客户端模块（`sse_client.py` / `streamablehttp_client.py`）负责把远程 HTTP 流桥接到本地 stdio；服务端模块（`mcp_server.py`）通过 Starlette 路由把本地 stdio 子进程暴露成 SSE 与 Streamable HTTP 端点；`proxy_server.py` 内的 `create_proxy_server()` 统一封装能力探测（Prompts / Resources / Tools / Logging 等），按需注册请求处理器。

## 三、运行模式与入口分流

`__main__.py` 中的参数解析逻辑决定了三种运行形态：默认服务器（单 stdio 后端）、命名服务器（多 stdio 后端）、客户端模式（HTTP→stdio）。

| 运行模式 | 触发条件 | 关键 CLI 参数 | 核心模块 |
| --- | --- | --- | --- |
| stdio → SSE/StreamableHTTP | 提供 stdio 命令 | `--port`、`--host`、`--stateless`、`--allow-origin` | `mcp_server.py`、`proxy_server.py` |
| stdio → 多命名服务器 | 提供 `--named-server-config` 或 `--named-server` | `--named-server-config <file>` | `config_loader.py`、`mcp_server.py` |
| SSE/StreamableHTTP → stdio | 第一个位置参数为 URL | `--transport`、`-H/--headers`、`--verify-ssl` | `sse_client.py` / `streamablehttp_client.py` |

资料来源：[src/mcp_proxy/__main__.py:1-160]()、[src/mcp_proxy/config_loader.py:1-80]()

`config_loader.load_named_server_configs_from_file()` 负责把 JSON 中的 `mcpServers` 字典解析为 `StdioServerParameters` 列表，每个命名子进程都会通过 `mcp_server.run_mcp_server()` 在 `/servers/<name>/` 前缀下挂载独立的 SSE/Streamable HTTP 路由。

## 四、关键模块职责

- **`proxy_server.py`** — 通过 `remote_app.initialize()` 拉取远端能力声明并按需注册 `ListPromptsRequest`、`GetPromptRequest`、`ListResourcesRequest`、`ReadResourceRequest`、`ListToolsRequest`、`CallToolRequest` 等处理器，构成可复用的「透明代理」核心。
- **`mcp_server.py`** — 实现本地 HTTP/SSE 暴露层，使用 `SseServerTransport("/messages/")` 与 `StreamableHTTPSessionManager`，并在应用根挂载 `/status` 健康检查端点（`_handle_status`）以及 CORS、`/mcp`、`/sse`、`/messages/` 等路由。
- **`httpx_client.py`** — 自定义的 `custom_httpx_client` 替换了 SDK 默认的 `create_mcp_http_client`，注入请求/响应日志并支持 `verify_ssl` 选项（`True` / `False` / PEM 路径）。
- **`sse_client.py` / `streamablehttp_client.py`** — 客户端模式的两个并联实现，结构高度对称：建立远端流 → 打开 `ClientSession` → 调用 `create_proxy_server(session)` → 通过 `stdio_server` 暴露给本地。
- **`__main__.py`** — 装配 `argparse` 参数组（SSE server options、client options、stdio client options），并在 `_create_mcp_settings()` 中合并 `--host` 与已弃用的 `--sse-host`、`--port` 与 `--sse-port`。

## 五、社区关注与已知限制

社区中较为活跃的话题主要聚焦在「跨模式桥接」与「传输层语义差异」：
- Issue #74 / #83：希望将多个 SSE 服务转换为 Streamable HTTP 暴露，或反向；当前 `mcp-proxy` 已通过 `--transport` 与 Named Servers 组合支持，但单端口内不同路径的混用仍受 `MCPServerSettings.stateless` 等参数统一控制。
- Issue #69：连接远程 StreamableHTTP 时日志错误——可使用 `--debug` 配合 `httpx_client.py` 的请求日志辅助排查。
- Issue #53：远程 MCP 鉴权头传递——可通过 `-H/--headers` 注入。
- Issue #108 / #224：安全增强（API Key、审计层）仍属社区提议阶段，当前代码尚未内置鉴权中间件，部署时建议结合网络层或反向代理进行访问控制。

资料来源：[src/mcp_proxy/mcp_server.py:1-120]()、[src/mcp_proxy/httpx_client.py:1-60]()

## See Also

- [SSE 客户端模式（sse_client.py）](sse-client.md)
- [StreamableHTTP 客户端模式](streamablehttp-client.md)
- [Named Servers 配置与 JSON 结构](named-servers.md)
- [命令行参数参考](cli-reference.md)

---

<a id='page-2'></a>

## 客户端模式（SSE/StreamableHTTP → stdio）

### 相关页面

相关主题：[概览与系统架构](#page-1), [客户端模式（stdio → SSE/StreamableHTTP）](#page-3), [安装、部署、扩展与常见故障](#page-4)

<details>
<summary>相关源码文件</summary>

以下源码文件用于生成本页说明：

- [README.md](https://github.com/sparfenyuk/mcp-proxy/blob/main/README.md)
- [src/mcp_proxy/__main__.py](https://github.com/sparfenyuk/mcp-proxy/blob/main/src/mcp_proxy/__main__.py)
- [src/mcp_proxy/sse_client.py](https://github.com/sparfenyuk/mcp-proxy/blob/main/src/mcp_proxy/sse_client.py)
- [src/mcp_proxy/streamablehttp_client.py](https://github.com/sparfenyuk/mcp-proxy/blob/main/src/mcp_proxy/streamablehttp_client.py)
- [src/mcp_proxy/proxy_server.py](https://github.com/sparfenyuk/mcp-proxy/blob/main/src/mcp_proxy/proxy_server.py)
- [src/mcp_proxy/httpx_client.py](https://github.com/sparfenyuk/mcp-proxy/blob/main/src/mcp_proxy/httpx_client.py)
- [src/mcp_proxy/__init__.py](https://github.com/sparfenyuk/mcp-proxy/blob/main/src/mcp_proxy/__init__.py)
</details>

# 客户端模式（SSE/StreamableHTTP → stdio）

## 概述与适用场景

`mcp-proxy` 的**客户端模式**是该工具的核心功能之一：它将一个远程的、可通过 SSE（Server-Sent Events）或 StreamableHTTP 协议访问的 MCP（Model Context Protocol）服务器，在本地进程内转换为标准的 stdio MCP 服务器。资料来源：[README.md](README.md) 中明确将"SSE to stdio"列为项目支持的两种主要模式之一。

这一模式解决了只支持 stdio 传输的 MCP 客户端（如 Claude Desktop、某些 IDE 插件）无法连接远程 MCP 服务器的问题。通过在远端与本地之间架设一个轻量代理进程，上游 MCP 服务器可以使用 HTTP 类协议部署，而下游客户端仍以进程内管道方式交互，无需感知网络通信细节。资料来源：[src/mcp_proxy/sse_client.py:1-10](src/mcp_proxy/sse_client.py) 与 [src/mcp_proxy/streamablehttp_client.py:1-9](src/mcp_proxy/streamablehttp_client.py) 模块的文档字符串均说明"创建一个本地服务器，将请求代理到远端 SSE/StreamableHTTP 服务器"。

自 v0.7.0 起，客户端模式同时支持 SSE 与 StreamableHTTP 两种传输协议（社区公告：https://github.com/sparfenyuk/mcp-proxy/releases/tag/v0.7.0 "feat: support streamable transport in client mode"）。

## 架构与数据流

客户端模式的运行入口位于 `src/mcp_proxy/__main__.py`，CLI 解析 `command_or_url` 后判断走 SSE 还是 StreamableHTTP 分支：

```mermaid
flowchart LR
    A[stdio MCP 客户端<br>如 Claude Desktop] -->|stdin/stdout| B[mcp-proxy 进程]
    B -->|HTTP/SSE 或 StreamableHTTP| C[远程 MCP 服务器]
    C -->|响应/事件| B
    B -->|stdio 帧| A
```

在任一传输实现中，核心逻辑是一致的：

1. 使用 MCP Python SDK 的 `sse_client()` 或 `streamablehttp_client()` 与远端建立连接。资料来源：[src/mcp_proxy/sse_client.py:21-28](src/mcp_proxy/sse_client.py) 与 [src/mcp_proxy/streamablehttp_client.py:25-33](src/mcp_proxy/streamablehttp_client.py)。
2. 用 `ClientSession` 包装读/写流，对远端执行 `initialize()`，获取其 `serverInfo` 与 `capabilities`。资料来源：[src/mcp_proxy/proxy_server.py](src/mcp_proxy/proxy_server.py) 中的 `create_proxy_server()` 函数。
3. 调用 `create_proxy_server()` 在本地构造一个新的 `server.Server`，将 `prompts`、`resources`、`tools`、`logging` 等能力按需注册为转发处理器（`request_handlers`），所有请求被中继到远端 `ClientSession`。资料来源：[src/mcp_proxy/proxy_server.py](src/mcp_proxy/proxy_server.py)。
4. 最后通过 `stdio_server()` 将本地服务器绑定到 stdin/stdout，对外暴露为 stdio MCP 服务器。资料来源：[src/mcp_proxy/sse_client.py:30-36](src/mcp_proxy/sse_client.py) 与 [src/mcp_proxy/streamablehttp_client.py:35-41](src/mcp_proxy/streamablehttp_client.py)。

整个进程对外呈现的是"远端 MCP 服务器 + 本地 stdio 适配层"的组合，因此下游客户端的协议视图与直连远端一致。

## CLI 配置与运行参数

在 `src/mcp_proxy/__main__.py` 中，当 `command_or_url` 以 `http://` 或 `https://` 开头时，自动进入客户端模式，并通过 `--transport` 选择 SSE 或 StreamableHTTP。相关判断逻辑参见 [src/mcp_proxy/__main__.py](src/mcp_proxy/__main__.py)。主要参数整理如下：

| 参数 | 是否必填 | 说明 | 示例 |
| --- | --- | --- | --- |
| `command_or_url` | 是 | 远端 MCP 服务器的 SSE 或 StreamableHTTP 端点 URL | `http://example.io/sse` |
| `--transport` | 否 | 选择上游传输协议，取值 `sse` 或 `streamablehttp`；未指定时按 URL 默认推断 | `--transport streamablehttp` |
| `--headers` | 否 | 附加到上游请求的 HTTP 头，可多次传入 | `--headers Authorization 'Bearer my-secret-access-token'` |
| `--client-id` / `--client-secret` / `--token-url` | 否 | 三者同时提供时启用 OAuth2 Client Credentials 流程 | 见 [src/mcp_proxy/__main__.py](src/mcp_proxy/__main__.py) |
| 环境变量 `API_ACCESS_TOKEN` | 否 | 若设置，自动以 `Authorization: Bearer <token>` 形式注入上游请求 | `API_ACCESS_TOKEN=xxx` |

调用入口与协议分发代码位于 [src/mcp_proxy/__main__.py](src/mcp_proxy/__main__.py)：当 `args_parsed.transport == "streamablehttp"` 时调用 `run_streamablehttp_client()`，否则调用 `run_sse_client()`。需要注意 `--named-server` 在此模式下会被忽略，并打印一条警告日志。资料来源：[src/mcp_proxy/__main__.py](src/mcp_proxy/__main__.py) 中 `_parsed.named_server_definitions` 处的判断逻辑。

## 认证、SSL 与常见问题

**上游认证。** `--headers` 用于静态设置请求头；若希望通过环境变量集中管理 token，可设置 `API_ACCESS_TOKEN`，客户端模式会把它转换为 `Bearer` 头。资料来源：[src/mcp_proxy/__main__.py](src/mcp_proxy/__main__.py)。如果目标 MCP 服务器要求 OAuth2，三件套 `--client-id` / `--client-secret` / `--token-url` 启用 `OAuth2ClientCredentials`，由底层 `httpx.Auth` 实现。资料来源：[src/mcp_proxy/__main__.py](src/mcp_proxy/__main__.py)。

**SSL 校验控制。** `run_sse_client` 与 `run_streamablehttp_client` 都接受 `verify_ssl` 参数：传 `False` 可禁用证书校验（自 v0.10.0 起支持 `--no-verify-ssl`，参见 https://github.com/sparfenyuk/mcp-proxy/releases/tag/v0.10.0），或传入 CA bundle 路径。底层由 `custom_httpx_client()` 构造 `httpx.AsyncClient`。资料来源：[src/mcp_proxy/httpx_client.py](src/mcp_proxy/httpx_client.py) 与 [src/mcp_proxy/sse_client.py:18-19](src/mcp_proxy/sse_client.py)。

**能力转发。** 仅当远端在 `initialize` 响应中声明了对应能力时，`proxy_server.py` 才会注册 `ListPromptsRequest`、`ListResourcesRequest`、`ListToolsRequest` 等转发处理器，因此未暴露的能力不会变成空响应。资料来源：[src/mcp_proxy/proxy_server.py](src/mcp_proxy/proxy_server.py)。

**已知限制（来自社区反馈）。**

- 远程 StreamableHTTP 连接在某些网关后可能失败（例如 issue #69 报告 Higress 网关场景），通常与上游 `Accept` 头协商或重定向行为有关，可结合 `--debug`（v0.6.0 引入）抓取 [src/mcp_proxy/httpx_client.py](src/mcp_proxy/httpx_client.py) 中自定义 `httpx` 客户端打印的请求/响应日志辅助排查。
- 透传自定义 `Authorization` 头（issue #53）应使用 `--headers`，并确认 `--transport` 与上游匹配，否则请求会被发送到错误的端点。
- `serverInfo.version` 在代理下当前返回的是 MCP Python SDK 的版本，而非被代理的远端服务器版本（issue #214）。这是因为 `create_proxy_server()` 使用 SDK 默认值构造本地 `server.Server`，未来修复需在 `proxy_server.py` 中同步 `response.serverInfo` 的版本字段。

## See Also

- [README.md § SSE to stdio](README.md) —— 官方文档中对应章节
- 服务端模式（stdio → SSE/StreamableHTTP）：见 `src/mcp_proxy/mcp_server.py`
- 配置加载（命名服务器）：见 `src/mcp_proxy/config_loader.py`
- 仓库主页：https://github.com/sparfenyuk/mcp-proxy

---

<a id='page-3'></a>

## 客户端模式（stdio → SSE/StreamableHTTP）

### 相关页面

相关主题：[概览与系统架构](#page-1), [客户端模式（SSE/StreamableHTTP → stdio）](#page-2)

<details>
<summary>相关源码文件</summary>

以下源码文件用于生成本页说明：

- [README.md](https://github.com/sparfenyuk/mcp-proxy/blob/main/README.md)
- [src/mcp_proxy/__main__.py](https://github.com/sparfenyuk/mcp-proxy/blob/main/src/mcp_proxy/__main__.py)
- [src/mcp_proxy/sse_client.py](https://github.com/sparfenyuk/mcp-proxy/blob/main/src/mcp_proxy/sse_client.py)
- [src/mcp_proxy/streamablehttp_client.py](https://github.com/sparfenyuk/mcp-proxy/blob/main/src/mcp_proxy/streamablehttp_client.py)
- [src/mcp_proxy/httpx_client.py](https://github.com/sparfenyuk/mcp-proxy/blob/main/src/mcp_proxy/httpx_client.py)
- [src/mcp_proxy/proxy_server.py](https://github.com/sparfenyuk/mcp-proxy/blob/main/src/mcp_proxy/proxy_server.py)
</details>

# 客户端模式（stdio → SSE/StreamableHTTP）

## 概述

`mcp-proxy` 的"客户端模式"是一种**反向**桥接场景：进程本身以本地 stdio MCP 服务器的方式运行，但其所有 JSON-RPC 请求都会转发到一个远程的 SSE 或 StreamableHTTP MCP 服务器。该模式让那些只支持 stdio 传输的 LLM 客户端工具（例如本地编辑器插件、Claude Desktop 适配器）能够消费任何暴露为 HTTP 端点的 MCP 服务。

资料来源：[src/mcp_proxy/__main__.py:1-50](https://github.com/sparfenyuk/mcp-proxy/blob/main/src/mcp_proxy/__main__.py)、[README.md](https://github.com/sparfenyuk/mcp-proxy/blob/main/README.md)

当命令行第一个位置参数 `command_or_url` 以 `http://` 或 `https://` 开头时，`mcp-proxy` 即进入客户端模式；随后通过 `--transport` 选择上游协议是 `sse`（默认）还是 `streamablehttp`。所有 stdio 专属选项（如 `--named-server`、`--port`）在该模式下都会被忽略并打印警告。

```mermaid
graph LR
    A["本地 stdio 客户端<br/>(如编辑器/Agent)"] <-->|JSON-RPC over stdio| B["mcp-proxy<br/>(客户端模式)"]
    B <-->|SSE 或 StreamableHTTP| C["远程 MCP 服务器"]
    style A fill:#e6f9ff,stroke:#333
    style B fill:#e6e6ff,stroke:#333
    style C fill:#e6ffe6,stroke:#333
```

## 工作流程

启动后，`__main__.py` 解析参数并按以下顺序工作：

1. **识别客户端模式**：检测 `command_or_url` 是否为 `http(s)://` URL；若是，则记日志 "Starting SSE/StreamableHTTP client and stdio server"，并跳过任何 stdio 默认/命名服务器配置。资料来源：[src/mcp_proxy/__main__.py:1-20](https://github.com/sparfenyuk/mcp-proxy/blob/main/src/mcp_proxy/__main__.py)
2. **构造 HTTP 头**：合并 `--headers` 与 `API_ACCESS_TOKEN` 环境变量；若设置了 `API_ACCESS_TOKEN`，则注入 `Authorization: Bearer <token>` 到请求头字典。资料来源：[src/mcp_proxy/__main__.py:1-50](https://github.com/sparfenyuk/mcp-proxy/blob/main/src/mcp_proxy/__main__.py)
3. **构建认证对象**：当同时提供 `--client-id`、`--client-secret` 与 `--token-url` 时，构造 `OAuth2ClientCredentials` 用于 OAuth2 客户端凭据流；任一缺失则退化为无认证。资料来源：[src/mcp_proxy/__main__.py:1-50](https://github.com/sparfenyuk/mcp-proxy/blob/main/src/mcp_proxy/__main__.py)
4. **派发到对应客户端**：根据 `--transport` 调用 `run_sse_client`（[sse_client.py](https://github.com/sparfenyuk/mcp-proxy/blob/main/src/mcp_proxy/sse_client.py)）或 `run_streamablehttp_client`（[streamablehttp_client.py](https://github.com/sparfenyuk/mcp-proxy/blob/main/src/mcp_proxy/streamablehttp_client.py)）。两者均通过 `partial(custom_httpx_client, verify_ssl=verify_ssl)` 注入统一日志与 SSL 设置。资料来源：[src/mcp_proxy/sse_client.py:1-40](https://github.com/sparfenyuk/mcp-proxy/blob/main/src/mcp_proxy/sse_client.py)、[src/mcp_proxy/streamablehttp_client.py:1-40](https://github.com/sparfenyuk/mcp-proxy/blob/main/src/mcp_proxy/streamablehttp_client.py)
5. **建立会话并代理**：在远端会话中执行 `initialize()`，按远端 `capabilities` 注册 `list_prompts`/`list_resources`/`list_tools`/`call_tool` 等处理器；远端 `serverInfo.name` 透传为本地 `Server` 名。资料来源：[src/mcp_proxy/proxy_server.py:1-50](https://github.com/sparfenyuk/mcp-proxy/blob/main/src/mcp_proxy/proxy_server.py)

## 配置选项

| 名称 | 必需 | 说明 | 示例 |
| --- | --- | --- | --- |
| `command_or_url` | 是 | 远程 MCP 服务器的 SSE/StreamableHTTP 端点 | `http://127.0.0.1:8080/sse` |
| `--transport` | 否 | 上游协议：`sse`（默认）或 `streamablehttp` | `streamablehttp` |
| `--headers` | 否 | 自定义 HTTP 头；重复传入可叠加 | `Authorization 'Bearer my-token'` |
| `--client-id` / `--client-secret` / `--token-url` | 否 | OAuth2 客户端凭据流，三者必须同时提供 | — |
| `--no-verify-ssl` | 否 | 禁用证书验证（自签名/内部 CA） | — |
| `API_ACCESS_TOKEN`（环境变量） | 否 | 自动作为 `Authorization: Bearer …` 注入 | `sk-xxx` |

资料来源：[src/mcp_proxy/__main__.py:1-50](https://github.com/sparfenyuk/mcp-proxy/blob/main/src/mcp_proxy/__main__.py)、[README.md](https://github.com/sparfenyuk/mcp-proxy/blob/main/README.md)

## HTTP 客户端与认证

`custom_httpx_client` 是所有出站流量的统一工厂，定义于 [src/mcp_proxy/httpx_client.py](https://github.com/sparfenyuk/mcp-proxy/blob/main/src/mcp_proxy/httpx_client.py)。它在 `create_mcp_http_client` 基础上做了三件事：

- 默认 `follow_redirects=True`、`timeout=30s`。资料来源：[src/mcp_proxy/httpx_client.py:1-50](https://github.com/sparfenyuk/mcp-proxy/blob/main/src/mcp_proxy/httpx_client.py)
- 支持 `verify_ssl=False` 禁用证书校验，或指向 CA bundle 路径，对应 `--no-verify-ssl` 与自建 CA 场景。资料来源：[src/mcp_proxy/httpx_client.py:1-50](https://github.com/sparfenyuk/mcp-proxy/blob/main/src/mcp_proxy/httpx_client.py)
- 注入 `event_hooks` 在请求/响应阶段输出 DEBUG 日志，便于排查网络握手问题。资料来源：[src/mcp_proxy/httpx_client.py:1-50](https://github.com/sparfenyuk/mcp-proxy/blob/main/src/mcp_proxy/httpx_client.py)

## 常见问题与社区反馈

- **URL 路径中的占位符**：当 URL 形如 `https://host/mcp-time/{api-key}` 时，Issue #69 报告连接失败——大括号属于 MCP 服务自身的模板占位符，`mcp-proxy` 不会解析，必须在外部替换为真实值。资料来源：[GitHub Issue #69](https://github.com/sparfenyuk/mcp-proxy/issues/69)
- **认证头覆盖顺序**：`API_ACCESS_TOKEN` 与 `--headers Authorization` 同时存在时，后者会覆盖前者（`dict.update` 行为）；Issue #53 报告的"无法设置请求头"多源于此。资料来源：[src/mcp_proxy/__main__.py:1-50](https://github.com/sparfenyuk/mcp-proxy/blob/main/src/mcp_proxy/__main__.py)、[GitHub Issue #53](https://github.com/sparfenyuk/mcp-proxy/issues/53)
- **`serverInfo.version` 偏差**：本地 stdio 客户端在 `initialize` 时收到的 `serverInfo` 中 `name` 来自远端，但 `version` 仍是 mcp-proxy（基于 MCP Python SDK）的版本。Issue #214 指出这是当前实现的已知限制，`create_proxy_server` 透传了 `serverInfo.name` 但未重写 `version`。资料来源：[src/mcp_proxy/proxy_server.py:1-50](https://github.com/sparfenyuk/mcp-proxy/blob/main/src/mcp_proxy/proxy_server.py)、[GitHub Issue #214](https://github.com/sparfenyuk/mcp-proxy/issues/214)
- **OAuth2 凭据缺失**：当三个 `--client-id/--client-secret/--token-url` 未同时给出时，`OAuth2ClientCredentials` 不会被构造，连接将以匿名方式进行，可能在远端 401。资料来源：[src/mcp_proxy/__main__.py:1-50](https://github.com/sparfenyuk/mcp-proxy/blob/main/src/mcp_proxy/__main__.py)

## See Also

- [服务器模式（stdio → SSE/StreamableHTTP）]()
- [命名服务器（Named Servers）与多 stdio 后端]()
- [OAuth2 客户端凭据认证]()
- [Docker 多架构镜像（ARM/AMD64）]()

---

<a id='page-4'></a>

## 安装、部署、扩展与常见故障

### 相关页面

相关主题：[概览与系统架构](#page-1), [客户端模式（SSE/StreamableHTTP → stdio）](#page-2), [客户端模式（stdio → SSE/StreamableHTTP）](#page-3)

<details>
<summary>相关源码文件</summary>

以下源码文件用于生成本页说明：

- [README.md](https://github.com/sparfenyuk/mcp-proxy/blob/main/README.md)
- [src/mcp_proxy/__main__.py](https://github.com/sparfenyuk/mcp-proxy/blob/main/src/mcp_proxy/__main__.py)
- [src/mcp_proxy/config_loader.py](https://github.com/sparfenyuk/mcp-proxy/blob/main/src/mcp_proxy/config_loader.py)
- [src/mcp_proxy/mcp_server.py](https://github.com/sparfenyuk/mcp-proxy/blob/main/src/mcp_proxy/mcp_server.py)
- [src/mcp_proxy/httpx_client.py](https://github.com/sparfenyuk/mcp-proxy/blob/main/src/mcp_proxy/httpx_client.py)
- [src/mcp_proxy/proxy_server.py](https://github.com/sparfenyuk/mcp-proxy/blob/main/src/mcp_proxy/proxy_server.py)
</details>

# 安装、部署、扩展与常见故障

`mcp-proxy` 是一个用于在不同传输协议之间桥接 MCP 服务器的 Python 工具，支持 stdio、SSE 与 StreamableHTTP 之间的相互转换。本页聚焦于该项目的安装方式、生产部署路径、扩展方式以及社区中常见的故障模式与对应缓解措施。

## 一、安装方式

### 1.1 通过 PyPI 安装稳定版

推荐使用 `uv` 或 `pipx` 进行全局工具安装，避免污染系统 Python 环境：

```bash
# 推荐方式
uv tool install mcp-proxy

# 替代方式
pipx install mcp-proxy
```

安装完成后可直接调用 `mcp-proxy` 命令行。`__main__.py` 中的 `argparse` 入口会根据参数选择 stdio-to-SSE 或 SSE-to-stdio 两种主运行模式。资料来源：[src/mcp_proxy/__main__.py:1-120]()

### 1.2 通过 GitHub 仓库安装最新版

开发版可通过 `uv tool install` 直接指定 GitHub 仓库，以跟踪尚未发布的提交。该方式适合需要使用 `--no-verify-ssl` 或 `--stateless` 等较新特性的场景。

### 1.3 通过容器镜像部署

`mcp-proxy` 提供多平台清单（multi-platform manifest）容器镜像，发布在 GHCR 与 Docker Hub：

- `ghcr.io/sparfenyuk/mcp-proxy:v0.12.0`
- `sparfenyuk/mcp-proxy:v0.12.0`

镜像同时支持 `linux/amd64` 与 `linux/arm64`，因此在 ARM 服务器（如 Apple Silicon、AWS Graviton）上也可直接拉取。社区早期曾请求 ARM 镜像支持（#168），现已在 v0.12.0 中作为多架构清单发布。资料来源：[README.md:1-180]()

## 二、生产部署模式

### 2.1 命令行与 named-server 配置

`mcp-proxy` 支持在单个进程内代理多台 stdio 服务器（named servers），通过 `--named-server-config` 指定 JSON 配置文件：

```bash
mcp-proxy --transport sse --port=8080 --named-server-config ./servers.json
```

该功能在 v0.8.0 引入，由 `config_loader.py` 中的 `load_named_server_configs_from_file` 函数解析，校验 `mcpServers` 顶层键、读取每个服务器的 `command`、`args`、`env`，并默认继承代理进程的工作目录与环境变量。`timeout` 与 `transportType` 字段虽出现在配置中，但当前实现下被忽略，传输类型隐式为 stdio。资料来源：[src/mcp_proxy/config_loader.py:1-100]()、[README.md:120-180]()

### 2.2 StreamableHTTP 与 SSE 服务端设置

在 SSE 模式下，`mcp_server.py` 中 `MCPServerSettings` 定义了绑定主机、端口、CORS、暴露头与日志级别。其默认值为：

| 选项 | 默认值 | 说明 |
|------|--------|------|
| `--port` | 0（随机端口） | SSE 服务监听端口 |
| `--host` | `127.0.0.1` | 仅绑定回环，需显式改为 `0.0.0.0` 才能跨主机访问 |
| `--stateless` | False | StreamableHTTP 是否启用无状态模式 |
| `--allow-origin` | 空 | 默认禁止任何跨域来源 |

每个代理实例的路由由 `create_single_instance_routes` 创建，挂载到 `/mcp`（StreamableHTTP）、`/sse` 与 `/messages/` 路径下；多 named server 通过 `Mount(f"/servers/{name}", ...)` 子挂载实现。资料来源：[src/mcp_proxy/mcp_server.py:1-200]()

### 2.3 Docker Compose 与容器扩展

官方 README 提供了 Docker Compose 示例，便于在容器中并行启动多个 MCP 服务器并由 `mcp-proxy` 聚合。用户可通过自定义 `Dockerfile` 在基础镜像之上预装常用 MCP 服务器（如 `mcp-server-fetch`），从而实现“开箱即用”的代理容器。镜像从 v0.9.0 起尊重 SIGTERM/SIGINT 关闭信号（#98），因此在 Compose 重启策略下行为更可控。

## 三、扩展点

### 3.1 HTTP 客户端补丁

`httpx_client.py` 中的 `custom_httpx_client` 替换了底层 `create_mcp_http_client`，注入了 `request` 与 `response` 事件钩子：

- 请求侧打印方法、URL、头部（`Authorization`、`x-api-key`、`Cookie` 自动遮蔽为 `***MASKED***`）。
- 响应侧仅在 `DEBUG` 级别打印状态行与头部。

这一扩展使 `--debug` 与 `--log-level` 选项对下游 HTTP 调用同样生效，便于排查超时或鉴权失败。资料来源：[src/mcp_proxy/httpx_client.py:1-120]()

### 3.2 代理服务器能力探测

`proxy_server.py` 的 `create_proxy_server` 通过 `await remote_app.initialize()` 读取远端能力，再动态为 `Server` 实例注册 `ListPromptsRequest`、`GetPromptRequest`、`ListResourcesRequest`、`ReadResourceRequest`、`ListToolsRequest`、`CallToolRequest` 等处理器。该结构使得新增 MCP 能力时无需修改代理核心，只需在 SDK 升级后补齐对应处理器即可。

### 3.3 健康检查端点

`mcp_server.py` 暴露 `/status` 全局端点，返回最近一次 API 活动（`api_last_activity`）与已注册的服务器实例列表，可被外部探针或负载均衡器用于存活检测。资料来源：[src/mcp_proxy/mcp_server.py:120-200]()

## 四、常见故障与缓解

### 4.1 StreamableHTTP 连接失败

社区 #69 报告使用 `docker run ... mcp-proxy:latest https://.../mcp/{api-key}` 时无法连接远端 StreamableHTTP 服务器。根因通常是未指定 `--transport streamablehttp`，因为默认客户端传输为 SSE。当 URL 以 `/mcp` 结尾或使用 POST/GET JSON 模式时，必须显式声明：

```bash
mcp-proxy --transport streamablehttp https://example.com/mcp
```

### 4.2 自定义头部未生效

#53 反映配置了 `Authorization` 但远端仍返回未鉴权响应。原因是 `--headers` 仅作用于代理→上游客户端连接，并不修改客户端→代理的入站请求。需通过反向代理或后续计划的 `X-API-Key` 中间件（#108）来保护入站端点。资料来源：[src/mcp_proxy/__main__.py:120-200]()

### 4.3 `serverInfo` 版本不匹配

#214 指出 `initialize` 响应返回的是 MCP Python SDK 版本而非远端服务器版本。这是 `create_proxy_server` 中 `app = server.Server(name=response.serverInfo.name)` 复用 SDK 默认 `serverInfo` 的副作用。临时缓解是不依赖 `serverInfo.version` 做兼容性判断；长期需在代理中透传远端 `serverInfo`。

### 4.4 SSL 证书校验失败

自 v0.10.0 起，`--no-verify-ssl` 与 `--verify-ssl` 提供禁用或指定 PEM 包的选项（#94），可用于自签名证书场景。注意该选项仅影响代理作为客户端时的出站校验，不影响 SSE 监听端。

### 4.5 运行时环境变量注入

#120 提出了对“每个用户一组环境变量”的代理需求。当前 `config_loader.py` 仅在加载时读取 `env`，未提供请求级注入。缓解方式是在启动前通过外部编排器为每个用户生成独立 `mcp-proxy` 进程实例，或在更高层通过 OAuth2 令牌交换（`--client-id`、`--client-secret`、`--token-url`）动态换取凭据。

## 五、See Also

- 项目主页：[README.md](https://github.com/sparfenyuk/mcp-proxy/blob/main/README.md)
- 发行说明：[Releases](https://github.com/sparfenyuk/mcp-proxy/releases)
- 相关社区议题：#108（API 鉴权）、#168（ARM 镜像）、#214（serverInfo 版本）

---

<!-- evidence_pipeline_checked: true -->
<!-- evidence_injected: true -->

---

## Doramagic 踩坑日志

项目：sparfenyuk/mcp-proxy

摘要：发现 11 个潜在踩坑项，其中 2 个为 high/blocking；最高优先级：安装坑 - 来源证据：docker: ARM images。

## 1. 安装坑 · 来源证据：docker: ARM images

- 严重度：high
- 证据强度：source_linked
- 发现：GitHub 社区证据显示该项目存在一个安装相关的待验证问题：docker: ARM images
- 对用户的影响：可能增加新用户试用和生产接入成本。
- 证据：community_evidence:github | https://github.com/sparfenyuk/mcp-proxy/issues/168 | 来源讨论提到 docker 相关条件，需在安装/试用前复核。

## 2. 安全/权限坑 · 来源证据：Add API key authentication to secure proxy endpoints

- 严重度：high
- 证据强度：source_linked
- 发现：GitHub 社区证据显示该项目存在一个安全/权限相关的待验证问题：Add API key authentication to secure proxy endpoints
- 对用户的影响：可能影响授权、密钥配置或安全边界。
- 证据：community_evidence:github | https://github.com/sparfenyuk/mcp-proxy/issues/108 | 来源讨论提到 api key 相关条件，需在安装/试用前复核。

## 3. 安装坑 · 来源证据：Complementary audit layer for mcp-proxy: HELM AI Kernel tamper-evident per-decision receipts

- 严重度：medium
- 证据强度：source_linked
- 发现：GitHub 社区证据显示该项目存在一个安装相关的待验证问题：Complementary audit layer for mcp-proxy: HELM AI Kernel tamper-evident per-decision receipts
- 对用户的影响：可能增加新用户试用和生产接入成本。
- 证据：community_evidence:github | https://github.com/sparfenyuk/mcp-proxy/issues/224 | 来源类型 github_issue 暴露的待验证使用条件。

## 4. 配置坑 · 可能修改宿主 AI 配置

- 严重度：medium
- 证据强度：source_linked
- 发现：项目面向 Claude/Cursor/Codex/Gemini/OpenCode 等宿主，或安装命令涉及用户配置目录。
- 对用户的影响：安装可能改变本机 AI 工具行为，用户需要知道写入位置和回滚方法。
- 证据：capability.host_targets | https://github.com/sparfenyuk/mcp-proxy | host_targets=mcp_host, claude

## 5. 能力坑 · 能力判断依赖假设

- 严重度：medium
- 证据强度：source_linked
- 发现：README/documentation is current enough for a first validation pass.
- 对用户的影响：假设不成立时，用户拿不到承诺的能力。
- 证据：capability.assumptions | https://github.com/sparfenyuk/mcp-proxy | README/documentation is current enough for a first validation pass.

## 6. 维护坑 · 来源证据：bug: serverInfo returns the version of the MCP Python SDK which this MCP proxy uses, not the version of the MCP server…

- 严重度：medium
- 证据强度：source_linked
- 发现：GitHub 社区证据显示该项目存在一个维护/版本相关的待验证问题：bug: serverInfo returns the version of the MCP Python SDK which this MCP proxy uses, not the version of the MCP server it is proxying to
- 对用户的影响：可能增加新用户试用和生产接入成本。
- 证据：community_evidence:github | https://github.com/sparfenyuk/mcp-proxy/issues/214 | 来源讨论提到 python 相关条件，需在安装/试用前复核。

## 7. 维护坑 · 维护活跃度未知

- 严重度：medium
- 证据强度：source_linked
- 发现：未记录 last_activity_observed。
- 对用户的影响：新项目、停更项目和活跃项目会被混在一起，推荐信任度下降。
- 证据：evidence.maintainer_signals | https://github.com/sparfenyuk/mcp-proxy | last_activity_observed missing

- 严重度：medium
- 证据强度：source_linked
- 发现：no_demo
- 证据：downstream_validation.risk_items | https://github.com/sparfenyuk/mcp-proxy | no_demo; severity=medium

## 9. 安全/权限坑 · 存在评分风险

- 严重度：medium
- 证据强度：source_linked
- 发现：no_demo
- 对用户的影响：风险会影响是否适合普通用户安装。
- 证据：risks.scoring_risks | https://github.com/sparfenyuk/mcp-proxy | no_demo; severity=medium

## 10. 维护坑 · issue/PR 响应质量未知

- 严重度：low
- 证据强度：source_linked
- 发现：issue_or_pr_quality=unknown。
- 对用户的影响：用户无法判断遇到问题后是否有人维护。
- 证据：evidence.maintainer_signals | https://github.com/sparfenyuk/mcp-proxy | issue_or_pr_quality=unknown

## 11. 维护坑 · 发布节奏不明确

- 严重度：low
- 证据强度：source_linked
- 发现：release_recency=unknown。
- 对用户的影响：安装命令和文档可能落后于代码，用户踩坑概率升高。
- 证据：evidence.maintainer_signals | https://github.com/sparfenyuk/mcp-proxy | release_recency=unknown

<!-- canonical_name: sparfenyuk/mcp-proxy; human_manual_source: deepwiki_human_wiki -->
