Skip to main content

Overview

Some of the most popular agent surfaces are MCP clients with no pre-tool hook. Claude Desktop and Kimi run tools exclusively through Model Context Protocol servers and expose no place to run a policy check before a tool fires. Codex fires hooks for Bash but not for MCP calls. For this entire class of client, the enforcement point is the MCP transport itself. @sigilcore/mcp-proxy sits between the client and its MCP servers. Every tools/call request is evaluated against your operator’s warranty.md policy via Sigil Sign /v1/authorize before it reaches the real server, and is wrapped in a Sigil Intent Attestation. You change one line in your MCP client config to point a server at the proxy. No client code changes are required.
MCP client (Claude Desktop / Kimi / Codex MCP)
        ↓  tools/call
Sigil MCP Proxy (@sigilcore/mcp-proxy)
        ↓  POST /v1/authorize → Sigil Sign

APPROVED → request forwarded to the real MCP server
DENIED   → JSON-RPC error (-32001) returned to the client
PENDING  → call held for human approval, then resolved or timed out
What this governs. The proxy governs MCP tool calls only. It does not see a client’s built-in capabilities (Claude Desktop connectors and web search, Codex’s native Bash and file edits). Pair the proxy with a native hook where one exists: Codex hooks for Bash, Claude Code and Hermes for full tool coverage. The proxy is the right tool precisely where no native hook exists.

Quick Start

npm install -g @sigilcore/mcp-proxy
export SIGIL_API_KEY=sk_sigil_YOUR_KEY
npx @sigilcore/mcp-proxy -- npx @some/mcp-server
Get an API key at sigilcore.com/tools/keys and generate a signed policy at sigilcore.com/tools/warrant.

MCP Client Config

Wrap an existing server by changing one line in your MCP client config. The proxy launches and supervises the upstream server and authorizes every call to it. This form works in any client that reads a standard mcpServers block, including Claude Desktop, Kimi (kimi-cli / Kimi Code), and Codex MCP config.
{
  "mcpServers": {
    "postgres": {
      "command": "npx",
      "args": ["@sigilcore/mcp-proxy", "--", "npx", "@some/pg-mcp"]
    }
  }
}
For Codex, keep the Codex Bash hook for shell governance alongside the proxy so both surfaces Codex exposes are covered.

Configuration

Generate a starter config with npx @sigilcore/mcp-proxy --init. Precedence is CLI flags > environment variables > config file > defaults.
CLI FlagEnv VarConfig KeyDefault
--keySIGIL_API_KEY(env only)(required)
--sign-urlSIGIL_SIGN_URLsignUrlhttps://sign.sigilcore.com
--log-levelSIGIL_LOG_LEVELlogLevelinfo
--server-idserverIdderived from command/URL
--server-nameserverNamesame as serverId
--pending-timeoutSIGIL_PENDING_TIMEOUTpendingTimeout30000
--unsafe-bypass(CLI only)(CLI only)false
--remote
--portauto

Server Identity

  • serverId is the binding identity and is security-critical. It is used in the txCommit preimage and in policy evaluation. It is auto-derived from the package name (stdio) or the full URL (HTTP) when not set explicitly.
  • serverName is a display label for logs only and defaults to serverId.

Fail-Closed by Default

The proxy is fail-closed: when Sigil Sign is unreachable, tool calls are blocked. To allow ungoverned calls during a Sign outage, pass --unsafe-bypass. This option is intentionally CLI-only (no env var, no config key) so it is always visible in your MCP client config.
npx @sigilcore/mcp-proxy --unsafe-bypass -- npx @some/mcp-server
Every bypassed call emits an ungoverned_tool_call error-level log. Authentication failures (401) are never bypassed.

HTTP/SSE Transport

Proxy a remote MCP server with --remote:
npx @sigilcore/mcp-proxy --remote https://api.example.com/mcp
Remote servers often require auth. Configure upstream headers in your config file using environment variable references. Every header value must reference at least one $IDENTIFIER env var; raw secrets are rejected at load time.
{
  "upstream": {
    "headers": {
      "Authorization": "Bearer $UPSTREAM_TOKEN",
      "X-Custom-Header": "$CUSTOM_HEADER_VALUE"
    }
  }
}
A convenience shortcut for the Authorization header:
export SIGIL_UPSTREAM_AUTH="Bearer sk-abc123..."
npx @sigilcore/mcp-proxy --remote https://api.example.com/mcp

Extractors

Map tool arguments to Sigil policy fields in sigil.config.json so the right warranty.md rules apply. For example, route a fetch tool’s url argument to the web_fetch policy field and a write tool’s path argument to file_write:
{
  "extractors": {
    "fetch": { "url": "url" },
    "write_file": { "path": "path" }
  }
}

Error Codes

  • -32001 — Sigil policy denial (DENIED, fail-closed block, or hold timeout)
  • -32002 — Sigil authentication failure (invalid API key)

Conformance

The proxy is a client of the SOF enforcement specification, not a signer. It submits intents and acts on decisions; the authorization itself is issued by Sigil Sign or any conforming signer. The intent wire format is the same /v1/authorize contract used by every agent-hooks adapter, documented in Getting Started and sigil-attestations.

Source