Skip to main content
Glama
WAF MCP Server

WAF MCP Server

by KratosUAE

WAF MCP Server

An MCP (Model Context Protocol) server for managing OWASP ModSecurity CRS via Docker. Gives AI assistants like Claude direct access to WAF monitoring, analysis, and configuration through a structured drill-down pipeline.

Built for Claude Code but works with any MCP-compatible client.

Why

LLM proxy services (LiteLLM, OpenRouter, etc.) sit behind WAFs that generate massive amounts of false positives — prompts contain code, SQL, HTML, shell commands that trigger every content-inspection rule in the book. Managing these WAFs requires constant monitoring, tuning exclusions, and investigating events.

This MCP server lets an AI assistant do that work directly:

  1. Overview — see total events, unique IPs, active rules at a glance

  2. Drill down — filter events by IP or rule, inspect matched data

  3. Act — disable rules, whitelist IPs, change engine mode — all without leaving the conversation

Related MCP server: Docker MCP Server

Tools

Analysis (drill-down pipeline)

Tool

Description

waf_overview

Dashboard: total events, unique IPs/rules, events last hour

waf_top_ips

Top IPs by event count with geo enrichment (ipinfo.io)

waf_top_rules

Most triggered rules with severity and description

waf_fp_candidates

Rules that fired on HTTP 2xx responses (false positive candidates)

waf_events_by_ip

Events filtered by source IP

waf_events_by_rule

Events filtered by rule ID

waf_event_detail

Full event: headers, request body, all rule matches with matched data

Actions

Tool

Description

waf_status

Container health, engine mode, rules loaded, paranoia level

waf_set_engine

Switch between On, Off, DetectionOnly

waf_set_paranoia

Set CRS paranoia level (1–4)

waf_disable_rule

Disable a rule by ID (adds SecRuleRemoveById to exclusions)

waf_enable_rule

Re-enable a previously disabled rule

waf_allow_ip

Whitelist an IP (bypass WAF entirely)

waf_deny_ip

Remove an IP from whitelist

waf_test

Run test suite: scanner detection, SQLi, XSS, path traversal

Common parameters

since — All analysis tools accept a since parameter to control the time window. Default is "24h". Supports Docker duration syntax: "1h", "24h", "7d", "30m". Days are automatically converted to hours (Docker's --since doesn't support the d suffix natively).

waf_overview(since: "7d")        # last 7 days
waf_events_by_ip(ip: "1.2.3.4", since: "1h")  # last hour

verbose — waf_events_by_ip, waf_events_by_rule, and waf_event_detail accept verbose: true. By default, matchedData and requestBody are truncated to keep responses within context limits:

Field

Default

Verbose

matchedData (per rule)

150–200 chars

4000 chars

requestBody

500 chars

8000 chars

Prerequisites

  • Docker with a running owasp/modsecurity-crs container

  • Docker Compose managing the ModSecurity container

  • Node.js 18+

  • ModSecurity configured with JSON Serial audit log (SecAuditLogFormat JSON)

Installation

git clone https://github.com/KratosUAE/waf_mcp.git
cd waf_mcp
npm install
npm run build

Configuration

Environment variables

Variable

Required

Default

Description

WAF_COMPOSE_DIR

Yes

—

Path to directory containing docker-compose.yml

WAF_DOMAIN

No

https://localhost

Domain for WAF test requests

WAF_LOGS_SINCE

No

24h

Default time window for log queries

WAF_CONTAINER_PATTERN

No

modsecurity

Grep pattern to find the ModSecurity container

WAF_EXCLUSIONS_FILE

No

modsecurity/REQUEST-900-EXCLUSION-RULES-BEFORE-CRS.conf

Path to CRS exclusions file (relative to compose dir)

WAF_COMPOSE_FILE

No

docker-compose.yml

Docker Compose filename

IPINFO_TOKEN

No

—

ipinfo.io token for IP geolocation

WAF_DEBUG

No

—

Set to any value to enable debug logging

Connect to Claude Code

claude mcp add --transport stdio --scope user \
  -e WAF_COMPOSE_DIR=/path/to/your/compose/dir \
  -e WAF_DOMAIN=https://your-domain.com \
  waf -- node /path/to/waf_mcp/dist/index.js

Or manually add to ~/.claude.json:

{
  "mcpServers": {
    "waf": {
      "type": "stdio",
      "command": "node",
      "args": ["/path/to/waf_mcp/dist/index.js"],
      "env": {
        "WAF_COMPOSE_DIR": "/path/to/your/compose/dir",
        "WAF_DOMAIN": "https://your-domain.com"
      }
    }
  }
}

Docker Compose setup

The server expects a ModSecurity container managed by Docker Compose. Example service definition:

modsecurity:
  image: owasp/modsecurity-crs:nginx-alpine
  environment:
    - BACKEND=http://your-app:8080
    - MODSEC_RULE_ENGINE=DetectionOnly
    - MODSEC_AUDIT_LOG=/dev/stderr
    - MODSEC_AUDIT_LOG_FORMAT=JSON
    - MODSEC_AUDIT_LOG_TYPE=Serial
    - MODSEC_AUDIT_ENGINE=RelevantOnly
    - MODSEC_REQ_BODY_ACCESS=On
    - MODSEC_REQ_BODY_LIMIT=52428800
    - MODSEC_RESP_BODY_ACCESS=Off
    - PARANOIA=1
    - ANOMALY_INBOUND=5
  volumes:
    - ./modsecurity/REQUEST-900-EXCLUSION-RULES-BEFORE-CRS.conf:/etc/modsecurity.d/owasp-crs/rules/REQUEST-900-EXCLUSION-RULES-BEFORE-CRS.conf:ro

Key settings:

  • MODSEC_AUDIT_LOG=/dev/stderr — sends audit log to Docker logs (required for the MCP server to read events)

  • MODSEC_AUDIT_LOG_FORMAT=JSON — JSON format for structured parsing

  • Exclusions file mount — allows hot-reload of rule exclusions via nginx -s reload

CRS exclusions for LLM traffic

LLM API endpoints receive prompts containing code, SQL, HTML, and shell commands — all legitimate content that triggers WAF rules. Create an exclusions file to disable content-inspection rules on API paths:

# modsecurity/REQUEST-900-EXCLUSION-RULES-BEFORE-CRS.conf
SecRule REQUEST_URI "@rx ^(/v1/)?(chat/completions|completions|embeddings|responses|messages)|^/anthropic/" \
    "id:1000,phase:1,nolog,pass,\
    ctl:ruleRemoveById=921000-944999"

This disables rules 921000–944999 (all content-inspection categories: SQLi, XSS, RCE, LFI, RFI, etc.) on LLM API endpoints while keeping protocol enforcement, scanner detection, DoS protection, and IP reputation checks active.

Usage example

Typical workflow in Claude Code:

You: "Check the WAF — anything suspicious?"

Claude: [calls waf_overview]
  → 332 events, 4 unique IPs, 12 rules triggered

Claude: [calls waf_top_ips]
  → 135.237.83.23 (Washington, US, Microsoft) — 320 events

Claude: [calls waf_events_by_ip, ip: "135.237.83.23", count: 5]
  → All POST /chat/completions, HTTP 200, rules: 942360, 932100...

Claude: [calls waf_event_detail, index: 42]
  → User-Agent: OpenAI/JS 6.26.0, body contains tool descriptions
  → Rule 942360 matched "update" in cron action descriptions

Claude: "This is your OpenClaw bot — all false positives.
         Want me to whitelist this IP?"

You: "Yes"

Claude: [calls waf_allow_ip, ip: "135.237.83.23"]
  → Done. IP whitelisted.

Investigating older events:

You: "Check IP 185.206.249.230 — it was flagged yesterday"

Claude: [calls waf_events_by_ip, ip: "185.206.249.230", since: "7d"]
  → 2 events from Apr 7, GET /v1/skills, HTTP 401, no rules triggered
  → Apple Private Relay IP (Singapore), just unauthorized API probes

Development

npm run build        # Compile TypeScript
npm test             # Run tests (43 tests)
npm run test:watch   # Watch mode
WAF_DEBUG=1 npm start  # Run with debug logging

Architecture

src/
├── index.ts           # MCP server setup, tool registration
├── waf-manager.ts     # Core service: Docker exec, log parsing, config management
├── types.ts           # TypeScript interfaces
├── config.ts          # Environment-based configuration
├── logger.ts          # stderr-only logger (stdout reserved for MCP protocol)
└── tools/
    ├── overview.ts        # L0: dashboard
    ├── top-ips.ts         # L1: IP aggregation
    ├── top-rules.ts       # L1: rule aggregation
    ├── fp-candidates.ts   # L1: false positive detection
    ├── events-by-ip.ts    # L2: drill-down by IP
    ├── events-by-rule.ts  # L2: drill-down by rule
    ├── event-detail.ts    # L3: full event inspection
    ├── status.ts          # Container status
    ├── set-engine.ts      # Engine mode control
    ├── set-paranoia.ts    # Paranoia level control
    ├── disable-rule.ts    # Rule management
    ├── enable-rule.ts     # Rule management
    ├── allow-ip.ts        # IP whitelist
    ├── deny-ip.ts         # IP whitelist
    ├── test.ts            # WAF test suite
    └── utils.ts           # Shared utilities

Events are parsed from Docker logs and cached for 30 seconds. Rapid drill-down calls (overview → top IPs → events by IP → event detail) hit the cache instead of re-parsing. The cache is invalidated when the since parameter changes.

License

MIT

Available Tools

15 tools
waf_allow_ipB

Whitelist an IP address to bypass WAF inspection entirely.

Inputs: ip (required).

waf_deny_ipB

Remove an IP address from the WAF whitelist.

Inputs: ip (required).

waf_disable_ruleA

Disable a specific ModSecurity rule by ID to suppress false positives.

Inputs: ruleId (required).

waf_enable_ruleA

Re-enable a previously disabled ModSecurity rule by ID.

Inputs: ruleId (required).

waf_event_detailA

Full deep-dive into a single event by index. Shows all request headers, body snippet, all rule matches with matched data, and response code.

Inputs: index (required), verbose, since.

waf_events_by_ipA

Drill into events from a specific IP address. Shows timestamps, methods, URIs, HTTP codes, and triggered rules.

Inputs: ip (required), count, verbose, since.

waf_events_by_ruleA

Drill into events that triggered a specific rule. Shows timestamps, IPs, methods, URIs, HTTP codes, and matched data.

Inputs: ruleId (required), count, verbose, since.

waf_fp_candidatesA

Rules that triggered on HTTP 2xx responses — likely false positives. Critical for WAF tuning.

Inputs: since.

waf_overviewA

High-level WAF dashboard: total events, unique IPs, unique rules, events in last hour. Start here to assess if anything needs attention.

Inputs: since.

waf_set_engineA

Change WAF engine mode: On (actively blocking), Off (disabled), or DetectionOnly (log without blocking).

Inputs: mode (required).

waf_set_paranoiaA

Set CRS paranoia level (1-4). Level 1 is minimal rules, level 4 is maximum security with more false positives.

Inputs: level (required).

waf_statusA

Get WAF container health, engine mode, rules loaded, and paranoia level.

Inputs: no named parameters.

waf_testA

Run the WAF test suite to verify blocking and pass-through rules are working correctly.

Inputs: no named parameters.

waf_top_ipsA

Top attacking IPs with hit counts, geo info, and last seen timestamp. Use to identify most active sources.

Inputs: count, since.

waf_top_rulesA

Most frequently triggered WAF rules with severity and description. Use to identify dominant attack patterns.

Inputs: count, since.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    A4/5.0

    Scored across 15 tools

    Disambiguation5/5

    Each tool has a clearly distinct purpose: IP management, rule toggling, event analysis, engine settings, and testing. No two tools overlap in functionality.

    Naming Consistency5/5

    All tools follow a consistent 'waf_verb_noun' pattern, making it easy to predict what each tool does based on its name.

    Tool Count5/5

    15 tools is an appropriate number for a WAF management server, covering operations, monitoring, and tuning without being overwhelming.

    Completeness5/5

    The tool set covers the full lifecycle of WAF management: IP whitelisting/blacklisting, rule enable/disable, engine mode, paranoia levels, event drilling, false positive detection, and testing. No obvious gaps.

    Maintenance

    ActivityInactive
    ResponsivenessNo recent community issues

    Related MCP Connectors

    Related MCP Servers

    • A
      license
      Not graded
      quality
      Not graded
      maintenance
      Enables AI assistants to interact with Docker containers through safe, permission-controlled access to inspect, manage, and diagnose containers, images, and compose services with built-in timeouts and AI-powered analysis.
      -
    • A
      license
      Not graded
      quality
      D
      maintenance
      Provides Docker management tools for AI agents, including inspecting containers, images, Dockerfiles, and Compose configurations.
      44 npm
      1
      MIT
    • A
      license
      Not graded
      quality
      C
      maintenance
      Enables AI agents to autonomously check, diagnose, and recover Dockerized services through safe, tool-based ops without direct host shell access.
      MIT