Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

### Added
- Added suite capability reporting via `wireshark_get_capabilities` and the `wireshark://capabilities` resource.
- Added optional Wireshark suite tools for `editcap`-based trimming, splitting, time shifting, and deduplication, plus `text2pcap` import support.

### Changed
- Live capture now prefers `dumpcap` when available while keeping `tshark` as the only required Wireshark dependency.
- Installer diagnostics now classify Wireshark tools as required, recommended, or optional.

## [0.6.4] - 2026-03-14

### Fixed
Expand Down
26 changes: 24 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ Drop a <code>.pcap</code> file, ask questions in plain English — get answers b

## What is this?

Wireshark MCP is an [MCP Server](https://modelcontextprotocol.io/introduction) that wraps `tshark` into structured tools, letting AI assistants like Claude or Cursor perform deep packet analysis without you touching the command line.
Wireshark MCP is an [MCP Server](https://modelcontextprotocol.io/introduction) that turns `tshark` into a structured analysis interface, then layers in optional Wireshark suite utilities such as `capinfos`, `mergecap`, `editcap`, `dumpcap`, and `text2pcap` when they are available. The result is a packet-analysis server that still works with only `tshark`, but gets stronger automatically on hosts with more of the Wireshark toolchain installed.

```
You: "Find all DNS queries going to suspicious domains in this capture."
Expand All @@ -53,6 +53,9 @@ Claude: [calls wireshark_extract_dns_queries → wireshark_check_threats]

- **Python 3.10+**
- **Wireshark** installed with `tshark`
- `tshark` is the only required Wireshark CLI dependency
- Optional suite tools such as `capinfos`, `mergecap`, `editcap`, `dumpcap`, and `text2pcap` are auto-detected and enable extra MCP features when present
- Live capture prefers `dumpcap` when available, but falls back to `tshark` so a minimal installation still works
- `tshark` on your `PATH` is recommended, but `wireshark-mcp --install` also records detected absolute Wireshark tool paths for GUI clients
- Any [MCP-compatible client](https://modelcontextprotocol.io/clients): Claude Desktop, Claude Code, Cursor, VS Code, etc.

Expand Down Expand Up @@ -143,7 +146,7 @@ This detects all installed MCP clients and writes the config automatically. Exis
The generated entry always uses the current Python interpreter (`python -u -m wireshark_mcp.server`), forwards your current `PATH`, and stores detected absolute Wireshark tool paths when available, so GUI MCP clients do not need `wireshark-mcp` or `tshark` to be discoverable on their own.

> ⚠️ **Restart your MCP client** after running `--install` for changes to take effect.
> 🔎 If analysis tools still fail to launch, run `wireshark-mcp --doctor` to verify Python, `tshark`, and client config detection.
> 🔎 If analysis tools still fail to launch, run `wireshark-mcp --doctor` to verify Python, required vs optional Wireshark CLI tools, and client config detection.

### Manual Configuration

Expand Down Expand Up @@ -388,6 +391,7 @@ Your task is to diagnose network performance issues in <file.pcap>.
| `wireshark_security_audit` | **One-call security audit**: 8-phase analysis (threat intel, credential scan, port scan, DNS tunnel, cleartext, anomalies) with risk scoring (0-100) and recommendations |
| `wireshark_quick_analysis` | **One-call traffic overview**: file info, protocol distribution, top talkers, conversations, hostnames, anomaly summary, suggested next steps |
| `wireshark_open_file` | **Smart file opener**: analyzes pcap content and dynamically activates protocol-specific tools (Progressive Discovery) |
| `wireshark_get_capabilities` | **Toolchain capability report**: required, recommended, and optional Wireshark suite tools visible to the current MCP server |

> 💡 These tools replace the need to manually chain 5-10 tool calls. Just call one and get a complete report.

Expand Down Expand Up @@ -456,6 +460,23 @@ Your task is to diagnose network performance issues in <file.pcap>.

</details>

<details>
<summary><b>Suite Utilities</b> — optional Wireshark companion tools</summary>

<br>

These tools are additive. The server still starts with only `tshark`, and only advertises or uses the extra workflows below when the corresponding Wireshark companion binaries are present.

| Tool | Description |
|---|---|
| `wireshark_editcap_trim` | Trim a capture to a timestamp window using `editcap` |
| `wireshark_editcap_split` | Split a capture by packet count or interval using `editcap` |
| `wireshark_editcap_time_shift` | Shift packet timestamps by a relative offset using `editcap` |
| `wireshark_editcap_deduplicate` | Remove duplicate packets using `editcap`'s duplicate window |
| `wireshark_text2pcap_import` | Convert ASCII or hex dumps into capture files using `text2pcap` |

</details>

<details>
<summary><b>Security Analysis</b></summary>

Expand Down Expand Up @@ -511,6 +532,7 @@ Your task is to diagnose network performance issues in <file.pcap>.
| `wireshark://reference/display-filters` | Complete display filter syntax cheatsheet with common examples |
| `wireshark://reference/protocol-fields` | Protocol field name reference for filters and extraction |
| `wireshark://guide/usage` | Recommended analysis workflows and tips |
| `wireshark://capabilities` | Current required, recommended, and optional Wireshark suite capabilities |

## MCP Prompts

Expand Down
26 changes: 24 additions & 2 deletions README_zh.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@

## 这是什么?

Wireshark MCP 是一个 [MCP 服务器](https://modelcontextprotocol.io/introduction), `tshark` 封装为结构化工具,让 Claude、CursorAI 助手无需命令行即可执行深度数据包分析
Wireshark MCP 是一个 [MCP 服务器](https://modelcontextprotocol.io/introduction), `tshark` 为基础提供结构化分析接口,并在宿主机可用时自动接入 `capinfos`、`mergecap`、`editcap`、`dumpcap`、`text2pcap`Wireshark 伴随工具。也就是说,只安装 `tshark` 就能工作;安装得更完整时,MCP 会自动获得更强的能力

```
你: "分析这个抓包里有没有可疑的 DNS 查询。"
Expand All @@ -53,6 +53,9 @@ Claude: [调用 wireshark_extract_dns_queries → wireshark_check_threats]

- **Python 3.10+**
- **Wireshark** 已安装并包含 `tshark`
- `tshark` 是唯一必需的 Wireshark CLI 依赖
- `capinfos`、`mergecap`、`editcap`、`dumpcap`、`text2pcap` 等工具都按可选增强能力处理,探测到后会自动启用对应 MCP 功能
- 实时抓包在可用时会优先使用 `dumpcap`,缺失时自动回退到 `tshark`,因此最小安装仍然可用
- 最好让 `tshark` 出现在 `PATH` 中,但 `wireshark-mcp --install` 也会尽量把探测到的 Wireshark 绝对路径写入 GUI 客户端配置
- 任意 [MCP 客户端](https://modelcontextprotocol.io/clients): Claude Desktop、Claude Code、Cursor、Codex 等

Expand Down Expand Up @@ -142,7 +145,7 @@ wireshark-mcp --install
自动检测已安装的 MCP 客户端并写入配置,不会覆盖已有设置。
自动生成的配置会固定使用当前 Python 解释器(`python -u -m wireshark_mcp.server`),同时透传当前 `PATH`,并在可探测到时写入 Wireshark 工具绝对路径,因此 GUI MCP 客户端不需要自己再去猜 `wireshark-mcp` 或 `tshark` 在哪里。

> 如果分析工具依然无法启动,运行 `wireshark-mcp --doctor` 检查 Python、`tshark` 和客户端配置探测结果
> 如果分析工具依然无法启动,运行 `wireshark-mcp --doctor` 检查 Python、必需/可选 Wireshark CLI 工具以及客户端配置探测结果

### 手动配置

Expand Down Expand Up @@ -387,6 +390,7 @@ LLM 在有结构化、具体的提示词时表现最好。以下是针对常见
| `wireshark_security_audit` | **一键安全审计**:8 阶段分析(威胁情报、凭证扫描、端口扫描、DNS 隧道、明文协议、异常检测),输出风险评分(0-100)和修复建议 |
| `wireshark_quick_analysis` | **一键流量概览**:文件信息、协议分布、Top Talkers、会话统计、域名/主机名、异常摘要、下一步建议 |
| `wireshark_open_file` | **智能打开文件**:分析 pcap 内容并自动激活协议相关工具(Progressive Discovery)|
| `wireshark_get_capabilities` | **工具链能力视图**:显示当前 MCP 服务可见的必需、推荐和可选 Wireshark suite 工具 |

> 💡 这些工具替代了手动串联 5-10 次 tool call。只需一次调用即可获得完整报告。

Expand Down Expand Up @@ -455,6 +459,23 @@ LLM 在有结构化、具体的提示词时表现最好。以下是针对常见

</details>

<details>
<summary><b>Suite Utilities</b> — 可选 Wireshark 伴随工具</summary>

<br>

这些工具都属于增强项。即使只有 `tshark`,服务也可以正常启动;只有在检测到对应 Wireshark 伴随二进制时,下面这些额外工作流才会被暴露和使用。

| 工具 | 描述 |
|---|---|
| `wireshark_editcap_trim` | 使用 `editcap` 按时间窗口裁剪抓包 |
| `wireshark_editcap_split` | 使用 `editcap` 按包数或时间间隔拆分抓包 |
| `wireshark_editcap_time_shift` | 使用 `editcap` 按相对偏移调整时间戳 |
| `wireshark_editcap_deduplicate` | 使用 `editcap` 按重复窗口去重 |
| `wireshark_text2pcap_import` | 使用 `text2pcap` 将 ASCII 或十六进制转储导入为抓包文件 |

</details>

<details>
<summary><b>安全分析</b></summary>

Expand Down Expand Up @@ -510,6 +531,7 @@ LLM 在有结构化、具体的提示词时表现最好。以下是针对常见
| `wireshark://reference/display-filters` | 完整的显示过滤器语法速查表 |
| `wireshark://reference/protocol-fields` | 常用协议字段名参考 |
| `wireshark://guide/usage` | 推荐的分析工作流和使用技巧 |
| `wireshark://capabilities` | 当前 Wireshark suite 的必需、推荐与可选能力概览 |

## MCP Prompts

Expand Down
26 changes: 15 additions & 11 deletions src/wireshark_mcp/installer.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,9 @@
import tempfile
from typing import Any, cast

from .toolchain import WIRESHARK_TOOL_ENV_VARS, WIRESHARK_TOOL_ORDER, WIRESHARK_TOOL_REQUIREMENTS

SERVER_NAME = "wireshark-mcp"
WIRESHARK_TOOL_ENV_VARS = {
"tshark": "WIRESHARK_MCP_TSHARK_PATH",
"capinfos": "WIRESHARK_MCP_CAPINFOS_PATH",
"mergecap": "WIRESHARK_MCP_MERGECAP_PATH",
"editcap": "WIRESHARK_MCP_EDITCAP_PATH",
}


# ---------------------------------------------------------------------------
Expand Down Expand Up @@ -511,18 +507,26 @@ def print_install_doctor() -> None:
print("Wireshark MCP doctor")
print(f" Python: {_get_python_executable()}")
print()
print("Wireshark CLI tools:")
print("Wireshark suite tools:")

detected_tools = _detect_wireshark_tool_paths()
for env_var, tool_path in detected_tools.items():
tool_name = env_var.removeprefix("WIRESHARK_MCP_").removesuffix("_PATH").lower()
status = tool_path or "missing"
print(f" {tool_name}: {status}")
for requirement in ("required", "recommended", "optional"):
print(f" {requirement}:")
for tool_name in WIRESHARK_TOOL_ORDER:
if WIRESHARK_TOOL_REQUIREMENTS[tool_name] != requirement:
continue
env_var = WIRESHARK_TOOL_ENV_VARS[tool_name]
status = detected_tools.get(env_var) or "missing"
print(f" {tool_name}: {status}")

if not detected_tools["WIRESHARK_MCP_TSHARK_PATH"]:
print()
print("Warning: tshark was not found.")
print(" Install Wireshark CLI tools or set WIRESHARK_MCP_TSHARK_PATH before starting the MCP server.")
else:
print()
capture_backend = "dumpcap" if detected_tools.get("WIRESHARK_MCP_DUMPCAP_PATH") else "tshark"
print(f"Preferred capture backend: {capture_backend}")

print()
print("MCP client targets:")
Expand Down
10 changes: 9 additions & 1 deletion src/wireshark_mcp/resources.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
"""MCP Resources for Wireshark MCP — expose reference data to LLMs."""

import json
import logging

from mcp.server.fastmcp import FastMCP

from .tshark.client import TSharkClient

logger = logging.getLogger("wireshark_mcp")

# ── Display Filter Reference ────────────────────────────────────────────────
Expand Down Expand Up @@ -189,7 +192,7 @@
"""


def register_resources(mcp: FastMCP) -> None:
def register_resources(mcp: FastMCP, client: TSharkClient) -> None:
"""Register all MCP Resources."""

@mcp.resource("wireshark://reference/display-filters")
Expand All @@ -206,3 +209,8 @@ def get_protocol_field_reference() -> str:
def get_usage_guide() -> str:
"""Wireshark MCP usage guide with recommended analysis workflows."""
return WIRESHARK_MCP_GUIDE

@mcp.resource("wireshark://capabilities")
def get_capabilities() -> str:
"""Machine-readable capability summary for the current Wireshark toolchain."""
return json.dumps(client.describe_capabilities(), indent=2)
12 changes: 9 additions & 3 deletions src/wireshark_mcp/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,15 @@
from .tools.agents import register_agent_tools
from .tools.capture import register_capture_tools
from .tools.decode import register_decode_tools
from .tools.edit import register_edit_tools
from .tools.extract import register_extract_tools
from .tools.files import register_files_tools
from .tools.imports import register_import_tools
from .tools.registry import ToolRegistry, register_open_file_tool
from .tools.stats import register_stats_tools
from .tools.suite import register_suite_tools
from .tools.visualize import register_visualize_tools
from .tshark.client import TSharkClient
from .tshark.client import WiresharkSuiteClient

logger = logging.getLogger("wireshark_mcp")

Expand All @@ -42,7 +45,7 @@ def _build_server() -> FastMCP:
allowed_dirs = [d.strip() for d in allowed_dirs_env.split(",") if d.strip()] or None

mcp = FastMCP("Wireshark MCP", dependencies=["tshark"])
client = TSharkClient(allowed_dirs=allowed_dirs)
client = WiresharkSuiteClient(allowed_dirs=allowed_dirs)

# ── Core tools (always registered) ──────────────────────────────────
register_capture_tools(mcp, client)
Expand All @@ -52,6 +55,9 @@ def _build_server() -> FastMCP:
register_decode_tools(mcp)
register_visualize_tools(mcp, client)
register_agent_tools(mcp, client)
register_suite_tools(mcp, client)
register_edit_tools(mcp, client)
register_import_tools(mcp, client)

# ── Progressive Discovery ───────────────────────────────────────────
# Build the contextual tool catalog (not registered yet)
Expand All @@ -62,7 +68,7 @@ def _build_server() -> FastMCP:
register_open_file_tool(mcp, client, registry)

# ── Resources and Prompts ───────────────────────────────────────────
register_resources(mcp)
register_resources(mcp, client)
register_prompts(mcp)

return mcp
Expand Down
37 changes: 37 additions & 0 deletions src/wireshark_mcp/toolchain.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
"""Shared Wireshark suite tool metadata."""

from __future__ import annotations

from typing import Literal

ToolRequirement = Literal["required", "recommended", "optional"]

WIRESHARK_TOOL_ENV_VARS: dict[str, str] = {
"tshark": "WIRESHARK_MCP_TSHARK_PATH",
"capinfos": "WIRESHARK_MCP_CAPINFOS_PATH",
"mergecap": "WIRESHARK_MCP_MERGECAP_PATH",
"editcap": "WIRESHARK_MCP_EDITCAP_PATH",
"dumpcap": "WIRESHARK_MCP_DUMPCAP_PATH",
"text2pcap": "WIRESHARK_MCP_TEXT2PCAP_PATH",
}

WIRESHARK_TOOL_REQUIREMENTS: dict[str, ToolRequirement] = {
"tshark": "required",
"capinfos": "recommended",
"mergecap": "recommended",
"editcap": "optional",
"dumpcap": "optional",
"text2pcap": "optional",
}

WIRESHARK_TOOL_PURPOSES: dict[str, str] = {
"tshark": "Core packet analysis and protocol dissection",
"capinfos": "Capture-file metadata and summary statistics",
"mergecap": "Capture-file merging",
"editcap": "Capture trimming, splitting, time shifting, and deduplication",
"dumpcap": "Preferred backend for live capture",
"text2pcap": "Import ASCII/hex dumps into capture files",
}

WIRESHARK_CAPTURE_BACKEND_ORDER = ("dumpcap", "tshark")
WIRESHARK_TOOL_ORDER = tuple(WIRESHARK_TOOL_ENV_VARS.keys())
81 changes: 81 additions & 0 deletions src/wireshark_mcp/tools/edit.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
from mcp.server.fastmcp import FastMCP

from ..tshark.client import TSharkClient
from .envelope import normalize_tool_result


def register_edit_tools(mcp: FastMCP, client: TSharkClient) -> None:

@mcp.tool()
async def wireshark_editcap_trim(
input_file: str,
output_file: str,
start_time: str = "",
stop_time: str = "",
) -> str:
"""
Trim a capture file to a timestamp window using editcap.

Args:
input_file: Source capture file
output_file: Destination capture file
start_time: Optional inclusive start time in editcap format
stop_time: Optional exclusive stop time in editcap format

Returns:
Success message or JSON error
"""
return normalize_tool_result(await client.editcap_trim(input_file, output_file, start_time, stop_time))

@mcp.tool()
async def wireshark_editcap_split(
input_file: str,
output_prefix: str,
packets_per_file: int = 0,
seconds_per_file: int = 0,
) -> str:
"""
Split a capture into multiple files using editcap.

Args:
input_file: Source capture file
output_prefix: Output filename prefix or base path
packets_per_file: Split after this many packets per file
seconds_per_file: Split after this many seconds per file

Returns:
Success message or JSON error
"""
return normalize_tool_result(
await client.editcap_split(input_file, output_prefix, packets_per_file, seconds_per_file)
)

@mcp.tool()
async def wireshark_editcap_time_shift(input_file: str, output_file: str, seconds: float) -> str:
"""
Shift packet timestamps by a relative number of seconds using editcap.

Args:
input_file: Source capture file
output_file: Destination capture file
seconds: Relative time adjustment in seconds

Returns:
Success message or JSON error
"""
return normalize_tool_result(await client.editcap_time_shift(input_file, output_file, seconds))

@mcp.tool()
async def wireshark_editcap_deduplicate(input_file: str, output_file: str, duplicate_window: int = 5) -> str:
"""
Remove duplicate packets using editcap's duplicate window matching.

Args:
input_file: Source capture file
output_file: Destination capture file
duplicate_window: Number of prior packets to compare against

Returns:
Success message or JSON error
"""
return normalize_tool_result(await client.editcap_deduplicate(input_file, output_file, duplicate_window))
Loading
Loading