@strixgov/mcp-proxy
v0.1.0
Published
Strix MCP Proxy — the distribution wedge for governed agent tool execution. Point your MCP client at the proxy instead of the underlying server; every callTool is intercepted, evaluated against policy, and emits a signed Ed25519 receipt. Designed so Mode
Downloads
99
Maintainers
Readme
@strixgov/mcp-proxy
The distribution wedge for governed agent tool execution. Point your MCP client at the proxy instead of the underlying server — every callTool becomes intercepted, evaluated against policy, and emits a signed Ed25519 receipt. Designed so Mode 3 enforcement is the v0.2.0 upgrade path, not a rewrite.
npm install -g @strixgov/mcp-proxy
strix-mcp-proxy --config ./proxy-config.jsonCompared to @strixgov/mcp-adapter, which is a library you integrate into
your own MCP server code: the proxy is a standalone process you run in
front of any existing MCP server, with zero changes to your tool
implementations. It's the "change your MCP endpoint" path — the lowest-friction
way to put Strix governance in front of an agent in production.
What it does
MCP Client ──stdio──▶ [strix-mcp-proxy] ──stdio──▶ Upstream MCP Server (Notion, GitHub, Filesystem, …)
▲
│
governMCPServer:
classify → policy → approval → receiptFor every incoming callTool:
- Classify the tool via the configured companion pack (heuristic fallback for unknown).
- Evaluate policy —
ALLOW/DENY/APPROVAL_REQUIRED. - Hold for an approver when policy demands it.
- Execute via the upstream MCP server (only on
ALLOW). - Sign an Ed25519 receipt — allowed or denied — verifiable against the public JWKS by
@strixgov/verifier.
Tool implementations are untouched. The MCP client (Claude Desktop, mcp-cli, IDE integration, your own code) doesn't need to know Strix exists — it just spawns this proxy in place of the upstream server.
5-line integration (Claude Desktop)
// ~/Library/Application Support/Claude/claude_desktop_config.json
{
"mcpServers": {
"notion": {
"command": "strix-mcp-proxy",
"args": ["--config", "/Users/you/strix-proxy/notion.json"]
}
}
}The config file at notion.json points the proxy at the real Notion MCP
server and sets your policy. See examples/notion-proxy-config.json
for a complete example.
Config file shape
{
"serverId": "notion", // namespace for capability ids
"upstream": {
"command": "npx",
"args": ["-y", "@notionhq/notion-mcp-server"]
},
"capabilities": "@strixgov/capabilities-mcp-common/notion", // import path
"policy": {
"rules": {
"mcp.notion.create_database": "DENY" // per-capability override
},
"riskOverrides": {
"LOW": "ALLOW",
"MEDIUM": "APPROVAL_REQUIRED",
"HIGH": "APPROVAL_REQUIRED",
"CRITICAL": "DENY"
},
"default": "DENY"
},
"approval": { "enabled": false },
"storagePath": "~/.strix-mcp-proxy/notion" // optional; JSONL receipts on disk
}capabilities can be either:
- a bare import path (
@strixgov/capabilities-mcp-common/notion,@strixgov/capabilities-mcp-common/github, etc.) — resolved at startup - an inline array of
McpCapabilityobjects (caller-managed classification)
CLI flags (no config file needed for simple cases)
strix-mcp-proxy \
--upstream-command npx \
--upstream-arg "-y" --upstream-arg "@notionhq/notion-mcp-server" \
--server-id notion \
--capabilities @strixgov/capabilities-mcp-common/notion \
--policy-default DENY \
--risk-low ALLOW \
--risk-medium APPROVAL_REQUIRED \
--risk-critical DENY \
--storage-path ~/.strix-mcp-proxy/notionRun strix-mcp-proxy --help for the full flag list.
What ships with the proxy
| Feature | v0.1.0 | v0.2.0 (planned) |
|---|---|---|
| MCP stdio transport (consumer side) | ✓ | — |
| MCP stdio transport (upstream side) | ✓ | — |
| MCP HTTP transport (either side) | — | ✓ |
| Companion-pack classification | ✓ | — |
| Heuristic fallback for unknown tools | ✓ | — |
| Fail-closed default policy | ✓ | — |
| Per-capability rules + risk overrides | ✓ | — |
| Approval gate (any approver implementation) | ✓ | — |
| Local-mode signed receipts (in-memory or JSONL) | ✓ | — |
| Connected mode (sync receipts to strixgov.com) | ✓ | — |
| Mode 1 (Observed) | ✓ | — |
| Mode 2 (Approval-Gated) | ✓ | — |
| Mode 3 (Capability-Enforced) — execution_authorization_v1 token mint + transport | — | ✓ |
| Posture B reference impl (HTTP outbound enforcement) | — | ✓ |
See docs/strategy/mcp-mode-ladder-v1.md
for the framing of Mode 1 / 2 / 3 and the exact public claim available
at each enforcement strength.
The upgrade path to Mode 3
Mode 3 — Capability-Enforced — is the upgrade, not a rewrite. The
v0.1.0 proxy already routes every outbound call through a single
buildUpstreamIface() seam in src/proxy.mjs. In v0.2.0 a new option
(mode: "enforced") will wrap that seam with the
execution_authorization_v1 token mint + transport step per
docs/architecture/mcp-mode-3-enforcement-v1.md.
Operators turn on Mode 3 by adding "mode": "enforced" to the config
file. Upstream MCP servers that opt in to validation (via
@strixgov/mcp-token-validator)
refuse to act on sensitive tools unless the token is present.
The cryptographic primitive is already shipped — see
@strixgov/mcp-token-validator.
v0.1.0 of the proxy does not mint these tokens yet; what it does is
make sure the seam exists so v0.2.0 plugs in cleanly.
Listening to receipts
import { startProxy } from "@strixgov/mcp-proxy";
const handle = await startProxy({
upstream: { command: "npx", args: ["-y", "@notionhq/notion-mcp-server"] },
serverId: "notion",
capabilities: notionCapabilities,
policy: { default: "DENY", riskOverrides: { LOW: "ALLOW" } },
onReceipt: (r) => {
console.log(r.decision, r.capabilityId, r.signature);
},
});Every receipt is byte-compatible with @strixgov/verifier:
npx @strixgov/verifier chain ~/.strix-mcp-proxy/notion/receipts.jsonlThe verifier has zero Strix runtime dependency. Strix is not on the trust path of receipt verification.
What this proxy is NOT
- Not an MCP server you call directly. It's a wrap of an existing MCP server. You need an upstream.
- Not a replacement for
@strixgov/mcp-adapter. The adapter is the library; the proxy is the standalone process. They share the same governance core (@strixgov/tool-gateway) and produce byte-identical receipts. - Not Mode 3 today. v0.1.0 ships Mode 1 + Mode 2. Mode 3 enforcement is the v0.2.0 upgrade path, designed for, but not implemented in, this release.
Security posture
See SECURITY.md for the security-team-facing
posture, including:
- Credential boundary — three deployment positions (proxy holds / proxy passes through / proxy never sees the credential) with the audit-posture trade-off of each.
- What the proxy stores — only signed receipts (with
invocationHash, NOT raw args), the gateway signing key, and policy config. Never auth credentials. Never raw tool args. - Process model — what happens on crash / mid-approval / disk full. Fail-closed at every boundary; the proxy will not start without a loadable signing key.
- Multi-tenant boundary — single-tenant by design in v0.1.0; run one proxy process per tenant for isolation.
- What the proxy does NOT govern — out-of-wrapper traffic, the agent's internal state, the upstream's own argument handling (SQL/command injection inside the upstream is the upstream's responsibility).
Report security issues via GitHub Security Advisory on
github.com/Strixgov/strix. The companion operator runbook at
docs/runbooks/operate-mcp-proxy.md
covers daily operations, receipt-log rotation, and upgrade
discipline.
License
Source-available under the Elastic License 2.0.
You may use, modify, and self-host the proxy internally — including in production — provided you do not offer it as a hosted or managed service to third parties.
If you run the proxy in a commercial product or want hosted approvals,
connected mode, retention, or compliance evidence packs, email
[email protected].
The trust primitives the proxy depends on
(@strixgov/verifier,
@strixgov/tool-gateway,
@strixgov/mcp-token-validator)
remain MIT-licensed. Strix is not on the trust path of receipt
verification or token validation — that property is unchanged by
this license boundary.
Requirements
- Node.js ≥ 18
- An upstream MCP server (stdio transport)
