mcp-server-zap
Python MCP server for OWASP ZAP — Docker-first, extensible, ~37 tools.
A Model Context Protocol server that exposes OWASP ZAP as tools for Claude Code, Claude Desktop, Cursor, Continue, and any other MCP-compatible LLM client. Spider, active scan, fuzzing, brute force, intercept, schema-driven scanning, the Automation Framework, regex search, and HTML/JSON/Markdown/SARIF reporting — all driven from natural-language conversation.
flowchart LR
Client[Claude / Cursor / Continue]
Server[mcp-server-zap]
ZAP[OWASP ZAP daemon]
Target[Target Application]
Client -- "MCP (stdio or HTTP)" --> Server
Server -- "ZAP REST API" --> ZAP
ZAP -- "HTTP proxy / scans" --> Target
Why this server?
In April 2026 the OWASP ZAP project shipped an official MCP add-on that runs inside the ZAP process with a deliberately limited tool set. If you primarily drive ZAP from its desktop GUI and want one-click MCP, install that add-on.
This project is the alternative for teams that prefer a Python, Docker-first deployment with broader API coverage and explicit auth:
| Official ZAP MCP add-on | mcp-server-zap (this project) | |
|---|---|---|
| Process model | Java add-on inside ZAP | External Python process |
| Install | ZAP Marketplace (one click) | uvx mcp-server-zap or docker compose up |
| Tool count | ~17 (intentionally minimal) | ~37 |
| Transport | HTTP only (port 8282) | Stdio (default) + optional HTTP |
| Auth | Optional shared key | API-key + HS256 JWT |
| Source | Closed/binary (alpha) | MIT, public src/ layout |
| Best for | ZAP Desktop power users | Python/Docker DevOps teams, CI pipelines |
Both projects target the same API. Pick the one that matches your workflow.
Authorized Use Only
This is a security-testing tool. Use it only on systems you own or have written permission to test. Brute-force, fuzzing, and active-scan tools generate traffic indistinguishable from a real attack. Misuse is illegal in most jurisdictions and is solely the operator's responsibility.
Features
- Crawl — Spider and AJAX spider for SPA-heavy targets.
- Scan — Active vulnerability scanning, passive scan status, scan policies and scanner controls.
- Schema import — OpenAPI, GraphQL, SOAP, and Postman collections feed the scanner.
- Attack — Parameter fuzzing and login brute-force.
- Intercept — Toggle break mode, add URL-pattern breakpoints.
- Auth and context — ZAP contexts, sessions, session-token introspection.
- Search — Regex over recorded requests and responses for secret-leak hunting.
- Automation — Run ZAP Automation Framework YAML plans end-to-end.
- Report — HTML, JSON, Markdown, themed templates, and SARIF for GitHub Code Scanning.
Quick Start
Option A — uvx (recommended for local Claude clients)
1. Run a ZAP daemon
docker run -u zap -p 8080:8080 -i ghcr.io/zaproxy/zaproxy:stable \
zap.sh -daemon -host 0.0.0.0 -port 8080 \
-config api.disablekey=true \
-config api.addrs.addr.name=.* -config api.addrs.addr.regex=true
For non-localhost or multi-user setups, drop
api.disablekey=trueand setZAP_API_KEY.
2. Add the MCP server
Claude Desktop — edit ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) or %APPDATA%\Claude\claude_desktop_config.json (Windows):
{
"mcpServers": {
"zap": {
"command": "uvx",
"args": ["mcp-server-zap"],
"env": {
"ZAP_URL": "http://localhost:8080",
"ZAP_API_KEY": ""
}
}
}
}
Claude Code:
claude mcp add zap -- uvx mcp-server-zap
Cursor / Continue / other MCP clients use the same JSON shape under their mcpServers block.
Option B — Docker Compose (bundles ZAP + MCP server)
git clone https://github.com/Karacali/mcp-zap.git
cd zap-mcp
cp .env.example .env # set MCP_API_KEY
docker compose up -d
This spins up ZAP and mcp-server-zap on the same network. The MCP server exposes the HTTP transport on 127.0.0.1:8765. Auto-remap rewrites localhost targets to host.docker.internal so you can scan apps running on your dev machine from inside the container.
Connect a remote-MCP-aware client to http://127.0.0.1:8765/ with Authorization: Bearer $MCP_API_KEY.
For local debugging (binds ZAP UI to localhost:8080):
docker compose -f docker-compose.yml -f docker-compose.dev.yml up
3. Try it
Run a spider scan against https://target.example.com
What's the status of the active scan?
List High-risk alerts
Search responses for "api_key|token|secret"
Generate an HTML report
Environment Variables
| Variable | Default | Description |
|---|---|---|
ZAP_URL |
http://localhost:8080 |
ZAP daemon URL |
ZAP_API_KEY |
(empty) | ZAP API key, if configured |
ZAP_MCP_REPORT_DIR |
reports |
Directory where HTML/JSON reports are written |
ZAP_MCP_CONTAINER |
(auto) | Force localhost → host.docker.internal remap (set automatically when /.dockerenv is present) |
MCP_TRANSPORT |
stdio |
stdio or http |
MCP_HTTP_HOST |
127.0.0.1 |
HTTP transport bind host (used when MCP_TRANSPORT=http) |
MCP_HTTP_PORT |
8765 |
HTTP transport port |
MCP_AUTH_MODE |
disabled |
disabled, apikey, or jwt (HTTP transport only) |
MCP_API_KEY |
(empty) | Required when MCP_AUTH_MODE=apikey |
MCP_JWT_SECRET |
(empty) | HMAC secret (HS256) for MCP_AUTH_MODE=jwt |
MCP_LOG_LEVEL |
INFO |
Python logging level |
Tool Reference
| Tool | Purpose |
|---|---|
zap_version |
Connectivity probe; returns ZAP version |
spider_scan, spider_status |
Classic spider crawl |
ajax_spider_scan, ajax_spider_status |
AJAX spider for SPAs |
forced_browse |
Hidden directory/file discovery |
get_sites, get_urls, open_url |
Site and URL listing, proxy open |
active_scan, active_scan_status, passive_scan_status, stop_scan, list_scans |
Vulnerability scanning |
get_alerts |
List findings (filter by URL / risk) |
set_scan_policy, list_scan_policies, list_scanners |
Scan policy controls |
get_messages, get_message_by_id |
Inspect proxied traffic |
send_request |
Send raw HTTP request through ZAP |
search_in_requests, search_in_responses |
Regex search across history |
fuzz_request |
Parameter fuzzing |
brute_force_login |
Login brute-force |
set_break, add_break_point |
Intercept controls |
set_context, list_contexts, new_session, list_sessions, get_session_tokens |
Context and session management |
import_openapi, import_graphql, import_soap, import_postman |
Schema-driven endpoint discovery |
run_automation_plan, automation_plan_status |
ZAP Automation Framework YAML plans |
generate_html_report, generate_json_report, generate_markdown_report |
Legacy core report API (HTML / JSON / Markdown) |
generate_report |
Modern Reports add-on (themed HTML, PDF, SARIF for GitHub Code Scanning, etc.) |
Example Scenario
A typical conversation that runs an end-to-end scan:
You: Open https://juice-shop.example via the proxy and start a spider on it.
Claude: [calls open_url, then spider_scan → returns scan_id 0]
You: How's the spider going?
Claude: [calls spider_status with scan_id=0 → "100%, 184 URLs found"]
You: Now run an active scan on the same target.
Claude: [calls active_scan → scan_id 1]
You: Show me the High-risk alerts when it's done.
Claude: [polls active_scan_status, then get_alerts(risk_level="High")]
You: Generate an HTML report.
Claude: [calls generate_html_report → writes ./reports/zap-report.html]
Troubleshooting
| Symptom | Likely cause | Fix |
|---|---|---|
zap_version returns disconnected |
ZAP daemon not reachable from the MCP server | Check ZAP_URL. From inside Docker the value should be http://zap:8080, not http://localhost:8080 |
Spider scan returns 0 URLs after 100% |
Some sites need AJAX spider | Use ajax_spider_scan instead |
Scanning localhost:3000 from compose stack hits the wrong target |
Container's loopback isn't your host | We auto-remap to host.docker.internal. Ensure ZAP_MCP_CONTAINER=1 is set (already set in our Dockerfile) |
| HTTP transport returns 401 | Auth mode mismatch | Set MCP_AUTH_MODE=apikey and MCP_API_KEY=<value>, then send Authorization: Bearer <value> |
import_openapi says "add-on not installed" |
OpenAPI add-on missing in your ZAP build | zap.sh -addoninstall openapi or install from the ZAP Marketplace |
fuzz_request payloads all return error |
ZAP probably can't reach the original message_id host |
Re-record the request (open_url), then use the new ID |
| Reports missing | Output directory unwritable | Set ZAP_MCP_REPORT_DIR to a writable path |
Local Development
git clone https://github.com/Karacali/mcp-zap.git
cd zap-mcp
# uv (recommended)
uv sync --all-extras
uv run mcp-server-zap
# or pip
python -m venv .venv && source .venv/bin/activate
pip install -e ".[dev]"
mcp-server-zap
Quality gates:
uv run pytest -q
uv run ruff check src tests
uv run pyright src
Security
For responsible-disclosure procedures and reporting vulnerabilities in this MCP wrapper, see SECURITY.md. ZAP itself is maintained by OWASP — vulnerabilities in ZAP go to the ZAP project.
Contributing
See CONTRIBUTING.md. PRs welcome — run ruff, pyright, and pytest before submitting.
License
MIT.
Metadata
Release files for mcp-server-zap 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| mcp_server_zap-0.1.0.tar.gz | 25.8 kB | With provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| mcp_server_zap-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 51.6 kB
Release files / mcp_server_zap-0.1.0.tar.gz
| Download URL | mcp_server_zap-0.1.0.tar.gz |
|---|---|
| Size | 25.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
451ba5432592842b8f4b3d7f52597398b0098d3957950d1c43a3812b87d9c981
|
|
BLAKE2b-256 checksum How to use checksums |
659948b8b3da7df73d3dd0d98fcdfad32fc9d665e2c1edfdf8a7e94d19e0a074
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Apr 27, 2026.
Transparency logRelease files / mcp_server_zap-0.1.0-py3-none-any.whl
| Download URL | mcp_server_zap-0.1.0-py3-none-any.whl |
|---|---|
| Size | 25.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
7746c35afd8933a9bd6715b6662aa2e5913ae0c082fd8b07de2b33b28da51e12
|
|
BLAKE2b-256 checksum How to use checksums |
16c80459b9926f7d76cb8fb44cb38b16bca97e522d7ff0aedecbd32bf4b8d6bc
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Apr 27, 2026.
Transparency logSecurity for mcp-server-zap 0.1.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
All 2 files in this release have been uploaded with provenance metadata.
Attestation for mcp_server_zap-0.1.0.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Apr 27, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.