Cortex Gateway

io.github.wellknownmcp由 GitHub 账号 wellknownmcp 发布v0.2.0更新于 Oct 24, 2026

Self-hosted federated MCP gateway: one OAuth 2.1 MCP server in front of N apps, user-level scopes.

已验证Streamable HTTP可网页运行云端与基础设施开发者工具安全与监控

概览

AI 生成的概览

自托管的联邦式 MCP 网关,用一个受 OAuth 2.1 保护的 MCP 端点统一接入多个 HTTP 后端,并按用户划分权限范围。

可以做什么
  • 从多个联邦后端发现并汇总工具、资源与提示词,形成统一 MCP 目录,每 60 秒刷新
  • 以调用者本人的 JWT 转发调用后端工具,由各应用按该用户的权限执行
  • 查看身份与目录:whoami、find_tools、列出并读取 cortex 资源,以及自描述的架构资源
  • 提交并列出缺失能力工单,可选推送到 webhook
  • 按 OAuth 权限范围过滤目录,并用精简搜索模式控制工具列表长度
  • 对工具定义做指纹校验以发现 rug-pull 变更,可选隔离并由运维人员审核
适用场景
适用于组织或产品团队拥有多个内部应用或服务,希望员工或客户通过一个受 OAuth 保护的 MCP 连接器访问,并保持按用户的权限与集中审计,而不是为每个应用各配一个连接器。
运行要求
以远程 Streamable HTTP 端点或自托管容器/Node.js 进程运行。需要一个签发 RS256 JWT 并提供 JWKS 的 OAuth 2.1 授权服务器(OAUTH_ISSUER)、规范资源 URI(CORTEX_CANONICAL_URI)、后端标识与地址(CORTEX_BACKENDS、CORTEX_BACKEND_ _URL),以及用于目录发现的静态令牌(CORTEX_TECHNICAL_TOKEN)。PostgreSQL 可选,用于审计持久化。
安装前请注意
调用者的 JWT 会被转发给实际服务的后端,因此被攻陷的后端可能拿它向网关重放;明文 HTTP 后端仅允许回环地址。CORTEX_TECHNICAL_TOKEN 与 CORTEX_ADMIN_SECRET 是机密,CORTEX_BASELINE_PRIVATE_KEY 用于签署工具审批。审计记录虽经假名化,仍属个人数据,需要设定保留期限。工具调用以用户本人权限执行,MCP 到后端的适配器会把各用户的下游令牌存入令牌库。

安装

在 SourceWeft 中

  1. 打开 控制台中的 Cortex Gateway,将其添加到工作区。
  2. 连接 所需的 凭据。它们会被私密存储,绝不会在公开页面上展示。
  3. 为需要使用其工具的对话启用该服务。

Web executable,通过 Streamable HTTP。 远程服务在工作区中配置后即可从网页运行时运行。

交给智能体安装

把这段提示词粘贴到 Claude Code、Codex、Cursor 等智能体,或 SourceWeft 对话中。智能体会读取该服务器的安装指南,先向你展示发布者、端点和登录方式,经你同意后再把它添加到你的客户端。密钥不会写进任何命令。

阅读 https://sourceweft.com/mcp/io.github.wellknownmcp%2Fcortex-gateway/install.md,并按其中说明把这个 MCP 服务器接入我的客户端。修改任何配置之前,先告诉我它的发布者、端点和登录方式,等我确认。不要把 API 密钥写进命令或我会提交的文件;问我密钥应从哪里获取。

查看智能体所依据的安装指南

其他 MCP 客户端

把它添加到你客户端的 mcpServers 配置中。 客户端会在首次连接时完成 OAuth 登录。

{
  "mcpServers": {
    "cortex-gateway": {
      "type": "http",
      "url": "https://mcp.cortex-gateway.dev/mcp"
    }
  }
}

README

Cortex Gateway

[CI] [Docker] [License: MIT] [Glama score]

A federated MCP gateway: one spec-compliant, OAuth-protected MCP server in front of N plain-HTTP backends.

Your business apps stay ordinary web services. Each one exposes a single POST /api/cortex/backend endpoint (a ~120-line contract, no MCP library, no stdio). The gateway discovers their tools, merges them into one MCP catalog, enforces OAuth 2.1 + scopes, routes tools/call to the owning backend, and keeps a pseudonymized audit trail.

Built for one requirement: everyone in a company should be able to hand their own agent the keys — with exactly that person's rights, nothing more, nothing less. And when agents become autonomous assistants, the answer stays the same: the agent borrows the person's identity, the apps keep enforcing that person's rights. The gateway decides nothing, so there is nothing new to trust.

Put another way: zero-trust principles for AI agents — the missing link between your IAM (who your users are, what they may do) and the MCP ecosystem (how agents call tools). Not a full ZTNA product; the identity-and-access layer for agents.

A backend is a dedicated MCP reduced to its essence: a tool catalog plus tool invocation (and optional prompts/resources) over bare HTTP JSON-RPC — the transport and lifecycle machinery (initialize, sessions, SSE, version negotiation) lives once, in the gateway. Because the contract is a semantic subset of MCP, a native MCP server can also be federated through the built-in MCP→backend proxy adapter (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

Why

  • Permissions match the underlying app, automatically, at the user level. The gateway never copies or mirrors permissions — it propagates the real user identity (your JWT to first-party backends, the user's own linked token to proxied third-party MCP servers), so each app's native permission model applies per user, with nothing to sync and no service-account flattening. Unlike hosted tool aggregators, the token vault and the audit trail stay on your infrastructure.
  • One perimeter, not N connectors. Wiring each app as its own MCP connector also keeps native permissions — and leaves you with N consents, N token stores, no shared audit, no cross-app entitlements, and a flooded tool list. The gateway collapses that to one OAuth surface without giving up the per-user model: aggregation without permission loss.
  • Zero MCP lock-in in your apps. Backends speak a minimal JSON-RPC contract over plain HTTP. Remove the gateway and you can still call them directly (tests, batch jobs, other integrations).
  • One JWT, N backends. The agent authenticates once; the gateway propagates the token; every backend re-validates it and applies its own permissions. Revocation at the authorization server cuts everything.
  • Failure isolation. An unreachable backend just disappears from tools/list; the rest keeps working.
  • Context-aware federation. Backend filtering and a compact "search" mode keep the tool catalog from flooding the agent's context (docs/tool-search-mode.md).
  • Agent feedback loop. Agents can file report_missing_capability tickets when a tool is missing or insufficient — deduplicated, triaged, optionally pushed to a webhook when blocking.

Use cases

Company-wide agent surface. An organization runs N internal apps (CRM, quality docs, billing, analytics...). Each app adds the ~120-line backend endpoint; the gateway exposes them as ONE MCP connector protected by the company's SSO. Employees plug a single URL into Claude Desktop / claude.ai and get exactly the tools their token scopes allow, with a central audit trail. This is the setup the gateway was born in.

Product builder. You ship several products and want agents (yours or your customers') to operate them. Instead of maintaining one MCP server per product, every product implements the backend contract and the gateway is your single, versioned, OAuth-protected agent API. Adding a product to the agent surface is one env var.

Thematic hub / curated registry. Run a gateway as a topic endpoint — e.g. "all open-data tools for domain X" — that federates several providers behind one URL with one token. The scope model gives you per-provider opt-in, get_help/get_snapshot give agents self-describing discovery, and the audit trail tells you what is actually used. Providers either speak the (deliberately tiny) backend contract natively, or — for off-the-shelf MCP servers — get fronted by the built-in MCP→backend proxy adapter (docs/mcp-adapter.md).

Free / paid tool tiers. Scopes are entitlements. Let your authorization server grant mcp:yourapp:basic to free users and mcp:yourapp:pro to paying ones (your billing webhook updates the grant): the gateway then shows and allows each caller exactly the tools of their plan — no paywall logic in the gateway or the backends, tools just declare their scope. Revocation and downgrades propagate through the normal OAuth chain.

Federating native MCP servers (adapter, beta)

The built-in MCP→backend proxy adapter lets a bundle mix contract backends and off-the-shelf native MCP servers (Canva, Figma, ...): the adapter is an MCP client downstream (initialize, sessions, SSE framing) and a plain backend upstream, so the gateway core does not change. Per-user downstream OAuth is handled by a token vault (AES-256-GCM at rest) and a linking flow (RFC 9728 discovery, Dynamic Client Registration, PKCE): each user consents once per provider, then agents are identified on the whole bundle with a single Cortex token. See docs/mcp-adapter.md for a worked "design bundle" example (Canva + Figma + your own backend).

Roadmap

  • Per-backend audiences — exchange the caller's token for one audienced to the target backend (RFC 8693), so a backend can no longer replay what it receives against the gateway (docs/security.md §6).
  • Tool annotations and provenance — carry readOnlyHint / destructiveHint from the backend contract into tools/list, mark results with their origin, and confirm writes.
  • 2026-07-28 completeness — subscriptions/listen for list-change notifications to stateless clients; backends are still called over the backend contract, unaffected by the client's protocol generation.
  • Machine identity for discovery — replace the static technical token with a client_credentials flow once your AS supports it.
  • Shared event bus / rate-limit store — for multi-instance deployments.

Features

  • MCP spec 2026-07-28 (stateless: server/discover, no session, Mcp-Method / Mcp-Name headers validated against the body, cache hints) and 2025-11-25 / 2025-06-18 (Streamable HTTP: initialize, GET SSE for listChanged notifications, DELETE session termination) on the same endpoint, chosen per request
  • Primitives: tools, resources (incl. URI templates), prompts
  • OAuth 2.1 resource server: JWKS verification, audience per resource (RFC 8707), protected-resource metadata (RFC 9728), optional RFC 7662 introspection for revocation
  • Scope-based visibility: agents only see (and can call) the tools their token scopes allow; scopes_supported in discovery is derived live from the federated catalog
  • Dynamic discovery: backends are polled every 60s; new tools appear without redeploying the gateway, with SSE tools/list_changed push
  • Builtins: whoami (aggregated identity across backends), find_tools, report_missing_capability, list_cortex_tickets, list_cortex_resources, read_cortex_resource, plus a self-describing cortex://architecture resource generated live
  • Audit trail: one JSON line per call on stdout (hashed email, hashed params) + optional PostgreSQL persistence with retention cron
  • Origin allow-list (anti DNS-rebinding), per-token rate limiting, optional pool sandbox
  • Checked against the official MCP conformance suite in CI, through a real OAuth path: 22 of 32 server scenarios pass; the other 10 exercise optional capabilities the gateway does not declare (completions, logging, subscriptions, progress, sampling, elicitation) — listed with the reason in scripts/conformance/baseline.yml

Quickstart (no OAuth server needed)

bash
git clone https://github.com/wellknownmcp/cortex-gatewaycd cortex-gatewaynpm install
# 1. Start the demo backend (dependency-free)node examples/demo-backend/server.mjs &
# 2. Configure the gatewaycat > .env.local <<'EOF'OAUTH_ISSUER=https://auth.example.comCORTEX_BACKENDS=demoCORTEX_BACKEND_DEMO_URL=http://127.0.0.1:4820CORTEX_TECHNICAL_TOKEN=demo-technical-tokenCORTEX_DEV_BYPASS_TOKEN=dev-secretCORTEX_DEV_BYPASS_SCOPES=mcp:demo:readEOF
# 3. Run itnpm 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

In production you point OAUTH_ISSUER at your OAuth 2.1 authorization server (any server that issues RS256 JWTs with a JWKS endpoint and supports the scope claim), and MCP clients connect to https://your-host/mcp with a Bearer token whose aud is the gateway's canonical URI.

stdio bridge (for stdio-only clients and directory sandboxes)

The gateway is a remote Streamable HTTP server, but some MCP clients — and the Docker inspection harnesses of directories like Glama — only speak the stdio transport. scripts/stdio-bridge.mjs bridges the two: it boots the production build against an ephemeral local OAuth issuer (the real JWT verification path, no bypass), mints itself a short-lived token, and relays newline-delimited JSON-RPC between stdin/stdout and POST /mcp.

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

Self-granted scopes come from BRIDGE_SCOPES (gateway builtins need none); the gateway port from BRIDGE_GATEWAY_PORT (default 3213). Design notes and the gotchas (stdout purity, protocol-version negotiation, session echo): https://cortex-gateway.dev/guides/expose-http-mcp-server-over-stdio/.

Adding a backend

  1. Implement the contract in your app — one POST endpoint, list_tools + your tools (docs/backend-contract.md, reference implementation in examples/demo-backend/).
  2. Declare it:
    bash
    CORTEX_BACKENDS=demo,docsCORTEX_BACKEND_DOCS_URL=http://127.0.0.1:4001
  3. Done. The gateway discovers docs_* tools within 60s and pushes tools/list_changed to connected clients.

Configuration

Everything is env-driven — see .env.example for the full annotated list. The essentials:

VariableRequiredPurpose
CORTEX_CANONICAL_URIprodCanonical MCP resource URI (RFC 9728), default JWT audience
OAUTH_ISSUERyesYour OAuth 2.1 authorization server
CORTEX_BACKENDS + CORTEX_BACKEND_<ID>_URLyesFederated backends
CORTEX_TECHNICAL_TOKENyesStatic token for catalog discovery (catalog methods only)
CORTEX_ALLOWED_ORIGINSprodWeb origins allowed (exact or *.suffix)
CORTEX_TOOL_INTEGRITY_MODEnowarn (default) or block — rug-pull detection on tool definitions
CORTEX_ADMIN_SECRETwith blockSecret for /api/admin/tool-integrity, the operator endpoint that reviews and clears quarantines
CORTEX_TOOL_BASELINE_FILEwith blockWhere approved tool definitions persist; without it a restart re-approves the current state
CORTEX_BASELINE_PRIVATE_KEY / _PUBLIC_KEYnoEd25519 signing of that store. Public key alone = the gateway verifies approvals but cannot mint them
OAUTH_REQUIRED_SCOPESnoBaseline scope demanded before any dispatch
CORTEX_DATABASE_URLnoPostgreSQL for audit persistence + gateway tickets
CORTEX_TICKET_WEBHOOK_URLnoWebhook for blocking missing-capability tickets
CORTEX_BACKEND_<ID>_SCOPE_PREFIXESnoScope prefixes the backend may declare (default mcp:<id>:) — docs/security.md §7
CORTEX_BACKEND_<ID>_URI_SCHEMESnoURI schemes the backend may claim for resources (default <id>)
CORTEX_TRUSTED_PROXY_HOPSbehind a proxyNumber of trusted proxies in front, for reading X-Forwarded-For (default 0 = ignored)
CORTEX_WEBSITE_URLnowebsiteUrl shown by MCP clients (default: the gateway origin). Server icons: replace public/icon-{light,dark}.png

Security model

Two paths, and the difference between them is the whole design: the catalog is discovered in the background with a technical token that can only list, and a call carries the user's own token all the way to the backend.

mermaid
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

The agent never holds a credential the user does not have, and no over-privileged service account exists anywhere on the path.

Agent access is secured by construction, not by gateway policy. The properties below are what to demand from any MCP tooling you wire into an AI app:

  • OAuth 2.1, not shared API keys — every caller authenticates as themselves; tokens are per-user, scoped and revocable.
  • No permission flattening — the real user's identity is propagated to each backend, so no over-privileged service account exists and the agent gets exactly the user's own rights.
  • Least privilege — the tool catalog is scope-filtered per caller; agents only see the tools their token allows.
  • Verifiable — the whole OAuth discovery chain is walkable without a token, so you (or a third-party scanner) can confirm the posture before connecting.

Under the hood:

  • The gateway decides nothing about business permissions. OAuth scope is the front door (checked twice: gateway + backend); application roles and ACLs live in each backend.
  • The static technical token can only reach catalog methods (src/contract/static-token.ts); every data method requires the end user's JWT.
  • Audit is pseudonymized by design (hashed email, hashed params). Pseudonymized is not anonymous: hashed identifiers remain personal data under GDPR Art. 4(5), so the audit trail stays in your record of processing and needs a retention period.
  • Sessions are bound to the token's sub; foreign session ids get 404.

Controls a federating gateway can enforce that a single server cannot. Because it sees every backend's tool definitions and every hop to them, the gateway is the place to catch what the ecosystem's incident reports keep finding — full details in docs/security.md:

  • Rug-pull detection. Tool definitions are fingerprinted (description, inputSchema, scope, version) at first sight and re-checked at every refresh. A backend that rewrites what a tool claims to do while keeping its name is reported, and with CORTEX_TOOL_INTEGRITY_MODE=block the tool is quarantined until an operator reviews it over /api/admin/tool-integrity — an HTTP endpoint, not an MCP tool, so a model cannot clear a rug pull on its own. Name-level change detection — what most implementations do — misses exactly this attack.
  • No plaintext to remote hosts. Every federated call forwards the caller's token, so an http:// backend URL pointing anywhere but loopback is refused at load. Same validation on the OAuth endpoints the adapter discovers from a third-party server's metadata, which is the class of bug behind CVE-2025-6514.
  • Attributable audit. Each line records which backend served the call and under which scope — not just the tool name.
  • Backends stay in their lane. A backend may only declare scopes under its own prefix and claim its own URI schemes; prompts are prefixed like tools. Resource reads are checked against the scope of the template the URI falls under, not only filtered at listing.

Honest scope: approvals persist across restarts (CORTEX_TOOL_BASELINE_FILE) and can be operator-signed, so this proves "this definition changed since you approved it here", not "this is the definition the vendor published".

Token forwarding, stated plainly. The caller's token is forwarded to the backend that serves the call, and its audience is the gateway. That is what removes the service account, and it means a federated backend is inside the trust boundary of the tokens it receives: one that is compromised could replay a token against the gateway. The gateway limits who receives it (only the serving backend, only backends the caller holds a scope on, never over plaintext); per-backend audiences through token exchange are on the roadmap. Details and recommendations: docs/security.md §6.

Compliance. These are the controls audits test for on automated access: least-privilege scopes, per-user identity (no over-privileged service account), a per-call attributable audit trail, and central revocation. They map to ISO 27001:2022 Annex A access-control and logging controls (A.5.15, A.5.16, A.5.17, A.5.18, A.8.2, A.8.15, A.8.16) and to SOC 2 CC6/CC7 — both of which apply today. The EU AI Act articles usually cited (Art. 12 record-keeping, Art. 14 human oversight) govern high-risk AI systems only, and after the 2026 Digital Omnibus those obligations were deferred to 2 Dec 2027 (stand-alone Annex III) and 2 Aug 2028 (Annex I embedded); most internal agent deployments are not high-risk, and a gateway is access infrastructure rather than an AI system. Self-hosted means the audit trail and token vault stay in your perimeter — no extra sub-processor under GDPR Art. 28, none in your SOC 2 scope. Cortex supplies the controls, not a certification. Full mapping: https://cortex-gateway.dev/answers/ai-agent-compliance-controls/

Development

bash
npm run typecheck   # tsc --noEmitnpm test            # vitestnpm run build       # prisma generate + next build

The database is optional in every environment: without CORTEX_DATABASE_URL the audit stays on stdout and gateway-local tickets are disabled.

License

MIT

来源:README.md,提交 87c04e5

工具

0
该服务器需要登录,因此 SourceWeft 无法在没有账号的情况下读取其工具,也未收录。已连接账号所能看到的内容可能因账号及其权限而异。

版本历史

1
  1. v0.2.0最新Sep 16, 2026

评分

已满足适用检查项的 85%

该评分衡量此收录条目的完整程度,依据注册中心条目、端点与公开来源计算得出。它不是对服务器本身的评价,也不表示服务器安全或当前可用:可连通性是带日期的检查结果,评分也不包含安装量或用户评价。

  • 近 30 天内可连通必需25 分
  • 已声明认证方式必需10 分
  • 已列出工具15 分

    请让服务器在无凭据时响应 tools/list,或发布可在沙箱中无凭据启动的软件包。

  • 描述必需15 分
  • 图标10 分
  • 文档15 分
  • 许可证10 分