ProxymanApp / ProxymanApp/Proxyman
MCP server: a request-modifying Scripting rule causes duplicate flow IDs → colliding flows are silently dropped from MCP results
@NghiaTranUIT is already working on this.
Since Jun 2, 2026.
- 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
- Add a Scripting rule with a request script (like the one above) scoped to host A.
- 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).
- In the macOS app, observe two rows sharing the same flow
id(the host-A and host-B flows). - From an MCP client, query
get_flows/filter_flows(e.g. by host B) andget_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
idwhen 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 viaget_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_flowsreturn 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
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Assessment
This issue has not been assessed yet.