MCP tool bundles: choose which tools sipnab's MCP server loads
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
fullbuild carries it. The default build does not. sipnab --versionlists 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
corebundle 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
initializerequest. - 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:
- The server’s handshake reply answers the MCP
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.
- This example defines a bundle named
[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-tools | Tools | Bytes | Bytes with --mcp-output-schemas |
|---|---|---|---|
core | 9 | 12,316 | 54,624 |
full | 76 | 89,667 | 270,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-schemasonly 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.
| Tools | Enabled 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
fullor 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. coredoes not includeserver_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-toolsaccepts 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.
Related guides
- Choosing which tools load: the bundle table with every tool in each bundle.
- Rules every tool follows: row limits, paging and how answers mark capture text.
- File tools — the shared rule:
what
--mcp-file-rootallows. - The
[mcp]config section:tools,output_schemasand[mcp.bundles]. - See it work and Add it to your client: starting the server and connecting a client.
- Security model: why the opt-in tools are off by default.