Skip to main content

MCP Integration

Wrap MCP calls with the SDK for deterministic enforcement, or offer cooperative policy checks to MCP clients.

Overview​

The Model Context Protocol (MCP) is an open standard for connecting AI models to external tools and data sources. Control Zero is built with MCP as a first-class integration point. An SDK wrapper using an enforcing guard() call blocks a denied MCP tool call before it executes. MCP Guard exposes the same decision as a cooperative check when application code cannot host the SDK.

This integration covers all tools that support MCP servers, including:

  • Claude Code (Anthropic's CLI coding tool)
  • Cline (VS Code AI coding extension)
  • Cursor (AI-powered IDE)
  • Windsurf (AI-powered IDE by Codeium)
  • Any MCP-compatible client

How It Works​

Control Zero uses the mcp.tool.call action and mcp://{server}/{tool} resource URIs. When application code calls guard(..., raise_on_deny=True), a deny raises PolicyDeniedError before tool execution. MCP Guard returns the decision to the client and remains cooperative.

Agent -> MCP Tool Call -> Control Zero Policy Check -> Tool Execution
|
v (if denied)
PolicyDeniedError

MCP Server Setup​

The Control Zero MCP server is published to the Control Zero npm registry as @controlzero/mcp-server and uses stdio transport. It carries the management tools and the cooperative check tool; see MCP Server for the tool list and MCP Cooperative Guard for check.

Installation​

Configure the Control Zero registry once: add @controlzero:registry=https://npm.controlzero.ai to your .npmrc (or run npm config set @controlzero:registry https://npm.controlzero.ai). It applies to npm install and npx for the whole @controlzero scope.

# Install globally
npm install -g @controlzero/mcp-server

# Or run directly without installing:
npx -p @controlzero/mcp-server controlzero-mcp

Environment Variables​

VariableRequiredDescription
CONTROLZERO_MGMT_KEYFor management toolsManagement key (cz_mgmt_*)
CONTROLZERO_API_KEYFor checkEnforcement key (cz_live_* or cz_test_*) for the project
CONTROLZERO_API_URLNoAPI base URL, default https://api.controlzero.ai

Set whichever keys the tools you use need. The examples below set both.

Client Configuration​

All clients launch the MCP server as a local stdio process.

Claude Code​

Add to .claude/settings.json:

{
"mcpServers": {
"controlzero": {
"command": "controlzero-mcp",
"env": {
"CONTROLZERO_MGMT_KEY": "cz_mgmt_your_key_here",
"CONTROLZERO_API_KEY": "cz_live_your_api_key_here"
}
}
}
}

Claude Desktop​

Add to claude_desktop_config.json:

{
"mcpServers": {
"controlzero": {
"command": "controlzero-mcp",
"env": {
"CONTROLZERO_MGMT_KEY": "cz_mgmt_your_key_here",
"CONTROLZERO_API_KEY": "cz_live_your_api_key_here"
}
}
}
}

Cline​

Add the Control Zero MCP server through the Cline settings panel in VS Code:

  1. Open Cline settings.
  2. Navigate to the MCP Servers section.
  3. Add a new stdio server with command: controlzero-mcp and set CONTROLZERO_MGMT_KEY and/or CONTROLZERO_API_KEY in the environment.

Cursor​

Configure MCP servers in Cursor settings:

  1. Open Cursor settings (Cmd/Ctrl + ,).
  2. Search for "MCP" in the settings.
  3. Add a new stdio server with command controlzero-mcp and environment variables CONTROLZERO_MGMT_KEY and/or CONTROLZERO_API_KEY.

Windsurf​

Windsurf supports MCP servers through its configuration:

  1. Open Windsurf settings.
  2. Add the Control Zero MCP server with command controlzero-mcp and set CONTROLZERO_MGMT_KEY and/or CONTROLZERO_API_KEY in the environment.

SDK Integration​

Python​

from controlzero import Client

cz = Client(api_key="cz_live_your_api_key_here")

async def call_mcp_tool(server: str, tool: str, arguments: dict) -> dict:
"""Call an MCP tool with policy enforcement."""

# Enforce the policy before calling the tool
cz.guard(
f"{server}/{tool}",
args={"agent_id": "coding-agent", "arguments": str(arguments)},
raise_on_deny=True,
)

# Policy check passed. Call the tool
return await mcp_client.callTool(server, tool, arguments)

Node.js​

function callMCPTool(server: string, tool: string, args: Record<string, any>) {
cz.guard(server, { method: tool, args, raiseOnDeny: true });

return mcpClient.callTool(server, tool, args);
}

Example Policy​

Control which MCP tools agents can use:

{
"name": "mcp-tool-governance",
"rules": [
{
"effect": "allow",
"action": "mcp.tool.call",
"resource": "mcp://filesystem/read_file"
},
{
"effect": "allow",
"action": "mcp.tool.call",
"resource": "mcp://filesystem/list_directory"
},
{
"effect": "deny",
"action": "mcp.tool.call",
"resource": "mcp://filesystem/write_file"
},
{
"effect": "deny",
"action": "mcp.tool.call",
"resource": "mcp://shell/execute"
},
{
"effect": "allow",
"action": "mcp.tool.call",
"resource": "mcp://database/read_query"
},
{
"effect": "deny",
"action": "mcp.tool.call",
"resource": "mcp://database/write_query"
}
]
}

When applied by the SDK wrapper shown above, this policy allows agents to read files and query databases, but blocks file writes and shell execution.

MCP Resource URI Format​

Control Zero uses a consistent URI format for MCP resources:

mcp://{server_name}/{tool_name}

Examples:

  • mcp://filesystem/read_file: Reading a file through the filesystem MCP server
  • mcp://github/create_issue: Creating a GitHub issue
  • mcp://database/execute_query: Running a database query
  • mcp://shell/execute: Executing a shell command
  • mcp://slack/send_message: Sending a Slack message

Next Steps​