Skip to main content
Glama
Winds-AI

autonomous-frontend-browser-tools

browser.network.inspect

Analyze and debug browser network requests by inspecting HTTP errors (4xx/5xx), payloads, and request sequences. Filter by URL, specify details like headers and timestamps, and troubleshoot issues missed by console tools.

Instructions

Inspect recent browser network requests (DevTools-like). Use for debugging HTTP failures (4xx/5xx), payloads, and request sequences. Note: This captures network errors that console tools miss.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
detailsYesFields to include for each entry. 'timestamp' is useful for chronological ordering.
limitNoMax entries to return
orderByNoSort fieldtimestamp
orderDirectionNoSort directiondesc
timeOffsetNoRelative window in seconds (e.g., 300 = last 5 minutes, max 86400).
urlFilterYesSubstring or pattern to filter request URLs. Tips: Use partial matches; try singular/plural variants if empty.

Implementation Reference

  • Registers the browser.network.inspect MCP tool, including schema definition and handler reference.
    server.tool( "browser.network.inspect", "Inspect recent browser network requests (DevTools-like). Use for debugging HTTP failures (4xx/5xx), payloads, and request sequences. Note: This captures network errors that console tools miss.", { urlFilter: z .string() .describe( "Substring or pattern to filter request URLs. Tips: Use partial matches; try singular/plural variants if empty." ), details: z .array( z.enum([ "url", "method", "status", "timestamp", "requestHeaders", "responseHeaders", "requestBody", "responseBody", ]) ) .min(1) .describe( "Fields to include for each entry. 'timestamp' is useful for chronological ordering." ), timeOffset: z .number() .optional() .describe( "Relative window in seconds (e.g., 300 = last 5 minutes, max 86400)." ), orderBy: z .enum(["timestamp", "url"]) .optional() .default("timestamp") .describe("Sort field"), orderDirection: z .enum(["asc", "desc"]) .optional() .default("desc") .describe("Sort direction"), limit: z.number().optional().default(20).describe("Max entries to return"), }, handleInspectBrowserNetworkActivity );
  • Primary MCP tool handler for browser.network.inspect: parses params, builds query for /network-request-details, fetches and formats response.
    async function handleInspectBrowserNetworkActivity(params: any) { const { urlFilter, details, timeOffset, orderBy, orderDirection, limit } = params; const currentTime = Date.now(); let finalTimeStart: number | undefined; let finalTimeEnd: number | undefined; if (timeOffset !== undefined) { if (timeOffset <= 0) { throw new Error("timeOffset must be a positive number"); } if (timeOffset > 86400) { throw new Error("timeOffset cannot exceed 24 hours (86400 seconds)"); } finalTimeStart = currentTime - timeOffset * 1000; finalTimeEnd = currentTime; console.log( `Time offset calculation: ${timeOffset}s ago = ${new Date( finalTimeStart ).toISOString()} to ${new Date(finalTimeEnd).toISOString()}` ); } const queryString = `?urlFilter=${encodeURIComponent( urlFilter )}&details=${details.join(",")}&includeTimestamp=true${ finalTimeStart ? `&timeStart=${finalTimeStart}` : "" }${finalTimeEnd ? `&timeEnd=${finalTimeEnd}` : ""}&orderBy=${ orderBy || "timestamp" }&orderDirection=${orderDirection || "desc"}&limit=${limit || 20}`; const targetUrl = `http://${discoveredHost}:${discoveredPort}/network-request-details${queryString}`; console.log(`MCP Tool: Fetching network details from ${targetUrl}`); return await withServerConnection(async () => { try { const response = await fetch(targetUrl); if (!response.ok) { const errorText = await response.text(); throw new Error( `Server returned ${response.status}: ${ errorText || response.statusText }` ); } const json = await response.json(); const results = json; if (Array.isArray(results) && results.length === 0) { const suggestions = generateSearchSuggestions(urlFilter); return { content: [ { type: "text", text: `No API calls found matching '${urlFilter}'. Try these search strategies:\n\n${suggestions.join( "\n" )}`, }, ], } as any; } return { content: [ { type: "text", text: JSON.stringify(results, null, 2), }, ], } as any; } catch (error: any) { console.error("Error fetching network request details:", error); return { content: [ { type: "text", text: `Failed to get network request details: ${error.message}`, }, ], isError: true, } as any; } }); }
  • Browser server endpoint /network-request-details: parses query params, applies filter/sort/project/limit using helpers on detailedNetworkLogCache.
    app.get("/network-request-details", (req, res) => { if ((process.env.LOG_LEVEL || "info").toLowerCase() === "debug") { console.log("[debug] /network-request-details hit", req.query); } try { const urlFilter = String(req.query.urlFilter ?? ""); const detailsCsv = String(req.query.details ?? "url,method,status"); const details = detailsCsv .split(",") .filter(Boolean) as any as NetworkFilterParams["details"]; const includeTimestamp = String(req.query.includeTimestamp ?? "true") === "true"; const timeStart = req.query.timeStart ? Number(req.query.timeStart) : undefined; const timeEnd = req.query.timeEnd ? Number(req.query.timeEnd) : undefined; const orderBy = String( req.query.orderBy ?? "timestamp" ) as any as NetworkFilterParams["orderBy"]; const orderDirection = String( req.query.orderDirection ?? "desc" ) as any as NetworkFilterParams["orderDirection"]; const limit = req.query.limit ? Number(req.query.limit) : 20; let results = filterNetworkLogs(detailedNetworkLogCache, { urlFilter, timeStart, timeEnd, }); results = sortNetworkLogs(results, orderBy, orderDirection); const projected = projectNetworkLogDetails( results, details, includeTimestamp ); const limited = limitResults(projected, limit); res.json(limited); } catch (e: any) { res .status(500) .json({ error: e?.message || "Failed to read network details" }); } });
  • Supporting helper functions: filterNetworkLogs, sortNetworkLogs, projectNetworkLogDetails, limitResults used by the network endpoint.
    /** * Refactor Temp: Tool — inspectBrowserNetworkActivity * Stateless helpers to filter, sort, and format network logs captured from the extension. * Keep HTTP bindings and in-memory caches in browser-connector.ts. */ export type OrderByField = "timestamp" | "url"; export type OrderDirection = "asc" | "desc"; export type DetailKey = | "url" | "method" | "status" | "timestamp" | "requestHeaders" | "responseHeaders" | "requestBody" | "responseBody"; export interface NetworkFilterParams { urlFilter: string; details: DetailKey[]; includeTimestamp?: boolean; timeStart?: number; timeEnd?: number; orderBy?: OrderByField; orderDirection?: OrderDirection; limit?: number; } /** * Apply URL substring filter and optional time window to logs. */ export function filterNetworkLogs< T extends { url?: string; timestamp?: number } >( logs: T[], params: Pick<NetworkFilterParams, "urlFilter" | "timeStart" | "timeEnd"> ): T[] { const term = (params.urlFilter || "").toLowerCase(); return logs.filter((log) => { const urlMatch = term ? (log.url || "").toLowerCase().includes(term) : true; const ts = typeof log.timestamp === "number" ? log.timestamp : undefined; const afterStart = params.timeStart ? ts ? ts >= params.timeStart : false : true; const beforeEnd = params.timeEnd ? ts ? ts <= params.timeEnd : false : true; return urlMatch && afterStart && beforeEnd; }); } /** * Sort logs by timestamp or url with direction. */ export function sortNetworkLogs<T extends { timestamp?: number; url?: string }>( logs: T[], orderBy: OrderByField = "timestamp", orderDirection: OrderDirection = "desc" ): T[] { const sorted = [...logs]; sorted.sort((a, b) => { if (orderBy === "url") { const ua = (a.url || "").toLowerCase(); const ub = (b.url || "").toLowerCase(); const cmp = ua.localeCompare(ub); return orderDirection === "asc" ? cmp : -cmp; } else { const ta = typeof a.timestamp === "number" ? a.timestamp : 0; const tb = typeof b.timestamp === "number" ? b.timestamp : 0; const cmp = ta - tb; return orderDirection === "asc" ? cmp : -cmp; } }); return sorted; } /** * Project only requested details to reduce payload size. */ export function projectNetworkLogDetails( logs: any[], details: DetailKey[], includeTimestamp: boolean = true ): any[] { const want = new Set(details); return logs.map((log) => { const out: any = {}; if (want.has("url")) out.url = log.url; if (want.has("method")) out.method = log.method; if (want.has("status")) out.status = log.status; if (includeTimestamp) out.timestamp = log.timestamp; if (want.has("requestHeaders")) out.requestHeaders = log.requestHeaders; if (want.has("responseHeaders")) out.responseHeaders = log.responseHeaders; if (want.has("requestBody")) out.requestBody = log.requestBody; if (want.has("responseBody")) out.responseBody = log.responseBody; return out; }); } /** * Enforce a hard limit on number of results. */ export function limitResults<T>(logs: T[], limit: number = 20): T[] { if (limit <= 0) return []; return logs.slice(0, limit); }

Other Tools

Related Tools

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/Winds-AI/Frontend-development-MCP-tools-public'

If you have feedback or need assistance with the MCP directory API, please join our Discord server