Notes

MCP tool bundles: choose which tools sipnab's MCP server loads

Feature updated

How --mcp-tools limits the tools sipnab's MCP server offers to an AI agent, what each bundle costs the agent's context, and which tools refuse until the operator enables them.

In short

sipnab can run as an MCP server.

  • An MCP server is a program an AI agent connects to.
  • The agent calls named tools on it, such as “list the calls in this capture”.

Each tool the server offers adds its description to the text the agent’s model reads before every answer. So sipnab lets the operator offer fewer tools, grouped into named bundles.

Separately from that choice, some tools stay switched off until the operator turns each one on. These are the tools that:

  • stop the server,
  • change which capture it holds,
  • send packets,
  • read or write files,
  • record findings,
  • read encrypted traffic,
  • change another system.

Who this is for

Anyone connecting an AI agent to sipnab’s MCP server who:

  • wants to give it only the tools it needs, or
  • needs to know which tools refuse by default.

What it does

On connecting, an agent asks the server for its tool list (the MCP request tools/list).

  • The answer carries each tool’s name, description and input schema.
    • The input schema is the description of the arguments it takes.
  • The agent’s client keeps all of it in the model’s context for the whole session.
    • The context is the text the model reads before every answer.

--mcp-tools decides which tools the server registers. So it decides what that list holds. It takes a comma-separated list of:

  • bundles: core, signaling, captures, security, media, relay, tfps, server, vcon, tls. Every tool is in exactly one bundle.
  • single tool names, to add one tool without its whole bundle.
  • your own bundles, defined under [mcp.bundles] in the config file.
  • full, every tool the build carries. This is the default.

A tool that is not registered does not exist for that session. A call to it gets the MCP error tool not found, not a refusal.

The MCP server needs the mcp Cargo feature (a compile-time option).

  • The full build carries it. The default build does not.
  • sipnab --version lists the features compiled into a binary.
  • A build without a feature does not register that feature’s tools. So its bundles are smaller.

Choose the tools the server loads

Every example below runs from the root of the sipnab repository. It reads a capture in it.

  • Each one sends the server MCP requests on its standard input.
  • It uses jq (a command-line JSON processor) to print one field of the reply.

The steps:

  • Start the server with only the core bundle and list what it registers:
printf '%s\n' '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18","capabilities":{},"clientInfo":{"name":"demo","version":"1"}}}' '{"jsonrpc":"2.0","method":"notifications/initialized"}' '{"jsonrpc":"2.0","id":2,"method":"tools/list"}' | sipnab -N --quiet -I tests/pcap-samples/sip-488-codec-reject.pcapng --mcp --mcp-tools core | jq -r 'select(.id==2) | .result.tools[].name'
aggregate_dialogs
capture_status
find_problems
get_capture_report
get_dialog
list_dialogs
rtp_stats
search_messages
triage_call

The same command with --mcp-tools full, or with no --mcp-tools, lists 76 tools on sipnab 0.5.222 built with every feature.

  • Combine bundles and single tools.
    • The server’s handshake reply answers the MCP initialize request.
    • It ends by naming what it loaded and which bundles it left out.
    • So an agent that misses a tool can tell the operator which bundle holds it:
printf '%s\n' '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18","capabilities":{},"clientInfo":{"name":"demo","version":"1"}}}' | sipnab -N --quiet -I tests/pcap-samples/sip-488-codec-reject.pcapng --mcp --mcp-tools core,relay,get_sdp_timeline | jq -r '.result.instructions'
sipnab MCP server — queries captured SIP dialogs, RTP streams, diagnostics and security findings. No tool edits a capture's contents. `open_capture` can change WHICH capture is loaded and stays off unless enabled server-side; every response carries `capture_identity`, so a swap is visible rather than silent. File exports write only under the configured file root, and stopping the server requires an explicit server-side opt-in. This server changes no external system: the tools that would (tfps_ban, tfps_unban) refuse unless the operator enables them with --allow-action. Tools loaded: core, relay, get_sdp_timeline. Other bundles, which the operator can add with --mcp-tools or [mcp] tools: signaling, captures, security, media, tfps, server, vcon, tls.
  • A name sipnab does not know stops the run with exit status 2. sipnab lists the valid bundles. Names are case-sensitive:
sipnab -N --quiet -I tests/pcap-samples/sip-488-codec-reject.pcapng --mcp --mcp-tools core,ladder
2026-10-12T00:41:51.376191Z ERROR sipnab::app::bootstrap: --mcp-tools: unknown tool or bundle 'ladder'; bundles: core, signaling, captures, security, media, relay, tfps, server, vcon, tls, or full; tool names are listed in the MCP tool reference
  • To set the list once, put it in the config file (-f/--config).
    • This example defines a bundle named voice.
    • It loads it beside core.
    • With it, the handshake reply printed Tools loaded: core, voice.
[mcp]
tools = ["core", "voice"]

[mcp.bundles]
voice = ["media", "get_sdp_timeline", "check_codec_negotiation"]

--mcp-tools on the command line replaces [mcp] tools.

Measure what a bundle costs

The size of the tools/list answer is what the client keeps in context. This command prints it in bytes for core. It is the sum of each tool entry’s compact JSON:

printf '%s\n' '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18","capabilities":{},"clientInfo":{"name":"demo","version":"1"}}}' '{"jsonrpc":"2.0","method":"notifications/initialized"}' '{"jsonrpc":"2.0","id":2,"method":"tools/list"}' | sipnab -N --quiet -I tests/pcap-samples/sip-488-codec-reject.pcapng --mcp --mcp-tools core | jq -r 'select(.id==2) | [.result.tools[] | tojson | utf8bytelength] | add'
12316

On sipnab 0.5.222 built with every feature, the same command gives:

--mcp-toolsToolsBytesBytes with --mcp-output-schemas
core912,31654,624
full7689,667270,810

Output schemas are a declared shape for each tool’s answer.

  • They are optional in MCP and off by default.
  • Responses carry the same JSON with or without them.
  • Turn them on with --mcp-output-schemas only for a client that checks answers against a declared shape.

Sizes change between releases as tools change. Run the command above against your own binary to get its figures, and change core to the list you plan to use.

Enable the tools that refuse by default

Registering a tool does not permit it. With the default full list, the tools below appear in tools/list. But they answer each call with an error that names the flag they need.

Leaving a tool out with --mcp-tools removes it. It does not replace the flag.

ToolsEnabled by
shutdown_server--mcp-allow-shutdown
open_capture--mcp-allow-open-capture
query_relay, relay_stats, relay_compare--mcp-allow-relay-query, plus a relay address from --rtpengine-control and a live source (these tools send packets to the relay; a run reading a capture file cannot use them)
start_tls_capture--mcp-allow-tls-capture
save_findings--mcp-allow-save-findings
tfps_ban, tfps_unban, actions_revert--allow-action tfps:mcp
list_captures, export_capture, export_audio, compare_captures, build_evidence_package--mcp-file-root <DIR>

Another note covers what each of these flags allows, and which to turn on for an agent: What to switch on when an agent drives sipnab.

Limits

  • The counts and byte sizes above are for sipnab 0.5.222 with every feature. Another release or a build with fewer features gives other numbers.
  • A custom bundle has three rules:
    • It cannot reuse a built-in bundle or tool name.
    • It cannot be empty.
    • It cannot hold full or another custom bundle.
  • sipnab refuses to start when a custom bundle breaks a rule, even if nothing uses it. The error names the bundle, for example [mcp.bundles] voice is empty.
  • core does not include server_capabilities, the tool that reports a binary’s features and settings. Add it by name if the agent needs it.

Terms used here

  • MCP (Model Context Protocol): a standard way for an AI agent to discover and call tools that a program offers.
  • Agent: an AI model that calls tools on its own to answer a question.
  • Tool: one named operation the MCP server offers, with declared arguments.
  • Bundle: a named group of tools that --mcp-tools accepts as one entry.
  • Context: the text a model reads before each answer. The tool list sits in it for the whole session.
  • Schema: a machine-readable description of a tool’s arguments or of the shape of its answer.
  • JSON-RPC: the request-and-reply message format MCP uses.
  • Capture: a recorded file of network packets, here a pcapng file.
  • Cargo feature: an option chosen at sipnab’s compile time. A feature left out removes its code from the binary.
  • Live source: a network interface or listener sipnab is reading now. It is the opposite of a capture file.
  • jq: a command-line program that reads JSON and prints selected fields.