Skip to content

Commit f837838

Browse files
cliffhallclaude
andcommitted
fix(network): include request / response bodies in search filter
Headers were already covered but bodies were not, so searches for strings that live inside the JSON-RPC payload (e.g. "jsonrpc", "initialize", a tool name) silently returned no matches. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent c101579 commit f837838

2 files changed

Lines changed: 61 additions & 11 deletions

File tree

clients/web/src/components/groups/NetworkStreamPanel/NetworkStreamPanel.test.tsx

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,15 @@ const entry: FetchRequestEntry = {
99
timestamp: new Date("2026-03-17T10:00:00Z"),
1010
method: "POST",
1111
url: "https://example.com/mcp",
12-
requestHeaders: { authorization: "Bearer abc" },
12+
requestHeaders: {
13+
authorization: "Bearer abc",
14+
"content-type": "application/json",
15+
},
16+
requestBody: '{"jsonrpc":"2.0","method":"initialize","id":1}',
1317
responseStatus: 200,
18+
responseStatusText: "OK",
19+
responseHeaders: { "content-type": "application/json" },
20+
responseBody: '{"jsonrpc":"2.0","id":1,"result":{}}',
1421
category: "transport",
1522
};
1623

@@ -51,6 +58,39 @@ describe("NetworkStreamPanel", () => {
5158
expect(screen.getByText("https://example.com/mcp")).toBeInTheDocument();
5259
});
5360

61+
it("matches against header keys and values", () => {
62+
renderWithMantine(
63+
<NetworkStreamPanel {...baseProps} filterText="content-type" />,
64+
);
65+
expect(screen.getByText("https://example.com/mcp")).toBeInTheDocument();
66+
});
67+
68+
it("matches against the request body", () => {
69+
renderWithMantine(
70+
<NetworkStreamPanel {...baseProps} filterText="initialize" />,
71+
);
72+
expect(screen.getByText("https://example.com/mcp")).toBeInTheDocument();
73+
});
74+
75+
it("matches against the response body", () => {
76+
renderWithMantine(
77+
<NetworkStreamPanel {...baseProps} filterText="jsonrpc" />,
78+
);
79+
expect(screen.getByText("https://example.com/mcp")).toBeInTheDocument();
80+
});
81+
82+
it("matches against responseStatusText", () => {
83+
renderWithMantine(<NetworkStreamPanel {...baseProps} filterText="ok" />);
84+
expect(screen.getByText("https://example.com/mcp")).toBeInTheDocument();
85+
});
86+
87+
it("is case-insensitive", () => {
88+
renderWithMantine(
89+
<NetworkStreamPanel {...baseProps} filterText="CONTENT-TYPE" />,
90+
);
91+
expect(screen.getByText("https://example.com/mcp")).toBeInTheDocument();
92+
});
93+
5494
it("invokes onClear and onExport", async () => {
5595
const user = userEvent.setup();
5696
const onClear = vi.fn();

clients/web/src/components/groups/NetworkStreamPanel/NetworkStreamPanel.tsx

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,13 @@ function formatTitle(count: number): string {
4040
return `Requests (${count})`;
4141
}
4242

43+
function headersToString(headers: Record<string, string> | undefined): string {
44+
if (!headers) return "";
45+
return Object.entries(headers)
46+
.map(([k, v]) => `${k}: ${v}`)
47+
.join("\n");
48+
}
49+
4350
function matchesFilters(
4451
entry: FetchRequestEntry,
4552
filterText: string,
@@ -48,18 +55,21 @@ function matchesFilters(
4855
if (!visibleCategories[entry.category]) return false;
4956
if (filterText) {
5057
const term = filterText.toLowerCase();
51-
const requestHeadersText = Object.entries(entry.requestHeaders)
52-
.map(([k, v]) => `${k}: ${v}`)
53-
.join("\n");
54-
const responseHeadersText = entry.responseHeaders
55-
? Object.entries(entry.responseHeaders)
56-
.map(([k, v]) => `${k}: ${v}`)
57-
.join("\n")
58-
: "";
5958
const status =
6059
entry.responseStatus !== undefined ? String(entry.responseStatus) : "";
61-
const searchable =
62-
`${entry.method} ${entry.url} ${status} ${requestHeadersText} ${responseHeadersText} ${entry.error ?? ""}`.toLowerCase();
60+
const searchable = [
61+
entry.method,
62+
entry.url,
63+
status,
64+
entry.responseStatusText ?? "",
65+
headersToString(entry.requestHeaders),
66+
headersToString(entry.responseHeaders),
67+
entry.requestBody ?? "",
68+
entry.responseBody ?? "",
69+
entry.error ?? "",
70+
]
71+
.join(" ")
72+
.toLowerCase();
6373
if (!searchable.includes(term)) return false;
6474
}
6575
return true;

0 commit comments

Comments
 (0)