Skip to main content
Glama
burp-mcp-plus

burp-mcp-plus


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 over url / 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 legacy array('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=False JSON 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:

  1. Set up Jython 2.7 in Burp → Settings → Extensions → Python environment.

  2. Burp → Extensions → Installed → Add → Python → burp-extension/deduped_history.py from this repo.

  3. 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>.js along with a _manifest.csv that 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 required

3. 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

<BURP_JAVA>

Path to the java binary that ships inside Burp Suite

<BURP_MCP_JAR>

Path to mcp-proxy-all.jar (downloaded by the BApp Store extension)

<REPO_DIR>

Where you cloned this repo

<UV>

"uv" if it's on your PATH; otherwise the absolute path to the uv binary

Claude Desktop

Edit your Claude Desktop config file:

  • macOS: ~/Library/Application Support/Claude/claude_desktop_config.json

  • Windows: %APPDATA%\Claude\claude_desktop_config.json

  • Linux (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:9876

On 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

/Applications/Burp Suite Professional.app/Contents/Resources/jre.bundle/Contents/Home/bin/java

Linux

~/BurpSuitePro/jre/bin/java (or wherever you extracted Burp's installer)

Windows

C:\Users\<you>\AppData\Local\Programs\BurpSuitePro\jre\bin\java.exe

<BURP_MCP_JAR> — downloaded by Burp's BApp Store when you install the MCP Server extension:

OS

Typical path

macOS / Linux

~/.BurpSuite/bapps/<extension-id>/burp-mcp-all.jar (or ~/.BurpSuite/mcp-proxy/mcp-proxy-all.jar depending on Burp version)

Windows

C:\Users\<you>\AppData\Roaming\BurpSuite\bapps\<extension-id>\burp-mcp-all.jar

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)

/opt/homebrew/bin/uv

macOS Homebrew (Intel)

/usr/local/bin/uv

Linux / curl install

~/.local/bin/uv

Windows

%USERPROFILE%\.local\bin\uv.exe

pipx install uv (any OS)

check pipx environment

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 pytest before opening a PR. The builder in src/burp_mcp_plus/builder.py is pure logic and easy to test offline.

  • No new free-form content parameters. 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 / preview knob.

  • 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 tools
collaborator_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_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

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:

  1. Mutate a history entry: pass history_id plus any of method/path/ set_headers/remove_headers/body.

  2. Build from scratch: pass url + method + headers + body. Optionally inherit_from_history_id to 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

    A3.6/5.0

    Scored across 20 tools

    Disambiguation5/5

    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).

    Naming Consistency5/5

    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.

    Tool Count5/5

    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.

    Completeness4/5

    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

    ActivityMaintained
    ResponsivenessNo recent community issues

    Related MCP Connectors

    Related MCP Servers

    • A
      license
      Not graded
      quality
      D
      maintenance
      Enables 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.
      1
      MIT
    • A
      license
      B
      quality
      B
      maintenance
      Enables LLMs to efficiently read, write, and refactor code using precise AST-based operations, reducing token usage and context window waste.
      25
      539 npm
      3
      MIT
    • A
      license
      A
      quality
      D
      maintenance
      Provides 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.
      7
      1
      MIT
    • F
      license
      A
      quality
      C
      maintenance
      Enables 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
      -