Docs Look up a tool in the MCP tls bundle

Look up a tool in the MCP tls bundle

On this page

The tls bundle reads SIP inside TLS without keys through kernel uprobes, and lists which TLS libraries this host runs.

Load only these tools with --mcp-tools tls, or combine bundles as Choosing which tools load describes. Every tool on this page follows the rules every tool follows, and each section states only what its tool does differently. The MCP tool reference lists the other bundles and finds any tool by name.

ToolParametersReturns
start_tls_captureflavors, librariesinstalls kernel uprobes and reads SIP plaintext with no key; needs --mcp-allow-tls-capture
stop_tls_capture–stops that capture and removes its kernel probes
list_tls_libraries–which TLS libraries this host runs, and whether sipnab could read their plaintext without keys

Capture control (opt-in, off by default)

The tools that change server state rather than read it. Every one stays off until you turn it on server-side.

start_tls_capture

Installs kernel uprobes on this host’s TLS libraries and reads SIP plaintext from them — no key, no certificate, and no restart of the process observed.

Needs --mcp-allow-tls-capture. It is off by default and separate from --mcp-allow-open-capture, because it is a different act: that one reads a file an operator placed in a directory, this one attaches probes to a running process’s TLS library and reads its plaintext.

Call list_tls_libraries first.

ParameterTypeDefaultMeaning
flavorsarray of stringevery one foundopenssl, wolfssl
librariesarray of stringdiscoverprobe these paths instead of discovering
// start_tls_capture { }                                  // every library found
// start_tls_capture { "flavors": ["openssl"] }          // one flavor only
// start_tls_capture { "libraries": ["/proc/954/root/usr/lib/libssl.so.3"] }
{
  "schema_version": 1,
  "running": true,
  "targets": ["/proc/954/root/usr/lib/libssl.so.3:SSL_write"],
  "messages": 0,
  "lost": null,
  "uptime_sec": 0,
  "error": null,
  "summary": "Probing 1 TLS library. ..."
}

Three refusals, each before any kernel state exists, and each says which one it is rather than a bare failure:

  • not root — sipnab drops privileges after opening its capture devices, so a server started with --user cannot attach probes later.
  • a live source is already running — sipnab’s stores have one writer, so a uprobe capture cannot run beside one.
  • a capture is still loading — poll capture_status until load.done.

An attach failure arrives later, not here. A background thread installs the probes, so the call returns as soon as that thread starts. Poll stop_tls_capture or capture_status to see whether messages actually arrive.

stop_tls_capture

Stops the running capture and removes its kernel probes. Safe to call when nothing is running — it says so rather than failing.

No parameters. Returns:

// stop_tls_capture { }
{
  "schema_version": 1,
  "running": false,
  "targets": ["/proc/954/root/usr/lib/libssl.so.3:SSL_write"],
  "messages": 412,
  "lost": 0,          // records the kernel DROPPED: messages that existed and are missing
  "uptime_sec": 96,
  "error": null,
  "summary": "The TLS capture has stopped and its probes are removed."
}

Keep calling until running is false. The stop is a request: the worker owns the probes and removes them on its way out, which is a kernel round trip per probe. Probes left installed cost every process that maps the library, and they outlive sipnab.

lost is worth reading. It counts records the kernel dropped because the reader fell behind — messages that existed and are missing, which is a different fact from a quiet trunk and the only one you cannot discover any other way. The dialogs already collected stay in the store after the stop.

list_tls_libraries

Which TLS libraries processes on this host are actually mapping, and whether sipnab could attach a uprobe to read their plaintext. Ask before concluding that reading SIP over TLS needs keys — and read privileged and probe_path before concluding it can.

No parameters. Returns:

{
  "schema_version": 1,
  "supported": true,          // false off Linux, or without the `native` feature
  "privileged": true,         // running as root
  "libraries": [
    {
      "flavor": "OpenSSL",
      "path": "/usr/lib/aarch64-linux-gnu/libssl.so.3",
      "inode": 21143,         // the identity; the PATH is not unique
      "process_count": 12,
      "symbol": "SSL_write",
      "probe_path": "/proc/954/root/usr/lib/aarch64-linux-gnu/libssl.so.3"
    },
    {
      "flavor": "wolfSSL",
      "path": "/usr/lib/aarch64-linux-gnu/libwolfssl.so.42.2.0",
      "inode": 17433084,
      "process_count": 1,
      "symbol": "wolfSSL_write",
      "probe_path": null      // in use, but NOT capturable from here
    }
  ],
  "unreachable_count": 1,
  "summary": "1 of 2 TLS libraries could be read with `sipnab --uprobe-tls`, without any key or certificate. 1 cannot be reached from this server's mount namespace and would be missed."
}

Read privileged before believing an empty list. Unprivileged, /proc/<pid>/maps is readable only for the server’s own processes, so a short list is evidence about privilege rather than about the host. summary says which of the two situations produced the answer, so a relayed conclusion does not lose it.

probe_path: null is a finding, not a blank. That library is carrying traffic sipnab cannot capture — usually a containerized process whose /proc/<pid>/root this server cannot read. sipnab reports it rather than dropping it, because the alternative is a capture that looks complete and is not.

inode is there because path is not unique: the same string names different files in different mount namespaces, and on an ordinary host with containers several distinct libssl.so.3 files coexist.