mcpField
C
cortex-gateway

cortex-gateway

远程服务
github.com/wellknownmcp安全122 天前更新
代码仓库

关于 cortex-gateway

Cortex Gateway 是可自托管的 MCP 网关,将普通 HTTP 后端汇聚到一个受 OAuth 2.1 保护的端点。它聚合工具并传递用户身份和作用域,使各后端按自身权限规则处理请求。

主要功能

  1. 01汇聚 HTTP 后端的工具目录
  2. 02OAuth 2.1 与基于作用域的可见性
  3. 03向后端传递用户身份
  4. 04动态发现与工具变更通知
  5. 05匿名化审计记录
  6. 06MCP 服务代理适配器

适用场景

  1. 01为员工提供统一的企业 MCP 端点
  2. 02汇集多个产品的工具
  3. 03通过主题中心整合不同提供方
  4. 04按订阅作用域控制工具访问

MCP 相关

通过单个 MCP 服务提供汇聚后的工具、资源和提示词,并将工具调用路由到 HTTP 后端。也可通过适配器代理原生 MCP 服务。

配置

远程服务无需本地安装。选择你使用的客户端,复制配置或使用一键安装。

服务地址https://mcp.cortex-gateway.dev/mcp
一键复制安装命令
Claude CodeTerminal
Cursor.cursor/mcp.json
VS Code.vscode/mcp.json
Claude Desktopclaude_desktop_config.json
Windsurf~/.codeium/windsurf/mcp_config.json

命令在终端中运行;JSON 粘贴到对应客户端的 MCP 配置后重启。需要授权的服务会在首次连接时提示登录。

安装包
ocighcr.io/wellknownmcp/cortex-gateway:v0.2.0

工具

详细介绍

Cortex Gateway

CI Docker License: MIT Glama score

一个联邦式 MCP 网关:在 N 个普通 HTTP 后端前,提供一个符合规范、受 OAuth 保护的 MCP 服务。

你的业务应用仍是普通 Web 服务。每个应用都暴露一个 POST /api/cortex/backend 端点(一份约 120 行的契约,无需 MCP 库,也不使用 stdio)。网关会发现这些应用的工具,将它们合并为一个 MCP 目录,强制执行 OAuth 2.1 和作用域,将 tools/call 路由至相应后端,并保留经过假名化处理的审计记录。

它只为一个需求而构建:公司里的每个人都应该能够把自己的密钥交给自己的 Agent——权限恰好与本人相同,不多也不少。当 Agent 成为自主助手时,答案也不变:Agent 借用用户的身份,应用继续执行该用户的权限。网关不做任何决策,因此也没有任何新的信任对象。

换句话说:为 AI Agent 奉行零信任原则——连接 IAM(用户身份及其可执行操作)与 MCP 生态系统(Agent 调用工具的方式)的缺失环节。它不是完整的 ZTNA 产品,而是面向 Agent 的身份与访问层。

后端是精简到核心功能的专用 MCP:通过纯 HTTP JSON-RPC 提供工具目录和工具调用(以及可选的提示词和资源)——传输和生命周期机制(initialize、会话、SSE、版本协商)只需在网关中实现一次。由于这份契约是 MCP 的语义子集,原生 MCP 服务也可以通过内置的 MCP→backend 代理适配器进行联邦接入(docs/mcp-adapter.md)。

[MCP agent: Claude Desktop / claude.ai Custom Connector / any MCP client]
         │  HTTPS + OAuth 2.1 JWT (Bearer)
         ▼
[cortex-gateway]  ←— thin gateway, no business logic
         │  HTTPS + the same JWT propagated (RFC 8707)
         ▼
[your backends]   ←— domain owners, plain HTTP, own their ACLs

为什么

  • 权限会自动与底层应用保持一致,精确到用户级别。 网关从不复制或镜像权限——它会传递真实用户身份(向第一方后端传递你的 JWT,向代理的第三方 MCP 服务传递用户自己关联的令牌),因此每个应用都会针对每位用户应用自己的原生权限模型,无需同步,也不会将权限扁平化为服务账号权限。与托管式工具聚合器不同,令牌库和审计记录都保留在你的基础设施上。
  • 只有一个边界,而不是 N 个连接器。 将每个应用分别接入为 MCP 连接器,同样可以保留原生权限,但你会面对 N 个授权、N 个令牌存储、没有共享审计、没有跨应用授权,以及被淹没的工具列表。网关将它们整合为一个 OAuth 接入面,同时保留按用户区分的权限模型:聚合而不丢失权限。
  • 应用不会被 MCP 锁定。 后端通过纯 HTTP 使用最简 JSON-RPC 契约。移除网关后,你仍然可以直接调用它们(用于测试、批处理作业和其他集成)。
  • 一个 JWT,N 个后端。 Agent 只需认证一次;网关传递令牌;每个后端都会重新验证令牌并应用自己的权限。在授权服务器上撤销令牌即可切断所有访问。
  • 故障隔离。 无法访问的后端只会从 tools/list 中消失,其余部分仍可正常工作。
  • 上下文感知的联邦接入。 后端筛选和精简的“搜索”模式可避免工具目录占满 Agent 的上下文(docs/tool-search-mode.md)。
  • Agent 反馈闭环。 缺少或不充分的工具会促使 Agent 提交 report_missing_capability 工单——系统会对工单去重、分流,并可在阻塞时推送至 Webhook。

使用场景

全公司统一的 Agent 接入层。 一个组织运行 N 个内部应用(CRM、质量文档、账单、分析……)。每个应用添加约 120 行的后端端点;网关将它们作为一个 MCP 连接器公开,并由公司的 SSO 保护。员工只需将一个 URL 接入 Claude Desktop / claude.ai,即可获得其令牌范围允许使用的工具,并拥有集中式审计记录。这正是该网关最初诞生的场景。

产品构建者。 你发布了多个产品,并希望 Agent(你自己的或客户的)能够操作这些产品。无需为每个产品维护一个 MCP 服务,只需让每个产品实现后端契约,网关就能成为统一的、带版本控制且受 OAuth 保护的 Agent API。只需设置一个环境变量,即可将产品添加到 Agent 接入层。

主题中心 / 精选注册表。 将网关作为一个主题端点运行,例如“领域 X 的所有开放数据工具”,通过一个 URL 和一个令牌联合多个提供方。范围模型支持按提供方选择性启用;get_help/get_snapshot 让 Agent 能够自描述地发现工具;审计记录则能告诉你实际使用情况。提供方可以原生支持(刻意保持精简的)后端契约;对于现成的 MCP 服务,则可通过内置的 MCP→后端代理适配器接入(docs/mcp-adapter.md)。

免费 / 付费工具层级。 范围即权益。让你的授权服务器向免费用户授予 mcp:yourapp:basic,向付费用户授予 mcp:yourapp:pro(由你的账单 Webhook 更新授权):随后,网关会向每个调用方展示并允许使用其套餐对应的工具,不必在网关或后端中加入付费墙逻辑,工具只需声明其范围。撤销和降级会沿正常的 OAuth 链路传递。

联合原生 MCP 服务(适配器,测试版)

内置的 MCP→后端代理适配器支持在一个工具包中混用契约后端和现成的原生 MCP 服务(Canva、Figma 等):适配器作为下游 MCP 客户端(initialize、会话、SSE 分帧),作为上游则是普通后端,因此网关核心无需改动。每个用户的下游 OAuth 由令牌库(静态数据采用 AES-256-GCM 加密)和关联流程(RFC 9728 发现、动态客户端注册、PKCE)处理:每位用户只需对每个提供方授权一次,之后 Agent 就能凭单个 Cortex 令牌访问整个工具包。请参阅 docs/mcp-adapter.md,了解一个完整的“设计工具包”示例(Canva + Figma + 你自己的后端)。

路线图

  • 按后端设定受众 —— 将调用方的令牌交换为受众指向目标后端的令牌(RFC 8693),这样后端就无法再将收到的令牌用于向网关重放请求(docs/security.md §6)。
  • 工具注释和来源信息 —— 将后端契约中的 readOnlyHint / destructiveHint 传递到 tools/list,在结果中标注其来源,并确认写入操作。
  • 2026-07-28 完整性 —— 为无状态客户端提供列表变更通知的 subscriptions/listen;后端仍通过后端契约调用,不受客户端协议版本的影响。
  • 用于发现的机器身份 —— 一旦你的 AS 支持 client_credentials 流程,就用它替代静态技术令牌。
  • 共享事件总线 / 速率限制存储 —— 用于多实例部署。

功能

  • 支持 MCP 规范 2026-07-28(无状态:server/discover,无会话, 根据请求正文校验 Mcp-Method / Mcp-Name 标头,缓存提示) 和 2025-11-25 / 2025-06-18(Streamable HTTP:initialize,通过 GET SSE 发送 listChanged 通知,使用 DELETE 终止会话),通过同一端点按请求选择
  • 基元:工具、资源(包括 URI 模板)、提示词
  • OAuth 2.1 资源服务:JWKS 验证、每个资源对应的受众 (RFC 8707)、受保护资源元数据(RFC 9728)、可选的 RFC 7662 内省以撤销令牌
  • 基于作用域的可见性:Agent 只能看到(并调用)其令牌作用域允许的工具; 发现信息中的 scopes_supported 根据联合目录实时生成
  • 动态发现:每 60 秒轮询后端;无需重新部署网关即可显示新工具,并通过 SSE 推送 tools/list_changed
  • 内置工具:whoami(聚合各后端的身份信息)、 find_tools、report_missing_capability、list_cortex_tickets、 list_cortex_resources、read_cortex_resource,以及实时生成的 自描述 cortex://architecture 资源
  • 审计记录:每次调用在标准输出中写入一行 JSON(哈希后的电子邮件、哈希后的参数),并可选持久化到 PostgreSQL,同时通过定时任务清理过期记录
  • Origin 允许列表(防止 DNS 重绑定)、按令牌限流、可选的池沙箱
  • CI 中通过真实 OAuth 流程对照官方 MCP 一致性测试套件进行验证:32 个服务端场景中有 22 个通过;其余 10 个测试的是网关未声明的可选功能(补全、日志记录、订阅、进度、采样、引导),以及未支持原因,详见 scripts/conformance/baseline.yml

快速开始(无需 OAuth 服务端)

git clone https://github.com/wellknownmcp/cortex-gateway
cd cortex-gateway
npm install

# 1. Start the demo backend (dependency-free)
node examples/demo-backend/server.mjs &

# 2. Configure the gateway
cat > .env.local <<'EOF'
OAUTH_ISSUER=https://auth.example.com
CORTEX_BACKENDS=demo
CORTEX_BACKEND_DEMO_URL=http://127.0.0.1:4820
CORTEX_TECHNICAL_TOKEN=demo-technical-token
CORTEX_DEV_BYPASS_TOKEN=dev-secret
CORTEX_DEV_BYPASS_SCOPES=mcp:demo:read
EOF

# 3. Run it
npm run dev

# 4. Talk MCP (dev bypass replaces the Bearer JWT locally)
curl -s http://localhost:3213/mcp \
  -H 'Content-Type: application/json' \
  -H 'X-Dev-Mode: dev-secret' \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}' | jq '.result.tools[].name'
# → whoami, ..., demo_get_help, demo_echo, demo_get_time

curl -s http://localhost:3213/mcp \
  -H 'Content-Type: application/json' \
  -H 'X-Dev-Mode: dev-secret' \
  -d '{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"demo_echo","arguments":{"message":"hello"}}}' | jq

在生产环境中,将 OAUTH_ISSUER 指向你的 OAuth 2.1 授权 服务端(任何签发带 JWKS 端点且包含 scope 声明的 RS256 JWT 的服务端均可),MCP 客户端通过 https://your-host/mcp 连接,并提供 aud 为网关规范 URI 的 Bearer 令牌。

stdio 桥接(适用于仅支持 stdio 的客户端和目录沙箱)

网关是一个远程 Streamable HTTP 服务,但部分 MCP 客户端——以及 Glama 等目录的 Docker 检查工具——只支持 stdio 传输。scripts/stdio-bridge.mjs 可桥接两者:它会使用临时本地 OAuth 签发方启动生产构建(走真实 JWT 验证流程,不绕过验证),为自身签发短期令牌,并在 stdin/stdout 与 POST /mcp 之间转发以换行符分隔的 JSON-RPC。

npm run build
npm run start:stdio   # stdio MCP server on stdin/stdout

自行授予的作用域来自 BRIDGE_SCOPES(网关内置工具无需作用域); 网关端口来自 BRIDGE_GATEWAY_PORT(默认值为 3213)。设计说明和注意事项(stdout 内容纯净、协议版本协商、会话回显): https://cortex-gateway.dev/guides/expose-http-mcp-server-over-stdio/.

添加后端

  1. 在你的应用中实现此契约——一个 POST 端点、list_tools + 你的工具(docs/backend-contract.md,参考实现位于 examples/demo-backend/)。
  2. 声明它:
    CORTEX_BACKENDS=demo,docs
    CORTEX_BACKEND_DOCS_URL=http://127.0.0.1:4001
    
  3. 完成。网关会在 60 秒内发现 docs_* 工具,并向已连接的客户端推送 tools/list_changed。

配置

所有配置均由环境变量驱动——完整的注释列表请参阅 .env.example。核心配置如下:

变量必需用途
CORTEX_CANONICAL_URIprod规范 MCP 资源 URI(RFC 9728),默认 JWT 受众
OAUTH_ISSUER是你的 OAuth 2.1 授权服务器
CORTEX_BACKENDS + CORTEX_BACKEND_<ID>_URL是联邦后端
CORTEX_TECHNICAL_TOKEN是用于发现目录的静态令牌(仅限目录方法)
CORTEX_ALLOWED_ORIGINSprod允许的 Web 来源(精确匹配或 *.suffix)
CORTEX_TOOL_INTEGRITY_MODE否warn(默认)或 block——检测工具定义是否被暗中替换
CORTEX_ADMIN_SECRET使用 block 时/api/admin/tool-integrity 的密钥;此运维端点用于审核并解除隔离
CORTEX_TOOL_BASELINE_FILE使用 block 时已批准工具定义的持久化位置;未设置时,重启后会重新批准当前状态
CORTEX_BASELINE_PRIVATE_KEY / _PUBLIC_KEY否对该存储进行 Ed25519 签名。仅配置公钥时,网关可以验证批准结果,但无法签发批准
OAUTH_REQUIRED_SCOPES否调用任何工具前必须具备的基础作用域
CORTEX_DATABASE_URL否用于持久化审计记录和网关票据的 PostgreSQL
CORTEX_TICKET_WEBHOOK_URL否用于能力缺失阻止票据的 Webhook
CORTEX_BACKEND_<ID>_SCOPE_PREFIXES否后端可声明的作用域前缀(默认 mcp:<id>:)——docs/security.md §7
CORTEX_BACKEND_<ID>_URI_SCHEMES否后端可为资源声明的 URI 方案(默认 <id>)
CORTEX_TRUSTED_PROXY_HOPS位于代理之后时前置可信代理的数量,用于读取 X-Forwarded-For(默认 0 = 忽略)
CORTEX_WEBSITE_URL否MCP 客户端显示的 websiteUrl(默认:网关来源)。服务器图标:替换 public/icon-{light,dark}.png

安全模型

有两条路径,而两者的区别正是整个设计的核心:目录在后台通过只能列出内容的技术令牌发现,而调用则会携带用户自己的令牌一路传递到后端。

sequenceDiagram
    autonumber
    participant Agent as AI agent
    participant GW as Cortex Gateway
    participant AS as Authorization server
    participant App as Backend app

    rect rgba(128,128,128,0.10)
    note over GW,App: Catalog refresh — every 60s, no user involved
    GW->>App: tools/list (CORTEX_TECHNICAL_TOKEN)
    App-->>GW: full tool catalog
    note over GW: Fingerprint each definition<br/>(rug-pull detection)
    end

    note over GW,AS: JWKS fetched once and cached —<br/>tokens are verified locally, not per call

    Agent->>GW: tools/list (user JWT)
    note over GW: Verify signature, issuer, audience<br/>Filter the cached catalog by the token's scopes
    GW-->>Agent: only the tools this user may call

    Agent->>GW: tools/call demo_echo (user JWT)
    note over GW: Check the scope declared by that tool
    GW->>App: tools/call — the user's JWT, forwarded
    note over App: Applies its own roles and ACLs<br/>to that user
    App-->>GW: result, under the user's own rights
    GW-->>Agent: result
    note over GW: One audit line: who, which tool,<br/>which backend, which scope

Agent 从不会持有用户没有的凭据,整个链路中也不存在权限过高的服务账户。

Agent 访问的安全性由架构保障,而不是依赖网关策略。将任何 MCP 工具接入 AI 应用时,都应要求具备以下特性:

  • OAuth 2.1,而非共享 API 密钥——每位调用者都以自己的身份进行身份验证;令牌按用户签发、具有作用域且可撤销。
  • 不扁平化权限——将真实用户的身份传递到每个后端,因此不存在权限过高的服务账户,Agent 获得的恰好是用户自身的权限。
  • 最小权限——工具目录会根据调用者进行作用域筛选;Agent 只能看到其令牌允许使用的工具。
  • 可验证——无需令牌即可遍历完整的 OAuth 发现链,因此你(或第三方扫描器)可以在连接前确认其安全状态。

底层机制:

  • 网关不决定任何业务权限。OAuth 作用域是入口(由网关和后端各检查一次);应用角色和 ACL 位于各个后端中。

  • 静态技术令牌只能访问目录方法(src/contract/static-token.ts);所有数据方法都要求使用最终用户的 JWT。

  • 审计记录在设计上采用假名化处理(电子邮件哈希、参数哈希)。假名化不等于匿名化:根据 GDPR 第 4(5) 条,哈希标识符仍属于个人数据,因此审计记录必须纳入你的处理活动记录,并设置保留期限。

  • 会话与令牌的 sub 绑定;外部会话 ID 将返回 404。 联邦网关可以实施而单个服务无法实施的控制措施。 网关可以查看每个后端的工具定义以及对它们的每次调用,因此正是捕捉生态系统事件报告中反复发现的问题的理想位置——完整详情见 docs/security.md:

  • 检测恶意替换。 首次发现工具定义时,会对其进行指纹识别(description、inputSchema、scope、version),并在每次刷新时重新检查。如果后端在保留工具名称的同时改写其声称的功能,系统会报告此情况;若设置 CORTEX_TOOL_INTEGRITY_MODE=block,该工具会被隔离,直到操作员通过 /api/admin/tool-integrity 审核——这是一个 HTTP 端点,而非 MCP 工具,因此模型无法自行解除隔离。大多数实现采用的名称级变更检测,恰恰无法发现这种攻击。

  • 不向远程主机发送明文。 每次联邦调用都会转发调用方的令牌,因此在加载时会拒绝指向回环地址以外任何位置的 http:// 后端 URL。对于适配器从第三方服务元数据中发现的 OAuth 端点,也会进行相同验证;CVE-2025-6514 正是由这类漏洞引发。

  • 可归属的审计记录。 每行记录都会注明哪个后端处理了调用以及所用的作用域,而不只是工具名称。

  • 后端各守其界。 后端只能声明其自身前缀下的作用域,并声明其自身的 URI 方案;提示词的前缀处理方式与工具相同。读取资源时,会根据 URI 所属模板的作用域进行检查,而不只是过滤资源列表。

明确说明范围:审批记录会在重启后保留(CORTEX_TOOL_BASELINE_FILE),且可由操作员签名,因此这只能证明“此定义自你在此处批准后发生了变化”,而不能证明“这就是供应商发布的定义”。

明确说明令牌转发。 调用方的令牌会转发给处理该调用的后端,且令牌的受众是网关。这正是移除服务账户的方式;这也意味着联邦后端处于其收到的令牌的信任边界内:若后端遭到入侵,就可能针对网关重放令牌。网关会限制令牌接收方(仅处理调用的后端、仅限调用方持有其作用域的后端,绝不通过明文传输);通过令牌交换实现按后端划分受众已列入路线图。详情与建议见:docs/security.md §6。

合规性。 这些是审计自动化访问时会检查的控制措施:最小权限作用域、按用户标识身份(不使用权限过高的服务账户)、每次调用均可归属的审计记录,以及集中撤销。它们对应 ISO 27001:2022 附录 A 中的访问控制和日志记录控制措施(A.5.15、A.5.16、A.5.17、A.5.18、A.8.2、A.8.15、A.8.16),也对应 SOC 2 CC6/CC7——两者目前均适用。通常会被引用的《欧盟 AI 法案》条款(第 12 条记录保存、第 14 条人工监督)仅适用于高风险 AI 系统;在 2026 年《数字综合法案》之后,这些义务已推迟至 2027 年 12 月 2 日(独立的附件 III)和 2028 年 8 月 2 日(嵌入式的附件 I)。大多数内部 Agent 部署不属于高风险,且网关是访问基础设施,而非 AI 系统。可自托管意味着审计记录和令牌保险库保留在你的安全边界内——无需增加 GDPR 第 28 条所述的处理者,也不会增加 SOC 2 的审计范围。Cortex 提供的是控制措施,而非认证。完整映射见: https://cortex-gateway.dev/answers/ai-agent-compliance-controls/

开发

npm run typecheck   # tsc --noEmit
npm test            # vitest
npm run build       # prisma generate + next build

在所有环境中,数据库都是可选的:如果未设置 CORTEX_DATABASE_URL,审计记录会输出到 stdout,且会禁用网关本地工单。

许可证

MIT

评论

支持 Markdown

第一次接触 MCP?

从协议是什么,到在客户端里装上第一个服务,这几条回答覆盖了大多数入门问题。

一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。