Back to Blog

[ AI / CYBERSECURITY ]

From Packet to Prompt

MK

M.Koffi

MAR 14, 2024 · 5 MIN READ

From Packet to Prompt

Holla amigos!

Today we’re going to dive into how an MCP server works and see how to connect it to TShark for network‑capture analysis.

The goal: let an LLM ask in natural language, “How many HTTP packets are in sample.pcap?” and get the answer instantly.

Theory Section

CONCEPT 1 : MCP in a Nutshell

MCP (Model Context Protocol) is a text protocol with three objectives:

  1. Encapsulate each message cleanly so no line is lost or overflows.
  2. Tag messages with key/value pairs (e.g., id, content‑type) to keep context.
  3. Simplify life for both humans and machines — an MCP message stays readable in tcpdump while being trivial to parse in Python, Go, or Rust.

In short, MCP strikes the ideal balance between the minimalism of raw TCP streams and the overkill of full HTTP when you only need to exchange small structured packets.

CONCEPT 2 : What Is an MCP Server?

It’s the receiving program that:

In our project, the business tool is TShark: we want an LLM to drive TShark to analyze network captures.

CONCEPT 3 : Why TShark?

“It’s a bit like eavesdropping on everything computers say to each other on a network.”

TShark is the command‑line version of Wireshark:

Practical Section

1. Hardware & Prerequisites

Item Recommended version Required Why?
OS Debian 12 / Parrot 6.x NO Stable and security‑oriented
Python ≥ 3.11 YES asyncio + strong typing
Wireshark / TShark ≥ 4.2 YES Faster display filters

Quick Install

sudo apt update
sudo apt install -y python3 python3-venv wireshark tshark

2. Project Structure

├── mcp-agent
│   ├── fastagent.config.yaml
│   ├── fastagent.secrets.yaml
│   └── venv-agent
└── mcp-srv-tshark
    ├── pcaps/
    ├── server.py
    ├── tools.py
    └── venv-mcp-server

Two folders, two roles: mcp-agent is the brain (LLM + FastAPI + OpenAI keys). tshark-mcp is the hand that executes system commands.

Section 1: Setting Up the mcp‑agent

Create the Directory

mkdir -p tuto-mcp-agent/mcp-agent
mkdir -p tuto-mcp-agent/tshark-mcp
cd tuto-mcp-agent

Python Virtual Environment

cd mcp-agent
python -m venv env-agent
source env-agent/bin/activate

Install Dependencies

pip install fast-agent-mcp fastapi

Example: fastagent.config.yaml

mcp:
  servers:
    tshark_mcp:
      transport: "http"
      url: "http://localhost:5001/mcp"
      read_transport_sse_timeout_seconds: 120

agents:
  netcli:
    model: gpt-4o-mini
    servers: [tshark_mcp]
    system: |
      You're a network expert. Always use the "tshark_query" tool to analyze offline PCAP files.

providers:
  openai:
    reasoning_effort: "medium"

Example: fastagent.secrets.yaml

openai:
  api_key: "sk-..."

Launching the mcp-agent

Section 2: Setting Up the MCP Server

Create Project & Install

mkdir mcp-srv-tshark && cd mcp-srv-tshark
mkdir pcaps
python -m venv env-mcp
source env-mcp/bin/activate
pip install fastapi pydantic uvicorn

File: tools.py

import subprocess, json, os, asyncio, shlex
from pathlib import Path

PCAP_ROOT = (Path(__file__).resolve().parent / "pcaps").as_posix()

def _safe_path(fname: str) -> str:
    path = os.path.abspath(os.path.join(PCAP_ROOT, fname))
    if not path.startswith(PCAP_ROOT):
        raise ValueError("Chemin PCAP interdit")
    if not os.path.isfile(path):
        raise FileNotFoundError(path)
    return path

TOOL_DEFS = [{
    "name": "tshark_query",
    "description": "Execute TShark on a pcap file offline",
    "inputSchema": {
        "type": "object",
        "properties": {
            "file":   { "type": "string",  "description": "Name of the pcap file (inside pcaps/)" },
            "filter": { "type": "string",  "description": "TShark display filter (-Y)", "default": "" },
            "limit":  { "type": "integer", "description": "Max packets (0 = no limit)",  "default": 0 }
        },
        "required": ["file"]
    }
}]

async def call_tool(name: str, args: dict):
    if name != "tshark_query":
        raise ValueError(f"Tool {name} non géré")
    file  = _safe_path(args["file"])
    flt   = args.get("filter", "")
    limit = int(args.get("limit", 0))
    cmd   = ["tshark", "-r", file, "-T", "json"]
    if limit > 0: cmd += ["-c", str(limit)]
    if flt:       cmd += ["-Y", flt]
    proc = await asyncio.create_subprocess_exec(
        *cmd, stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE)
    out_b, err_b = await proc.communicate()
    if proc.returncode != 0:
        raise RuntimeError(err_b.decode("utf-8","replace").strip() or "TShark error")
    frames  = json.loads(out_b.decode("utf-8","replace"))
    return f"{len(frames)} paquets renvoyés pour filtre '{flt}'"

File: server.py

from fastapi import FastAPI, Request
from tools import TOOL_DEFS, call_tool

app = FastAPI(title="TShark MCP Server")
PROTOCOL = "2025-03-26"

@app.post("/mcp")
async def mcp_entry(request: Request):
    payload = await request.json()
    if isinstance(payload, list):
        return [await handle(msg) for msg in payload]
    return await handle(payload)

async def handle(msg):
    if msg["method"] == "initialize":
        return {"jsonrpc":"2.0","id":msg["id"],"result":{
            "protocolVersion": PROTOCOL,
            "capabilities": {"tools": {"listChanged": False}},
            "serverInfo": {"name": "SK-Tshark-Mcp","version": "0.1.0"}}}
    if msg["method"] == "tools/list":
        return {"jsonrpc":"2.0","id":msg["id"],"result":{"tools": TOOL_DEFS}}
    if msg["method"] == "tools/call":
        result = await call_tool(msg["params"]["name"], msg["params"].get("arguments",{}))
        return {"jsonrpc":"2.0","id":msg["id"],"result":{
            "content":[{"type":"text","text":result}],"isError":False}}
    return {"jsonrpc":"2.0","id":msg.get("id"),
            "error":{"code":-32601,"message":f"Unknown method {msg['method']}"}}

if __name__ == "__main__":
    import uvicorn
    uvicorn.run(app, host="0.0.0.0", port=5001)

Launching the MCP server

✅ Expected Result

At the end of this tutorial, you’ll be able to ask the LLM something like:

“How many HTTP packets are in sample.pcap?”

And the agent will call TShark via MCP, analyze the file, and return a structured answer — all through natural language.

The LLM analyzing a pcap file end-to-end through the MCP server

Mission accomplished! 🚀


Related Posts

Beyond VPNs: The Dark Art of DNS and ICMP Tunneling

[ CYBERSECURITY ]

Beyond VPNs: The Dark Art of DNS and ICMP Tunneling

Tails on the Go

[ CYBERSECURITY ]

Tails on the Go