ward

local MCP proxy: policy, redaction, approvals, traces, replay.

install

brew install oliver-morrow/tap/ward

path

client tools/call
  -> ward classify + CEL policy
  -> allow | redact | deny | require_approval
  -> upstream stdio/http
  -> sqlite trace
  -> replay server

demo

$ go build -o ./mock-mcp ./testdata/mock_mcp.go
$ ward proxy stdio --config examples/local-demo.yaml -- ./mock-mcp
Starting MCP server: ./mock-mcp []
Trace storage: ~/.ward/ward.db

> tools/call echo {"message":"hello ward"}
< allow    echo -> upstream
< result   {"text":"hello ward"}

> tools/call get_secret {"key":"demo"}
< allow    get_secret -> upstream
< redact   secret_value="[REDACTED]"

> tools/call write_file {"path":"/tmp/ward-demo","content":"unsafe"}
< deny     -32000 "Filesystem writes are blocked in the local demo"

> tools/call shell_exec {"command":"ls -la"}
< approve  appr_... waiting

$ ward approve appr_...
$ ward traces
tr_... tools/call allow | redact | deny | require_approval

$ ward replay serve tr_...