内容
# Meta MCP 管理器
[](https://github.com/arthurkatcher/meta-mcp-manager/actions/workflows/ci.yml)
[](LICENSE)
[](https://www.python.org/downloads/)
**拥有您所有工具的统一MCP端点。**
自我托管的控制平面,聚合标准输入输出和远程MCP服务器,保持活跃,索引工具以便检索,并为Cursor、Claude、ChatGPT等代理提供单一可流式HTTP接口。
```
Cursor / Claude / ChatGPT
│ 一个连接
▼
Meta MCP 管理器 ──► GitHub · Logfire · Context7 · 您的标准输入服务器 · …
│
搜索 → 模式 → 调用
管理服务器 · 管理认证(管理员)
```
- **突破客户端工具限制** — 代理看到一个小型固定的元工具集,而不是500个模式。
- **兼容Cursor的配置** — 直接使用您已经使用的`mcp.json`。
- **入站OAuth** — Claude/ChatGPT粘贴您的网址;支持PKCE + DCR + 同意页面。
- **出站OAuth** — 通过`manage_auth`连接受保护的上游服务(例如Logfire)。
- **开源,单二进制Docker镜像** — MIT许可,无需电话验证。
---
## 目录
- [为什么](#为什么)
- [功能](#功能)
- [快速开始](#快速开始)
- [Docker](#docker)
- [连接客户端](#连接客户端)
- [元工具](#元工具)
- [配置](#配置)
- [OAuth](#oauth)
- [品牌与连接器打包](#品牌与连接器打包)
- [架构](#架构)
- [开发](#开发)
- [安全说明](#安全说明)
- [状态与路线图](#状态与路线图)
- [贡献](#贡献)
- [安全](#安全)
- [许可证](#许可证)
---
## 为什么
AI客户端对工具数量有限制,并且每次模式变更都会消耗令牌。直接加载数十个MCP:
1. 达到限制(例如某些IDE中的~40个工具)。
2. 降低工具选择准确性。
3. 使OAuth、重启和库存管理变得不可行。
元工具位于中间:**一个公共MCP**,多个上游,**搜索优先**发现。
---
## 功能
| 领域 | 功能 |
|------|------------|
| **传输** | 保持**标准输入**连接池;远程**流式HTTP**(+ SSE,根据配置) |
| **发现** | BM25 `搜索工具`,分页`列出服务器` / `列出工具` |
| **管理员** | `管理服务器` CRUD;启用/禁用/重新加载 |
| **出站认证** | OAuth 2.1 + PKCE到上游;加密令牌库;刷新 |
| **入站认证** | OAuth AS + PRM适用于Claude/ChatGPT;本地客户端的API密钥 |
| **作用域** | `meta:read`(目录),`meta:invoke`(调用),`meta:admin`(管理_*) |
| **运维** | 健康检查JSON,审计日志(仅参数键),Docker Compose |
| **打包** | Logo SVG,文档/法律页面,CSP + 安全头 |
---
## 快速开始
### 要求
- Python **3.11+**
- 可选:Node(`npx`)如果您的上游MCP需要它
- 可选:[uv](https://github.com/astral-sh/uv)
### 安装与运行
```bash
git clone https://github.com/arthurkatcher/meta-mcp-manager.git
cd meta-mcp-manager
python -m venv .venv
source .venv/bin/activate # Windows: .venv\Scripts\activate
pip install -e ".[dev]"
# 或:uv pip install -e ".[dev]"
cp config/mcp.example.json mcp.json
# 根据需要编辑路径/服务器
export META_API_KEY="$(openssl rand -hex 16)"
meta serve --config mcp.json --host 127.0.0.1 --port 8080 --data-dir ./data
```
| 网址 | 描述 |
|-----|-------------|
| `http://127.0.0.1:8080/mcp` | MCP端点 |
| `http://127.0.0.1:8080/health` | 健康检查 + 统计信息 |
| `http://127.0.0.1:8080/docs` | 人性化文档 |
| `http://127.0.0.1:8080/static/logo.svg` | Logo |
```bash
curl -s http://127.0.0.1:8080/health | jq .
```
---
## Docker
```bash
export META_API_KEY="$(openssl rand -hex 16)"
docker compose up --build
```
Compose挂载`config/mcp.docker.json`并持久化`/data`。对于公共客户端(Claude/ChatGPT),请设置:
```bash
export META_PUBLIC_URL=https://your.domain.example
export META_OAUTH_PASSWORD="$META_API_KEY" # 或单独的同意密码
docker compose up --build
```
---
## 连接客户端
### Cursor / VS Code(API密钥)
```json
{
"mcpServers": {
"meta": {
"url": "http://127.0.0.1:8080/mcp",
"headers": {
"Authorization": "Bearer YOUR_META_API_KEY"
}
}
}
}
```
### Grok(`~/.grok/config.toml`)
```toml
[mcp_servers.meta]
url = "http://127.0.0.1:8080/mcp"
enabled = true
[mcp_servers.meta.headers]
Authorization = "Bearer YOUR_META_API_KEY"
```
或:`grok mcp add --transport http meta http://127.0.0.1:8080/mcp --header "Authorization: Bearer YOUR_META_API_KEY"`
### Claude Desktop(标准输入桥接 + API密钥)
```json
{
"mcpServers": {
"meta": {
"command": "npx",
"args": [
"-y",
"mcp-remote",
"http://127.0.0.1:8080/mcp",
"--header",
"Authorization: Bearer YOUR_META_API_KEY"
]
}
}
}
```
### Claude / ChatGPT(远程 + 入站OAuth)
1. 使用HTTPS公开Meta(隧道或反向代理):
```bash
ngrok http 8080
export META_PUBLIC_URL=https://YOUR_SUBDOMAIN.ngrok-free.dev
meta serve --config mcp.json --host 0.0.0.0 --port 8080 \
--public-url "$META_PUBLIC_URL" --api-key "$META_API_KEY"
```
2. 在客户端添加远程MCP网址:
`https://YOUR_SUBDOMAIN.ngrok-free.dev/mcp`
3. 使用 **`META_OAUTH_PASSWORD`** 或 **`META_API_KEY`** 完成浏览器同意。
无需为该路径设置静态Bearer头。
---
## 元工具
| 工具 | 目的 |
|------|---------|
| `搜索工具` | 目录的BM25搜索 |
| `获取工具模式` | `服务器/工具`的完整JSON模式 |
| `调用工具` | 调用上游工具 |
| `列出服务器` | 分页服务器库存 |
| `列出工具` | 分页工具目录(可选`服务器`过滤) |
| `统计信息` | 计数 / 健康检查 |
| `管理服务器` | 创建 · 更新 · 删除 · 获取 · 列出 · 启用 · 禁用 · 重新加载 |
| `管理认证` | 登录 · 状态 · 注销 · 刷新(无原始令牌到模型) |
**代理路径:** `搜索工具` → `获取工具模式` → `调用工具`。
### 添加上游MCP(+ OAuth)
```text
manage_servers(action="create", server_id="logfire",
url="https://logfire-us.pydantic.dev/mcp")
# 如果runtime_status == "auth_required":
manage_auth(action="login", server_id="logfire")
# 打开authorization_url → Meta /oauth/callback完成
manage_auth(action="status", server_id="logfire")
搜索工具(query="列出项目")
调用工具(tool_id="logfire/project_list", arguments={})
```
管理员工具需要作用域 **`meta:admin`**。API密钥授予完全管理员权限。
---
## 配置
### `mcp.json`(兼容Cursor)
```json
{
"mcpServers": {
"filesystem": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-filesystem", "/data"]
},
"context7": {
"url": "https://mcp.context7.com/mcp"
},
"protected": {
"url": "https://example.com/mcp",
"headers": {
"Authorization": "Bearer ${env:SERVICE_TOKEN}"
},
"auth": {
"CLIENT_ID": "${env:OAUTH_CLIENT_ID}",
"CLIENT_SECRET": "${env:OAUTH_CLIENT_SECRET}",
"scopes": ["read", "write"]
}
}
}
}
```
`${env:NAME}`在加载时插值。
### 环境变量
| 变量 | 描述 |
|----------|-------------|
| `META_API_KEY` | 本地客户端的Bearer密钥;默认同意密码(如果未设置) |
| `META_OAUTH_PASSWORD` | 入站OAuth的同意密码(可选) |
| `META_PUBLIC_URL` | 公共基准URL(OAuth重定向/ PRM所需) |
| `META_CONFIG` | `mcp.json`的路径 |
| `META_DATA_DIR` | SQLite,保险库,日志 |
| `META_HOST` / `META_PORT` | 绑定地址 |
| `META_OAUTH_ENABLED` | 入站OAuth AS(默认`true`) |
| `META_ALLOW_API_KEY` | 在`/mcp`上接受API密钥(默认`true`) |
| `META_REQUIRE_API_KEY` | 在`/mcp`上要求认证(默认`true`) |
| `META_STRICT_STDIO` | 要求绝对标准输入命令(默认`false`) |
| `META_STDIO_ALLOW_PREFIXES` | 允许的路径前缀(`:`分隔)当严格 |
命令行界面:
```bash
meta serve --config mcp.json --host 127.0.0.1 --port 8080 \
--api-key "$META_API_KEY" --public-url "$META_PUBLIC_URL"
```
---
## OAuth
### 两个方向
| 方向 | 含义 |
|-----------|---------|
| **出站** | Meta → 上游MCP(Logfire,Linear,…)通过`manage_auth` + `/oauth/callback` |
| **入站** | Claude/ChatGPT → Meta通过PRM/AS + `/oauth/authorize` + `/oauth/token` |
### 入站发现端点
| 端点 | 规范角色 |
|----------|-----------|
| `GET /.well-known/oauth-protected-resource` | RFC 9728 PRM |
| `GET /.well-known/oauth-authorization-server` | RFC 8414 AS元数据 |
| `POST /oauth/register` | 动态客户端注册 |
| `GET/POST /oauth/authorize` | 授权码 + 同意 |
| `POST /oauth/token` | 代码交换 / 刷新 |
### 作用域
| 作用域 | 访问权限 |
|-------|--------|
| `meta:read` | 搜索,列出,模式,统计信息(目录) |
| `meta:invoke` | 当`META_REQUIRE_INVOKE_SCOPE=true`时,`调用工具` |
| `meta:admin` | `管理服务器`,`管理认证` |
默认OAuth同意授予 **`meta:read` + `meta:invoke`** (目录 + 调用工具)。
**`meta:admin` 永远不会默认** — 必须显式请求。 API密钥获取所有作用域。
设置 `META_REQUIRE_INVOKE_SCOPE=true` 以强制 `调用工具` 需要 `meta:invoke` (推荐您也颁发只读令牌)。
### 速率限制(默认,每个主体/分钟)
| 接口 | 默认值 | 环境变量 |
|---------|---------|-----|
| `调用工具` | 60 | `META_RATE_CALL_TOOL` |
| `管理_*` | 30 | `META_RATE_MANAGE` |
| 目录(`搜索` / `列出_*` / `统计信息`) | 180 | `META_RATE_CATALOG` |
| OAuth注册 / 令牌 / 授权 | 单独 | (内置) |
窗口:`META_RATE_WINDOW_SEC`(默认60)。将限制设置为`0`以禁用该桶。超过工具的返回`错误:rate_limited`。
### 产品数据库(一个SQLite文件)
所有持久数据存储在 **`{META_DATA_DIR}/meta.db`** (WAL)。多个表,一个文件用于备份/ UI:
| 表 | 目的 |
|----------|---------|
| `servers`, `tools` | 上游MCP + 工具模式的目录 |
| `activity` | Meta工具调用日志(活动UI) |
| `oauth_tokens`, `oauth_pending` | 出站OAuth(令牌块Fernet加密) |
| `oauth_clients`, `auth_codes`, `access_tokens`, … | 入站OAuth AS |
| `meta_schema` | 模式版本 |
磁盘上仍然单独存储:`mcp.json`(配置模板),`token.key`(Fernet密钥,模式0600),可选JSONL镜像`logs/audit.jsonl`。
旧版拆分文件(`activity.db`,`oauth.db`,`inbound_oauth.db`)**合并到`meta.db`一次**启动后重命名`*.migrated`。
**活动列:** `event_id`,`ts`,`duration_ms`,`meta_tool`,`actor_label`(`oauth · Claude`,…),`ok`,`error_code`,`args_keys`(仅名称),`target_tool_id`,…
当可用时,OAuth参与者使用注册的 **client_name**。
入站Bearer机密(访问/刷新/授权代码/客户端密钥)存储为 **SHA-256摘要**在SQLite中(仅发行时为明文)。
### 生产检查清单
| 控制 | 环境变量 / 操作 |
|---------|----------------|
| 强大的API密钥 | `META_API_KEY` ≥16字符,唯一 |
| 同意密码 | `META_OAUTH_PASSWORD`(首选与API密钥分开) |
| 公共绑定 | 自动`strict_stdio`;拒绝弱密钥 |
| DCR锁定 | `META_DCR_TOKEN=…`和/或`META_DCR_REDIRECT_ALLOWLIST=claude.ai,.openai.com` |
| 禁用DCR | `META_DCR_ENABLED=false` |
| 目录仅OAuth | `META_REQUIRE_INVOKE_SCOPE=true` + 按需授予`meta:invoke` |
| SSRF | `META_ALLOW_PRIVATE_URLS=false`当不需要本地MCP时 |
| 活动保留 | `META_ACTIVITY_RETENTION_DAYS=30`(默认) |
| 单个工作线程 | 不设置`WEB_CONCURRENCY>1`(启动时拒绝) |
| 备份 | `meta backup --out /safe/path`(复制`meta.db`,`token.key`,`mcp.json`) |
| TLS | 在反向代理/隧道中终止 |
---
## 品牌与连接器打包
| 资产 | 路径 |
|-------|------|
| Logo | `/static/logo.svg` |
| Favicon | `/static/favicon.svg` |
| 文档 | `/docs` |
| 条款 | `/legal/terms` |
| 隐私 | `/legal/privacy` |
| 品牌包 | `/brand` |
PRM包括`logo_uri`,`resource_documentation`,`resource_tos_uri`,`resource_policy_uri`。
HTML/OAuth响应发送CSP和标准安全头。
参见 [docs/CONNECTOR.md](docs/CONNECTOR.md) 获取完整接口和生产检查清单。
---
## 架构
```
src/meta_manager/
app.py # HTTP路由,生命周期
main.py # CLI:meta serve
config/ # 加载/保存mcp.json,设置
runtime/ # 标准输入 + HTTP会话池
catalog/ # SQLite目录 + BM25
edge/ # 元工具,认证中间件,CSP
oauth/ # 出站保险库 + 入站AS
admin/ # 管理服务器 / 管理认证
brand/ # 文档/法律HTML
static/ # Logo,Favicon
```
设计说明: [ARCHITECTURE.md](ARCHITECTURE.md)。
---
## 开发
```bash
source .venv/bin/activate
pip install -e ".[dev]"
pytest -q --timeout=90
# 可选真实MCP压力测试(Meta必须运行):
# META_URL=http://127.0.0.1:8080/mcp META_API_KEY=... python scripts/hardcore_eval_real.py
```
`fixtures/`下的fixtures提供了stdio math/echo/many-tools和一个HTTP时间服务器,用于无需脆弱公共远程的CI。
---
## 安全说明
- **自我托管:** 您操作实例;保护`META_API_KEY` / `META_OAUTH_PASSWORD`和网络暴露。
- 优先使用 **HTTPS** 和 **稳定域名** 进行入站OAuth(不是长期免费隧道)。
- 上游令牌存储在`META_DATA_DIR`下(Fernet加密保险库);备份并限制该目录。
- 管理工具可以添加任意命令(标准输入)和网址 — 将`meta:admin`视为根权限。
- 审计日志记录工具ID和参数 **键**,而非秘密值。
- `/legal/*`下的法律页面是 **开源自我托管模板**,而非正式法律顾问。
---
## 状态与路线图
**v0.1 — 可生产单操作员自我托管:** 联邦,BM25搜索,温暖标准输入,远程HTTP,出站OAuth,入站OAuth(PRM/AS/DCR/PKCE),具有作用域门控的管理工具,Docker,连接器品牌,统一SQLite,活动日志,速率限制,基于资源的令牌。
**仍在多租户SaaS范围之外:** 外部IdP,分布式速率限制(Redis),多副本HA,市场列表。
参见 [CHANGELOG.md](CHANGELOG.md) 获取发行说明。
---
## 贡献
参见 [CONTRIBUTING.md](CONTRIBUTING.md) 和 [CODE_OF_CONDUCT.md](CODE_OF_CONDUCT.md)。欢迎PR和问题。
---
## 安全
请私下报告漏洞 — [SECURITY.md](SECURITY.md)。
---
## 许可证
[MIT](LICENSE) — Copyright (c) 2026 Meta MCP Manager 贡献者
MCP 配置
以下是此 MCP Server 的配置信息,可直接复制到 Cursor 或其他 MCP 客户端中使用。
mcp.json
连接信息
猜你喜欢
暂无推荐服务器