Skip to main content

Overview

Some agent surfaces expose tools through Model Context Protocol servers without a reliable native pre-tool boundary. For those routed calls, the enforcement point can be the MCP transport itself. Codex can also run hooks for supported MCP calls, but hook-process failures may still continue; the proxy is the stronger boundary for a server that is reachable only through it. @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.
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), other MCP servers, or any route that can bypass it. Pair it with a host hook where one exists, but treat that hook according to its documented failure boundary. No combination here implies universal coverage of a host’s native tools.

Quick Start

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.
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.

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.

Action taxonomy and enrichment

Each governed call uses the action mcp.<serverId>.<toolName>. The proxy keeps the binding identity in metadata.serverId, the tool name in metadata.toolName, and the complete tool arguments in metadata.arguments. Sign matches MCP policy against those exact metadata values. It does not split the action string because server IDs may contain dots, slashes, URLs, or scoped package names. The ## mcp block supports exact values and trailing * prefix wildcards:
Without a ## mcp block, all mcp.* actions are denied. Extractors may copy bounded tool arguments into policy fields, but those fields remain agent provenance unless the proxy runs behind a dedicated credential that the governed agent cannot read.

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.
Every bypassed call emits an ungoverned_tool_call error-level log. Authentication failures (401) are never bypassed. The proxy sets @sigilcore/agent-hooks failMode: "closed" explicitly. It handles the structured SIGIL_UNREACHABLE and failOpen result fields, so an English response message cannot turn an outage into an accidental approval.

Policy 2.2 and 2.3 result inspection

An inspection-enabled proxy can enforce Policy 2.2 or 2.3 after an exact covered tools/call completes and before its result reaches the client. Coverage comes only from exact response.web_fetch_tools and response.http_tools mappings under ## mcp. The deterministic local ruleset returns ALLOW or BLOCK; blocked disclosure carries no result content. This does not inspect ## tool_calls, built-in client features, MCP resources, prompts, subscriptions, or unknown methods. An inspection profile refuses those MCP methods, and cannot be combined with --unsafe-bypass. Policy 2.2 returns ALLOW or BLOCK. Policy 2.3 can also redact mapped UTF-8 ranges, use an authenticated operator-hosted scanner, and record time-bounded observe findings that never change disposition. Raw content stays inside the operator trust boundary and never reaches hosted Sigil Sign, the durable ledger, logs, metrics, traces, or hosted receipts. See Policy 2.3 response controls for the scanner boundary, rollback order, exact grammar, and limitations.

HTTP/SSE Transport

Proxy a remote MCP server as the upstream with --remote:
The published proxy is still client-facing over stdio. --remote changes the upstream transport; it does not expose a server-facing Streamable HTTP endpoint. Therefore the current package cannot itself be registered as a Cowork remote custom connector. That setup requires a separately deployed, authenticated Streamable HTTP gateway that applies the same authorization before forwarding each tools/call. 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.
A convenience shortcut for the Authorization header:

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:

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