stop_capture_session
Stop a network packet capture session and analyze captured data with customizable filters and output formats for security analysis and troubleshooting.
Instructions
Stop a running capture session and analyze packets. LLMs control all analysis parameters including display filters and output formats. Can use saved configurations.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| sessionId | Yes | Session ID returned from start_capture_session | |
| displayFilter | No | Wireshark display filter for analysis (e.g., "tls.handshake.type == 1") | |
| outputFormat | No | Output format: json (-T json), fields (custom -e), or text (default wireshark output) | text |
| customFields | No | Custom tshark field list (only used with outputFormat=fields) | |
| sslKeylogFile | No | ABSOLUTE path to SSL keylog file for TLS decryption | |
| configName | No | Name of saved configuration to use for analysis parameters |
Implementation Reference
- src/tools/stop-capture-session.ts:22-130 (handler)Main handler function for stopping the capture session: validates session, stops process if running, analyzes pcap with tshark, handles configs and SSL decryption, cleans up temp file, returns formatted analysis results.export async function stopCaptureSessionHandler(args: any, activeSessions: Map<string, CaptureSession>) { try { let { sessionId, displayFilter, outputFormat, customFields, sslKeylogFile, configName } = args; const session = activeSessions.get(sessionId); if (!session) { return { content: [{ type: 'text' as const, text: `Error: No active session found with ID '${sessionId}'. Use 'list_capture_sessions' to see active sessions.`, }], isError: true }; } // If configName is provided, load and use that configuration for analysis if (configName) { const savedConfig = await loadFilterConfig(configName); if (!savedConfig) { return { content: [{ type: 'text' as const, text: `Error: Configuration '${configName}' not found. Use manage_config with action 'list' to see available configurations.`, }], isError: true }; } // Override analysis parameters with saved config (saved config takes precedence) if (savedConfig.displayFilter) displayFilter = savedConfig.displayFilter; if (savedConfig.outputFormat) outputFormat = savedConfig.outputFormat; if (savedConfig.customFields) customFields = savedConfig.customFields; console.error(`Using saved configuration '${configName}' for analysis: ${JSON.stringify(savedConfig)}`); } console.error(`Stopping capture session: ${sessionId}`); // Check if the capture process has already completed naturally if (session.process && !session.process.killed && session.status === 'running') { console.error(`Terminating capture process for session ${sessionId}`); session.process.kill('SIGTERM'); // Wait a moment for graceful termination await new Promise(resolve => setTimeout(resolve, 2000)); } else if (session.status === 'completed') { console.error(`Capture session ${sessionId} already completed naturally`); } else { console.error(`Capture session ${sessionId} process already terminated`); } // Remove from active sessions activeSessions.delete(sessionId); try { // Check if file exists await fs.access(session.tempFile); // Wait a bit more to ensure file is fully written await new Promise(resolve => setTimeout(resolve, 1000)); // Analyze captured file using the reusable function const output = await analyzePcap( session.tempFile, displayFilter, outputFormat, customFields, sslKeylogFile ); const keylogToUse = sslKeylogFile || process.env.SSLKEYLOGFILE; // Clean up temporary file await fs.unlink(session.tempFile).catch(err => console.error(`Failed to delete ${session.tempFile}: ${err.message}`) ); const duration = new Date().getTime() - session.startTime.getTime(); const durationSec = (duration / 1000).toFixed(1); // Trim output if too large const trimmedOutput = trimOutput(output, outputFormat); const configInfo = configName ? `\nUsing saved config: ${configName}` : ''; return { content: [{ type: 'text' as const, text: `Capture session '${sessionId}' completed!${configInfo}\nInterface: ${session.interface}\nDuration: ${durationSec}s\nDisplay Filter: ${displayFilter || 'none'}\nOutput Format: ${outputFormat}\nSSL Decryption: ${keylogToUse ? 'Enabled' : 'Disabled'}\n\nPacket Analysis Results:\n${trimmedOutput}`, }], }; } catch (fileError: any) { console.error(`Error analyzing session ${sessionId}: ${fileError.message}`); return { content: [{ type: 'text' as const, text: `Error analyzing session '${sessionId}': Capture file not found or unreadable. This could mean no packets were captured.\nDetails: ${fileError.message}`, }], isError: true, }; } } catch (error: any) { console.error(`Error stopping capture session: ${error.message}`); return { content: [{ type: 'text' as const, text: `Error: ${error.message}` }], isError: true }; } }
- Zod schema defining input parameters for the stop_capture_session tool, including sessionId (required), optional analysis filters, formats, fields, SSL keylog, and config.export const stopCaptureSessionSchema = { sessionId: z.string().describe('Session ID returned from start_capture_session'), displayFilter: z.string().optional().describe('Wireshark display filter for analysis (e.g., "tls.handshake.type == 1")'), outputFormat: z.enum(['json', 'fields', 'text']).optional().default('text').describe('Output format: json (-T json), fields (custom -e), or text (default wireshark output)'), customFields: z.string().optional().describe('Custom tshark field list (only used with outputFormat=fields)'), sslKeylogFile: z.string().optional().describe('ABSOLUTE path to SSL keylog file for TLS decryption'), configName: z.string().optional().describe('Name of saved configuration to use for analysis parameters') };
- src/index.ts:33-37 (registration)Registration of the stop_capture_session tool on the MCP server, using the schema and handler from stop-capture-session module.'stop_capture_session', 'Stop a running capture session and analyze packets. LLMs control all analysis parameters including display filters and output formats. Can use saved configurations.', stopCaptureSessionSchema, async (args) => stopCaptureSessionHandler(args, activeSessions) );