Skip to main content
Glama

start_network_capture

Capture network traffic in browser sessions to analyze API calls, debug network issues, and monitor real-time data flows including HTTP requests, WebSocket frames, and streaming responses.

Instructions

Start capturing network traffic on the current browser session. Monitors all HTTP requests and responses, WebSocket frames, and streaming data. Can filter by POST requests only, streaming responses only, or specific URL patterns. Essential for analyzing API calls, debugging network issues, or monitoring real-time data flows.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
sessionIdYesSession ID obtained from initialize_session
optionsNoOptional capture configuration

Implementation Reference

  • Core handler function that initializes network capture session, sets up CDP event listeners for HTTP requests, responses, WebSocket frames, applies filters, stores data in session object, and returns capture status.
    export async function startNetworkCapture(sessionId, options = {}) {
      const session = global.activeSessions?.get(sessionId);
      if (!session) {
        throw new Error(
          `Session ${sessionId} not found. Call initializeSession first.`
        );
      }
    
      const {
        capturePostOnly = false,
        captureStreaming = false,
        urlFilters = [],
        maxCaptures = 100,
      } = options;
    
      // Initialize capture storage
      const captureData = {
        sessionId,
        startTime: Date.now(),
        requests: [],
        responses: [],
        wsFrames: [],
        streamingResponses: [],
        options: { capturePostOnly, captureStreaming, urlFilters, maxCaptures },
      };
    
      // Store capture data in session
      session.networkCapture = captureData;
    
      // Set up CDP session for network monitoring
      const client = await session.context.newCDPSession(session.page);
      await client.send("Network.enable");
      await client.send("Fetch.enable", {
        patterns: [{ requestStage: "Response" }],
      });
    
      // Store client reference for cleanup
      captureData.cdpClient = client;
    
      // Network request capture
      client.on("Network.requestWillBeSent", (params) => {
        try {
          const { requestId, request, timestamp } = params;
    
          // Apply filters
          if (capturePostOnly && request.method !== "POST") return;
          if (
            urlFilters.length > 0 &&
            !urlFilters.some((pattern) => request.url.includes(pattern))
          )
            return;
    
          const requestData = {
            requestId,
            url: request.url,
            method: request.method,
            timestamp,
            headers: request.headers,
            postData: request.postData || null,
          };
    
          captureData.requests.push(requestData);
    
          // Limit storage
          if (captureData.requests.length > maxCaptures) {
            captureData.requests.shift();
          }
        } catch (e) {
          // Ignore capture errors
        }
      });
    
      // Network response capture
      client.on("Network.responseReceived", async (params) => {
        try {
          const { requestId, response } = params;
          const matchingRequest = captureData.requests.find(
            (r) => r.requestId === requestId
          );
          if (!matchingRequest) return;
    
          // Apply streaming filter if enabled
          if (captureStreaming) {
            const isStreaming =
              NetworkUtilities.isStreamingHeaders(response.headers) ||
              response.mimeType?.includes("stream") ||
              response.headers["transfer-encoding"] === "chunked";
            if (!isStreaming) return;
          }
    
          const responseData = {
            requestId,
            url: response.url,
            status: response.status,
            statusText: response.statusText,
            headers: response.headers,
            mimeType: response.mimeType,
            timestamp: Date.now(),
          };
    
          // Try to capture response body for small responses
          if (
            response.headers["content-length"] &&
            parseInt(response.headers["content-length"]) < 10000
          ) {
            try {
              const body = await client.send("Network.getResponseBody", {
                requestId,
              });
              responseData.body = body.body;
              responseData.base64Encoded = body.base64Encoded;
            } catch (e) {
              // Body capture failed, continue without it
            }
          }
    
          captureData.responses.push(responseData);
    
          // Limit storage
          if (captureData.responses.length > maxCaptures) {
            captureData.responses.shift();
          }
        } catch (e) {
          // Ignore capture errors
        }
      });
    
      // WebSocket frame capture
      client.on("Network.webSocketFrameReceived", (params) => {
        try {
          const frameData = {
            timestamp: Date.now(),
            type: "received",
            opcode: params.response.opcode,
            payload: params.response.payloadData,
          };
    
          captureData.wsFrames.push(frameData);
    
          if (captureData.wsFrames.length > maxCaptures) {
            captureData.wsFrames.shift();
          }
        } catch (e) {
          // Ignore capture errors
        }
      });
    
      client.on("Network.webSocketFrameSent", (params) => {
        try {
          const frameData = {
            timestamp: Date.now(),
            type: "sent",
            opcode: params.response.opcode,
            payload: params.response.payloadData,
          };
    
          captureData.wsFrames.push(frameData);
    
          if (captureData.wsFrames.length > maxCaptures) {
            captureData.wsFrames.shift();
          }
        } catch (e) {
          // Ignore capture errors
        }
      });
    
      return {
        sessionId,
        captureId: `capture_${Date.now()}`,
        status: "active",
        options: captureData.options,
        message: "Network capture started successfully",
      };
    }
  • MCP tool schema definition including name, description, and inputSchema with parameters for sessionId and optional capture options.
    {
      name: "start_network_capture",
      description:
        "Start capturing network traffic on the current browser session. Monitors all HTTP requests and responses, WebSocket frames, and streaming data. Can filter by POST requests only, streaming responses only, or specific URL patterns. Essential for analyzing API calls, debugging network issues, or monitoring real-time data flows.",
      inputSchema: {
        type: "object",
        properties: {
          sessionId: {
            type: "string",
            description: "Session ID obtained from initialize_session",
          },
          options: {
            type: "object",
            description: "Optional capture configuration",
            properties: {
              capturePostOnly: {
                type: "boolean",
                description: "Only capture POST requests (default: false)",
                default: false,
              },
              captureStreaming: {
                type: "boolean",
                description:
                  "Only capture streaming responses (default: false)",
                default: false,
              },
              urlFilters: {
                type: "array",
                items: { type: "string" },
                description:
                  "Array of URL patterns to filter captures (default: [])",
                default: [],
              },
              maxCaptures: {
                type: "number",
                description:
                  "Maximum number of captures to store (default: 100)",
                default: 100,
              },
            },
          },
        },
        required: ["sessionId"],
      },
    },
  • src/index.js:555-565 (registration)
    Tool dispatch registration in the CallToolRequestSchema switch statement that validates parameters and invokes the startNetworkCapture handler.
    case "start_network_capture": {
      const { sessionId, options = {} } = args;
      if (!sessionId) {
        throw new McpError(
          ErrorCode.InvalidParams,
          "sessionId parameter is required"
        );
      }
      result = await startNetworkCapture(sessionId, options);
      break;
    }
  • Re-export of network capture tools from networkCapture.js, enabling import in src/index.js.
    export {
      startNetworkCapture,
      stopNetworkCapture,
      getNetworkCaptureStatus,
      clearNetworkCapture,
    } from "./networkCapture.js";
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full burden. It discloses behavioral traits such as what gets monitored (HTTP requests/responses, WebSocket frames, streaming data) and filtering capabilities, but lacks details on permissions, rate limits, or what happens if a capture is already running.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is appropriately sized and front-loaded, with the first sentence stating the core purpose and subsequent sentences adding useful context without redundancy. Every sentence earns its place by elaborating on capabilities and use cases.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the complexity of a network capture tool with no annotations and no output schema, the description is adequate but incomplete. It covers what the tool does and why to use it, but lacks details on output format, error handling, or dependencies like requiring an initialized session.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents all parameters thoroughly. The description adds marginal value by mentioning filtering options (POST requests, streaming responses, URL patterns) but does not provide additional syntax or format details beyond what the schema specifies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the verb 'start capturing' with the specific resource 'network traffic on the current browser session' and distinguishes it from siblings like stop_network_capture and get_network_capture_status by indicating it initiates monitoring rather than stopping or checking status.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It provides clear context for when to use this tool ('essential for analyzing API calls, debugging network issues, or monitoring real-time data flows'), but does not explicitly mention when not to use it or name specific alternatives among siblings like stop_network_capture for ending captures.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other 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/pyscout/webscout-mcp'

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