Korzen
Bot Protection

Your AI assistant (MCP)

Ask Claude, Codex or Cursor why a request was blocked or what attacked your site: a read-only MCP server reads your own dashboard's views with an MCP key.

Bot Protection has an MCP server: your AI assistant can read your dashboard's views and answer "why was this request blocked?", "what attacked /login yesterday?" or "which AIs read my site this week?". It reads the same data the dashboard shows you, of your own account alone. It is read-only: it changes no setting, calls no /v1/decide and sends nothing anywhere.

Make an MCP key

On the dashboard's Set-up page, under MCP keys, choose Create an MCP key. It starts with kz_mk_ and is shown once: copy it into your assistant's configuration. Anyone who can make an API key can make one. An MCP key is not an API key: it works only on the MCP server, and an API key is refused there. Keep it out of a repository, as you would any secret.

The server is at https://korzen.dev/bot-protection/mcp, over Streamable HTTP. Each client sends the key in the Authorization: Bearer header.

Connect your assistant

Claude Code

claude mcp add --transport http korzen https://korzen.dev/bot-protection/mcp \
  --header "Authorization: Bearer $KORZEN_MCP_KEY"

Claude Desktop

In claude_desktop_config.json (Settings, Developer, Edit config), through mcp-remote, which passes the header:

{
  "mcpServers": {
    "korzen": {
      "command": "npx",
      "args": ["-y", "mcp-remote", "https://korzen.dev/bot-protection/mcp", "--header", "Authorization:${KORZEN_MCP_HEADER}"],
      "env": { "KORZEN_MCP_HEADER": "Bearer kz_mk_..." }
    }
  }
}

Codex

In ~/.codex/config.toml, with the key in the environment variable KORZEN_MCP_KEY:

[mcp_servers.korzen]
url = "https://korzen.dev/bot-protection/mcp"
bearer_token_env_var = "KORZEN_MCP_KEY"

Cursor

In ~/.cursor/mcp.json, or .cursor/mcp.json in a project:

{
  "mcpServers": {
    "korzen": {
      "url": "https://korzen.dev/bot-protection/mcp",
      "headers": { "Authorization": "Bearer ${env:KORZEN_MCP_KEY}" }
    }
  }
}

The web connectors of Claude and ChatGPT ask for a sign-in with OAuth, which the server does not offer yet: use a client that takes a header, as above.

The tools

ToolWhat it reads
get_decisionone decision, by the request_id that /v1/decide answered: its class, bot score, kinds of evidence, country, network and crawler, as the Decisions page shows it, with your thresholds
list_decisionsthe Decisions page's rows, with its filters: find (a request ID, an IP or a User-Agent), path, class, country, asn, crawler, evidence, ua, since, older, and up to 50 rows by limit
attacksthe overview's attacks, with the window's decisions and bots; since is 24h, 7d or 30d
ai_trafficthe AI traffic page: which AI crawlers and assistants read your site, how often, and which pages; since as above

Each answer is JSON. What your visitors wrote, a path or a User-Agent's family, comes under visitor_supplied, with control, bidirectional and zero-width characters written as \u{...} escapes: a visitor can put words meant for your assistant in a User-Agent, and the server hands them over as data, never as an instruction. Keep your client's approval of tool calls on.

What the server never does

  • It never changes anything: no setting, no rule, no key, no plan.
  • It never reads another account's data: a key reads its own account alone.
  • It never calls /v1/decide, sends an event or counts as a decision: it is free.
  • It never sends your data to a third party, and never logs your key or what a tool answered: each call's log line keeps the tool, the names of its arguments and the size of the answer.
  • It never shows more than the dashboard does, nor how detection decides.

Limits

Each MCP key makes up to 60 calls a minute and 2,000 a day; past them the server answers 429 with RateLimit and Retry-After headers. A call answers within 5 seconds, or says it took too long. An account holds up to 25 MCP keys.

Revoke a key

On the Set-up page, each MCP key shows when it was made and when it was last used, to the minute. Revoke stops it at once: the assistant's next call is refused with 401. Your API keys and your server's calls are not affected.