ProxymanApp / ProxymanApp/Proxyman

MCP server: a request-modifying Scripting rule causes duplicate flow IDs → colliding flows are silently dropped from MCP results

Open
#2,687 4 comments 0 reactions 1 assignee View on GitHub

@NghiaTranUIT is already working on this.

Since Jun 2, 2026.

✅ Done bug
Dominant language
No language data
Stars
7k
Forks
237
PR merge metrics
No merged PRs in 30d

Description

Description

When a request-modifying Scripting rule is active, Proxyman can assign the same flow id to two distinct, concurrent flows. The built-in MCP server then exposes only one of the two: the other is missing from get_flows / filter_flows (by url, host or requestBody) and cannot be fetched via get_flow_detail (the shared id resolves to the sibling). Both flows remain visible, with the same id, in the macOS app UI.

Disabling the request-modifying Scripting rule removes the collision — the same user action then yields unique ids and all flows are exposed by the MCP.

The triggering rule simply reassigns the request body and overrides a header in onRequest:

async function onRequest(context, url, request) {
  var body = JSON.parse(request.rawBody);
  request.headers["Content-Type"] = "application/json";
  request.body = body;
  return request;
}

Consequence for MCP consumers (important). The collision is undetectable from the MCP side: a masked flow is indistinguishable from a flow that never happened, and a returned flow gives no hint that a sibling is hidden behind the same id. An automated MCP client / AI agent therefore cannot trust absence or counts and may confidently assert "the app did not send request X" when it actually did — this caused real misdiagnoses on our side before we noticed the duplicate ids in the UI.

Steps to Reproduce

  1. Add a Scripting rule with a request script (like the one above) scoped to host A.
  2. Run an app that fires, at nearly the same instant, a request to host A (scripted) and another request to a different host B (not scripted).
  3. In the macOS app, observe two rows sharing the same flow id (the host-A and host-B flows).
  4. From an MCP client, query get_flows / filter_flows (e.g. by host B) and get_flow_detail(<shared id>) — the host-B flow is absent / unfetchable. Then disable the Scripting rule and repeat → the collision disappears and the flow is exposed normally.

Current Behavior

  • Two different concurrent flows are assigned the same id when a request-modifying Scripting rule is active.
  • The MCP server returns only one of them; the other is silently omitted from get_flows / filter_flows (all keys: url, host, requestBody) and unreachable via get_flow_detail (which returns the sibling).
  • The loss is invisible to the MCP client (no error, plausible non-empty results), making it impossible to detect from the MCP alone.

Expected Behavior

  • Every captured flow has a unique id, even when modified by a Scripting rule.
  • get_flows / filter_flows return all matching flows.
  • get_flow_detail(id) unambiguously returns the requested flow.

Environment

  • App version: Proxyman 6.9.0 (build 60900), built-in MCP server
  • macOS version: macOS 26.5 (build 25F71), Apple Silicon
  • Traffic captured from an iOS Simulator app with SSL proxying enabled

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.