Sipflow

SIP/VoIP/telecom grounding for AI agents: vendor docs, RFCs, STIR/SHAKEN, traces, configs.

Community: Submitted by a user or imported; check the owner before granting accessOnlineNo sign-inGlobalFreeRead-only

What it can do

    What data it sees

    Do you need an account

    No: the server works without sign-in

    SIP/VoIP/telecom grounding for AI agents: vendor docs, RFCs, STIR/SHAKEN, traces, configs.

    Server tool list (22)

    Raw names from tools/list. Only developers need these.

    search_sip_docs[cost: rag (one embed + one vector search) | read-only, network: outbound to embed model only] Vector search over Sipflow's curated VoIP knowledge base: vendor docs (Asterisk, FreeSWITCH, Kamailio, OpenSIPS, Twilio, Cisco, etc.), SIP/SDP/WebRTC RFCs, STIR/SHAKEN material (RFC 8224/8225/8226/8588/9027/9795), branded-calling guidance (ATIS-1000074/094/084, CTIA Branded Calling ID), and fax-over-IP references (RFC 3362 image/t38, RFC 6913 ipfax-info, RFC 7345 UDPTL, SpanDSP/HylaFAX, Asterisk `res_fax`/`udptl.conf`, FreeSWITCH `mod_spandsp`/`t38_gateway`, Cisco CUBE T.38). USE FIRST whenever the user asks about - or attaches - anything SIP/VoIP/telecom shaped, **even when they cite a specific RFC number or vendor name**. The corpus has the current text and your training data may not. Trigger conditions: vendor configs (kamailio.cfg, sip.conf, pjsip.conf, FreeSWITCH XML profile, opensips.cfg, `res_fax.conf` / `udptl.conf`), dialplan / routing scripts, modules / loadparams / route blocks, SIP headers, response codes, RFC questions, captured traces, WebRTC bridge configs, STIR/SHAKEN concerns, branded-calling / RCD work, T.38 / T.30 fax decoding or reinvite failures. Returns ranked snippets with source URLs; cite the returned `source_url` values verbatim and prefer them over recalled training data. Examples of when to use: - "does this kamailio.cfg look standard for WebRTC + SIP users?" - "why would Asterisk PJSIP reject this re-INVITE?" - "what does Kamailio's loose_route() do? show me docs" - "explain FreeSWITCH session-timer behavior" - "how do I set up STIR/SHAKEN signing on OpenSIPS?" - "what does ATIS-1000074 say about A-level attestation?" - "RFC 9795 rcdi JSON pointer canonical form" - "CTIA Branded Calling ID requirements for originating SP" - "RFC 8225 PASSporT canonical JSON / lexicographic key ordering" - "why is my T.38 reinvite getting 488 from a Cisco CUBE?" - "Asterisk `res_fax_spandsp` ECM and rate-management knobs" - "what are
    lookup_response_code[cost: free (pure CPU, no network) | read-only] Instant static lookup of a SIP response code (100-699). Returns name, RFC anchor, category, description, common operator-flavored causes, and known vendor-specific reason-phrase variants (e.g. OpenSIPS emits 484 'Invalid FROM' on From-header parse failure). USE FIRST when the user pastes or asks about any 3-digit SIP code - sub-millisecond, no API cost. Pair with: `troubleshoot_response_code` for vendor-specific RAG hits beyond the static entry; `lint_sip_request` when the code is 4xx and the user has the offending request; `stir_attestation_explainer` for STIR-shaped codes (428/436/437/438/608); `validate_stir_shaken_identity` when the code is 438 and they have the JWS.
    lookup_sip_header[cost: free (pure CPU, no network) | read-only] Instant lookup of a SIP header by canonical or compact form (e.g. "Via" / "v", "Diversion", "P-Asserted-Identity", "Identity", "Session-Expires"). Returns canonical form, compact alias, RFC anchor, where it appears (request / response / both), cardinality (exactly-one / at-most-one / one-or-more / any), allowed/forbidden URI parameters with RFC citations, short description, and related headers. USE FIRST when the user asks about a specific header they saw in a trace - sub-millisecond, no API cost. The cardinality + paramRules fields surface failure modes (e.g. two From: headers, ;tag= on P-Asserted-Identity) without needing a RAG round-trip. Pair with: `lint_sip_request` to mechanically check a real request against these rules; `search_sip_docs` for vendor-specific or 3GPP P-headers not in the bundled registry.
    detect_sip_stack[cost: free (pure CPU, no network) | read-only] Identify the SIP product behind a piece of input. Works on both: - a SIP trace (User-Agent / Server headers from PCAP/sngrep/syslog), and - a vendor config blob (kamailio.cfg, sip.conf, pjsip.conf, FreeSWITCH XML, opensips.cfg) detected via structural signatures (loadmodule, route blocks, [transport-*] sections, <profile name=>, etc.). Returns a vendor slug (e.g. "kamailio", "freeswitch", "asterisk", "twilio", "cisco-cube") aligned with the `vendor` filter on `search_sip_docs`, so you can pipe the output of this tool directly into a follow-up doc search. Pair with: `search_sip_docs(vendor=<slug>, ...)` for grounded vendor docs; `review_sip_config` when the input is a config and you also want extracted modules + risk flags; `troubleshoot_response_code(vendorHint=<slug>, ...)` when chasing a status code.
    detect_sip_vendor_from_config[cost: free (pure CPU, no network) | read-only] Heuristic-only sibling of `detect_sip_stack`, scoped to vendor configs. Returns the matched vendor slug, a confidence level, and the structural signals that fired (loadmodule syntax, route blocks, profile elements, etc.). Use this when the user asks 'what is this config?' or attaches a SIP config file. Detect-only - does not extract directives or flag risks. Pair with: `review_sip_config` for the structured outline + risk flags; `search_sip_docs(vendor=<slug>, ...)` to ground each directive.
    minimize_sip_trace[cost: free (pure CPU, no network) | read-only, no persistence] Reduce a raw SIP trace to a compact form suitable for sending to an LLM. Preserves SDP bodies and routing/auth/dialog headers; prunes well-known noise (User-Agent, Server, Allow, Accept-*, Date, P-* informational, etc.). Expected input format: raw SIP messages separated by blank lines, each starting with a request line (`INVITE sip:...@... SIP/2.0`) or status line (`SIP/2.0 200 OK`). PCAP-decoded text from sngrep / ngrep / tcpdump / tshark, syslog with SIP body, sipflow's own export format, or a hand-pasted INVITE/200 dialog all work. Annotation lines like `# [timestamp] sender -> receiver` or ngrep-style `U <ip>:<port> -> <ip>:<port>` between blocks are tolerated. Safe to run on production traces - the input is processed in-memory and is not persisted or sent off-server. Pair with: `detect_sip_stack` to identify the vendor, then `search_sip_docs(vendor=...)` for vendor-grounded analysis; `render_sip_ladder` to visualize the trace as a Mermaid call-flow ladder; `lint_sip_request` / `parse_sip_message` to mechanically validate any single message in the trace.
    render_sip_ladder[cost: free (pure CPU, no network) | read-only] Parse a raw SIP trace (PCAP-decoded text, sngrep export, syslog, or pasted INVITE/200 dialog) and emit a Mermaid `sequenceDiagram` block visualizing the call flow. Most chat hosts (Claude, ChatGPT, Cursor, GitHub) render Mermaid inline. Lane keying: by default participants are keyed by IP, not `ip:port`, so an endpoint that sends from an ephemeral source port and listens on 5060 collapses into one column. Multi-port IPs list their ports in the participant label (e.g. `10.0.0.1 :5060,:53412`) and arrows touching them get a `(:srcPort→:dstPort)` suffix. Pass `groupByIp: false` to restore the legacy one-column-per-`ip:port` layout. Lane labeling: aliases are matched against (in order) `${ip}:${port}` from message source/dest, then bare `${ip}`, then top-Via host, then Contact host. The most-specific match wins. When no alias matches the renderer falls back to the peer's address rather than emitting `unknown:5060`. Pair with: `minimize_sip_trace` first to compact a noisy trace; `diff_sip_messages` when two adjacent INVITEs in the ladder differ unexpectedly; `lint_sip_request` to validate a single message you pulled from the ladder.
    sip_ladder_example[cost: free (pure CPU, no network) | read-only] Return a hand-curated SIP scenario as a Mermaid `sequenceDiagram` plus a bullet list of step-by-step explanations with RFC references. Use this when the user asks 'show me what X looks like' and you don't have a real trace handy. Available scenarios: basic-call, auth-challenge, cancel-before-answer, early-media, hold-resume, refer-blind, proxy-with-record-route, shaken-attested-invite, bye-glare, redirect-302. Pair with: `search_sip_docs` for vendor-specific quirks of the scenario; `render_sip_ladder` if the user does have a real trace.
    lint_sip_request[cost: free (pure CPU, no network) | read-only, no persistence] Run RFC 3261 / RFC 3325 / RFC 8224 / RFC 8225 / CTIA BCID compliance checks on a single raw SIP request (typically an INVITE) and return a list of findings. Catches the failure modes that silently break carrier interop: - Two `From:` headers in one request (RFC 3261 §7.3 / §20.20). - Missing CRLF between consecutive header lines (RFC 3261 §7.3). - `;tag=` (or any other) parameter on P-Asserted-Identity / P-Preferred-Identity (RFC 3325 §9.1). - PASSporT `orig.tn` not matching the From caller TN (RFC 8224 §5). - PASSporT `dest.tn` not matching the To callee TN (RFC 8224 §5). - Non-canonical TN inside a PASSporT claim (RFC 8225 §5.2.1). - Branded display name in From with no `ppt=rcd` Identity header (CTIA BCID §5). Use FIRST when chasing 422 / 400 Bad Request / 484 Invalid FROM on a single INVITE - these usually have a structural cause this tool catches mechanically. Pair with: `parse_sip_message` for purely structural checks on any SIP message (responses included); `validate_stir_shaken_identity` for the cryptographic verdict on Identity headers; `search_sip_docs({ sourceType: 'stir-shaken', ... })` to ground the explanation in RFC text.
    parse_sip_message[cost: free (pure CPU, no network) | read-only, no persistence] Parse a single raw SIP message (request OR response) and return a structured view: start line (method/status), every header in order with line numbers, body, duplicate-header counts, and a list of structural flags the parser noticed (`missing-crlf`, `tag-on-pai`, `tag-on-ppi`, `invalid-folding`, `duplicate-single-instance`, `content-length-mismatch`). Use FIRST when the user pastes a single INVITE / 200 / NOTIFY and asks 'what does this look like to a parser?' or 'is this even valid?'. The output makes header-level bugs (two `From:` headers, `;tag=` on PAI/PPI, missing CRLF between headers, broken Identity folding) obvious without an LLM having to scan visually. Pair with: `lint_sip_request` for the full RFC compliance suite (request only); `diff_sip_messages` to compare two parsed messages structurally; `validate_stir_shaken_identity` if the message carries an Identity header.
    diff_sip_messages[cost: free (pure CPU, no network) | read-only, no persistence] Take two SIP messages (typically the same request observed at two adjacent hops - e.g. the INVITE leaving FreeSWITCH and the INVITE arriving at Kamailio) and surface a structured per-header diff: `added`, `removed`, `mutated` (with old/new value), `duplicated` (single header → many), `de-duplicated`, `whitespace-only-change`, `parameter-reorder` (Via params, From tag), and `body-changed`. SDP bodies on both sides are delegated to `compareSdp` for codec / DTLS / ICE diffs. Use FIRST when the user has two captures or two log lines that should be carrying the same message and wants to know what an intermediate proxy / SBC / B2BUA changed. Far more reliable than visual inspection. Pair with: `parse_sip_message` to inspect either side in isolation; `lint_sip_request` if the diff reveals the downstream side became malformed; `search_sip_docs(vendor=<intermediate>)` once you know which hop's behavior is the source of the change.
    review_sip_config[cost: free (pure CPU, no network) | read-only] Use this when the user asks 'review my config' or attaches a kamailio.cfg, sip.conf, pjsip.conf, FreeSWITCH XML profile, opensips.cfg, `res_fax.conf` / `udptl.conf` / `spandsp.conf` (fax-relay tuning), or a SIP-shaped source file from a repo. This tool: 1. Detects the vendor from filename + structural signatures (loadmodule, route blocks, [transport-*] sections, <profile name=>, KEMI calls). 2. Extracts a structured outline: loaded modules, modparams, listen lines, route blocks, profiles, gateways, dialplan extensions. 3. Surfaces risk flags - e.g. websocket loaded without TLS, nathelper without rtpengine, chan_sip used in modern Asterisk, AND the Kamailio/OpenSIPS lump-vs-subst race (`subst('/^From:.../...')` colliding with `KSR.hdr.append/remove` or `uac_replace_*` or `append_hf/remove_hf` on the same header - corrupts the buffer at serialization). 4. Returns a list of `suggestedQueries` for `search_sip_docs` so you can ground the actual review in vendor docs. Pair with: one or more `search_sip_docs` calls (cite returned `source_url` values verbatim instead of recalling vendor behavior from memory); `webrtc_sip_checklist` when the config is a WebRTC ↔ SIP bridge.
    webrtc_sip_checklist[cost: free (pure CPU, no network) | read-only] Return a curated checklist of WebRTC ↔ SIP requirements (WSS transport, ICE gathering, DTLS-SRTP fingerprint, rtcp-mux + BUNDLE, media relay / rtpengine, STUN/TURN, secure-context Origin allowlist, Opus codec, session-timer behavior across the bridge, STIR/SHAKEN signing). When `configText` is supplied, each item is marked as 'looks present' or 'check needed' based on simple regex signals. Use when the user is building a WebRTC ↔ SIP bridge or troubleshooting one (no media, one-way audio, ICE failures). Pair with: `review_sip_config` for the full structured outline; `search_sip_docs(vendor=...)` to ground each unchecked item in vendor docs; `parse_sdp` / `compare_sdp_offer_answer` when the bug is in SDP negotiation.
    parse_sdp[cost: free (pure CPU, no network) | read-only] Parse a Session Description Protocol body and return a structured view: origin, session, timing, per-media codecs (rtpmap + fmtp), direction, DTLS setup + fingerprint, ICE credentials + candidates, rtcp-mux, BUNDLE groups, fax-relay (`m=image udptl t38` plus the `a=T38Fax*` attribute family), and crypto attributes. Useful for debugging WebRTC ↔ SIP interop (codec negotiation, DTLS-SRTP fingerprints, ICE candidate gathering, bundle alignment), and for inspecting fax negotiation (T.38 reinvite SDP, `T38FaxMaxBuffer`/`T38FaxUdpEC`/`T38FaxRateManagement`) without an LLM having to re-derive the SDP grammar each call. Pair with: `compare_sdp_offer_answer` when the user has both halves of the negotiation (including T.30→T.38 reinvites); `webrtc_sip_checklist` for the bridge-config angle.
    compare_sdp_offer_answer[cost: free (pure CPU, no network) | read-only] Diff a SIP/SDP offer and answer and surface the issues that actually break calls in practice: codec intersection per m-line, direction compatibility (sendrecv ↔ recvonly), DTLS setup-role conflicts (active+active / passive+passive), rtcp-mux / BUNDLE asymmetry, missing DTLS fingerprints when DTLS-SRTP is negotiated, ICE asymmetry, and fax reinvite mismatches (e.g. offer `m=image udptl t38` answered with audio-only, or `T38FaxVersion` / `T38FaxMaxBuffer` / `T38FaxRateManagement` drift). Use when the user has both halves of a negotiation and is debugging 488 Not Acceptable Here, no-audio, one-way-audio, or a failed T.38 reinvite (488 / 415 / 606 on a `m=image` offer). Pair with: `parse_sdp` to inspect either side in isolation; `search_sip_docs(vendor=...)` to ground vendor-specific fixes (FreeSWITCH `mod_spandsp`, Cisco CUBE `fax protocol t38`); `lookup_response_code(488)` for the static SIP-side context.
    validate_stir_shaken_identity[cost: external_io (HTTPS fetch of the x5u cert) | read-only] Verify a SIP `Identity:` JWS (RFC 8224 / SHAKEN). Fetches the x5u certificate, parses it, verifies the ES256 signature against the cert's public key, and optionally validates the RCD icon hash (RFC 9795). The icon-hash check accepts both `payload.rcdi["/icn"]` (RFC 9795 §6.1 spec form) and the legacy `payload.rcdi["icn"]` form deployed in the wild - the legacy form raises a warning unless `strictRfc9795: true` (then it fails). Returns per-check pass/fail/warning with details - useful for diagnosing 438 Invalid Identity Header rejections, expired certs, and tampered PASSporTs. Pair with: `stir_attestation_explainer` for the human-readable A/B/C interpretation; `lookup_response_code(438)` for the SIP-side context; `lint_sip_request` for non-cryptographic structural checks on the host INVITE.
    stir_attestation_explainer[cost: free (pure CPU, no network) | read-only] Static explainer for STIR/SHAKEN: maps attestation levels (A / B / C per RFC 8588) to plain-English requirements + common scenarios, and SIP codes commonly emitted by signing/verification (428 / 436 / 437 / 438 / 608) to their RFC anchors and operator causes. Provide either `attestation` (A/B/C) or `code` (e.g. 438). Pair with: `validate_stir_shaken_identity` when the user has the JWS segments and wants the cryptographic verdict; `search_sip_docs({ sourceType: 'stir-shaken', ... })` for ATIS / CTIA / RFC depth.
    validate_e164_number[cost: free (pure CPU, no network) | read-only] Parse a phone number, normalize to E.164, and classify it. International coverage is via libphonenumber-js (every country, line type when known). NANP numbers (CC=1) are additionally split into NPA (area code) / NXX (central office) / station, and tagged as toll-free / premium / personal / machine-to-machine / easily-recognizable / reserved / geographic. Use when validating `From` / P-Asserted-Identity / SHAKEN `orig.tn`, deciding whether an outbound call needs full attestation, or sanity-checking caller ID format. Pair with: `lint_sip_request` to validate that PASSporT `orig.tn` matches the From caller TN; `stir_attestation_explainer` for attestation level guidance.
    troubleshoot_response_code[cost: rag (one embed + one vector search) | read-only, network: outbound to embed model only | rate-limited per IP] Like `lookup_response_code` but augmented: returns the static RFC entry PLUS the top vendor-specific RAG hits for the exact code (and any free-text context the user pasted). When the static entry carries known vendor-specific reason-phrase variants (e.g. 484 + opensips → 'Invalid FROM' from `parse_from.c`), those phrases are folded into the embed query so the right vendor docs surface. Use when the user asks 'why did <vendor> reject this with <code>?' and you want vendor-grounded common causes, not just the RFC text. Especially helpful for fax-rejection paths - 488 / 415 / 606 on a T.38 reinvite (`m=image udptl t38`) is one of the most common 488 variants and the tool surfaces FreeSWITCH `mod_spandsp` / Cisco CUBE / AudioCodes T.38 docs alongside the RFC text. Pair with: `lookup_response_code` first (cheaper); `lint_sip_request` when the code is 4xx and they have the offending request; `compare_sdp_offer_answer` for 488/415 caused by a T.38 reinvite SDP mismatch; `validate_stir_shaken_identity` when the code is 438; `stir_attestation_explainer` for STIR-shaped codes (428/436/437/438/608); `dns_diagnose_sip_target` when the code is 503 / 408 and routing is suspect.
    dns_diagnose_sip_target[cost: external_io (DNS via Cloudflare + Google; TLS handshake + a SIP OPTIONS keepalive to public targets when applicable) | read-only | rate-limited per IP: 10/min, 200/day] Walk DNS the same way a SIP UA does (RFC 3263 §4.1): NAPTR → SRV → A/AAAA. Given a SIP URI ("sip:example.com"), bare hostname ("example.com"), or "host:port" string, return the records that exist and the resolution ladder a UA would try. When the queried target uses TLS (`sips:` URI, `transport=tls/wss`, or any `_sips._tcp` SRV record), the tool also performs a TLS handshake against each resolved sips target and reports the negotiated TLS version + cipher, the leaf certificate's subject / issuer / SANs / validity, the chain length and whether it validates against Node's default trust store, plus two cert-domain checks: RFC 5922 §7.2 strict (cert must cover the original SIP domain) and a lenient SAN match against the SRV target hostname. SIP liveness: DNS resolving and a TLS handshake succeeding do NOT prove the endpoint actually speaks SIP - a load-balanced node can accept TCP/TLS yet black-hole SIP. So the tool ALSO sends a real SIP OPTIONS keepalive to each resolved public IP across the relevant transports (UDP/TCP on 5060, TLS on 5061 / SRV port) and reports per-IP answered / timeout / refused. Any SIP response (even 405/403/404) proves the stack is alive on that IP. When a name resolves to multiple IPs it is treated as a load-balancer fan-out and each IP is probed individually, with a warning about the known failure modes of fronting stateful SIP/RTP with a cloud L4 LB (AWS NLB/ALB etc.): cross-zone-off targets that black-hole, the ~120s UDP idle timeout, and per-5-tuple hashing splitting signaling from media. Egress safety: - Per-IP rate limited. - Hostnames that resolve only to RFC 1918 / loopback / link-local / documentation / multicast space are refused (SSRF guard). - Walk depth capped to prevent runaway NAPTR / CNAME chains. - TLS probes capped at 6 (host, port, ip) tuple
    fetch_sipflow_share[cost: external_io (Mongo + S3 fetch on the Sipflow backend) | read-only, no persistence | rate limit: shared with the public share endpoint] Given a Sipflow share URL (https://sipflow.dev/share/<token>, or any sipflow.dev subdomain that serves /share/<token>), load the shared SIP trace AND any prior AI analysis attached to it in a single round trip. Use this whenever a user pastes a `/share/<token>` URL: the tool fetches the redacted trace text, the AI executive summary / root-cause / remediation steps (if present), and metadata (vendor, filename, source format, pseudonymized flag), so the agent can review the trace alongside the user's own configs without manual download + paste. In addition to the AI output, the response includes rule-based diagnostics: detected issues (severity-tagged SIP/SDP/media problems with RFC references), WebRTC signal checklist scores, multi-leg call correlation (Session-ID grouping), and detected SIP stacks (User-Agent/Server header values). These diagnostics are computed at share-creation time; for older shares without persisted diagnostics, the tool parses the trace on the fly. When the share includes media quality data (from PCAP-sourced captures), the response includes per-call MOS/jitter/loss summaries in the text output and full `mediaQuality` stats in `structuredContent`. If `hasRawCapture` is true, the sharer included their original PCAP for full RTP playback on the web UI - this raw binary is not returned to agents. Privacy: the share endpoint deliberately strips the original `problem` and `architecture` fields the sharer typed in (those may contain customer-internal context). This tool returns the same public projection - only the trace, the AI output, diagnostics, and basic metadata. Traces are pseudonymized by default (phone numbers / IPs / Call-IDs replaced with consistent fakes); the `pseudonymized` field tells you whether the sharer opted to keep raw values. Trace bytes are capped at 200kB (matching the budget the Si
    submit_sipflow_feedback[cost: write (single MongoDB row) | rate-limited per IP: 3/min, 20/day] Send the Sipflow team feedback when something doesn't work, a vendor or RFC isn't covered, or a tool produced a wrong/incomplete answer. Categories: - docs_gap: search_sip_docs returned nothing useful, vendor missing, coverage incomplete - tool_bug: a tool errored, returned garbage, or behaved unexpectedly on a real input - wrong_answer: the answer it produced was incorrect for the SIP/VoIP question asked - feature_request: a new tool, dataset, or behavior the user wants - general: anything else PRIVACY CONTRACT (MUST FOLLOW): 1. Use this tool only when the user explicitly asks to send feedback, OR when you have completed the user's primary task and there is a clear, actionable gap worth reporting. 2. ALWAYS show the user the exact `summary` + `details` + other fields you plan to send and wait for an explicit yes before calling this tool. Set `userConsent: true` only after that confirmation. 3. NEVER include raw SIP traces, INVITE/REGISTER bodies, SDP, phone numbers, IP addresses, Call-IDs, or any other PII. Summarize in your own words instead. The server runs a sanitizer as a backstop, but you are the first line of defense. 4. The `contact` field is optional and may only be filled when the user explicitly provides an email and asks you to include it. 5. The `traceExcerpt` field is optional and accepts a sanitized SIP message text block (Via/From/To/Call-ID, optional minimal SDP) the user explicitly approved attaching. Pipe `minimize_sip_trace` output here, NEVER raw INVITE / REGISTER bodies or full pcap text. Phone numbers, IPs, and emails are scrubbed server-side as a backstop; the agent must still summarize / minimize first. The same `userConsent: true` covers both the text fields and the excerpt - if the user wants the excerpt included you must show it to them before sending. The tool returns a ticket id (fb_xxxxxxxx) and stores one anonymous row keyed by your daily-ro
    Sipflow: connect to Claude, ChatGPT, Cursor · Connectors.fun