MCP Integration
Enforce Control Zero policies on MCP tool calls across all MCP-compatible tools.
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. Every MCP tool call can be governed by your policies before execution.
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 enforces policies on MCP tool calls using the mcp.tool.call action and mcp://{server}/{tool} resource URIs. The SDK evaluates each tool call against your policies before the tool executes.
Agent -> MCP Tool Call -> Control Zero Policy Check -> Tool Execution
|
v (if denied)
PolicyDeniedError
MCP Server Setup
The Control Zero MCP server uses SSE (Server-Sent Events) transport. Start it as a hosted HTTP service that clients connect to remotely.
Running the Server
cd apps/mcp-server
npm install
npm run build
npm start
The server listens on http://localhost:3100/sse by default.
Running with Docker
docker build -t cz-mcp-server apps/mcp-server/
docker run -p 3100:3100 \
-e CZ_API_KEY=cz_live_your_key \
-e CZ_BACKEND_URL=http://your-server:8080 \
cz-mcp-server
Environment Variables
| Variable | Required | Default | Description |
|---|---|---|---|
CZ_API_KEY | Yes | -- | Your Control Zero project API key |
CZ_BACKEND_URL | No | http://localhost:8080 | Backend API URL |
PORT | No | 3100 | Server listen port |
Client Configuration
All clients connect to the MCP server via the SSE endpoint URL.
Claude Code
// .claude/settings.json
{
"mcpServers": {
"controlzero": {
"type": "sse",
"url": "http://localhost:3100/sse",
"headers": {
"X-API-Key": "cz_live_your_api_key_here"
}
}
}
}
Claude Desktop
// claude_desktop_config.json
{
"mcpServers": {
"controlzero": {
"type": "sse",
"url": "http://localhost:3100/sse",
"headers": {
"X-API-Key": "cz_live_your_api_key_here"
}
}
}
}
Cline
Add the Control Zero MCP server through the Cline settings panel in VS Code:
- Open Cline settings.
- Navigate to the MCP Servers section.
- Add a new SSE server with URL:
http://localhost:3100/sse
Cursor
Configure MCP servers in Cursor settings:
- Open Cursor settings (Cmd/Ctrl + ,).
- Search for "MCP" in the settings.
- Add a new SSE server with URL
http://localhost:3100/sse.
Windsurf
Windsurf supports MCP servers through its configuration:
- Open Windsurf settings.
- Add the Control Zero MCP server with type
sseand URLhttp://localhost:3100/sse.
SDK Integration
Python
import controlzero
cz = controlzero.ControlZero()
cz.initialize()
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.enforce(
action="mcp.tool.call",
resource=f"mcp://{server}/{tool}",
context={
"agent_id": "coding-agent",
"arguments": str(arguments),
},
)
# Policy check passed -- call the tool
return await mcp_client.call_tool(server, tool, arguments)
Go
func callMCPTool(ctx context.Context, server, tool string, args map[string]any) (any, error) {
err := cz.Enforce(ctx, controlzero.CheckRequest{
Action: "mcp.tool.call",
Resource: fmt.Sprintf("mcp://%s/%s", server, tool),
Context: map[string]string{
"agent_id": "coding-agent",
},
})
if err != nil {
return nil, err
}
return mcpClient.CallTool(ctx, server, tool, args)
}
Node.js
async function callMCPTool(server: string, tool: string, args: Record<string, any>) {
await cz.enforce({
action: 'mcp.tool.call',
resource: `mcp://${server}/${tool}`,
context: { agent_id: 'coding-agent' },
});
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"
}
]
}
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 servermcp://github/create_issue-- Creating a GitHub issuemcp://database/execute_query-- Running a database querymcp://shell/execute-- Executing a shell commandmcp://slack/send_message-- Sending a Slack message
Next Steps
- See the MCP Tool Control Guide for detailed patterns.
- Learn about Policies for writing governance rules.
- Explore the Python SDK, Go SDK, or Node.js SDK.