burp-mcp-plus
burp-mcp-plus is a Python MCP wrapper that enhances Burp Suite's official MCP server with structured HTTP request building and local file ingestion, enabling efficient, token-cheap, and reliable LLM-driven security testing.
Live Burp Proxy History Interaction:
list_history— Browse recent proxy history entries with paginationsearch_history— Search proxy history using regex patterns, returning compact summariesinspect_history_entry— Pretty-print a specific history entry's headers, body, and target detailssitemap— Synthesize a host→method→paths tree from proxy history, with optional host regex filtering
Request Crafting & Sending:
repeater_from_history— Clone a history entry into Burp Repeater with optional structured overrides (method, path, headers, body)repeater_from_template— Build a request from scratch using a URL and send to Repeater, with optional auth/cookie inheritance from a history baselinesend_request— Send an HTTP request immediately (no Repeater tab) and return the responseintruder_from_history— Push a request to Burp Intruder with automatic§…§payload markers around specified substrings
Every request is built from typed fields plus a baseline, auto-generating correct CRLF, Host, Content-Length, User-Agent, and inherited cookies/auth to prevent malformed requests.
Out-of-Band Testing:
collaborator_generate— Generate Burp Collaborator OOB canary payloads (SSRF, blind XSS, etc.)collaborator_check— Poll Burp Collaborator for received interactions, optionally filtered by payload
Local Deduplicated HTTP Traffic Ingestion:
dedup_load— Load adeduped_requests.txtexport from the bundled Burp extensiondedup_list— List all registered dedup sourcesdedup_search— Regex-search dedup entries across url, request, response, params, or all fields, returning token-efficient snippetsdedup_get— Fetch a specific dedup entry by index (preview or full request/response)dedup_to_repeater— Send a dedup entry to Burp Repeater with optional structured overrides
Local JavaScript File Ingestion:
js_load— Load a_manifest.csvfrom the bundled JS Exporter Burp extensionjs_list— List all registered JS sourcesjs_files— Browse JS files in a source, optionally filtered by host regexjs_search— Grep across all on-disk JS files returning file:line snippetsjs_read— Read full content of a specific JS file by index, URL, path, or basename
Provides tools for interacting with Burp Suite, enabling AI agents to replay requests, search proxy history, send requests to Repeater/Intruder, generate and check Collaborator payloads, and synthesize sitemap from history, all with structured input to prevent malformed HTTP requests.
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., "@burp-mcp-plus replay history entry 3 with modified Authorization header"
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.
The problem
You hook up an LLM to Burp's official MCP server and ask it to "replay this request with a tampered cookie." It dutifully crafts a Repeater payload — and silently drops the Cookie header, gets a 401, and confidently tells you the endpoint requires no auth.
Or it forgets Content-Length. Or Host. Or uses LF instead of CRLF. Or pastes a JSON body with no headers at all.
This happens because the upstream Burp MCP takes a free-form content string. Whatever the model emits goes straight to the wire. There's no schema, no validation, no help.
The other thing that breaks long pentest sessions: token cost. Each get_proxy_http_history call ships kilobytes of repeated headers back to the model. Triage a target for an hour and you've burned a fortune re-paginating the same proxy history.
Related MCP server: mcp-code-context
What this fixes
burp-mcp-plus is a Python MCP wrapper that sits between your LLM and Burp's official MCP server. Two big ideas:
1. Structured input, not free-form strings
Every tool that touches HTTP takes typed fields — method, path, set_headers, body — and a baseline (a real entry from Burp's history, or a URL). The wrapper builds the wire format itself. Correct CRLF, auto-Host, auto-Content-Length, default User-Agent, inherited cookies. The LLM literally cannot produce a malformed request because there's no content parameter to put a malformed request in.
2. Local file ingestion for the boring stuff
If you've already triaged a target with the bundled Deduped HTTP History + JS Exporter Burp extension, the wrapper indexes the exports on disk. dedup_search and js_search return file:line + 60-char snippets — meaningfully cheaper than re-hitting Burp every time the model wants to look at past traffic. Full content is only fetched on demand.
Architecture
Plain Python stdio MCP server. Talks SSE to Burp's mcp-proxy-all extension on localhost:9876. Reads dedup/JS exports off disk. Works with any MCP host: Claude Desktop, Claude Code, Cursor, Continue, anything that speaks the protocol.
Features
Live Burp interaction
list_history/search_history— paginate or regex over proxy history. Returns compact summaries (id + method + url + status), not raw bytes.inspect_history_entry— pretty-print one entry's headers, body, target.repeater_from_history— clone a baseline, mutate any subset of (method, path, headers, body), push to Repeater. All other headers preserved verbatim from the baseline. Cookies, auth tokens, Sec-Fetch-, custom Anthropic- / X-* headers — all carry through.repeater_from_template— build from scratch with a URL. Optionally inherit auth from a history baseline.send_request— same shape, but actually sends and returns the response. Skip the Repeater dance when you just want to test.intruder_from_history— push to Intruder with§…§payload markers wrapped automatically around substrings you specify.sitemap— host → method → paths tree, synthesized from history. Burp's MCP doesn't expose Target; we synthesize one.collaborator_generate/collaborator_check— OOB canary payloads + interaction polling.
Local dedup file ingestion
Point at a deduped_requests.txt produced by the bundled extension and the model can search/replay endpoints from past sessions without round-tripping through Burp.
dedup_load/dedup_list— register file(s) under a name.dedup_search— regex overurl/request/response/params/all. Returns 60-char snippets.dedup_get— preview by default, full request/response on demand.dedup_to_repeater— replay a stored entry into a fresh Repeater tab with optional mutations. HTTP/2 lines auto-coerced to HTTP/1.1.
Local JS-export ingestion
Point at a _manifest.csv produced by the bundled extension's JS Exporter and the model can grep across all the JavaScript captured for a target.
js_load/js_list— register an export.js_files— browse the manifest, filter by host regex.js_search— grep across all on-disk JS. Returns file:line + snippet, max N matches per file (default 3). Transparently decodes the legacyarray('b', [...])byte-list format that older versions of the extension produced.js_read— fetch full content for files of interest.
Hardened against the real world
Tolerates Burp's NDJSON-with-no-separators history format.
Recovers parse-mid-stream when Burp truncates a long response with
... (truncated).strict=FalseJSON decoding for raw control bytes inside body strings.Specific error messages for empty inputs, status markers, malformed entries — pointing the model at the next tool to call.
20 tests covering wire-format building and edge cases (no Burp required to run them).
Install
1. Burp side
Install MCP Server from Burp's BApp Store. Confirm it's listening on http://127.0.0.1:9876 (Output tab).
If you want the dedup/JS ingestion features, install the bundled extension:
Set up Jython 2.7 in Burp → Settings → Extensions → Python environment.
Burp → Extensions → Installed → Add → Python →
burp-extension/deduped_history.pyfrom this repo.Two new tabs appear: Deduped History and JS Exporter.
Before you start capturing, two things the extension needs:
Set your target scope. Burp → Target → Scope → add the host(s) you're testing (e.g.
https://app.acme.com/.*). The extension only dedupes/exports in-scope traffic, so this keeps the output clean and avoids ingesting random third-party noise (CDNs, analytics, etc.).Pick an output directory for the JS Exporter. In the JS Exporter tab, set the output dir + project name before browsing. Files land at
<output_dir>/<project>/<host>/<flattened-path>/<file>.jsalong with a_manifest.csvthat the wrapper indexes.
Then browse the target. The Deduped History tab fills as new endpoints appear; the JS Exporter tab fills as new .js / .mjs responses come through. Hit Export in the Deduped History tab to write deduped_requests.txt.
2. Wrapper side
Requires Python 3.11+ and uv.
git clone https://github.com/titaniumtushar/burp-mcp-plus.git
cd burp-mcp-plus
uv sync
uv run pytest # offline tests; no Burp required3. Wire it into your MCP host
The configs below use four placeholders. Fill them in for your OS — quick reference at the bottom of this section.
Placeholder | What it is |
| Path to the |
| Path to |
| Where you cloned this repo |
|
|
Claude Desktop
Edit your Claude Desktop config file:
macOS:
~/Library/Application Support/Claude/claude_desktop_config.jsonWindows:
%APPDATA%\Claude\claude_desktop_config.jsonLinux (unofficial builds only — Claude Desktop isn't officially distributed for Linux):
~/.config/Claude/claude_desktop_config.json
{
"mcpServers": {
"burp": {
"command": "<BURP_JAVA>",
"args": [
"-jar", "<BURP_MCP_JAR>",
"--sse-url", "http://127.0.0.1:9876"
]
},
"burp-plus": {
"command": "<UV>",
"args": [
"run", "--directory", "<REPO_DIR>", "burp-mcp-plus"
]
}
}
}(Sample at examples/claude_desktop_config.json.)
Restart the host. Tools appear as mcp__burp-plus__*.
Claude Code CLI
Run from the repo directory (uses $PWD as <REPO_DIR>):
# Add the wrapper (user scope = available in every project)
claude mcp add burp-plus --scope user -- \
uv run --directory "$PWD" burp-mcp-plus
# Add the upstream Burp MCP too — substitute your <BURP_JAVA> and <BURP_MCP_JAR>
claude mcp add burp --scope user -- \
<BURP_JAVA> -jar <BURP_MCP_JAR> --sse-url http://127.0.0.1:9876On Windows PowerShell, replace $PWD with (Get-Location).Path. On cmd.exe, replace it with %CD%.
Verify with claude mcp list. Tools appear in any Claude Code session as mcp__burp-plus__* and mcp__burp__*. Use --scope project if you want it scoped to the current repo only (writes to .mcp.json), or --scope local for just-this-machine config.
Cursor
Edit ~/.cursor/mcp.json (global, available in every workspace) — same path on macOS / Linux / Windows (Cursor maps ~ to your home dir on every OS). Create the file if it doesn't exist:
{
"mcpServers": {
"burp": {
"command": "<BURP_JAVA>",
"args": [
"-jar", "<BURP_MCP_JAR>",
"--sse-url", "http://127.0.0.1:9876"
]
},
"burp-plus": {
"command": "<UV>",
"args": [
"run", "--directory", "<REPO_DIR>", "burp-mcp-plus"
]
}
}
}Then: Cursor → Settings → MCP → toggle both servers on. The status dot should go green; if it stays red, click View logs in the same panel to see why. Use .cursor/mcp.json in a workspace root instead of ~/.cursor/mcp.json if you want it scoped to one project.
Continue / Cline / other stdio MCP hosts
Same JSON shape, host-specific config path. The wrapper itself doesn't care which host launches it — all it needs is a stdio pipe.
Where the placeholders live on each OS
<BURP_JAVA> — the JRE bundled inside Burp:
OS | Typical path |
macOS |
|
Linux |
|
Windows |
|
<BURP_MCP_JAR> — downloaded by Burp's BApp Store when you install the MCP Server extension:
OS | Typical path |
macOS / Linux |
|
Windows |
|
To find the exact path on your machine: find ~/.BurpSuite -name "*.jar" (macOS / Linux) or look in %APPDATA%\BurpSuite\bapps\ (Windows).
<REPO_DIR> — wherever you ran git clone. Get it with pwd (POSIX shells) or cd (Windows cmd).
<UV> — most users can just use "uv" (the literal string) and let the system PATH resolve it. If your MCP host can't find uv that way, use the absolute path:
Install method | Typical path |
macOS Homebrew (Apple Silicon) |
|
macOS Homebrew (Intel) |
|
Linux / |
|
Windows |
|
| check |
To find it: which uv (POSIX) or where uv (Windows).
The bundled Burp extension
burp-extension/deduped_history.py is a Jython extension that produces the dedup/JS exports the wrapper indexes.
Tab 1: Deduped History. Watches proxy traffic. Adds a row only when a new (method, host, path, parameters) tuple appears. Re-fires when new query/body parameter names show up on an endpoint. Export the whole thing to deduped_requests.txt.
Tab 2: JS Exporter. Watches for JavaScript responses, saves each unique JS file to <output>/<project>/<host>/<flattened-path>/<name>.js, writes a _manifest.csv. Detects version strings from filenames and content hashes.
Token economics
Rough numbers from a typical pentest session:
Action | Upstream Burp MCP | burp-mcp-plus | Reduction |
List 50 history entries | ~60 KB | ~3 KB | 95% |
Search history (regex, 30 hits) | ~90 KB | ~4 KB | 95% |
Replay one auth'd request | ~5 KB request + ~5 KB confirmation | ~1 KB | 80% |
Find an endpoint in past triage | re-paginate proxy (~60 KB) | dedup_search (~600 B) | 99% |
Grep all JS for a pattern | not feasible | ~2 KB w/ snippets | — |
The wrapper's job is to keep the model focused on the smallest bytes that answer the question.
Tested with
Burp Suite Pro 2025.x
Anthropic MCP Server BApp 1.x
Claude Desktop on macOS
Python 3.11, 3.12, 3.13
macOS arm64, Linux x86_64
Should work on Windows but I haven't tested it. Reports welcome.
Security notes
This is a defensive tool for authorized testing. It's no more dangerous than Burp itself — but:
The MCP exposes your Burp's full power to whatever model you connect. Don't connect untrusted models.
File ingestion (
dedup_*,js_*) reads paths you provide. There's no sandbox; treat the wrapper's host as trusted.The wrapper doesn't authenticate to Burp's MCP — it relies on Burp's
localhost-only binding. Don't expose Burp's MCP port externally.Pentest scope discipline applies. The wrapper makes it easier to fire requests; it doesn't validate that you should.
Contributing
Issues and PRs welcome. A few ground rules:
Tests stay green.
uv run pytestbefore opening a PR. The builder insrc/burp_mcp_plus/builder.pyis pure logic and easy to test offline.No new free-form
contentparameters. That's the whole anti-pattern this tool exists to prevent. Add structured fields instead.Compact returns. If a new tool would return more than a few KB by default, add a
limit/field/previewknob.No hidden network calls. Tool side effects should be obvious from the name.
License
MIT.
Thanks
PortSwigger — Burp Suite and the official MCP server.
Anthropic — the MCP spec and Python SDK.
Everyone running long pentest sessions who got tired of debugging "why did my LLM drop the Cookie header again."
Available Tools
20 toolscollaborator_checkA
Poll Burp Collaborator for received interactions.
Returns whatever Burp's get_collaborator_interactions returns. If
payload is given, the result is filtered to interactions referencing
that payload string (best-effort substring match).
Inputs: payload. Returns: result
collaborator_generateA
Generate one or more Burp Collaborator payloads.
Use these as out-of-band injection canaries (SSRF, blind XSS, OOB SQLi,
etc.). Save the returned payloads, plant them, then poll
collaborator_check to see who phoned home.
Inputs: count. Returns: result
dedup_getA
Fetch a dedup entry by its 1-based index.
By default returns metadata + truncated request/response previews. Set
full=True to get the complete raw request and response.
Inputs: name (required), index (required), full. Returns: result
dedup_listA
List all registered dedup sources.
Inputs: no named parameters. Returns: result
dedup_loadA
Load a deduped_requests.txt file produced by the user's Burp
Deduped HTTP History + JS Exporter extension.
path: filesystem path (absolute or ~-expandable).
name: identifier to address this source by in later calls. Default:
parent directory name.
Inputs: path (required), name. Returns: result
dedup_searchA
Regex-search a registered dedup source.
field: one of url, request, response, params, or all.
Returns matches with index + url + status + a short snippet (token-thrifty).
Use dedup_get to fetch the full request/response.
Inputs: name (required), pattern (required), field, limit. Returns: result
dedup_to_repeaterB
Send a dedup entry to Burp Repeater, with optional structured overrides.
The dedup entry is the baseline (cookies, UA, etc. inherited). The
wrapper rebuilds the wire format and pushes it via Burp's
create_repeater_tab.
Inputs: name (required), index (required), tab_name, method, +4 more. Returns: result
inspect_history_entryA
Fetch and pretty-print a Burp proxy history entry by index.
history_id is the 0-based index into the most recent page_size entries
(Burp's MCP doesn't expose stable IDs; addressing is positional).
Use this to inspect cookies/headers before crafting a mutated request.
Inputs: history_id (required), page_size. Returns: result
intruder_from_historyC
Send a request to Burp Intruder, built from a history baseline.
payload_markers: list of substrings in the final request to wrap with
Burp's '§' insertion markers. The substring must appear verbatim in the
final wire format (after overrides are applied). Markers are added in
order; duplicate substrings are wrapped only once each.
Inputs: history_id (required), tab_name, method, path, +5 more. Returns: result
js_filesC
List JS files in a source, optionally filtered by host regex.
Inputs: name (required), host_filter, limit. Returns: result
js_listB
List all registered JS sources.
Inputs: no named parameters. Returns: result
js_loadC
Load a _manifest.csv produced by the JS Exporter side of the user's
Burp extension.
Inputs: manifest_path (required), name. Returns: result
js_readB
Read one JS file from a source.
ref: either the integer index (as string), the full URL, the path, the
saved_as path, or the basename. The first matching record wins.
Inputs: name (required), ref (required), max_bytes. Returns: result
js_searchA
Grep across all on-disk JS files in a source.
Returns file:line + small context snippets (token-thrifty). Use js_read
to fetch full content for files of interest.
Inputs: name (required), pattern (required), limit, max_matches_per_file, +2 more. Returns: result
list_historyA
List recent Burp proxy history entries with their history_index.
Use this to browse and find an entry to feed into the repeater/intruder tools when a regex search isn't precise enough.
Inputs: count, offset. Returns: result
repeater_from_historyA
Send a request to Burp Repeater, built from a history baseline plus optional structured overrides.
The baseline contributes Host, cookies, auth, UA, etc. so the resulting request is always complete. Overrides modify only what you specify.
Args: history_id: id of the proxy history entry to clone tab_name: optional Repeater tab label method/path/body: override the corresponding field set_headers: replace or add these headers (case-insensitive) remove_headers: header names to delete page_size: how many recent history entries to scan to find the id
Inputs: history_id (required), tab_name, method, path, +4 more. Returns: result
repeater_from_templateA
Send a request to Burp Repeater, built from scratch (URL + structured fields). Optionally inherit cookies/auth/UA from a history baseline.
Args:
url: full URL, e.g. https://api.example.com/v1/users?id=1
method: HTTP method (default GET)
headers: additional headers (overrides any inherited values)
body: request body
tab_name: Repeater tab label
inherit_from_history_id: copy headers from this baseline first; the
headers arg then overrides them. Host/Content-Length always
re-derived from the new url+body.
Inputs: url (required), method, headers, body, +3 more. Returns: result
search_historyA
Search Burp proxy history with a regex; returns a compact list of
matching entries with their history_index (0-based position in the
returned page). Feed history_index into the other tools as history_id.
Inputs: regex (required), count, offset. Returns: result
send_requestA
Issue an HTTP/1.1 request via Burp (no Repeater tab) and return the response. Two usage modes:
Mutate a history entry: pass
history_idplus any of method/path/ set_headers/remove_headers/body.Build from scratch: pass
url+ method + headers + body. Optionallyinherit_from_history_idto copy cookies/auth from a baseline.
Inputs: history_id, url, method, path, +6 more. Returns: result
sitemapA
Build a sitemap from Burp proxy history (no upstream Target tool exists).
Groups entries by (host, path, method) and counts occurrences. Returns
a tree-style JSON: { host: { method: [{path, count, last_status}] } }.
Use host_filter (regex) to scope to a specific target.
Inputs: host_filter, page_size. Returns: result
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 20 tools
Each tool targets a distinct Burp feature or action: collaborator generation vs. polling, dedup management (load, list, get, search, send to repeater), JS file handling (load, list, get, search), history browsing (list, search, inspect), repeater/intruder creation from history or template, direct request sending, and sitemap building. Overlaps like multiple tools that send to repeater are differentiated by source (history entry vs. template vs. dedup entry).
Tool names follow a consistent verb_noun pattern (e.g., collaborator_check, dedup_get, list_history, send_request) with occasional prepositions for specificity (e.g., dedup_to_repeater, repeater_from_history). The naming is predictable and readable across the entire set.
With 20 tools, the server covers multiple distinct aspects of Burp interaction (history, repeater, intruder, collaborator, dedup, JS files) without being overbearing. Each tool serves a clear purpose, and the count is well-scoped for a comprehensive Burp automation interface.
The tool set provides a solid coverage of core Burp workflow needs: history inspection, mutation and forwarding to repeater/intruder, collaborator interaction, dedup management, and JS file analysis. Minor gaps exist—such as no direct way to manage scope or proxy settings—but the surface is sufficient for typical automated testing scenarios.
Maintenance
Related MCP Connectors
50-vector prompt-injection, llms.txt poisoning, SSRF & OpenAPI scanner ($1 USDC).
Turn URLs, PDFs and DOCX into clean Markdown for agents, plus prompt-injection scanning
Agent-readiness scanner (0-5 score), robots.txt + llms.txt generators, managed agent enablement.
Real-time MCP & A2A prompt-injection, jailbreak, and tool-schema poisoning firewall for AI agents.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceEnables Large Language Models to safely browse and interact with local file systems through secure directory listing, file reading, and content search capabilities. Built with comprehensive security controls and high-performance handling of large directories and files.1MIT
- AlicenseBqualityBmaintenanceEnables LLMs to efficiently read, write, and refactor code using precise AST-based operations, reducing token usage and context window waste.25539 npm3MIT
- AlicenseAqualityDmaintenanceProvides AI agents with local file-processing capabilities for token counting, RAG chunking, CSV/JSON conversion, QR generation, and more, while keeping documents private on the user's machine.71MIT
- FlicenseAqualityCmaintenanceEnables LLM hosts like Claude Code or Codex CLI to inspect folder structures and read unstructured documents (PDF, PPTX, DOCX, SVG, and images) by returning raw text and images for the host to summarize or analyze.2-