SentinelMCP
Stateless enterprise policy firewall & token-cost proxy for MCP. It enforces identity, policy, and budget on every tool call.
README
SentinelMCP
Stateless enterprise policy firewall & token-cost proxy for MCP.
Drop it in front of any Model Context Protocol server. Every tool call gets checked for identity, policy, and budget before it reaches your infrastructure — no database, no sticky sessions, nothing new to operate at 3am.
The 2-minute problem
MCP made it trivial to wire an LLM agent up to real tools — databases, payment APIs, internal services. It did not ship a policy layer. If you've run an MCP server in production, you've probably already hit one of these:
Runaway loops. An agent gets stuck retrying a failing call, or a bad prompt sends it into a call-and-recall spiral. Nothing in the MCP spec stops it. You find out from the bill, not an alert.
Token budgets that don't exist until they explode. Nothing in a typical agent loop stops it from calling the same expensive tool hundreds of times in an hour. The common failure mode: a $40/day budget quietly becomes a $40k/month bill, and the first signal anyone gets is the invoice.
DNS-rebinding and confused-deputy risk. The Streamable HTTP transport spec requires Origin validation for exactly this reason — a malicious page can rebind DNS to reach a local MCP server your browser would otherwise block. Most self-hosted servers don't implement it. Stack a compromised or injected tool result on top, and "just add an MCP server" is a bigger attack surface than most teams have budgeted time to secure.
SentinelMCP won't stop a model from being tricked — no proxy can. What it does is make sure a tricked or runaway agent can't reach a tool it isn't allowed to call, blow through a budget nobody approved, or keep running once the numbers look wrong — without a human getting a say.
Key features
Zero-trust security
- Origin validation on every request — the DNS-rebinding mitigation the Streamable HTTP spec requires and most self-hosted servers skip. Loopback-only by default; explicit allowlist for anything else, override not extend.
- ID-JAG identity enforcement — real JWKS-backed JWT verification, asymmetric algorithms only (no HMAC-downgrade path), including the
resourceclaim binding that closes the confused-deputy hole: a token issued for one MCP server can't be replayed against another.
Token economics
- Structural token estimation — walks the actual JSON-RPC payload instead of
length / 4, pricing natural-language content and JSON structure at different, calibrated rates. Input measured exactly; output projected from a per-tool rolling average and trued up against the real response after every call. - 7-day sliding-window budgets per team, enforced against a fixed-memory circular buffer (168 hourly buckets) — bounded, no per-request log to prune, no unbounded growth under load.
- Spike detection independent of the hard cap — a sudden burst against a team's own recent baseline gets caught even while the cumulative total is nowhere near the limit. Catches the exponential-growth pattern before the raw budget does.
Human-in-the-loop, not hard failure
- A budget breach doesn't 500 the call. It returns
InputRequiredResult— a normal JSON-RPC success — carrying the projected overrun, the run-rate spike, and an HMAC-signed, request-boundresumeToken. POST /mcp/resumewith{ resumeToken, decision: "APPROVE" | "DENY", originalRequest }lets a human clear it. The token is bound to the exact call via a canonical-JSON hash of the request — approve this wire transfer, not whatever an agent decides to substitute next.- Delivery is transport-aware: the pause notice reaches the client over whichever channel the original call used.
Protocol support
- Streamable HTTP — the current MCP standard (spec 2025-03-26+), and the primary path.
- Legacy HTTP+SSE (spec 2024-11-05) for backward compatibility with clients that haven't migrated. Not the default; don't build new integrations against it.
Quickstart
git clone https://github.com/your-org/sentinelmcp.git
cd sentinelmcp
npm install
cp .env.example .env
Six required values in .env — everything else ships with a sane default:
| Variable | What it is |
|---|---|
MCP_UPSTREAM_URL |
The real MCP server SentinelMCP forwards allowed calls to |
JWKS_URI |
Your IdP's JWKS endpoint (Okta, Auth0, Azure AD, …) |
ID_JAG_ISSUER |
Expected iss claim on incoming ID-JAG tokens |
ID_JAG_AUDIENCE |
Expected aud claim |
ID_JAG_RESOURCE |
This gateway's resource identifier — the anti-confused-deputy binding |
HMAC_SECRET |
32+ random chars signing resume tokens — openssl rand -base64 32. Must be identical across every replica, or resume verification breaks depending on which one handles a given call. |
npm run build && npm start # production
# or, for local iteration:
npm run dev # tsx watch
Confirm it's alive:
curl http://localhost:8080/healthz
How it fits
flowchart LR
Client(["MCP Client<br/>Claude Desktop · Cursor · custom agent"])
subgraph Sentinel["SentinelMCP — stateless gateway"]
direction TB
Origin["Origin Guard<br/>DNS-rebinding check"]
Policy["Policy Gate<br/>tool denylist"]
Identity["Identity Gate<br/>ID-JAG · JWKS verify"]
Budget["Budget Gate<br/>sliding window + spike detect"]
Origin --> Policy --> Identity --> Budget
end
Upstream["Upstream MCP Server(s)"]
Resume["POST /mcp/resume<br/>HMAC-signed resumeToken"]
Client -->|"POST /mcp"| Origin
Budget -->|"allowed → forward"| Upstream
Upstream -->|"result"| Client
Budget -.->|"denied → paused<br/>InputRequiredResult"| Client
Client -.->|"human decides,<br/>out of band"| Resume
Resume -->|"APPROVE<br/>budget bypassed only —<br/>identity + policy still enforced"| Upstream
SentinelMCP sits in front of one or more upstream MCP servers as a reverse proxy. Every gate runs on every request; a denial short-circuits before the call ever reaches your tools. Only the budget gate can be bypassed, and only by an explicit, signed, single-call human approval — identity and policy are re-checked even on resume.
Two of the five subsystems keep state in memory (SSE session tracking and
the budget ledger) — the request/response path itself is stateless and
horizontally scalable behind a plain load balancer. See
docs/ENGINEERING.md for exactly which pieces, and
what that means for running more than one replica.
Quality
- 63 tests, 19 suites —
npm test. Unit coverage for the token estimator, the sliding-window budget algorithm (spike detection included, verified with an injectable clock rather than waiting real days), and the HMAC token service (round-trip, tampering, forged secrets, canonical-hash binding). Integration coverage runs the full request pipeline throughfastify.inject()against a real, ephemeral-port mock identity provider and mock upstream — no stubbed JWT verification, no mocked crypto. - Strict TypeScript —
strict,noUncheckedIndexedAccess,noImplicitOverride. Noanyin the source tree. - Zero test-framework dependencies — built on Node's own
node:test. - CI runs typecheck, the full suite, and a production build on every push, against Node 20 and 22.
The full engineering log — what's verified, every bug found during
development and how it was fixed, and every known limitation stated
plainly rather than glossed over — lives in
docs/ENGINEERING.md.
License
推荐服务器
Baidu Map
百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。
Playwright MCP Server
一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。
Magic Component Platform (MCP)
一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。
Audiense Insights MCP Server
通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。
VeyraX
一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。
graphlit-mcp-server
模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。
Kagi MCP Server
一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。
e2b-mcp-server
使用 MCP 通过 e2b 运行代码。
Neon MCP Server
用于与 Neon 管理 API 和数据库交互的 MCP 服务器
Exa MCP Server
模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。