search_history
Use a regex to search Burp proxy history and retrieve matching entries with their history indices for further processing in other tools.
Instructions
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.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| regex | Yes | ||
| count | No | ||
| offset | No |
Output Schema
| Name | Required | Description | Default |
|---|---|---|---|
| result | Yes |
Implementation Reference
- src/burp_mcp_plus/server.py:496-513 (handler)The actual tool handler for search_history. Defines the async function, accepts regex (str), count (int, default 50), offset (int, default 0), calls burp_client.call('get_proxy_http_history_regex', ...), normalizes results, summarizes entries, and returns JSON.
@mcp.tool() async def search_history(regex: str, count: int = 50, offset: int = 0) -> str: """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`. """ payload = await burp_client.call( "get_proxy_http_history_regex", {"regex": regex, "count": count, "offset": offset}, ) entries = _normalize_history(payload) summary: list[dict[str, Any]] = [] for i, e in enumerate(entries): try: summary.append(_summarize_entry(e, i)) except Exception as exc: summary.append({"history_index": i, "error": str(exc)}) return json.dumps(summary, indent=2) - src/burp_mcp_plus/server.py:496-497 (registration)The @mcp.tool() decorator on line 496 registers search_history as an MCP tool via the FastMCP instance created on line 29.
@mcp.tool() async def search_history(regex: str, count: int = 50, offset: int = 0) -> str: - src/burp_mcp_plus/server.py:43-68 (helper)_normalize_history — helper used by search_history to normalize the raw Burp history payload into a flat list of entry dicts.
def _normalize_history(history_payload: Any) -> list[dict[str, Any]]: """Normalize whatever Burp's history tool returned into a flat list of entries. Burp's MCP returns one JSON object per entry (across multiple text content blocks), each shaped like {"request": "...", "response": "...", "notes": ""}. There is no `id` field and no target metadata — host/port/scheme must be derived from the parsed request itself. Burp also sometimes returns plain text status messages like "Reached end of items" instead of any entries — treat those as empty. """ if isinstance(history_payload, list): return [e for e in history_payload if isinstance(e, dict)] if isinstance(history_payload, dict): for key in ("history", "items", "entries", "results"): v = history_payload.get(key) if isinstance(v, list): return [e for e in v if isinstance(e, dict)] if "request" in history_payload: return [history_payload] if isinstance(history_payload, str): if history_payload.strip().lower().startswith(_EMPTY_MARKERS): return [] raise RuntimeError( f"could not parse Burp history payload (type={type(history_payload).__name__})" ) - src/burp_mcp_plus/server.py:477-493 (helper)_summarize_entry — helper used by search_history to produce a compact summary dict (history_index, method, url, status) for each history entry.
def _summarize_entry(entry: dict[str, Any], index: int) -> dict[str, Any]: raw = _entry_raw_request(entry) parsed = parse_raw_request(raw) host, port, https = _derive_target(parsed, entry) scheme = "https" if https else "http" status: int | None = None resp = entry.get("response") or entry.get("rawResponse") or "" if isinstance(resp, str): m = _STATUS_RE.search(resp) if m: status = int(m.group(1)) return { "history_index": index, "method": parsed.method, "url": f"{scheme}://{host}:{port}{parsed.path}", "status": status, } - src/burp_mcp_plus/server.py:110-118 (helper)_entry_raw_request — helper used by _summarize_entry to extract raw HTTP request string from a history entry.
def _entry_raw_request(entry: dict[str, Any]) -> str: """Pull the raw HTTP/1.1 request bytes/string out of a history entry.""" for key in ("request", "rawRequest", "requestBytes", "requestString"): v = entry.get(key) if isinstance(v, str) and v: return v raise RuntimeError( "history entry has no request field (looked for: request, rawRequest, requestBytes, requestString)" )