A Model Context Protocol (MCP) server that empowers AI agents with Wireshark/tshark capabilities for deep packet analysis, live traffic capture, and protocol statistics.
wireshark-mcp
English · 简体中文
A server that exposes Wireshark / tshark packet-analysis capabilities as MCP (Model Context Protocol) tools. It lets AI clients such as Cursor / Claude Desktop read pcaps, filter with display filters, inspect layer-by-layer dissections, follow streams, run protocol/conversation statistics, and capture live traffic.
Stack: TypeScript +
@modelcontextprotocol/sdk, invokingtsharkviachild_process.spawn(array args, no shell — no command-injection risk).
Features (13 tools)
| Category | Tool | Purpose | Under the hood |
|---|---|---|---|
| File analysis | read_capture | Read a pcap; one-line summary per packet (supports display filters) | tshark -r -Y |
| File analysis | get_packet_detail | Full layer-by-layer dissection of one frame (text/json/pdml) | tshark -Y frame.number==N -V |
| File analysis | extract_fields | Extract chosen fields as delimited text | tshark -T fields -e ... |
| File analysis | capture_info | File-level metadata (packet count / duration / rate, etc.) | capinfos |
| Statistics | protocol_hierarchy | Protocol hierarchy statistics | tshark -z io,phs |
| Statistics | conversations | Conversation statistics (tcp/udp/ip/...) | tshark -z conv,<type> |
| Statistics | endpoints | Endpoint statistics | tshark -z endpoints,<type> |
| Statistics | expert_info | Expert info (anomalies/retransmissions/warnings) | tshark -z expert |
| Statistics | io_statistics | Throughput over time intervals | tshark -z io,stat,<iv> |
| Stream | follow_stream | Reassemble TCP/UDP/TLS/HTTP stream content | tshark -z follow,... |
| Live capture | list_interfaces | List capturable interfaces | tshark -D |
| Live capture | capture_live | Live capture (stop by count/duration, optional save) | tshark -i -c -a -w |
| Advanced | run_tshark | Pass through arbitrary tshark args (escape hatch) | tshark <args...> |
Requirements
- Node.js ≥ 18
- Wireshark / tshark (installing Wireshark also provides
tshark/capinfos/dumpcap)-
Verify the install:
tshark --version -
The server locates the binary in order: environment variable →
PATH→ common install dirs. Typical locations:| Platform | Typical path / install | |---|---| | macOS |
/Applications/Wireshark.app/Contents/MacOS/tshark| | Linux (apt) |/usr/bin/tshark(sudo apt install tshark) | | Linux (dnf) |/usr/bin/tshark(sudo dnf install wireshark-cli) | | Homebrew |/opt/homebrew/bin/tshark| | Windows |C:\Program Files\Wireshark\tshark.exe| -
If it lives elsewhere, set the
TSHARK_PATHenvironment variable explicitly (see below).
-
Install & Build
# 1. Get the code (git clone or download, then enter the project dir)
git clone <repo-url> wireshark-mcp
cd wireshark-mcp
# 2. Install dependencies
npm install
# 3. Build (output goes to dist/)
npm run build
This repo ships no build artifacts — run
npm run buildyourself. Usenpm run devto watch-compile during development. After building, the entry point isdist/index.js; the client config below needs its absolute path. Get the absolute path: runpwd(macOS/Linux) orcd(Windows) in the project root, then append/dist/index.js.
Connect from a client
Cursor (~/.cursor/mcp.json or project .cursor/mcp.json)
Replace
<ABSOLUTE_PATH_TO_PROJECT>with this project's absolute path on your machine (the directory containingpackage.json).
{
"mcpServers": {
"wireshark": {
"command": "node",
"args": ["<ABSOLUTE_PATH_TO_PROJECT>/dist/index.js"]
}
}
}
Claude Desktop (claude_desktop_config.json)
envis optional: only setTSHARK_PATHwhen tshark is not in a default location and cannot be auto-detected; otherwise omit the wholeenvblock.
{
"mcpServers": {
"wireshark": {
"command": "node",
"args": ["<ABSOLUTE_PATH_TO_PROJECT>/dist/index.js"],
"env": {
"TSHARK_PATH": "<PATH_TO_TSHARK>"
}
}
}
}
Optional environment variables
| Variable | Description |
|---|---|
| TSHARK_PATH | Path to the tshark executable |
| CAPINFOS_PATH | Path to the capinfos executable |
| DUMPCAP_PATH | Path to the dumpcap executable |
Tool usage examples
Arguments are structured JSON passed by the MCP client. Key parameters:
read_capture
{
"file": "/path/to/a.pcapng",
"filter": "http || dns", // optional: Wireshark display filter
"limit": 100 // optional: max lines returned, default 100
}
get_packet_detail
{ "file": "/path/to/a.pcapng", "frame_number": 42, "format": "text" }
extract_fields
{
"file": "/path/to/a.pcapng",
"fields": ["frame.number", "ip.src", "ip.dst", "tcp.stream", "http.host"],
"filter": "http.request",
"limit": 200
}
follow_stream
{ "file": "/path/to/a.pcapng", "protocol": "tcp", "stream_index": 0, "mode": "ascii" }
Tip: get
stream_indexby first extractingtcp.stream/udp.streamviaextract_fields.
conversations / endpoints
{ "file": "/path/to/a.pcapng", "type": "tcp" } // type: tcp|udp|ip|ipv6|eth
capture_live
{
"interface": "en0", // from list_interfaces
"count": 50, // one of count/duration, default count=50
"duration": 10, // optional: max capture seconds
"filter": "tcp port 443", // optional: BPF capture filter
"output_file": "/tmp/cap.pcapng" // optional: write to disk
}
Live capture on macOS/Linux usually needs privileges (ChmodBPF installed, or root).
run_tshark (advanced escape hatch)
{ "args": ["-r", "/path/a.pcapng", "-q", "-z", "http,tree"], "timeout_seconds": 60 }
Common use cases
Give the AI a capture file path and describe your goal in natural language; it will pick and chain the tools below.
| Scenario | Approach | Tools |
|---|---|---|
| Understand an unknown pcap fast | Overview first, then protocol mix | capture_info → protocol_hierarchy |
| Diagnose TCP retransmission/reordering/loss | Read expert info, locate the bad stream | expert_info → conversations → follow_stream |
| Analyze a specific HTTP request | Filter HTTP, extract fields, follow the whole stream | read_capture(filter: http) → extract_fields → follow_stream |
| Investigate DNS resolution | Extract query/response fields | extract_fields(dns.qry.name,dns.a) |
| Pinpoint TLS handshake failures | Filter handshake, inspect a single packet | read_capture(filter: tls.handshake) → get_packet_detail |
| Find who is using bandwidth | Sort endpoints/conversations by bytes, view throughput | endpoints / conversations → io_statistics |
| Capture live traffic, then analyze | Capture to disk, then analyze offline | list_interfaces → capture_live(output_file) → read_capture |
| Statistics not covered here | Call tshark's -z directly | run_tshark |
Example conversation
You: Analyze
/tmp/web.pcapng— why was this HTTP request slow?AI (auto-orchestrated): ①
capture_infofor duration/packet count → ②read_capturefilter=httpto find the request frame andtcp.stream→ ③expert_infoto check retransmissions on that stream → ④follow_streamto inspect the full request/response and timing.
Design & Security
- No injection risk: all external commands use
spawn(bin, argsArray)without a shell, so special characters in filters are never interpreted as commands. - Timeout protection: 60s by default; live capture scales with
duration/count. - Output cap: a single stdout over 32MB is auto-terminated and truncated to avoid overwhelming the process.
- Errors as data: tool-level exceptions are returned as
isErrortext per the MCP spec, readable by the client. - Result paging:
read_capture/extract_fields/follow_streamsupportlimitto bound the response size. - Output correctness: child-process output is decoded via
Buffer.concatto avoid garbled multi-byte UTF-8 characters split across data chunks.
Troubleshooting
| Symptom | Likely cause | Fix |
|---|---|---|
| Cannot execute tshark … | Wireshark not installed, or not in PATH/default dirs | Install Wireshark; or set TSHARK_PATH in the client env to the tshark executable |
| list_interfaces empty / capture_live permission error | Missing capture privileges | macOS: install Wireshark's ChmodBPF; Linux: use sudo or setcap cap_net_raw,cap_net_admin+eip $(which dumpcap) |
| tshark output exceeds the 32MB limit | Result too large | Add a more specific filter, lower limit, or use extract_fields to take only needed fields |
| Returns (no matching packets) / empty | Wrong filter, or genuinely no match | Verify it is display-filter syntax (not BPF); run read_capture without a filter first to confirm there is data |
| Client doesn't show the tools | Wrong path or not built | Ensure npm run build ran, args points to the real absolute dist/index.js, and restart the client |
| capture_live hangs until timeout | Using count but traffic is low | Use duration to bound seconds, or add a filter to match the target traffic |
Debug tip: run
node dist/index.jsdirectly; on a healthy start it prints a startup line to stderr (logs go to stderr, never polluting the stdio protocol).
Project structure
wireshark/
├── package.json
├── tsconfig.json
├── README.md # English docs (default)
├── README.zh-CN.md # Simplified Chinese docs
└── src/
├── index.ts # entry: create server, register tools, connect stdio
├── tshark.ts # tshark wrapper: locate / exec / timeout / errors / truncate
└── tools/
├── index.ts # aggregate registration
├── file.ts # read_capture / get_packet_detail / extract_fields / capture_info
├── stats.ts # protocol_hierarchy / conversations / endpoints / expert_info / io_statistics
├── follow.ts # follow_stream
├── live.ts # list_interfaces / capture_live
└── raw.ts # run_tshark
License
MIT