Horizon MCP Auth Proxy
by Razewang
README.md
# Horizon MCP Auth Proxy
这是一个可部署到 Prefect Horizon 的通用单上游 MCP 认证代理。它将原本需要
固定 HTTP 请求头的远程 Streamable HTTP MCP,包装为由 Horizon OAuth 保护的
MCP 地址。
```text
MCP 客户端 -- Horizon OAuth --> 本代理 -- 固定认证请求头 --> 远程 MCP
```
上游 MCP 不需要在本地或本仓库中运行。本仓库中的 `main.py:mcp` 本身就是
Horizon 所要求的 FastMCP 服务实例。
## 环境变量
代理只需要三个环境变量:
| 变量 | 说明 | 示例 |
| --- | --- | --- |
| `MCP_UPSTREAM_URL` | 完整的远程 Streamable HTTP MCP 地址 | `https://example.com/mcp` |
| `MCP_AUTH_HEADER_NAME` | 上游认证请求头名称 | `Authorization` |
| `MCP_AUTH_HEADER_VALUE` | 完整请求头值 | `Bearer your-token` |
`MCP_AUTH_HEADER_VALUE` 应在 Horizon 中作为 Secret 保存,不要提交到 GitHub。
### Bearer Token 示例
```text
MCP_UPSTREAM_URL=https://example.com/mcp
MCP_AUTH_HEADER_NAME=Authorization
MCP_AUTH_HEADER_VALUE=Bearer your-upstream-token
```
### Google Stitch 示例
```text
MCP_UPSTREAM_URL=https://stitch.googleapis.com/mcp
MCP_AUTH_HEADER_NAME=X-Goog-Api-Key
MCP_AUTH_HEADER_VALUE=your-google-api-key
```
## Horizon 部署
1. 将本仓库推送到 GitHub,并在 Horizon Deploy 中选择它。
2. Entrypoint 填写 `main.py:mcp`。
3. 开启 Horizon Authentication。Horizon 将负责客户端侧 OAuth。
4. 可以先不填写上游环境变量并完成第一次部署。此时服务是一个合法但没有工具的
`Horizon MCP Auth Proxy (Unconfigured)`。
5. 在部署设置中添加上述三个环境变量。
6. 重新部署或重启服务。环境变量在进程启动时读取,不会热更新。
7. 在 Horizon Inspector 中连接服务并确认上游工具已经出现。
部署后的客户端只连接:
```text
https://<server-name>.fastmcp.app/mcp
```
客户端不需要、也不应该携带上游 API Key。代码会禁用下游请求头转发,因此
Horizon OAuth 的 `Authorization` Bearer Token 不会发送到上游。
如果只配置了部分环境变量,服务会启动失败并明确列出缺失的变量。这可以避免
代理在错误凭据状态下运行。要恢复“待配置”状态,需要同时删除三个变量并重新部署。
## 支持范围
- 一个远程 Streamable HTTP MCP 上游
- 一个固定认证请求头
- `Authorization: Bearer ...`、API Key 和其他自定义认证头
- Horizon 管理的下游 OAuth
当前不支持 SSE-only、stdio、多上游、上游 OAuth 登录流程或配置热更新。
## 本地运行
安装依赖:
```powershell
python -m pip install -r requirements.txt
```
未配置状态可以直接启动:
```powershell
fastmcp run main.py:mcp --transport http --port 8000
```
完整配置可以复制 `.env.example` 为 `.env`,填写真实值后启动。FastMCP 默认加载
项目目录中的 `.env`,但真实 `.env` 已被 `.gitignore` 排除。
## 测试
```powershell
python -m pip install -r requirements-dev.txt
ruff check main.py tests
mypy --strict main.py
python -m pytest -q
python -m compileall main.py tests
fastmcp inspect main.py:mcp
```
`fastmcp inspect` 在未配置状态下应成功,并显示一个没有上游工具的有效 MCP 服务。
This server cannot be deployed
Maintenance
ActivitySlowing
ResponsivenessNo issues