OWASP ZAP MCP Server
Provides tools to drive OWASP ZAP, enabling crawling, authenticated scanning, active and passive scanning, vulnerability triage, context and user management, and report generation.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@OWASP ZAP MCP ServerRun an active scan against https://test.example.com and summarize any vulnerabilities found."
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
๐ท๏ธ OWASP ZAP MCP Server
Drive the world's most popular web app scanner from your AI assistant.
Point Claude, Cursor, or any MCP client at OWASP ZAP and run real crawls, authenticated scans, and vulnerability triage โ through 67 curated, safety-gated tools built straight from the official ZAP API.
Quick start ยท See it in action ยท The 67 tools ยท Authenticated scanning ยท Security ยท Responsible use
Authorized use only. Active scanning sends real attack payloads. Run it only against systems you have explicit, written permission to test. This server refuses cloud-metadata targets and can be pinned to an engagement scope โ but the responsibility is yours.
โก See it in action
Once it's connected, you drive ZAP in plain language. The model picks the right tools and chains them โ no REST calls, no ZAP UI:
๐ฌ You: Crawl
https://juice-shop.herokuapp.com, run an active scan, and summarise what you find.
Behind that one sentence, the assistant orchestrates the toolchain:
โ zap_access_url seed the target into ZAP's site tree
โก zap_spider_scan ๐ฏ crawl for pages, forms, and parameters
โข zap_active_scan ๐ฏ attack the discovered surface (SQLi, XSS, โฆ)
โฃ zap_get_alerts_summary triage findings by severity
โค zap_generate_report export a shareable HTML report๐ค Assistant: Crawled 41 URLs and completed the active scan. Findings by severity โ High: SQL injection on
/rest/products/search; Medium: missing CSP and reflected XSS; plus several low-severity header issues. Full report written to/zap/wrk/report.html.
Every attack-capable step (๐ฏ) is checked against the target-authorization policy first, so the model physically cannot fire a scan at an out-of-scope or cloud-metadata host โ regardless of what it's asked to do.
Related MCP server: VibeDefender MCP Server
โจ Why this exists
Talking to ZAP's raw REST API from an LLM is clumsy and risky: hundreds of endpoints, no guardrails, and it's easy to point an attack at the wrong host. This project gives your AI assistant a small, opinionated, safe surface:
๐ Safe by design
Cloud metadata endpoints (
169.254.169.254) are always refusedOptional scope allowlist + private-range blocking
Control port bound to localhost by default
๐ Real authenticated scanning
Full workflow: context โ auth method โ indicators โ user โ forced-user
scan_as_userfor spider, AJAX spider, and active scanThe thing most ZAP wrappers skip entirely
๐งฑ Reliable under load
One pooled async client, bounded retries with backoff
Typed errors + a uniform result envelope
A single bad call can never crash the server
๐ข Production posture
Fail-closed config, secrets never logged
Pinned, non-root, health-gated containers
Green CI on every push
๐๏ธ Architecture
flowchart LR
A["๐ค LLM client<br/>(Claude ยท Cursor)"] -->|MCP / Streamable HTTP<br/>127.0.0.1:8000| B
B["๐ท๏ธ zap-mcp-server<br/>67 tools ยท target policy<br/>pooled async client"] -->|internal docker net<br/>http://zap:8080| C
C["๐ก๏ธ zap-daemon<br/>OWASP ZAP 2.17.0<br/>API restricted to private ranges"]
B <-->|shared volume<br/>/zap/wrk| D["๐ zap-wrk<br/>reports ยท imports"]
C <-->|shared volume<br/>/zap/wrk| D
B -.->|refuses metadata / out-of-scope| X["โ blocked targets"]The MCP server reaches ZAP over the internal Docker network.
Both ports are published on
127.0.0.1only โ nothing is world-exposed.Every state-changing ZAP action requires the API key.
Shared
/zap/wrkvolume. ZAP resolves every file path in its API against its own filesystem, so both containers mount the same volume at the same path. This is what makes file-based tools work end to end: the agent stages an input (HAR, OpenAPI spec, URL list, automation plan) for ZAP to read, and reads back reports ZAP writes. A one-shotwrk-initservice prepares the directory as1000:1000mode2775(setgid) before ZAP starts; the MCP server joins gid1000viagroup_add, so both unprivileged users can read and write there and new files inherit the shared group automatically.
The optional all-in-one image collapses this into one container: same components
and the same MCP endpoint, but ZAP is reached over loopback and /zap/wrk is just
a local directory, so no volume sharing is needed. See Quick start.
๐ Quick start
Fastest path โ one image, zero config:
docker build -f Dockerfile.allinone -t zap-mcp-server:all-in-one .
docker run -d --name zap-mcp -p 127.0.0.1:8000:8000 zap-mcp-server:all-in-oneNo .env, no API key to invent โ ZAP's API is bound to loopback inside the
container and its key is generated at startup. First boot takes ~60โ90s while
ZAP's JVM warms up; wait for healthy, then you're live at
http://localhost:8000/mcp:
docker inspect --format '{{.State.Health.Status}}' zap-mcp # -> healthyThat green status is meaningful: the container reports healthy only when
both ZAP's API and the MCP endpoint answer.
For real engagements, the two-container compose setup is recommended โ independently upgradable ZAP, and restarting the server won't discard a live scan session.
Which setup should I use?
๐ All-in-one | ๐ Compose (recommended) | |
Launch |
|
|
Config before first run | none | create |
Containers | 1 | 2 |
ZAP API key | auto-generated per container | you supply it |
ZAP proxy/API reachable | no โ loopback-only in the container | yes, on |
Restart MCP without losing scan state | โ | โ |
Upgrade ZAP independently | โ rebuild | โ change the image tag |
Best for | first look, demos, CI throwaways | real engagements, long-running work |
Running two processes in one container is normally an anti-pattern, so the parts that usually break are handled explicitly:
s6-overlay is PID 1 โ reaps orphaned processes and forwards signals, rather than backgrounding with
&and leaking zombies.Ordered startup โ services run
apikey โ zap โ zap-ready โ mcp-server. Thezap-readygate polls ZAP's API and only then starts the MCP server, which is the single-container equivalent of compose'sdepends_on: service_healthy.No degraded state โ if ZAP never becomes ready the container exits non-zero instead of serving an MCP endpoint with a dead scanner behind it.
Self-healing โ if either process dies, s6 restarts it.
Clean shutdown โ
docker stopexits 0 in ~3s; s6's grace periods are kept under Docker's 10s SIGKILL deadline.Unprivileged โ s6 sets up as root, then both ZAP and the MCP server drop to uid 1000. Neither runs as root.
Pinned supervisor โ s6-overlay is fetched by version and checksum-verified at build time.
Overridable via -e: ZAP_API_KEY (use a fixed key), ZAP_STARTUP_TIMEOUT
(readiness budget, default 300s), plus the usual ZAP_TARGET_ALLOWLIST /
ZAP_BLOCK_PRIVATE_TARGETS scope controls.
The all-in-one image doesnot expose ZAP's HTTP proxy or API, so you cannot point a browser through it or open ZAP's own tooling. Use compose if you need that. Trade-offs worth knowing before you rely on it: a ZAP upgrade means rebuilding the image, restarting the MCP server also restarts ZAP and discards live scan state, and one health signal covers both processes so it is less obvious which half failed.
๐ Compose (recommended for real use)
# 1. Set your secret (never committed)
cp .env.example .env
# edit .env -> ZAP_API_KEY=<long-random-value>
# 2. Launch (ZAP starts, becomes healthy, then the MCP server starts)
docker compose up -d --build
# 3. Confirm
docker compose ps # both services: healthy
docker compose logs -f mcp-server # "Registered 67 MCP tools"Connect your client
Either option serves the same endpoint, so the client config is identical:
{
"mcpServers": {
"owasp-zap": { "url": "http://localhost:8000/mcp" }
}
}๐ Authenticated scanning in 6 steps
The capability most ZAP wrappers skip โ scan behind a login:
1. create_context โโโโโโโโโโโโโโบ scope it (include app, exclude /logout)
2. set_authentication_method โโโบ e.g. formBasedAuthentication
3. set_logged_in / out_indicator
4. new_user โ set_user_credentials โ set_user_enabled
5. set_forced_user (+ mode) โโโบ keeps the session alive during scans
6. spider_scan_as_user โ active_scan_as_userPrefer repeatable runs? Drive the whole pipeline with a ZAP
Automation Framework
plan via zap_run_automation_plan.
๐งฐ The 67 tools
Tools marked ๐ฏ are gated by the target-authorization policy. Every tool returns
a uniform envelope: {"status":"success",...} or
{"status":"error","code":...,"retryable":...}.
Group | Tools |
Core & health |
|
Spider |
|
AJAX spider |
|
Group | Tools |
Active scan |
|
Passive scan |
|
Findings & triage |
|
Group | Tools |
Context & scope |
|
Authentication |
|
Users |
|
Forced user |
|
Imports & automation |
|
Reports |
|
All tool names are prefixed with
zap_(e.g.zap_active_scan).
๐ก๏ธ Security model
Control | Behavior |
API key | Required. Server won't start without |
Metadata block |
|
Scope allowlist |
|
Private-range block |
|
Localhost binding | MCP |
Response caps | Large lists are bounded ( |
The MCP endpoint hasno built-in auth and can launch attacks. To expose it
beyond localhost, set MCP_BIND=0.0.0.0 and front it with an
authenticating reverse proxy.
Variable | Default | Description |
| (required) | Must match the ZAP daemon's key. |
|
| ZAP API base URL. |
| (empty) | Comma-separated allowed host suffixes. |
|
| Refuse private/loopback targets. |
|
| Host interface the MCP port binds to. |
|
| HTTP timeouts (s). |
|
| Retry policy. |
|
| Cap on returned list items. |
|
| Report output dir. Must be on the volume shared with ZAP. |
|
| All-in-one only: seconds to wait for ZAP's API before failing the container. |
๐งช Development
python -m venv .venv && source .venv/bin/activate
pip install -r requirements-dev.txt
pytest -q # policy, config, error envelope, tool behaviorCI runs py_compile + pytest on every push to main.
โ๏ธ Responsible use
Active scanning is an attack. In most jurisdictions, testing systems without permission is illegal. Before you scan:
โ Confirm the target is in scope for an engagement you're authorized to run
โ Pin scope with
ZAP_TARGET_ALLOWLIST; considerZAP_BLOCK_PRIVATE_TARGETS=trueโ Use a long random
ZAP_API_KEY; never commit.env
Cloud metadata endpoints are always refused and this cannot be overridden.
๐ License
MIT ยฉ Neeraj829784 โ swap the LICENSE file for Apache-2.0 if you
want an explicit patent grant.
This server cannot be deployed
Maintenance
Related MCP Connectors
AI pentesting: run scans, triage vulnerabilities, review PRs, manage schedules and assets.
Find, vet, and run MCP tools through a secure audited gateway with prompt-injection risk scoring
Zero-config MCP security scanner for AI-generated apps. 25K+ vulnerability patterns.
AI-callable tools for API mocking, testing, monitoring, security, and automation.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceEnables AI assistants to perform authorized security testing and penetration testing operations including SSL/TLS analysis, port scanning, vulnerability scanning, and HTTP security header audits through natural language interactions.1MIT
- AlicenseNot gradedqualityDmaintenanceProvides security assessment methodology, tool documentation, and step-by-step workflows to guide AI agents through vulnerability scanning, static analysis, and penetration testing of applications and URLs.1MIT
- AlicenseNot gradedqualityDmaintenanceEnables AI assistants to perform penetration testing and security assessments by exposing 60+ Kali Linux security tools including network scanning, web security testing, password cracking, exploitation frameworks, and OSINT capabilities through an AI-friendly interface.2MIT
- FlicenseAqualityDmaintenanceEnables AI assistants to perform authorized penetration testing and security assessments by exposing 20+ Kali Linux security tools (nmap, sqlmap, gobuster, hydra, etc.) through a safe, validated interface with command allowlists, rate limiting, and input sanitization.191-