@modular-intelligence/pcap-analysis
v1.0.2
Published
MCP server for network capture (PCAP) analysis via tshark
Readme
PCAP Analysis MCP Server
A Model Context Protocol (MCP) server for network packet capture (PCAP) analysis via tshark, the command-line interface for Wireshark. Enables Claude and other MCP clients to analyze network traffic data with tools for protocol hierarchy inspection, DNS extraction, HTTP request parsing, connection enumeration, and custom packet filtering.
Overview
This server provides programmatic access to network capture analysis without requiring direct Wireshark GUI interaction. It uses tshark under the hood to parse PCAP files and extract structured network intelligence. All analysis is performed locally—no data leaves your system.
Tools
The server exposes five specialized tools for different aspects of PCAP analysis:
| Tool | Purpose |
|------|---------|
| pcap_summary | High-level statistics and protocol breakdown |
| pcap_dns | DNS query and response extraction |
| pcap_http | HTTP request and response parsing |
| pcap_connections | Connection tuples with flow statistics |
| pcap_filter | Custom BPF-filtered packet output |
pcap_summary
Generates a comprehensive summary of a PCAP file including file metadata, protocol hierarchy, top IP talkers, and conversation count.
Input Schema:
{
"file": "string (absolute path to PCAP file, required)"
}Example Request:
{
"file": "/var/tmp/capture.pcap"
}Example Output:
{
"file": "/var/tmp/capture.pcap",
"file_size": 2457600,
"packet_count": 8942,
"capture_duration": 342.5,
"first_packet_time": "Feb 7, 2026 10:14:22.123456 PST",
"last_packet_time": "Feb 7, 2026 10:20:04.987654 PST",
"protocols": [
{
"name": "eth",
"packets": 8942,
"percentage": 100.0
},
{
"name": "ip",
"packets": 8635,
"percentage": 96.56
},
{
"name": "tcp",
"packets": 5420,
"percentage": 60.65
},
{
"name": "dns",
"packets": 284,
"percentage": 3.18
},
{
"name": "http",
"packets": 1203,
"percentage": 13.46
},
{
"name": "tls",
"packets": 2104,
"percentage": 23.54
}
],
"top_talkers": [
{
"ip": "192.168.1.100",
"packets": 3421,
"bytes": 1847362
},
{
"ip": "10.0.0.1",
"packets": 2156,
"bytes": 985621
},
{
"ip": "172.16.0.50",
"packets": 1842,
"bytes": 652184
}
],
"conversation_count": 42
}Description:
file_size: Capture file size in bytespacket_count: Total packets capturedcapture_duration: Time span between first and last packet (seconds)first_packet_time,last_packet_time: Capture window boundariesprotocols: Array of up to 20 protocols from Wireshark's protocol hierarchy. Percentage shows fraction of total packetstop_talkers: Up to 10 most active IP addresses by packet count. Includes both transmitted and received bytesconversation_count: Unique IP pairs that exchanged traffic
pcap_dns
Extracts DNS queries and responses from a PCAP, revealing domain resolution activity.
Input Schema:
{
"file": "string (absolute path to PCAP file, required)",
"max_results": "integer (1-5000, default: 500)"
}Example Request:
{
"file": "/var/tmp/capture.pcap",
"max_results": 100
}Example Output:
{
"file": "/var/tmp/capture.pcap",
"total_queries": 24,
"queries": [
{
"timestamp": "Feb 7, 2026 10:14:35.234567 PST",
"source": "192.168.1.100",
"query_name": "www.example.com",
"query_type": "A",
"response_code": "0",
"answers": ["93.184.216.34"]
},
{
"timestamp": "Feb 7, 2026 10:14:36.456789 PST",
"source": "192.168.1.100",
"query_name": "api.github.com",
"query_type": "A",
"response_code": "0",
"answers": ["140.82.113.5", "140.82.113.4"]
},
{
"timestamp": "Feb 7, 2026 10:14:37.678901 PST",
"source": "192.168.1.105",
"query_name": "internal.corp",
"query_type": "A",
"response_code": "3",
"answers": []
}
],
"unique_domains": [
"api.github.com",
"internal.corp",
"www.example.com"
]
}Description:
timestamp: When the DNS query was observedsource: IP address that initiated the queryquery_name: Domain name being resolvedquery_type: DNS record type (A, AAAA, MX, CNAME, etc.)response_code: DNS response code (0=success, 3=NXDomain, etc.)answers: List of resolved IP addresses or CNAME targetsunique_domains: Sorted list of all queried domains for quick reference
pcap_http
Extracts HTTP requests and responses, capturing web traffic details including method, URI, host, status codes, and user agents.
Input Schema:
{
"file": "string (absolute path to PCAP file, required)",
"max_results": "integer (1-5000, default: 500)"
}Example Request:
{
"file": "/var/tmp/capture.pcap",
"max_results": 50
}Example Output:
{
"file": "/var/tmp/capture.pcap",
"total_requests": 12,
"requests": [
{
"timestamp": "Feb 7, 2026 10:15:02.123456 PST",
"source": "192.168.1.100",
"destination": "93.184.216.34",
"method": "GET",
"uri": "/path/to/resource?key=value",
"host": "www.example.com",
"status_code": 200,
"content_type": "text/html; charset=utf-8",
"user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)"
},
{
"timestamp": "Feb 7, 2026 10:15:03.234567 PST",
"source": "192.168.1.100",
"destination": "93.184.216.34",
"method": "POST",
"uri": "/api/submit",
"host": "www.example.com",
"status_code": 201,
"content_type": null,
"user_agent": "curl/7.68.0"
},
{
"timestamp": "Feb 7, 2026 10:15:04.345678 PST",
"source": "192.168.1.105",
"destination": "140.82.112.22",
"method": "GET",
"uri": "/api/users",
"host": "api.github.com",
"status_code": 301,
"content_type": null,
"user_agent": "python-requests/2.28.1"
}
]
}Description:
timestamp: When the HTTP request or response was capturedsource: Client IP addressdestination: Server IP addressmethod: HTTP verb (GET, POST, PUT, DELETE, etc.)uri: Full request path and query stringhost: HTTP Host header valuestatus_code: HTTP response status (200, 404, 500, etc.). May be null for requests without captured responsescontent_type: Response Content-Type header, or null if not captureduser_agent: User-Agent header string, or null if not captured
pcap_connections
Lists all TCP/UDP connections (flow tuples) with packet and byte counts, timing information, and protocol type filtering.
Input Schema:
{
"file": "string (absolute path to PCAP file, required)",
"protocol": "string enum ('tcp', 'udp', 'all', default: 'all')",
"max_results": "integer (1-5000, default: 500)"
}Example Request:
{
"file": "/var/tmp/capture.pcap",
"protocol": "tcp",
"max_results": 25
}Example Output:
{
"file": "/var/tmp/capture.pcap",
"protocol": "tcp",
"total_connections": 8,
"connections": [
{
"source": "192.168.1.100",
"source_port": 52341,
"destination": "93.184.216.34",
"destination_port": 80,
"protocol": "tcp",
"packets": 45,
"bytes": 23456,
"duration": 12.34,
"start_time": "10:15:02.123456"
},
{
"source": "192.168.1.100",
"source_port": 52342,
"destination": "140.82.113.5",
"destination_port": 443,
"protocol": "tcp",
"packets": 128,
"bytes": 87634,
"duration": 45.67,
"start_time": "10:15:05.234567"
},
{
"source": "192.168.1.105",
"source_port": 61234,
"destination": "8.8.8.8",
"destination_port": 53,
"protocol": "tcp",
"packets": 3,
"bytes": 512,
"duration": 0.12,
"start_time": "10:15:15.345678"
}
]
}Description:
source,source_port: Initiating IP and portdestination,destination_port: Receiving IP and portprotocol: Protocol type filtered (tcp, udp, or ip for all)packets: Combined packet count from both directionsbytes: Combined byte count from both directionsduration: Connection lifetime in secondsstart_time: When the connection began (relative to capture start)
pcap_filter
Applies a Berkeley Packet Filter (BPF) expression to the PCAP and returns matching packets with full protocol details.
Input Schema:
{
"file": "string (absolute path to PCAP file, required)",
"filter": "string (BPF expression, required)",
"max_results": "integer (1-1000, default: 100)"
}BPF Filter Examples:
tcp port 80 # HTTP traffic
ip src 192.168.1.0/24 # Source subnet
tcp.flags.syn == 1 # TCP SYN packets
dns.qry.type == 1 # DNS A record queries
ip.len > 1000 # Packets larger than 1000 bytes
(tcp port 443) or (tcp port 80) # HTTPS or HTTPExample Request:
{
"file": "/var/tmp/capture.pcap",
"filter": "tcp port 80",
"max_results": 10
}Example Output:
{
"file": "/var/tmp/capture.pcap",
"filter": "tcp port 80",
"total_matched": 45,
"packets": [
{
"number": 107,
"timestamp": "Feb 7, 2026 10:15:02.123456 PST",
"source": "192.168.1.100",
"destination": "93.184.216.34",
"protocol": "http",
"length": 478,
"info": "GET /path/to/resource HTTP/1.1"
},
{
"number": 108,
"timestamp": "Feb 7, 2026 10:15:02.125123 PST",
"source": "93.184.216.34",
"destination": "192.168.1.100",
"protocol": "http",
"length": 1514,
"info": "HTTP/1.1 200 OK"
},
{
"number": 112,
"timestamp": "Feb 7, 2026 10:15:02.234567 PST",
"source": "192.168.1.100",
"destination": "93.184.216.34",
"protocol": "http",
"length": 234,
"info": "GET /path/to/image.jpg HTTP/1.1"
}
]
}Description:
number: Packet number in the capture file (1-indexed)timestamp: When packet was capturedsource: Source IP addressdestination: Destination IP addressprotocol: Highest layer protocol (http, dns, tls, ssh, etc.)length: Total packet size in bytesinfo: Protocol-specific summary (truncated to 200 chars)
BPF filters support full Wireshark display filter syntax. Filters are validated for injection safety (see Security section).
Prerequisites
Required: tshark
tshark is the command-line interface for Wireshark. Install it via your system package manager:
macOS (Homebrew):
brew install wiresharkUbuntu/Debian:
sudo apt-get install tsharkFedora/RHEL:
sudo dnf install wiresharkWindows (Chocolatey):
choco install wiresharktshark is a lightweight CLI tool (not the full GUI) and is included in all Wireshark distributions. Verify installation:
tshark --versionRequired: capinfos
capinfos is also included with Wireshark and provides file metadata extraction. It is automatically available once Wireshark is installed.
Verify:
capinfos --versionInstallation
Prerequisites
- Bun (v1.0+) – Install from https://bun.sh
- Node.js 18+ (if not using Bun)
Steps
- Clone or download this repository:
cd /path/to/mcp-servers/pcap-analysis- Install dependencies:
bun install- Build the server:
bun run buildThe compiled server will be available at dist/index.js.
Verify Installation
Test that the server starts:
bun run src/index.tsIf tshark/capinfos are installed correctly, the server will start without errors. Press Ctrl+C to exit.
Usage
Stdio Transport
The server uses the MCP stdio transport, meaning it communicates via standard input/output. It is designed to be invoked by MCP clients (Claude Desktop, Claude Code, etc.) rather than run directly.
Claude Desktop Configuration
Add the server to your Claude Desktop config at ~/.config/Claude/claude_desktop_config.json (macOS/Linux) or %AppData%\Claude\claude_desktop_config.json (Windows):
{
"mcpServers": {
"pcap-analysis": {
"command": "bun",
"args": ["/path/to/mcp-servers/pcap-analysis/dist/index.js"]
}
}
}Replace /path/to with the actual absolute path to the repository. Restart Claude Desktop to load the server.
Claude Code (MCP Settings)
In Claude Code, configure the server via MCP settings:
- Open Settings (Ctrl+, or Cmd+,)
- Go to MCP Servers
- Add server with:
- Command:
bun - Args:
/path/to/mcp-servers/pcap-analysis/dist/index.js - Name:
pcap-analysis
- Command:
Direct Testing
To test a tool from the command line, use the MCP Inspector or write a simple client. Example using Node.js with mcp-cli:
npm install -g mcp-cli
mcp-cli exec \
"bun /path/to/mcp-servers/pcap-analysis/dist/index.js" \
pcap_summary \
'{"file": "/path/to/your/capture.pcap"}'Security
This server implements several security measures to prevent misuse:
PCAP File Validation
All file paths are validated before use:
- File Existence: Path must point to an existing file
- File Type: Extension must be
.pcap,.pcapng, or.cap - File Size: Maximum 500 MB per file to prevent resource exhaustion
- Path Normalization: Paths are resolved and normalized to prevent directory traversal
Example error handling:
Input: {"file": "../../../etc/passwd"}
Error: Invalid file extension. Expected: .pcap, .pcapng, .cap
Input: {"file": "/var/huge-file.pcap"} (600 MB)
Error: File too large (600.0MB). Maximum: 500MBBPF Filter Injection Protection
Display filters (for pcap_filter tool) are validated to prevent shell injection:
- Length Limit: Filters are limited to 500 characters
- Character Whitelist: The following characters are blocked:
;,&,|,`,$,(,),{,}
These characters are not valid in BPF filter syntax and are rejected if present.
Example:
Input: {"filter": "tcp port 80; rm -rf /"}
Error: Filter contains disallowed characters
Input: {"filter": "tcp port $(cat /etc/passwd)"}
Error: Filter contains disallowed charactersTimeout Protection
All tshark/capinfos commands are subject to a 60-second timeout to prevent hanging processes on malformed or extremely large captures.
Output Buffer Limits
Command output is capped at 20 MB to prevent unbounded memory consumption.
License
MIT
