Skip to main content
Glama

list_network_requests

Monitor and filter network activity in Firefox to analyze HTTP requests, track performance, and debug web applications using customizable parameters.

Instructions

List network requests. Returns IDs for get_network_request.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
limitNoMax requests (default: 50)
sinceMsNoOnly last N ms
urlContainsNoURL filter (case-insensitive)
methodNoHTTP method filter
statusNoExact status code
statusMinNoMin status code
statusMaxNoMax status code
isXHRNoXHR/fetch only
resourceTypeNoResource type filter
sortByNoSort field (default: timestamp)
detailNoDetail level (default: summary)
formatNoOutput format (default: text)

Implementation Reference

  • Main handler function that fetches network requests from Firefox DevTools, applies filters, sorting, limiting, and formats the output in text or JSON.
    export async function handleListNetworkRequests(args: unknown): Promise<McpToolResponse> { try { const { limit = 50, sinceMs, urlContains, method, status, statusMin, statusMax, isXHR, resourceType, sortBy = 'timestamp', detail = 'summary', format = 'text', } = (args as { limit?: number; sinceMs?: number; urlContains?: string; method?: string; status?: number; statusMin?: number; statusMax?: number; isXHR?: boolean; resourceType?: string; sortBy?: 'timestamp' | 'duration' | 'status'; detail?: 'summary' | 'min' | 'full'; format?: 'text' | 'json'; }) || {}; const { getFirefox } = await import('../index.js'); const firefox = await getFirefox(); let requests = await firefox.getNetworkRequests(); // Apply time filter if (sinceMs !== undefined) { const cutoffTime = Date.now() - sinceMs; requests = requests.filter((req) => req.timestamp && req.timestamp >= cutoffTime); } // Apply filters if (urlContains) { const urlLower = urlContains.toLowerCase(); requests = requests.filter((req) => req.url.toLowerCase().includes(urlLower)); } if (method) { const methodUpper = method.toUpperCase(); requests = requests.filter((req) => req.method.toUpperCase() === methodUpper); } if (status !== undefined) { requests = requests.filter((req) => req.status === status); } if (statusMin !== undefined) { requests = requests.filter((req) => req.status !== undefined && req.status >= statusMin); } if (statusMax !== undefined) { requests = requests.filter((req) => req.status !== undefined && req.status <= statusMax); } if (isXHR !== undefined) { requests = requests.filter((req) => req.isXHR === isXHR); } if (resourceType) { const typeLower = resourceType.toLowerCase(); requests = requests.filter((req) => req.resourceType?.toLowerCase() === typeLower); } // Sort requests if (sortBy === 'timestamp') { requests.sort((a, b) => (b.timestamp || 0) - (a.timestamp || 0)); } else if (sortBy === 'duration') { requests.sort((a, b) => (b.timings?.duration || 0) - (a.timings?.duration || 0)); } else if (sortBy === 'status') { requests.sort((a, b) => (a.status || 0) - (b.status || 0)); } // Apply limit const limitedRequests = requests.slice(0, limit); const hasMore = requests.length > limit; // Format output based on detail level and format if (format === 'json') { // JSON format - return structured data based on detail level const responseData: any = { total: requests.length, showing: limitedRequests.length, hasMore, requests: [], }; if (detail === 'summary' || detail === 'min') { responseData.requests = limitedRequests.map((req) => ({ id: req.id, url: req.url, method: req.method, status: req.status, statusText: req.statusText, resourceType: req.resourceType, isXHR: req.isXHR, duration: req.timings?.duration, })); } else { // Full detail - apply header truncation to prevent token overflow responseData.requests = limitedRequests.map((req) => ({ id: req.id, url: req.url, method: req.method, status: req.status, statusText: req.statusText, resourceType: req.resourceType, isXHR: req.isXHR, timings: req.timings || null, requestHeaders: truncateHeaders(req.requestHeaders), responseHeaders: truncateHeaders(req.responseHeaders), })); } return jsonResponse(responseData); } // Text format (default) if (detail === 'summary') { const formattedRequests = limitedRequests.map((req) => { const statusInfo = req.status ? `[${req.status}${req.statusText ? ' ' + req.statusText : ''}]` : '[pending]'; return `${req.id} | ${req.method} ${req.url} ${statusInfo}${req.isXHR ? ' (XHR)' : ''}`; }); const header = `📡 ${requests.length} requests${hasMore ? ` (limit ${limit})` : ''}\n`; return successResponse(header + formattedRequests.join('\n')); } else if (detail === 'min') { // Compact JSON const minData = limitedRequests.map((req) => ({ id: req.id, url: req.url, method: req.method, status: req.status, statusText: req.statusText, resourceType: req.resourceType, isXHR: req.isXHR, duration: req.timings?.duration, })); return successResponse( `📡 ${requests.length} requests${hasMore ? ` (limit ${limit})` : ''}\n` + JSON.stringify(minData, null, 2) ); } else { // Full JSON including headers - apply truncation to prevent token overflow const fullData = limitedRequests.map((req) => ({ id: req.id, url: req.url, method: req.method, status: req.status, statusText: req.statusText, resourceType: req.resourceType, isXHR: req.isXHR, timings: req.timings || null, requestHeaders: truncateHeaders(req.requestHeaders), responseHeaders: truncateHeaders(req.responseHeaders), })); return successResponse( `📡 ${requests.length} requests${hasMore ? ` (limit ${limit})` : ''}\n` + JSON.stringify(fullData, null, 2) ); } } catch (error) { return errorResponse(error instanceof Error ? error : new Error(String(error))); } }
  • Tool definition with name 'list_network_requests' and detailed inputSchema for parameters like filters, sorting, and formatting.
    export const listNetworkRequestsTool = { name: 'list_network_requests', description: 'List network requests. Returns IDs for get_network_request.', inputSchema: { type: 'object' as const, properties: { limit: { type: 'number', description: 'Max requests (default: 50)', }, sinceMs: { type: 'number', description: 'Only last N ms', }, urlContains: { type: 'string', description: 'URL filter (case-insensitive)', }, method: { type: 'string', description: 'HTTP method filter', }, status: { type: 'number', description: 'Exact status code', }, statusMin: { type: 'number', description: 'Min status code', }, statusMax: { type: 'number', description: 'Max status code', }, isXHR: { type: 'boolean', description: 'XHR/fetch only', }, resourceType: { type: 'string', description: 'Resource type filter', }, sortBy: { type: 'string', enum: ['timestamp', 'duration', 'status'], description: 'Sort field (default: timestamp)', }, detail: { type: 'string', enum: ['summary', 'min', 'full'], description: 'Detail level (default: summary)', }, format: { type: 'string', enum: ['text', 'json'], description: 'Output format (default: text)', }, }, }, };
  • src/index.ts:106-147 (registration)
    Maps the tool name 'list_network_requests' to its handler function handleListNetworkRequests in the central toolHandlers Map.
    >([ // Pages ['list_pages', tools.handleListPages], ['new_page', tools.handleNewPage], ['navigate_page', tools.handleNavigatePage], ['select_page', tools.handleSelectPage], ['close_page', tools.handleClosePage], // Script evaluation - DISABLED (see docs/future-features.md) // ['evaluate_script', tools.handleEvaluateScript], // Console ['list_console_messages', tools.handleListConsoleMessages], ['clear_console_messages', tools.handleClearConsoleMessages], // Network ['list_network_requests', tools.handleListNetworkRequests], ['get_network_request', tools.handleGetNetworkRequest], // Snapshot ['take_snapshot', tools.handleTakeSnapshot], ['resolve_uid_to_selector', tools.handleResolveUidToSelector], ['clear_snapshot', tools.handleClearSnapshot], // Input ['click_by_uid', tools.handleClickByUid], ['hover_by_uid', tools.handleHoverByUid], ['fill_by_uid', tools.handleFillByUid], ['drag_by_uid_to_uid', tools.handleDragByUidToUid], ['fill_form_by_uid', tools.handleFillFormByUid], ['upload_file_by_uid', tools.handleUploadFileByUid], // Screenshot ['screenshot_page', tools.handleScreenshotPage], ['screenshot_by_uid', tools.handleScreenshotByUid], // Utilities ['accept_dialog', tools.handleAcceptDialog], ['dismiss_dialog', tools.handleDismissDialog], ['navigate_history', tools.handleNavigateHistory], ['set_viewport_size', tools.handleSetViewportSize], ]);
  • src/index.ts:150-191 (registration)
    Includes listNetworkRequestsTool in the allTools array provided to the MCP server for listing available tools.
    const allTools = [ // Pages tools.listPagesTool, tools.newPageTool, tools.navigatePageTool, tools.selectPageTool, tools.closePageTool, // Script evaluation - DISABLED (see docs/future-features.md) // tools.evaluateScriptTool, // Console tools.listConsoleMessagesTool, tools.clearConsoleMessagesTool, // Network tools.listNetworkRequestsTool, tools.getNetworkRequestTool, // Snapshot tools.takeSnapshotTool, tools.resolveUidToSelectorTool, tools.clearSnapshotTool, // Input tools.clickByUidTool, tools.hoverByUidTool, tools.fillByUidTool, tools.dragByUidToUidTool, tools.fillFormByUidTool, tools.uploadFileByUidTool, // Screenshot tools.screenshotPageTool, tools.screenshotByUidTool, // Utilities tools.acceptDialogTool, tools.dismissDialogTool, tools.navigateHistoryTool, tools.setViewportSizeTool, ];
  • Re-exports the tool definition and handler from network.ts for use in index.ts.
    export { listNetworkRequestsTool, getNetworkRequestTool, handleListNetworkRequests, handleGetNetworkRequest, } from './network.js';

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/freema/firefox-devtools-mcp'

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