Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Agent Integration & Test Guide

🌐 中文版:Agent 接入与测试指南

Put Vigils in front of your AI agent’s tools, so every tool call your agent makes is firewalled (default-deny), audited (tamper-evident hash chain), redacted (secrets / PII), and — when risky — sent to approval. Everything runs locally; nothing leaves your machine.

Works with any MCP-capable agent: Claude Code, Codex, Cursor, Zed, OpenCode, Continue, and more.

How it works

Vigils runs as an MCP gateway: your agent connects to vigil-hub over stdio, and vigil-hub proxies your real MCP tool servers (“upstreams”), gating every call.

┌──────────────────┐   stdio JSON-RPC   ┌────────────────────┐      ┌──────────────────┐
│  Your agent      │◄──────────────────►│  vigil-hub serve   │─────►│ Upstream MCP      │
│  Claude Code /   │                    │   --stdio          │      │ servers           │
│  Codex / Cursor /│                    │  ┌──────────────┐  │      │ (filesystem,      │
│  Zed / ...       │                    │  │ Firewall     │  │      │  github, db, ...) │
└──────────────────┘                    │  │ Audit ledger │  │      └──────────────────┘
                                        │  │ Redaction    │  │
                                        │  │ Approval     │  │
                                        │  └──────────────┘  │
                                        └────────────────────┘

Each upstream’s tools are namespaced with a __ (double-underscore) separator — <server>__<tool>, e.g. fs__read_file, github__create_issue — and aggregated into the tools/list your agent sees. When the agent calls one, Vigils evaluates it against the firewall before forwarding, records a decision in the audit ledger, and either allows it, denies it, or queues it for your approval.

Prerequisites

Install the CLI gateway, vigil-hub:

  • Prebuilt: download vigils-cli-<target>.tar.gz (.zip on Windows) from the latest release — it contains vigil-hub and vigil-native-host. Put vigil-hub on your PATH.
  • From source: cargo install --path apps/vigil-hub-cli

Verify: vigil-hub --help

Fastest path — Claude Code, one command (setup --all)

If you use Claude Code, you don’t need to hand-write configs at all. One command detects your setup and protects everything — your existing config is backed up and only Vigils’ own entries are added (fully reversible):

vigil-hub setup --all

setup --all wires up both layers:

  1. Native-tool input guard — a PreToolUse hook so every tool call (Bash, Edit, Write, Read, MCP tools, …) is checked before it runs; a real credential heading into a tool is blocked fail-closed and audited.
  2. MCP gateway — rewrites each of your stdio MCP servers to run through Vigils, so secrets in tool results are scrubbed before the model sees them and every call is audited. Defaults to monitor posture (your servers stay usable; raw-secret block, result redaction, and audit stay on). Add --enforce for default-deny gating.
vigil-hub setup --mcp --doctor    # pre-flight: will each wrapped MCP server actually start? (read-only PATH check)
vigil-hub inspect protection      # after using your agent: what Vigils caught (secrets blocked, leaks redacted, chain intact)
vigil-hub setup --all --uninstall # remove everything (config restored byte-for-byte)

Restart Claude Code and you’re protected. The rest of this guide is the manual path — use it for non-Claude agents (Codex / Cursor / Zed / …) or when you want explicit control over the serve gateway and its upstreams.json.

Step 1 — Smoke-test vigil-hub (30s, no agent needed)

Confirm the gateway speaks MCP before wiring any agent. Pipe an initialize + tools/list into it (MCP stdio is newline-delimited JSON-RPC):

printf '%s\n' \
 '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-03-26","capabilities":{},"clientInfo":{"name":"smoke","version":"0"}}}' \
 '{"jsonrpc":"2.0","id":2,"method":"tools/list"}' \
 | vigil-hub serve --stdio --ledger ./vigil.db

Expected stdout (two JSON-RPC responses):

{"id":1,"jsonrpc":"2.0","result":{"capabilities":{"tools":{"listChanged":false}},"protocolVersion":"2025-06-18","serverInfo":{"name":"vigil-hub","version":"0.1.7"}}}
{"id":2,"jsonrpc":"2.0","result":{"tools":[]}}

tools/list is empty because no upstreams are configured yet (next step). Startup banners go to stderr (stdout is reserved for the protocol).

Step 2 — Declare your tool servers (upstreams.json)

List the MCP servers you want Vigils to proxy. Bare commands resolve via PATH.

{
  "upstreams": [
    { "name": "fs",     "argv": ["npx", "-y", "@modelcontextprotocol/server-filesystem", "/data"] },
    { "name": "github", "argv": ["npx", "-y", "@modelcontextprotocol/server-github"] }
  ]
}

Pass it to serve:

vigil-hub serve --stdio --ledger ./vigil.db --upstream-config ./upstreams.json

For each entry Vigils registers the server, pins its launch command, and runs a gate-before-spawn check (argv + resolved-program drift) before starting the child process — then namespaces its tools (fs__…, github__…) into tools/list.

HTTP / remote MCP servers use OAuth onboarding instead: vigil-hub add-remote-mcp --url https://mcp.example.com/ --client-id <id> --scopes mcp:tools.read

Step 3 — Point your agent at vigil-hub

Use a shared ledger path so the desktop app and CLI see the same audit trail. The desktop app reads data_local_dir()/Vigil/ledger.sqlite3:

  • Windows: %LOCALAPPDATA%\Vigil\ledger.sqlite3
  • Linux: ~/.local/share/Vigil/ledger.sqlite3
  • macOS: ~/Library/Application Support/Vigil/ledger.sqlite3

The filename must be exactly ledger.sqlite3 (with the 3) and the directory must be data_local_dir() — a path mismatch means the desktop reads a different file and the Activity Feed stays empty. Easiest path: run vigil-hub setup --mcp / setup --all, which auto-targets this shared ledger. Do not omit --ledger on a manual serve --stdio — that uses an in-memory ledger the desktop can’t see. serve/wrap print the resolved ledger path on startup, so you can compare it with the desktop’s.

In the snippets below, replace the --ledger / --upstream-config paths and the vigil-hub path (use the absolute .exe path on Windows, e.g. C:\\Vigil\\vigil-hub.exe).

Claude Code

Project .mcp.json (or user-level ~/.claude.jsonmcpServers):

{
  "mcpServers": {
    "vigil": {
      "command": "vigil-hub",
      "args": ["serve", "--stdio", "--ledger", "~/.local/share/Vigil/ledger.sqlite3", "--upstream-config", "./upstreams.json"]
    }
  }
}

Run /mcp in Claude Code — vigil should show connected, with your upstream tools under it.

Codex (OpenAI Codex CLI)

~/.codex/config.toml (or project .codex/config.toml):

[mcp_servers.vigil]
command = "vigil-hub"
args = ["serve", "--stdio", "--ledger", "~/.local/share/Vigil/ledger.sqlite3", "--upstream-config", "./upstreams.json"]

Cursor

~/.cursor/mcp.json (or project .cursor/mcp.json):

{ "mcpServers": { "vigil": { "command": "vigil-hub", "args": ["serve", "--stdio", "--upstream-config", "./upstreams.json"] } } }

Zed

~/.config/zed/settings.json:

{ "context_servers": { "vigil": { "command": { "path": "vigil-hub", "args": ["serve", "--stdio", "--upstream-config", "./upstreams.json"] } } } }

OpenCode

Project opencode.json:

{ "mcp": { "vigil": { "type": "local", "command": ["vigil-hub", "serve", "--stdio", "--upstream-config", "./upstreams.json"], "enabled": true } } }

Continue (VS Code / JetBrains)

~/.continue/config.yaml:

mcpServers:
  - name: vigil
    command: vigil-hub
    args: ["serve", "--stdio", "--upstream-config", "./upstreams.json"]

Step 4 — Verify it’s actually gating

After your agent runs a tool call (or trigger one yourself), inspect the local ledger. inspect prints single-line JSON — pipe to jq:

vigil-hub inspect --db-path ./vigil.db protection            # at-a-glance: secrets blocked, leaks redacted, chain intact
vigil-hub inspect --db-path ./vigil.db activity --limit 20   # recent events / decisions
vigil-hub inspect --db-path ./vigil.db search "read_file"     # full-text search the trail
vigil-hub inspect --db-path ./vigil.db approvals list         # risky calls awaiting you
vigil-hub inspect --db-path ./vigil.db verify-chain           # tamper-evident chain check
# → {"kind":"ChainVerification","data":{"ok":true,"broken_at_event_id":null,"message":null}}

Or open the Vigils desktop app for a live view: Activity Feed, Approval Queue (approve / deny), Server Registry, Session Replay, and Privacy Findings.

What “gating” looks like: with the default firewall (deny-by-default), a risky tool call is either denied outright or surfaced in the Approval Queue — your agent’s call blocks until you approve. The decision is recorded in activity.

Optional — turn on the ML privacy filter

By default Vigils uses fast hard-fingerprint rules (no ML). To add the ONNX PII scanner, build the CLI with the ort feature and pass --enable-privacy-filter:

cargo install --path apps/vigil-hub-cli --features ort
vigil-hub serve --stdio --upstream-config ./upstreams.json --enable-privacy-filter

If the flag is set but the binary wasn’t built with --features ort, startup fails closed (it never silently runs without the filter you asked for).

Troubleshooting

  • command not found / agent can’t start vigil-hub — use the absolute path to vigil-hub (vigil-hub.exe on Windows) in the config; verify with vigil-hub --version.
  • Agent connects but no tools — you haven’t passed --upstream-config, or the file lists no upstreams. Add your upstreams.json.
  • An upstream fails to start — make sure its argv runs standalone and that npx/node (or whatever it needs) is on PATH.
  • Desktop app doesn’t show events — point --ledger at the same path the desktop app uses (Step 3), writable by the agent’s child process.
  • Garbled bytes in the agent log — nothing but JSON-RPC may go to stdout; vigil-hub keeps all banners on stderr.

References