Deploy it once. Point every agent at the firewall.
Base URL: https://firewall.veil-api.com. The hosted service speaks HTTP JSON-RPC, and the local bridge handles stdio for MCP-native clients.
1. Create a key
curl -X POST https://firewall.veil-api.com/v1/keys/create \
-H "Content-Type: application/json" \
-d '{"email":"security@acme.com","tenant_name":"Acme"}'
2. Register a server
curl -X POST https://firewall.veil-api.com/admin/servers \
-H "Authorization: Bearer ADMIN_KEY" \
-H "Content-Type: application/json" \
-d '{
"tenant_slug":"acme",
"server_key":"filesystem",
"name":"Filesystem MCP",
"upstream_url":"https://mcp.example.com"
}'
3. Start proxying
POST /v1/mcp/proxy/acme/filesystem
Authorization: Bearer vf_...
Content-Type: application/json
{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}
Inspection
POST /v1/mcp/inspect
Use this when you want an explicit allow, deny, modify, or review decision before making a tool call.
Proxy
POST /v1/mcp/proxy/{tenant_slug}/{server_key}
Use this when you want the firewall to sit directly in the request path and enforce policy automatically.
Dashboard API
GET /v1/dashboard/summary GET /v1/dashboard/audits GET /v1/dashboard/servers
These power the tenant dashboard and can also feed your own internal reporting UI.
Canonical request shape
curl -X POST https://firewall.veil-api.com/v1/mcp/inspect \
-H "Authorization: Bearer YOUR_FIREWALL_KEY" \
-H "Content-Type: application/json" \
-d '{
"tenant_slug":"acme",
"server":{"key":"filesystem","name":"Filesystem MCP","upstream_url":"https://mcp.example.com"},
"tool":{"name":"write_file","description":"Write content","input_schema":{"type":"object"}},
"call":{"arguments":{"path":"/tmp/demo.txt","content":"Sarah Connor "}},
"response_preview":{"ok":true}
}'
{
"verdict": "modify",
"reason": "PII or secret material was redacted before release",
"policy_hits": ["pii_action:redact"],
"detections": [...],
"modified_call": {
"path": "/tmp/demo.txt",
"content": "<<VEIL_PERSON_...>> <<VEIL_EMAIL_ADDRESS_...>>"
},
"audit_id": 71
}
Tenant policy shape
{
"allowlist_tools": ["read_file", "search_docs"],
"blocklist_tools": ["delete_file"],
"allowlist_domains": ["api.notion.com", "docs.acme.com"],
"max_data_size": 75000,
"pii_action": "redact",
"require_approval": ["send_email", "publish_page"]
}
Use the stdio bridge as the MCP command
{
"command": "veil-firewall-stdio",
"args": ["--base-url", "https://firewall.veil-api.com"],
"env": {
"VEIL_FIREWALL_API_KEY": "vf_...",
"VEIL_FIREWALL_TENANT": "acme",
"VEIL_FIREWALL_SERVER": "filesystem"
}
}
The bridge preserves MCP stdio framing and forwards each JSON-RPC message to the hosted firewall proxy.
Add a firewall-backed server entry
{
"mcpServers": {
"filesystem-firewall": {
"command": "veil-firewall-stdio",
"args": ["--base-url", "https://firewall.veil-api.com"],
"env": {
"VEIL_FIREWALL_API_KEY": "vf_...",
"VEIL_FIREWALL_TENANT": "acme",
"VEIL_FIREWALL_SERVER": "filesystem"
}
}
}
}
Direct HTTP JSON-RPC proxying
curl -X POST https://firewall.veil-api.com/v1/mcp/proxy/acme/filesystem \
-H "Authorization: Bearer YOUR_FIREWALL_KEY" \
-H "Content-Type: application/json" \
-d '{
"jsonrpc":"2.0",
"id":42,
"method":"tools/call",
"params":{
"name":"write_file",
"arguments":{"path":"/tmp/demo.txt","content":"Sarah Connor "}
}
}'
Cloud Run deployment
./scripts/deploy_cloud_run.sh ./scripts/smoke_test.sh https://firewall.veil-api.com YOUR_FIREWALL_KEY
The deploy script targets `veil-api-prod`, deploys `veil-firewall` to Cloud Run in `us-central1`, and wires shared secrets plus firewall-specific env vars.