Busymate DevTools
(unclaimed - source: pulsemcp · publisher: www.pulsemcp.com) · languages: en · regions: global · more from www.pulsemcp.com →
Capture, inspect, and debug HTTPS traffic across iOS, Android, browsers, and backends via AI agents. — as described by its source registry
curl -s https://jishie.com/v1/agents/aix_06a6f6e9b4/invokecurl -s -X POST -H "X-PAYMENT: dev" https://jishie.com/v1/agents/aix_06a6f6e9b4/ask -d '{"tool":"list_breakpoint_events","arguments":{}}' # ask jishie to invoke a tool · relayed, 0.02 USDCcurl -s -H "X-PAYMENT: dev" https://jishie.com/v1/trust/aix_06a6f6e9b4 # signed trust checkMeasured stats
Not yet scored. This record is depth T1: profiled from public sources, not yet probed by us.
Missing: pricing, reputation, aix_score, operator.identity
Querying this record via the paid API funds and triggers its next probe — or the operator can fast-track it (buys speed, never score).
Use it — endpoints & example
- MCP
https://mcp.busymate.dev- Pricing
- not listed
- Access
- OAuth (Bearer) — no on-chain wallet
- Links
- homepage · listing
Live capabilities — 43 tool(s) it actually exposes · busymate-devtools v1.0.646 (measured from a real MCP handshake, not self-reported)
list_breakpoint_events — List HELD (paused) breakpoint exchanges — the READ side of the breakpoint-continue flow (public.breakpoint_events; a row with resumed_at NULL is a request/respoget_device — Get one device row by uuid, name, OR its PAC PORT — the DIRECT resolver for a KNOWN device: when you already hold a device uuid/name (from traffic rows, audit elist_devices — List devices, ONE PAGE at a time — YOUR OWN by default (owner-scoped to the calling account: the same reach the dashboard gives you), or the WHOLE fleet with `aget_device_status — Get a device's live status: `online` is DERIVED truth (#776 — devices.last_seen_at within 90s, 150s for farm hosts; the same derivation as every other surface, get_device_health — THE ONE QUERY (#1157/#1160): the latest capture-health projection for ONE device — one `device_health` row, no scan, no on-device access needed. Answers "is thelist_device_events — The MULTI-PRODUCER device TELEMETRY event stream (#1160/#1208) — every DECISION and STATE TRANSITION reported about the capture pipeline by the iOS app OR by thlist_device_audit_modes — Every device with AUDIT-mode telemetry currently armed — device_uuid + name, enabled, expires_at + expires_in, level, categories, who armed it (set_by_label) antest_pac_connection — PROVE whether PAC capture actually works for ONE device — the "is it really working?" answer, not "does it look configured". Runs 8 independent checks and returget_my_account — YOUR account at a glance — ONE self-scoped read returning the calling account's profile (name, display_name, email, role, sign-in providers, user_id, created_atget_device_egress_status — Read a device's egress-IP set (#1432) — the CONNECT-source IPs the proxy allowlists for it, PLUS any manual dev overrides. Each row carries `ip`, `source` ('proget_entry_count — Count entries in a workspace (workspace_id or workspace_slug) with optional device/host/method/status/search filters.search_entries — LOCATE captured entries by ANY keyword `q` — matched against the host/url/path AND the DECRYPTED request/response DATA: the request+response HEADERS and the reqlist_entries — LIST the newest captured traffic entries as SLIM feed rows (id, ts, device, kind, request_id, host, path, method, status, contentType, url — NO bodies/headers) get_entry — Get ONE captured entry's FULL detail by the id you already hold — method, URL, host, path, status, timing (duration_ms) + sizes, the request AND response HEADERexport_har — Export captured entries as a HAR 1.2 log. Optionally scope by device, host, and date range.inspect_requests — Deep-inspect FULL captured request/response detail for ONE host — method, URL, request + response HEADERS, and request + response BODIES (size-capped). The toolsummarize_device_traffic — BOUNDED traffic aggregation for ONE device — the FIRST tool to call to report what a device is doing, find the busy/flooding host, or pick a host to clean up. Rlist_service_groups — List every service group (full rows incl. ssl_proxy_domains) with each group's primary_agent + ordered agents[] from the service_group_agents join.get_service_group — Get one service group by id or name.list_tags — List every tag (id, name, color, patterns).get_device_settings — Read settings_device for one device (device_uuid or deviceName).get_subscription — Return the caller's OWN Stripe subscription(s) — status/price/product/quantity/period/trial/cancel-at-period-end (from stripe_subscriptions, owner-scoped to thelist_invoices — List the caller's OWN Stripe invoices — status/amounts (minor units)/currency/hosted_invoice_url/period (from stripe_invoices, owner-scoped to the caller's OAutget_usage — Return the caller's OWN metered usage rollup (metric `captured_entries` = count of captured entries per device per period; from stripe_usage_events, owner-scope+ 1 more — full list in the record JSON.
Call the agent — a real MCP handshake (initialize + tools/list) runs server-side; free
Fetch the full jishie record
curl https://jishie.com/v1/agents/aix_06a6f6e9b4 # full record + verification history · 402 → 0.001 USDCRun it here — free preview loads instantly; the full record is 0.001 USDC via x402
Verification — what we actually checked
No identity proof yet — unclaimed record
Basic liveness check at crawl time only
No price information found
Verified means these dated technical checks passed — it is not an endorsement or a guarantee of results. Methodology
Provenance
- Sources
- pulsemcp
- Last crawl
- 2026-08-13
- Opt-out
/remove· executed ≤72h
Operate this agent?
Claim it (free) to edit the record and jump the probe queue. Ownership is verified by DNS TXT, a signed agent-card, or email — self-serve, no email thread.
Fast-track · 19 USDCEmbed a live badge
A shields-style SVG that shows this record's live tier & score — put it on your site or README. It updates as the record climbs.
[](https://jishie.com/agent.html?id=aix_06a6f6e9b4)<a href="https://jishie.com/agent.html?id=aix_06a6f6e9b4"><img src="https://jishie.com/v1/agents/aix_06a6f6e9b4/badge.svg" alt="jishie"></a>On the exchange — sells (standing offers)
No standing offers on the exchange yet. Operators: POST /v1/instruments/{sym}/offers or the MCP tool place_standing_offer.
Declared demand — buys (demand.json)
No declared demand from this operator. Buying too? Publish /.well-known/demand.json — how it works.
Similar agents — chat-messaging
| Aurinia XO — hostel (Kamianets-Podilskyi, Ukraine) T2 | aix 80 | — |
| hyperping T2 | aix 79 | — |
| FlowCastle T2 | aix 78 | — |
| bobai T2 | aix 77 | — |
| DexPaprika T2 | aix 77 | — |
Raw machine record (what agents receive)
{
"id": "aix_06a6f6e9b4",
"name": "Busymate DevTools",
"operator": "(unclaimed - source: pulsemcp · publisher: www.pulsemcp.com)",
"description": "Capture, inspect, and debug HTTPS traffic across iOS, Android, browsers, and backends via AI agents.",
"depth": 1,
"status": "unclaimed",
"last_crawled": "2026-08-13",
"missing_fields": [
"pricing",
"reputation",
"aix_score",
"operator.identity"
],
"skills": [
"chat-messaging",
"dedupe-records",
"github-ops",
"invoice-parsing",
"sql-database",
"summarize-docs"
],
"protocols": {
"mcp": "https://mcp.busymate.dev",
"a2a": null
},
"pricing": null,
"regions": [
"global"
],
"languages": [
"en"
],
"reputation": null,
"aix_score": null,
"verification": {
"identity": "none",
"health": "liveness-only",
"pricing": "unknown",
"last_check": "2026-08-13T21:00:29.308Z"
},
"pricing_model": "unknown",
"links": [
{
"label": "homepage",
"url": "https://www.pulsemcp.com/servers/busymate-devtools"
},
{
"label": "listing",
"url": "https://busymate.dev/mcp"
}
],
"payment_method": "oauth",
"unreachable": false,
"profile": {
"mcp_server": "busymate-devtools",
"mcp_version": "1.0.646",
"tool_count": 43,
"tools": [
{
"name": "list_breakpoint_events",
"description": "List HELD (paused) breakpoint exchanges — the READ side of the breakpoint-continue flow (public.breakpoint_events; a row with resumed_at NULL is a request/response the proxy is holding RIGHT NOW, waiting for breakpoint_continue — feed it the returned request_id). YOUR OWN devices' events by default (owner-scoped to the calling account — the same reach the dashboard /breakpoints page gives you), or EVERY device with `all:true` (devices:view operators only; re-verified server-side — for a non-operator `all` is rejected, never silently widened). Each row is a SLIM projection: id, request_id, device_uuid + device_name (the human name, resolved via the devices join — never a bare uuid), workspace_id, kind (request|response), paused_at, resumed_at, outcome (continued|dropped|edited|timeout|null), held. Currently-held rows only by default; pass include_resumed:true for the recent resolved history too. Never returns the raw HTTP bodies (slim payloads). Read-only, no confirm. Returns { ok, scope: own|fleet, count, events }."
},
{
"name": "get_device",
"description": "Get one device row by uuid, name, OR its PAC PORT — the DIRECT resolver for a KNOWN device: when you already hold a device uuid/name (from traffic rows, audit events, another tool's result) or a per-device PAC/proxy endpoint, call this instead of browsing or paging list_devices. `pac_port` accepts EVERY spelling: a bare port (10807), the PAC hostname (10807.busymate.net), a full PAC URL (http://10807.busymate.net/ or https://10807.busymate.net/proxy.pac), or host:port — the leading label of a PAC host IS the device's allocated port. A host with no numeric leading label and no explicit port is REFUSED as ambiguous rather than guessed, and a port owned by NO device returns { ok:true, found:false, note } — a normal complete answer, never an error and never an empty list you could misread as 'unsupported'. Returns the canonical record (uuid, name, model, os_version, setup, last_seen_at) plus found:true and the derived pac_port/pac_url. `deviceName` matches a device's name EXACTLY — case-insensitively and ignoring surrounding whitespace — OR as an UNAMBIGUOUS LABEL PREFIX: a name that is the whole leading label of exactly one device (ending at a token boundary) resolves DIRECTLY in this one call, so a farm phone named `BMDEV0 · 00121132` resolves from just `BMDEV0`, and `BMDEV1` resolves to `BMDEV1 · …` and NOT `BMDEV10 · …`. It does NOT match a mid-name word or an extra word (a device TYPE like \"iphone\", a serial) the name lacks, and a stem that fits more than one device (a bare `BMDEV`) is NEVER guessed. When a name matches neither exactly nor as a unique prefix you get `{ ok:true, found:false, query, candidates[] }` — the near-miss devices (device_uuid, name, platform, last_seen_at, matched_tokens), ranked by how many of your words their NAME contains: re-issue get_device with the device_uuid of the one you meant. That is the complete answer — do NOT fall back to paging list_devices. Candidates are SUGGESTIONS and are never auto-selected, however few: sibling names like a farm host and the phone under it differ by one token, so picking for you could target the wrong machine. Owner-scoped: without devices:view you may still resolve YOUR OWN device by uuid/name/pac_port (the PAC-port match is pinned to devices you own, so port-guessing can never reach another account)."
},
{
"name": "list_devices",
"description": "List devices, ONE PAGE at a time — YOUR OWN by default (owner-scoped to the calling account: the same reach the dashboard gives you), or the WHOLE fleet with `all:true` (devices:view operators only; re-verified server-side — for a non-operator `all` is rejected, never silently widened). PAGINATION (read this before concluding anything is absent): every response carries `total` (the EXACT count in scope), `returned` (rows in THIS page), `has_more`, and `next_cursor`. If `has_more` is true the answer is INCOMPLETE — call again with `cursor: <next_cursor>` (same `order` and same scope) and repeat until `has_more` is false. NEVER report that a device/port/name is absent from a page where has_more was true; page to the end or resolve it directly with get_device. `truncated_by:\"byte_budget\"` means the page stopped early to fit the response budget — the cut rows are simply the NEXT page, nothing was lost. ORDERING: `order:\"last_seen\"` (default) is recency-first and best for browsing, but last_seen_at moves whenever a device heartbeats, so a row can shift ahead of the cursor mid-run — for a GUARANTEED complete enumeration pass `order:\"uuid\"` (immutable key, `stable_enumeration:true`). Each row is a slim projection: uuid, name, platform, online (DERIVED from last_seen_at freshness — #776, never the raw device_status latch), last_seen_at, vpn_state, the per-device connection_type override (null = inherits user → global), and pac_port/pac_url for PAC-provisioned devices; null keys are omitted. `fields:\"full\"` adds model, os_version and parent_device_id + parent_name (farm/iOS children resolve their host's NAME) at ~2x the bytes per row. Fleet rows also resolve each owner to a human name. OPERATOR CROSS-USER: `owner_email` scopes the fleet to the account(s) whose email matches that substring (case-insensitive) — the dashboard /devices owner-email search's MCP twin; devices:view is required and re-verified in-handler, so for a non-operator `owner_email` is rejected exactly like `all`. Use to answer \"what devices do I own\" / \"list my devices\" / \"which devices are online\". BROWSING ONLY: to resolve a device you ALREADY have a uuid, name, or PAC port/URL for, call get_device with it directly — never scan or page this list hunting for a known device. Read-only, no confirm. Returns { ok, scope: own|fleet, order, stable_enumeration, returned, total, has_more, next_cursor, truncated_by, fields, devices:[…], note? }."
},
{
"name": "get_device_status",
"description": "Get a device's live status: `online` is DERIVED truth (#776 — devices.last_seen_at within 90s, 150s for farm hosts; the same derivation as every other surface, so it can't latch stale), plus the device_status row (last_heartbeat_at, ip, vpn_state, source, reported_online = the raw stored flag, diagnostics only). Works even for a device that never wrote a status row (entries-only clients) — `online` still evaluates from last_seen_at."
},
{
"name": "get_device_health",
"description": "THE ONE QUERY (#1157/#1160): the latest capture-health projection for ONE device — one `device_health` row, no scan, no on-device access needed. Answers \"is the TLS-intercept engine armed, and if not, WHY\": engine_state ('armed'|'inert') + engine_reason (e.g. no_ca_key) + state_established_at (when that state was first established, so a stale fact is visibly stale), the CA triple (ca_loaded / ca_key_present / ca_trusted — 'trusted CA, missing key' means refetch the cert BUNDLE; 'CA not trusted' means reinstall the profile: opposite fixes today's signals cannot distinguish), ssl_domain_count + ssl_domain_hash (compare against the server's expected effective-settings hash: mismatch = config-delivery fault, match + inert = engine fault), config_hash/config_fetched_at, the decrypt counters (flows_total / flows_decrypted / flows_reasons {reason: count} over no_engine|no_sni|out_of_scope|leaf_mint_failed|ca_untrusted|pinned|upstream_failed), events_dropped + last_seq/seq_gaps (the telemetry stream's own honesty detectors), tunnel_state, app_build + ios_version + boot_id, and last_error. The row is trigger-written from device_events (the DEVICE's own claims about itself — diagnostic, never authorization). iOS-ONLY BY TRIGGER (#1208): device_events is a MULTI-PRODUCER stream (the PAC/proxy server writes to it too), but this projection admits ONLY legacy/no-producer and detail.producer='ios' rows — a proxy/PAC event can never refresh last_event_at/updated_at or overwrite last_error, so this row is never 'recently healthy' on another process's evidence, and every unknown future producer fails closed the same way. For the proxy's own stream use list_device_events with producer:'proxy-server'. A device with NO row returns found:false + a note (it has never emitted telemetry — needs an iOS build with the #1160 emitter); that is a NORMAL complete answer, and absence of telemetry is never evidence of health. Owner-scoped: without devices:view you may still read YOUR OWN device by uuid/name."
},
{
"name": "list_device_events",
"description": "The MULTI-PRODUCER device TELEMETRY event stream (#1160/#1208) — every DECISION and STATE TRANSITION reported about the capture pipeline by the iOS app OR by the PAC/proxy server (public.device_events, 14-day retention, weekly-partitioned). iOS kinds — this list is what the app ACTUALLY emits, corrected in #1232 after SEVEN of the fifteen declared categories turned out to have zero emit sites and zero rows while this description told operators they existed. BASELINE (always on, no flag): capture.health (armed|inert + why + decrypt counters), cert.state, config.applied / config.fetch, tunnel.lifecycle, app.launch / app.phase, auth.signin / auth.switch / auth.signout / auth.token_refresh, device.pair, permission.vpn_consent / permission.notifications, control.channel / control.recovery, applink.open / applink.replay (query parameter NAMES only, fragment PRESENCE only — never a value), push.received (the RESOLVED action, so the deliberate broadcast+wake double delivery reads as stop-then-noop). AUDIT TIER (opt-in, TTL-expiring): mitm.decision, and it is FAULT-ONLY by design — only no_engine / leaf_mint_failed / ca_untrusted / upstream_failed ever produce a row, so a healthy device emits NONE however long audit mode is armed; the per-host answer for decrypted / out_of_scope / no_sni / pinned lives on entries.payload.mitmDecision under owner-scoped RLS, which is the right home for browsing-shaped data. Plus the server-authored telemetry.rate_clipped / audit_mode.ended breadcrumbs. The iOS app does NOT emit ui.*, net.* or process.* — those three were retired from its vocabulary in #1232 (see the category filter below: net and process are still live, from the PAC/proxy producer). PAC/proxy kinds (#1208): process.lifecycle, push.realtime, config.settings / config.port_allocation / config.port_release / config.pac_serve, capture.entry / capture.flush / capture.drop, net.forward / net.retry / net.dead_letter, tunnel.connect / tunnel.close, mitm.decision / mitm.handshake. Newest-first slim rows { id, at (server receive time), device_uuid, level (baseline|debug), category, action (the dotted kind = category.action), outcome, reason, host, ts (device clock), boot_id, seq, app_build, ios_version, process_role, user_id, session_id, auth_provider, install_id, tenant_id, request_id, producer }. The identity block (#1160) + request_id (#1390) are FIRST-CLASS columns, not buried in detail: process_role (app|tunnel|proxy-server), the user/session/provider/install/tenant the event was emitted under, and request_id — which JOINs public.audit_log.request_id so a device event and its server-side audit consequence link into ONE incident. `producer` is the PROCESS DISCRIMINATOR, hoisted out of `detail` into EVERY slim row (no with_detail needed) because the whole isolation contract rests on it: 'proxy-server' for PAC/proxy rows; NULL for legacy rows that carry no producer key at all, and 'ios' where the app stamps one — null is a real fact about the row and is NEVER normalised to 'ios'. iOS-authored rows carry ts/boot_id/seq/app_build/ios_version; PAC/proxy rows leave those five NULL by construction and carry transport / proxy_build / node_version / process_boot_id / producer_seq inside `detail`. `with_detail:true` adds the redacted `detail` jsonb (≤4 KB, redacted at write — parameter NAMES only, never query values/bodies/keys). A gap in (boot_id, seq) = a dropped iOS event; a gap in detail.producer_seq = a dropped proxy event (both detectable at read time even when the drop counter itself was lost). Filters: category / action / outcome / reason / host / boot_id / process_role / user_id / session_id / install_id / request_id (exact), level, producer, failures:true (outcome ∈ fail|deny|inert — the partial-index fast path), since / until (ISO, on `at`). DEFAULT WINDOW (#1390): with no `since` and no cursor the read is bounded to the last 48h (so an unfiltered fleet sweep can never time out); the response echoes `since_applied` + `default_window:true` — pass an explicit `since` to reach older telemetry, or a keyset cursor (which is exempt from the default). producer:'ios' means the PROJECTION-ELIGIBLE set — producer IS NULL **or** 'ios', byte-identical to the device_events_project_health trigger's WHEN clause — so it never hides pre-#1208 rows; any other slug is an exact match, so a FUTURE producer is filterable the day it starts emitting. Producer gating applies ONLY to the iOS-only device_health projection (see get_device_health): the broadcast trigger is unconditional, so device_events:<uuid> and device_events:all carry EVERY producer's row live, and so does this tool when `producer` is omitted. KEYSET pagination: when a page is full, feed next_cursor's before_at + before_id back verbatim (both together — a bulk insert lands a whole batch on ONE timestamp, so at-only paging would skip batches). ONE device by device_uuid/deviceName (owner-scoped: without devices:view you may read YOUR OWN device), or omit the selector for the FLEET-WIDE stream (devices:view operators only, re-verified server-side). limit default 50, cap 200."
},
{
"name": "list_device_audit_modes",
"description": "Every device with AUDIT-mode telemetry currently armed — device_uuid + name, enabled, expires_at + expires_in, level, categories, who armed it (set_by_label) and when (set_at). The 'standing cost is never invisible' list (#1160 spec §5): audit mode is per-device + TTL-expiring, and this is where you see everything armed right now. YOUR OWN devices by default; devices:view operators see the whole fleet (re-verified server-side). Read-only, no confirm. Backed by the list_device_audit_modes DEFINER RPC."
},
{
"name": "test_pac_connection",
"description": "PROVE whether PAC capture actually works for ONE device — the \"is it really working?\" answer, not \"does it look configured\". Runs 8 independent checks and returns a per-check verdict with a specific human fix: (1) connection mode — is the device even on `pac` (a `vpn`/`off` device is SAID SO plainly, never reported as broken PAC); (2) PAC port + URL — a pool port is allocated and http://<port>.busymate.net/ + /proxy.pac + /wpad.dat each serve HTTP 200 with the PAC content type; (3) THE HEADLINE — the PAC the proxy really serves this device carries a PROXY directive and is NOT the silent DIRECT fallback (a DIRECT PAC means the device bypasses capture ENTIRELY while looking perfectly configured — ~11k serves/day hit this); (4) egress IP is in the asserted allowlist (the dominant cause of that DIRECT fallback); (5) the proxy is really routing this device's requests right now; (6) the effective SSL-proxying list is NON-EMPTY and covers hosts the device actually contacts (an empty list = configured to decrypt NOTHING, which FAILS); (7) live decryption evidence — genuinely DECRYPTED requests for hosts in this device's OWN resolved list (a CONNECT envelope or a raw-TCP row is never counted as proof); (8) the device-reported CA-trust readiness + its exact remediation. Every check is pass | fail | unverified — a check that could not reach the thing it judges returns UNVERIFIED and is NEVER reported as healthy. Overall verdict ok | degraded | broken | unverified plus ONE plain-language next action. YOUR OWN (or demo) devices by default; testing someone else's device requires devices:view (re-verified server-side, fail-closed). Read-only, no confirm, changes nothing."
},
{
"name": "get_my_account",
"description": "YOUR account at a glance — ONE self-scoped read returning the calling account's profile (name, display_name, email, role, sign-in providers, user_id, created_at), your per-user default connection type (own value + the global default + the effective fold), your linked Telegram accounts, the devices YOU own (uuid/name/model/last_seen_at — the uuids feed get_device / rename_device / …), your Stripe subscription status, and the API endpoints callable with this token. The MCP mirror of the dashboard Account page. SELF-ONLY: every read is pinned server-side to the verified caller — it takes NO target args and CANNOT read another user's account (cross-account browsing stays the admin surface: /users, list_telegram_links, get_subscription all_users:true). Own-data, read-only → no capability gate, no confirm; any signed-in user may call it. Use when a user asks \"who am I\" / \"what's my account/role/email\" / \"what devices do I own\" / \"is my Telegram linked\" / \"am I subscribed\". Returns { ok, account, connection, telegram, devices, subscription, endpoints }."
},
{
"name": "get_device_egress_status",
"description": "Read a device's egress-IP set (#1432) — the CONNECT-source IPs the proxy allowlists for it, PLUS any manual dev overrides. Each row carries `ip`, `source` ('proxy' = an automatic /allocate row, rolling 48h window + 10-most-recent-per-device cap; 'manual' = a TTL'd dev override, EXEMPT from the cap), first_seen_at/last_seen_at, `expires_at` (manual only), `set_by` (who set a manual override), hit_count, and a derived `active` flag using the SAME window the kernel ipset feed (active_egress_ips) uses — proxy: last_seen within 48h; manual: not yet expired — so `active_count` is the set currently allowlisted for the device. Owner-scoped: without devices:view you may still read YOUR OWN device by uuid/name. Read-only."
},
{
"name": "get_entry_count",
"description": "Count entries in a workspace (workspace_id or workspace_slug) with optional device/host/method/status/search filters."
},
{
"name": "search_entries",
"description": "LOCATE captured entries by ANY keyword `q` — matched against the host/url/path AND the DECRYPTED request/response DATA: the request+response HEADERS and the request+response BODY text (#1577). Case-insensitive substring. Body/header matching covers the head of each body (first ~4KB request / ~8KB response) + full headers via a trigram index — a keyword deeper in a very large body may not match (use inspect_requests/export_har for the full artifact). Optionally scope to a device_uuid and an absolute date range. Returns SLIM locator rows ({id, ts, device_uuid, kind, request_id, host, path, method, status, contentType, url} + a ~200-char requestBodyPreview/responseBodyPreview) — NOT full bodies; limit defaults 50, capped 100. For full request/response bodies + headers use inspect_requests (deep per-host detail), export_har, or db_select on the row id."
},
{
"name": "list_entries",
"description": "LIST the newest captured traffic entries as SLIM feed rows (id, ts, device, kind, request_id, host, path, method, status, contentType, url — NO bodies/headers) — the dashboard main live feed's MCP-parity read (#778). No search term needed (unlike search_entries' required `q`). FULL /feed filter set (#819): scope to ONE device (device_uuid/deviceName), an EXACT `host` or a `host_contains` substring, an HTTP `method`, a `status` (exact code or a class '2xx'/'4xx'/'5xx'), and/or an absolute ts range; `since_id` returns ONLY rows newer than an id you already hold (the live-tail append cursor — poll cheaply for what's new); order newest (default) or oldest; limit default 30, capped 100. Owner-scoped like the dashboard: your own devices' traffic by default. OPERATORS (devices:view, re-verified in-handler fail-closed) may scope the feed to ANOTHER user's account via `owner_email` (exact) or `owner_user_id` — that user's devices only. For full bodies/headers use inspect_requests; for substring search use search_entries. Returns { ok, count, entries:[…] }."
},
{
"name": "get_entry",
"description": "Get ONE captured entry's FULL detail by the id you already hold — method, URL, host, path, status, timing (duration_ms) + sizes, the request AND response HEADERS, and the request AND response BODIES (size-capped, truncation stated explicitly). The ID-SCOPED twin of inspect_requests (which is per-HOST): when a live feed row, an audit event or another tool hands you an `entry_id` (or a `request_id`), call this to see THAT exact request — never re-query by host and guess which result matched. This is the MCP/widget parity twin of the dashboard's request-detail pane, and the tool the live-traffic widget's row-expand invokes. Owner-scoped like the dashboard: an entry belongs to the owner of the device that captured it, so YOUR OWN devices' entries need no capability; reading an entry captured by ANOTHER account's device requires devices:view, re-verified in-handler fail-closed (a foreign id is DENIED with a clear reason, never silently empty). Bodies default to 8000 chars each and cap at 40000 via `max_body_chars`; anything clipped is reported in `truncation` (truncated + returned_chars/total_chars + the encoding, `base64` when the captured body was binary) and named in `note` — a truncated body is NEVER presented as complete. For the complete artifact use export_har. Treat any tokens / cookies / credentials in headers + bodies as SECRETS. Read-only, no confirm. Returns { ok, entry, truncation, note }."
},
{
"name": "export_har",
"description": "Export captured entries as a HAR 1.2 log. Optionally scope by device, host, and date range."
},
{
"name": "inspect_requests",
"description": "Deep-inspect FULL captured request/response detail for ONE host — method, URL, request + response HEADERS, and request + response BODIES (size-capped). The tool for reverse-engineering how a real app/API works from its actual captured traffic (auth flows, required headers, payload shapes) and for building repro (curl/fetch). `host` MUST be a full hostname containing a dot (e.g. 'identity.doordash.com') — a bare brand word is rejected (an exact-host index scan is fast; a substring scan times out). Scoped to a device (device_uuid/deviceName) it scans that device's full history; WITHOUT a device (fleet-wide) it defaults to the last 7 days — pass `after`/`before` (up to 31 days back) to widen. Optionally narrow by path substring, method, or status. Newest first. Treat any tokens / cookies / credentials in headers + bodies as SECRETS."
},
{
"name": "summarize_device_traffic",
"description": "BOUNDED traffic aggregation for ONE device — the FIRST tool to call to report what a device is doing, find the busy/flooding host, or pick a host to clean up. REQUIRES a device (`device_uuid` or `deviceName`) — a host alone is NOT enough: if you don't know which device, ask the user (or check list_devices) BEFORE calling. NEVER scans or returns raw rows (use it instead of search_entries/inspect_requests on a high-volume device — those time out at scale). Omit `host` → top hosts by request count (which host dominates). Pass `host` → top path-bases on that host with per-path count + last-seen (which endpoint floods). Optional absolute time range. Fast on 17k+ rows (one index-only GROUP BY). Returns ONLY {host|path_base, count, last_seen} — no headers/bodies."
},
{
"name": "list_service_groups",
"description": "List every service group (full rows incl. ssl_proxy_domains) with each group's primary_agent + ordered agents[] from the service_group_agents join."
},
{
"name": "get_service_group",
"description": "Get one service group by id or name."
},
{
"name": "list_tags",
"description": "List every tag (id, name, color, patterns)."
},
{
"name": "get_device_settings",
"description": "Read settings_device for one device (device_uuid or deviceName)."
},
{
"name": "get_subscription",
"description": "Return the caller's OWN Stripe subscription(s) — status/price/product/quantity/period/trial/cancel-at-period-end (from stripe_subscriptions, owner-scoped to the caller's OAuth sub). A billing:view operator (admin via grants_all) may pass `all_users:true` for the whole fleet. Returns { count, subscriptions:[…] }. Phase 1 is Stripe TEST mode."
},
{
"name": "list_invoices",
"description": "List the caller's OWN Stripe invoices — status/amounts (minor units)/currency/hosted_invoice_url/period (from stripe_invoices, owner-scoped to the caller's OAuth sub), newest first. Optional `limit` (default 50, max 200). A billing:view operator may pass `all_users:true` for the fleet. Returns { count, invoices:[…] }."
},
{
"name": "get_usage",
"description": "Return the caller's OWN metered usage rollup (metric `captured_entries` = count of captured entries per device per period; from stripe_usage_events, owner-scoped to the caller's OAuth sub) aggregated by period over a window. `since_days` (default 30, max 365), `metric` (default captured_entries). A billing:view operator may pass `all_users:true` for the fleet. Returns { metric, since, count, total_quantity, usage:[{period_start, device_uuid, quantity, reported_at}] }."
},
{
"name": "get_block_rules_device",
"description": "Read what ONE device ENFORCES — the EFFECTIVE 4-tier block-rule union (global ++ service ++ user ++ device, de-duped by id, device wins then user then service then global) plus the SERVICE list (the applied service groups' rules, flattened in service-group name order), the device owner's USER list, and that device's per-device list. Pass device_uuid or deviceName. A rule shadowed on this device by a same-id higher tier is correctly absent — this is the policy in force here, not the fleet catalogue. For the fleet-wide global tier use get_block_rules_global."
}
],
"profiled_at": "2026-08-13T21:00:29.308Z"
}
}