HALBERD
Every request must pass the gate.
A JSON-RPC firewall for MCP agents.
tools/call → policy → audit → upstream
The Sentry's Challenge
§Try Halberd in the browser
State your purpose, traveller.
The real internal/policy engine compiled to WebAssembly and running client-side. Pick a rule pack, paste a JSON-RPC envelope, and see what the sentry would do.
The Threats at the Gate
§The five named threat categories
Halberd v0.1 ships request- and response-side coverage for four of the five threats below, on both the HTTP and stdio transports.
Tool poisoning
A compromised MCP server slips role-tag spoofs, ANSI escapes, or zero-width Unicode into a tool response to hijack the agent's next turn.
The garrison: Response inspector strikes ANSI and zero-width Unicode in place.
Argument injection
The agent is induced to call a legitimate tool with hostile arguments: DROP TABLE, --upload-pack=…, statement chaining via ;--.
The garrison: Per-tool regex denylist, type checks, max-length, and allowlist enums.
Out-of-scope I/O
A narrow-purpose tool gets pushed to read /etc/shadow, hit a private IP, or write outside its sandbox.
The garrison: Path-traversal, absolute-path, and home-expansion patterns already deny on filesystem and git packs.
Capability creep
Mid-session, an MCP server pushes "tools/list_changed" and adds a tool the agent calls before any human reviews it.
The garrison: Tool inventory pinned to the bundle; any unknown tool is denied by default.
Exfiltration via response
A tool response carries AWS keys, GitHub tokens, or RSA private keys back into the model context.
The garrison: Built-in scanners redact aws_access_key, github_token, and rsa_private_key on the wire.
The Armory
§Bundled rule packs
Pre-forged bundles. Carry one to the gate, or forge your own.
Each pack is a YAML policy bundle calibrated against a specific MCP server. The DSL is intentionally narrow: type · max_length · allow_values · deny_patterns · response-side secret scanners.
The Gatehouse Keys
§Install Halberd at your own gate
Take these and stand a watch of your own.
Pre-built binaries ship for linux and darwin × amd64 and arm64. Each archive bundles all four binaries plus every rule pack.
Download a release
curl -L https://github.com/Builder106/Halberd/releases/latest/download/\
halberd_${VERSION}_${OS}_${ARCH}.tar.gz | tar -xz
./halberd versionBuild from source
brew install go git clone https://github.com/Builder106/Halberd && cd Halberd go build -o bin/ ./cmd/... ./bin/halberd lint policies/mcp-server-postgres.yaml
Wrap a local stdio server (Claude Desktop)
Edit ~/Library/Application Support/Claude/claude_desktop_config.json — point at halberd-stdio instead of the real server:
"mcpServers": {
"postgres": {
"command": "/usr/local/bin/halberd-stdio",
"args": [
"--policy", "/etc/halberd/postgres.yaml",
"--audit", "/var/log/halberd/postgres.jsonl",
"--", "mcp-server-postgres", "--conn-string", "postgresql://..."
]
}
}HTTP transport (remote MCP)
Sit between your agent and a remote MCP server:
halberd-http \ --policy policies/mcp-server-postgres.yaml \ --target http://upstream:8080 \ --listen :9090 \ --audit halberd.jsonl