tshark-mcp

io.github.Kx96xx由 GitHub 帳號 Kx96xx 發布v0.2.0更新於 Nov 5, 2026

Read-only packet capture analysis with tshark: Diameter, GTP, SIP, RTP, SIGTRAN, DNS, TCP and TLS.

概覽

AI 產生的概覽

唯讀的 MCP 伺服器,用 tshark 分析本機封包擷取檔,讓助理帶幀號說明失敗的通話、attach 與工作階段。

可以做什麼
  • 對未知擷取檔做整體研判:排序後的發現、擷取品質與中繼資料檢查,以及正常與故障擷取檔的比對
  • 檢視封包:依顯示過濾器取欄位、單一訊框完整解析、專家告警、會話統計、欄位與過濾器查詢
  • 分析電信信令:Diameter、GTP、PFCP、SIP、SIGTRAN/MAP、NAS 與 IMS 註冊、簡訊投遞、原因碼查詢
  • 檢查語音與媒體:SIP 對話、通話 KPI 與話段、SDP 與實際 RTP 對照、抖動與 MOS、DTMF
  • 診斷 IP 傳輸:TCP 健康度與連線、DNS、TLS/QUIC 握手、HTTP 時延、ICMP 錯誤、通道
  • 跨協定追蹤單一用戶,在擷取目錄中尋找識別碼,並可選擇把過濾後的子集匯出成新的 pcapng
適用情境
當你手上有行動核心網路、IMS 或 IP 網路的 pcap 檔,想讓助理回答 attach 為何失敗、為何單向語音、資料工作階段為何變慢等問題,又不想給它 shell 和原始 tshark 時適用。
執行需求
以 stdio 方式在本機執行 PyPI 套件 tshark-mcp-server,可用 uvx 或 pipx;需要 Python 3.10+ 與 tshark 4.0 或更新版本(在 PATH 中或由 TSHARK_MCP_TSHARK 指定)。必須設定 TSHARK_MCP_ALLOW_DIRS(或 --allow-dir)指明可讀取的擷取目錄。另提供 Docker 映像。
安裝前請注意
擷取檔含有 IMSI、MSISDN、IMEI、IP 位址等用戶識別碼,結果離開伺服器前應開啟 TSHARK_MCP_REDACT(ids 或 ids+ips)。只有設定 TSHARK_MCP_EXPORT_DIR 時 export_subset 才會寫出新的 pcapng 檔,且該目錄不得與允許目錄重疊。可選的 streamable-http 傳輸沒有身分驗證。來自封包的文字屬於不可信資料。

安裝

在 SourceWeft 中

  1. 開啟 儀表板中的 tshark-mcp,將其新增到工作區。
  2. 為需要使用其工具的對話啟用該服務。

Desktop only,透過 STDIO。 STDIO 服務會啟動本機處理程序,因此需要 SourceWeft 桌面主機。

其他 MCP 客戶端

參照 儲存庫 中的啟動說明。

README

tshark-mcp

[CI] [PyPI] [Downloads] [Python 3.10 to 3.13] [Licence MIT]

Ask your AI assistant why a call, an attach or a session failed, and get the answer from your own pcap, with frame numbers. tshark-mcp is a read-only MCP server: it runs tshark -r on captures in directories you allow, pairs requests with answers across Diameter, GTP, SIP/RTP, SIGTRAN, DNS, TCP and TLS, and names the cause codes.

sh
claude mcp add tshark-mcp -- uvx --from tshark-mcp-server tshark-mcp --allow-dir /path/to/pcaps

(needs uv and tshark; other clients below)

[A real MCP client session: sip_dialogs and media_path_check on the one-way audio example]

A live session, not a mock-up: an MCP client starts the PyPI package over stdio and calls two tools on examples/sip_one_way_audio.pcap. Recorded with vhs from docs/media/demo.tape.

Why

  • Telecom captures need correlation, not grep. A failed attach, a dropped bearer or one-way audio spans Diameter, GTP, SIP, RTP and MAP. The tools pair requests with answers, name the result codes (Diameter 5420, GTP cause 78, Q.850 cause 16) and say what never got a reply.
  • An agent with a shell and tshark is a liability. This server can only run tshark -r <file> on files inside directories you allow, under hard caps on size, packets, output and time. It cannot capture, resolve names or load code, and it writes nothing unless the operator turns on export_subset with --export-dir.
  • It tells you when the capture itself cannot be trusted: duplicate packets from a SPAN session, bytes the capture missed, cut-short frames, checksum offload, clocks that run backwards.

Install and connect

  1. Install tshark (it comes with Wireshark): brew install --cask wireshark, apt-get install tshark or dnf install wireshark-cli.

  2. Run the server from PyPI with uv (nothing to install; Python 3.10 or newer):

    sh
    uvx --from tshark-mcp-server tshark-mcp --allow-dir /path/to/pcaps

    Or install it once and use the tshark-mcp command: uv tool install tshark-mcp-server or pipx install tshark-mcp-server.

    Requirements: Python 3.10+, tshark 4.0 or newer (tested with 4.2 and 4.6); the mcp (2.1+) and pydantic (2.12+) packages are installed automatically. The package is published as tshark-mcp-server (the PyPI name tshark-mcp belongs to an unrelated project); the command stays tshark-mcp. From a clone: uv tool install . or pipx install ..

    Or build the container (tshark included, non-root, captures mounted read-only): docker build -t tshark-mcp ., then use docker run --rm -i --read-only --tmpfs /tmp --cap-drop ALL --network none -v /path/to/pcaps:/captures:ro tshark-mcp as the server command.

  3. Connect a client, naming the directory that holds your captures.

    Claude Code:

    sh
    claude mcp add tshark-mcp -- uvx --from tshark-mcp-server tshark-mcp --allow-dir /path/to/pcaps

    Or as a Claude Code plugin (the server plus seven investigation skills; needs uv), which asks for the capture directory and redaction when enabled:

    /plugin install tshark-mcp --marketplace Kx96xx/tshark-mcp

    Claude Desktop as an extension: python mcpb/build.py && npx -y @anthropic-ai/[email protected] pack build/mcpb build/tshark-mcp.mcpb, then open build/tshark-mcp.mcpb and pick the capture directories.

    Claude Desktop (claude_desktop_config.json), Cursor, or any client that starts stdio servers:

    json
    {  "mcpServers": {    "tshark-mcp": {      "command": "uvx",      "args": ["--from", "tshark-mcp-server", "tshark-mcp", "--allow-dir", "/path/to/pcaps"]    }  }}

    With uv tool install or pipx, use "command": "tshark-mcp" and drop the first three args.

    MCP Registry clients (VS Code and the directories that index the registry) find it as io.github.Kx96xx/tshark-mcp: they run the PyPI package with uvx and ask for TSHARK_MCP_ALLOW_DIRS, the one required setting. Each GitHub release publishes the new version there (server.json).

    To run it by hand: tshark-mcp --allow-dir /path/to/pcaps [--allow-dir /more] [--log-file ~/tshark-mcp.jsonl]. TSHARK_MCP_ALLOW_DIRS (colon-separated) works instead of the flag. Three small synthetic captures to start with are in examples/.

Found a bug or a wrong answer?

Never attach a capture with real subscriber data (IMSI, MSISDN, IMEI, IP addresses) to a public issue. Share the tool call and its output, and if a capture is needed, a minimal synthetic or anonymised one (--redact ids+ips masks identifiers in the output, not in the file).

What you can ask it

Start with "What is wrong in this capture?": the assistant calls incident_summary, which runs every check the capture's protocols allow and returns ranked findings with frame numbers and the next call to make, plus the protocols it has no check for. Then ask the specific question:

  • "Which capture in this directory mentions IMSI 001010123456789, and when?"
  • "Why did this subscriber's attach fail?" (Diameter result codes and the AVPs behind them)
  • "Was the GTP session created? What cause came back, and which PAA?"
  • "What is our ASR to this destination, and did post-dial delay go up?"
  • "Why is there one-way audio on this call?"
  • "What was the call quality: loss, jitter, MOS?"
  • "Why can't this UE register on IMS?" and "Where did the SMS go?"
  • "Is this a purge storm? How often is the MME looping?"
  • "Where does the failing capture first differ from the working one?"
  • "Which DNS resolver is failing, and for which names?"
  • "Is the upload slow because of the network, the server or the receiver?"
  • "Can I trust the loss numbers in this file at all?"
  • "What does Experimental-Result 5420 mean, and which spec section do I quote?"

One real answer, trimmed. The capture is examples/sip_one_way_audio.pcap: a SIP call where the called side never sends media. The agent finds the Call-ID with sip_dialogs, then calls:

media_path_check(path="/captures/sip_one_way_audio.pcap", call_id="[email protected]")
json
{  "offer":  {"message": "INVITE", "media_endpoint": "198.51.100.9:40010", "codecs": ["PCMA/8000", "telephone-event/8000"]},  "answer": {"message": "200 INVITE", "media_endpoint": "192.0.2.70:30010", "codecs": ["PCMA/8000", "telephone-event/8000"]},  "directions": [    {"direction": "offerer to answerer", "expected": "198.51.100.9:40010 > 192.0.2.70:30010",     "streams": [{"ssrc": "0x6a6a6a6a", "packets": 250, "codec": "PCMA/8000", "first_frame": 6}], "status": "as negotiated"},    {"direction": "answerer to offerer", "expected": "192.0.2.70:30010 > 198.51.100.9:40010", "streams": [], "status": "missing"}  ],  "issues": [{"kind": "one_way_media", "detail": "no RTP seen answerer to offerer (192.0.2.70:30010 > 198.51.100.9:40010): one-way audio as captured"}],  "verdict": "no RTP seen answerer to offerer (192.0.2.70:30010 > 198.51.100.9:40010): one-way audio as captured"}

The caller's RTP arrived exactly where the SDP answer asked for it and nothing came back, so the fault is behind the media gateway, not the caller's NAT or codec. Every row carries frame numbers (first_frame: 6), so packet_detail can show the packet behind any claim. More worked examples, one per tool, are in docs/TOOLS.md; a full investigation of a failed attach is in docs/EXAMPLE.md.

Safety model

  • Read-only by construction. The only program started is tshark, from an argv list with -n and -r, never a shell. Capture, write, export and extension flags are refused before a process exists. tshark gets an empty profile, so no personal Lua script, plugin or extcap loads, and at most two tshark processes run at once.
  • One write tool, off by default. export_subset writes a filtered subset of a capture to a NEW pcapng file, only when the server was started with --export-dir DIR (a directory outside every --allow-dir), never overwrites, never writes elsewhere and is capped by --export-max-mb (50). Without the flag it refuses every call.
  • Allowlist and caps. Every path must resolve inside an --allow-dir. File size (500 MB), packets dissected per call (500), frames read per run (200 000), JSON per call (30 KB) and run time (60 s) are capped; the numbers are configurable, none can be switched off.
  • Packet text is data, not instructions. Strings copied from packets are cleaned, capped and named in untrusted_text_fields. Optional redaction (--redact ids) replaces IMSIs, MSISDNs, IMEIs, SIP users and UE addresses with stable tokens before anything leaves the server.

Transport is stdio only; --transport streamable-http is for local experiments and has no authentication. Details, the full caps table and the redaction rules: docs/SAFETY.md. How to report a vulnerability: SECURITY.md.

Tools

Fifty-five tools. Every one returns JSON with a typed `outputSchema`, pages with `limit`

and offset, takes start/end to read one time window of a capture (ISO 8601, epoch seconds, "+120s" after the capture start, "-30s" before its end), and returns failures as {"error": {...}} with isError: true and a fix hint. The tool list is compact by default (less than half the size of the full list); each tool's full schema is the resource schema://tools/<name>, and --schema-profile full publishes them all. Only the default toolset (33 tools, about 60% of the list: incident_summary, the capture overview, the most used TCP/IP and telecom tools) is listed unless you add --toolsets mobile,voice,network (or all); see AGENTS.md. Full arguments, fields and examples: docs/TOOLS.md. Every tool with limit also takes output="summary" (the summary plus three rows, under 8 KB), columns (row keys to keep) and max_output_kb (a lower cap for one call); every result says what it cost in tokens_estimate.

ToolOne line
incident_summaryStart here. First call on an unknown capture: ranked findings with evidence frames, confidence and the next call to make, plus the protocols no check covers
diff_capturesBefore and after a change: per destination, DNS name and resolver, SNI, HTTP endpoint and TCP server, what appeared, vanished, got worse or better
throughput_timelineBytes, goodput, retransmissions, window stalls, SYNs, DNS and ICMP per interval; per-stream verdict (loss, receiver, idle, sender)
tunnels_overviewGRE, ERSPAN, VXLAN, Geneve, IP-in-IP, IPsec (IKE/ESP), WireGuard, OpenVPN, L2TP and GTP-U tunnels: endpoints, traffic each way, inner protocols, overhead against the MTU, handshake outcome
export_subsetOff unless --export-dir: write the packets matching a filter and window to a new pcapng file for a vendor (never overwrites, size-capped, headers_only cuts payloads)
tls_certificatesCertificate chains servers sent (TLS 1.2 and older): expiry and days left, SAN against SNI, self-signed, missing or misordered intermediates, weak signatures and keys, OCSP stapling, clients that refused them
quic_connectionsQUIC / HTTP/3 per connection from the clear headers: version, Retry, Version Negotiation, handshake both ways, 1-RTT both ways, migration, spin-bit RTT, TCP fallback, UDP 443 blocked
find_identifierWhich captures in a directory mention an IMSI, MSISDN, IP, Call-ID or Session-Id
capture_indexA directory of ring-buffer files in time order: span, packets, holes and overlaps between files, which files cover an incident window
pcap_infoPacket count, duration, link type, protocol hierarchy, active limits
capture_metadatapcapng writer, interfaces, snaplen, capture filter and the drop counters tshark cannot show
capture_qualityCan loss and timing conclusions be drawn from this file? Verdict with reasons
conversationsTop talkers at IP, TCP, UDP, SCTP or Ethernet level
filter_packetsRows of fields for any display filter (the escape hatch)
packet_detailOne frame's full dissection, as in Wireshark's details pane
expert_infotshark's expert warnings, errors and malformed packets, with frames
find_fieldsSearch tshark's field names without reading a capture
check_filterCompile a display filter and name its fields without reading a capture
cause_lookupWhat a Diameter, GTP, PFCP, NAS, S1AP/NGAP, SIP, Q.850, MAP, SCCP, SGsAP or SMS cause means, with the 3GPP/ITU reference
diameter_peersPer Diameter peer: CER/CEA capabilities, watchdog cadence and misses, DPR and restarts, success ratio, routing errors with the realm, Failed-AVP names and RTT per application, with a verdict
diameter_transactionsRequests paired with answers, result codes named, RTT, unanswered
diameter_sessionsThe same grouped by Session-Id, with per-session counts
diameter_avpsThe AVPs behind each transaction: flags with bit names, Subscription-Data digest, Gy/Rx/Cx/Sh/S13 digests with failed codes explained, full tree; authentication material never returned
gtp_sessionsGTPv2-C requests paired with responses across NATs and proxy chains, cause names, PAA
gtp_iesThe IEs behind each GTPv2-C transaction: APN, PDN type, QoS, ULI, PCO names, offending IE, likely causes of a reject
gtpv1_sessionsGTPv1-C (Gn/Gp) PDP contexts paired, with cause names
gtp_user_planeGTP-U packets, bytes and inner addresses per tunnel
gtp_tunnel_healthInner TCP loss, reordering, MSS/MTU and ICMP per GTP-U tunnel
pfcp_sessionsPFCP (N4/Sx) sessions, rejections, reports, usage and peer restarts
message_ratesMessages per interval, bursts, storms and subscriber loops with the nodes involved
dns_transactionsQueries paired with responses, unanswered ones included, per-server latency, failing names
tls_handshakesClient offer versus server choice, alerts, certificate, outcome per connection
http_transactionsHTTP/1.x pairs and HTTP/2 / gRPC streams: status, size, timing; per-endpoint 5xx share and p99
response_timesNetwork, server and receiver time per TCP flow (HTTP/1, HTTP/2, gRPC)
tcp_healthPer-stream loss by location, resets with their likely source, windows, MTU black holes
tcp_connectionsEvery connection attempt: connected, refused, filtered or ICMP-prohibited, who closed it; per destination success rate
icmp_errorsEvery ICMP/ICMPv6 error by sender, kind and quoted flow: fragmentation needed, rejects, routing loops, lost pings
sip_dialogsMessages grouped by Call-ID with outcome after any challenge
sip_call_detailOne call: timings, SDP, Reason headers, who hung up
call_kpisASR, NER, SER, PDD and ACD per peer, trunk, number prefix, user agent or interval
call_legsStitch the legs of one call across B2BUAs, SBCs and CSCFs (icid, Session-ID, X- headers, media, number), with a confidence per link, which hop failed and who rewrote the status
volte_call_chainOne VoLTE call through SIP, Rx, Gx, GTPv2-C bearer creation, PFCP and RTP: each link's status, the first broken link and a verdict
sigtran_healthWhy an SS7-over-IP link flapped or a GT is unreachable: SCTP episodes, aborts and heartbeats, M3UA ASP state, DUNA/DAVA outages, SCCP returns and TCAP aborts per association, with a verdict
sms_deliverySMS over MAP and SGs: SRI-for-SM, forwardSM, report, paging and the CP/RP exchange per message, with a verdict (delivered, rejected, absent subscriber, paging failed, no response), content-free
media_path_checkSDP-negotiated media against the RTP seen: one-way audio, NAT, 488
rtp_streamsPer-stream loss, jitter, RTCP and an E-model MOS estimate, linked to the call
dtmf_eventsRFC 4733 and SIP INFO digits in order, checked against the SDP
ims_registrationREGISTER flows per UE with a verdict: registered, expired, deregistered, challenge-loop, failed
sms_over_imsEach SMS over IMS with its RP answer and a verdict
sctp_associationsHandshake, heartbeats, retransmissions, aborts per association
sigtran_messagesM3UA, SCCP, TCAP and MAP with operation names, IMSI and MSISDN
trace_subscriberOne timeline for a subscriber across Diameter, GTP, PFCP, MAP and SIP
nas_proceduresAttach, TAU, service request, PDN and bearer procedures per UE from S1AP and NAS EPS: outcome, EMM/ESM and S1AP causes named, timing, ciphered messages counted, unanswered paging
roaming_attach_checkWhy a roamer cannot attach or get a bearer: each attempt's steps, the ULA subscription held against the Create Session, checks and a verdict
compare_capturesA working and a failing capture side by side, with the first divergence

Prompts

Six MCP prompts turn the common investigations into guided workflows: the tool calls in order, what to cite, when to stop and the shape of the answer. Claude Code shows them as /mcp__tshark-mcp__<name>. The path arguments complete to capture files under the allowed directories (at most 50 names per answer, never outside the allowlist).

PromptArgumentsWalks through
one_way_audiopath, call_idmedia_path_check, sip_call_detail, rtp_streams
subscriber_cannot_attachpath, imsi / msisdn, home_plmntrace_subscriber, diameter_sessions, roaming_attach_check, gtp_sessions, gtp_ies, cause_lookup
trust_this_capturepathpcap_info, capture_metadata, capture_quality, expert_info
working_vs_failingpath_a, path_b, imsicompare_captures, then the protocol tool at the first divergence
ims_registration_or_smspath, imsi / impu / numberims_registration, sms_over_ims, sip_dialogs
slow_data_sessionpath, teid / ue_ipcapture_quality, gtp_user_plane, gtp_tunnel_health, pfcp_sessions, tcp_health

Redaction

Telecom captures carry IMSIs, MSISDNs, IMEIs, SIP users and UE addresses. Start the server with --redact ids (or TSHARK_MCP_REDACT=ids), or pass redact="ids" on a call, and those values come back as stable keyed tokens such as imsi:3f2a9c1b0d that still join across tools and work as arguments in later calls. ids+ips hides every IP address too. A call can raise the server's level, never lower it. What is found, what is not, and how the pre-scan works: docs/SAFETY.md.

Limitations

  • No live capture, by design. The server reads files that already exist and nothing else.
  • No decryption: IPsec, TLS and ciphered NAS are reported as tshark sees them. tls_handshakes reads only the clear part of the handshake; after a TLS 1.3 ServerHello its outcome is inferred from the record pattern and says so.
  • Large captures are slow. tshark reads the whole file for every call; a 500 MB capture with a selective filter takes tens of seconds, so prefer pre-sliced captures.
  • Pairing follows what is in the file. A request whose answer was captured on another interface is unanswered; one the capture stopped too soon to answer is also near_capture_end. How GTP responses are matched across NATs and proxies is in docs/TOOLS.md.
  • MAP decoding relies on tshark's dissectors; a segmented XUDT whose other segments are missing is reported as segmented, not guessed.

Roadmap

  1. 5G core: HTTP/2 SBI (Nnrf, Nausf, Nsmf).
  2. Streaming per-call progress so a long tshark run can be cancelled from the client.
  3. Optional S1AP/NGAP and NAS summaries with EMM/ESM cause names.

Development

sh
python3 -m venv .venv && . .venv/bin/activatepip install -e '.[dev]'pytestpython -m evals            # task-success scenarios over the stdio server (docs/EVALS.md)

The suite runs in about a minute; CI runs it on Python 3.10 to 3.13 with the tshark that Ubuntu 24.04 ships (4.2). Every capture the tests use is synthetic, built by tests/pcapgen.py at run time with documentation addresses and test identities, and the three captures under examples/ come from the same generator, so nothing in the repository contains traffic from a real network (the list of scenarios is in docs/TOOLS.md). Sixteen task-success scenarios (docs/EVALS.md) check that the right tool answers an operator's question with the right facts; a model-driven mode is there and off by default. Conventions for contributors and for agents: CONTRIBUTING.md, AGENTS.md.

Licence

MIT, Copyright (c) 2026 Karl Hulse.

來源:README.md,提交 a2ec027

工具

0
SourceWeft 曾在隔離沙箱中以無憑證方式啟動該軟體包一次,以列出其工具,但未能完成:伺服器未能啟動。

版本歷史

1
  1. v0.2.0最新Nov 5, 2026

評分

已滿足適用檢查項的 50%

該評分衡量此收錄條目的完整程度,依據註冊中心條目、端點與公開來源計算得出。它不是對伺服器本身的評價,也不表示伺服器安全或目前可用:可連通性是帶日期的檢查結果,評分也不包含安裝量或使用者評價。

  • 近 30 天內可連通25 分

    請保持端點能夠回應 MCP 握手;SourceWeft 每 30 天探測一次。

  • 已宣告認證方式10 分

    請在註冊中心條目中宣告憑證請求標頭,或保持端點能夠回應探測,以便判定其認證方式。

  • 已列出工具15 分

    請讓伺服器在無憑證時回應 tools/list,或發布可在沙箱中無憑證啟動的軟體包。

  • 描述必需15 分
  • 圖示10 分
  • 文件15 分
  • 授權條款10 分