MCP Gateway Quickstart (90 seconds)
vanzik v2.0updated view on github
You'll go from "Claude Desktop talks to MCP servers" to "Claude Desktop talks to MCP servers, gated by a policy file" in under 90 seconds.
By the end, every tool call Claude wants to make passes through Vanzik, is evaluated against a YAML policy, and shows up live on a dashboard you can approve / deny from.
Prerequisites#
- Claude Desktop installed: https://claude.ai/download
- Go 1.26+ (for
go install): https://go.dev/dl/ npx(Node.js 20+, a current LTS): https://nodejs.org/ — used to launch the upstream MCP servers
This walkthrough uses Claude Desktop. The same pattern works for Cursor,
Cline, Continue.dev, and Zed — see examples/ for ready
configs.
30 seconds — install Vanzik#
go install lictorate.com/vanzik/v2/cmd/vanzik@latest
go install lictorate.com/vanzik/v2/cmd/vanzik-mcp-gateway@latest
Confirm both binaries are on PATH:
which vanzik vanzik-mcp-gateway
# /Users/you/go/bin/vanzik
# /Users/you/go/bin/vanzik-mcp-gateway
If which finds nothing, add $(go env GOPATH)/bin to your shell's
PATH and re-source the rc file.
30 seconds — run the policy server#
Generate an API key and start the central Vanzik server with a default policy:
export VANZIK_API_KEY="$(openssl rand -hex 32)"
git clone https://github.com/lictorate/vanzik.git
vanzik server \
--policy vanzik/configs/default.yaml \
--dashboard \
--watch \
--api-key "$VANZIK_API_KEY"
Open the dashboard: http://127.0.0.1:8080/dashboard — log in with the API key you just exported. Leave this terminal running.
30 seconds — wire Claude Desktop#
In Claude Desktop, click menu → Settings → Developer → Edit Config to
open claude_desktop_config.json. Replace its contents with:
{
"mcpServers": {
"vanzik": {
"command": "vanzik-mcp-gateway",
"args": [
"--upstream", "fs:npx -y @modelcontextprotocol/server-filesystem /tmp",
"--guard-url", "http://127.0.0.1:8080",
"--policy", "/absolute/path/to/vanzik/configs/default.yaml",
"--policy-mode", "strict",
"--fail-mode", "deny"
],
"env": {
"VANZIK_API_KEY": "<paste the key from step 2 here>"
}
}
}
}
Replace /absolute/path/to/vanzik/configs/default.yaml with your
actual clone path. Claude Desktop does not expand shell variables in flag
strings, so put the API key in the env block. Without VANZIK_API_KEY
there, the gateway falls back to the key vanzik setup saved.
The exact file path of claude_desktop_config.json:
| OS | Path |
|---|---|
| macOS | ~/Library/Application Support/Claude/claude_desktop_config.json |
| Windows | %APPDATA%\Claude\claude_desktop_config.json |
Save, then fully quit and restart Claude Desktop (Cmd-Q on macOS, not just close the window).
Verify (the satisfying part)#
First create a file to read — in a terminal, not through Claude:
echo "hello from Vanzik" > /tmp/hello.txt
Open a new chat and ask:
"Read the file
/tmp/hello.txtand tell me what's in it."
Claude calls fs:read_text_file. The mcp_tool rule *:read_* allows
it and the filesystem rule for reads under /tmp/** allows the path, so
the call goes through. Watch the dashboard — an ALLOW event appears in
the live feed within a second.
Now ask Claude to write a file:
"Create
/tmp/new.txtcontaininghi."
The dashboard logs a DENY from the rule deny:mcp_tool:*:write_file
("Writes via MCP are blocked by default policy"). Claude reports that the
tool returned an error with that reason embedded. The filesystem server's
other write tools — edit_file, move_file, create_directory — are
denied the same way.
Finally:
"Read
/etc/passwd."
Also a DENY: /etc isn't on the filesystem read allow-list, so the
request falls through to default deny.
That's the loop. Every tool call → policy check → audit log → live dashboard. No agent code change required.
Next steps#
- Customize the policy:
docs/POLICY_REFERENCE.mdfor the full schema, includingrequire_approvalrules that pause the call until you click the dashboard's approve button. - Add more upstreams (github, fetch, slack, postgres):
docs/MCP_GATEWAY.md § Multi-upstreamand the official server catalog at https://github.com/modelcontextprotocol/servers. - Approval flow walkthrough:
docs/APPROVAL_WORKFLOW.mdshows howREQUIRE_APPROVALdecisions flow through Slack / webhooks / the dashboard. - Other MCP clients:
- Cursor:
examples/cursor-config.json - Cline (VS Code):
examples/cline-config.json - Continue.dev:
examples/continue-config.json - Zed:
examples/zed-config.json
- Cursor:
- Threat model. The gateway is wire-level for the configured upstreams — but an agent that controls its own runtime can still bypass it by pointing at a different MCP server. Read README § Limitations & Threat Model before you trust this as a last line of defense.