Add device sweep to resolve Claude connector UUIDs#217
Conversation
Fetch the backend's unresolved-UUID list, match each against the local Claude session files (Claude Code + CoWork folders), and report the resolved name + tools back via the single-server scan endpoint with the originating UUID. Only UUIDs the backend asked for are sent; HTTP via curl per the Zscaler constraint.
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using high effort and found 2 potential issues.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 23ea63a. Configure here.
vigneshsubbiah16
left a comment
There was a problem hiding this comment.
🛡️ Automated Security Review (consensus)
2 findings — 1 high-confidence, 1 to triage. Reviewers: Cursor, Claude, Semgrep, Gitleaks.
🔴 HIGH — Local connector url sent beyond documented device scope
scripts/coding_discovery_tools/sweep_connectors.py:154-155 (also report_connector ~143-165)
Impact: Resolved sweeps POST the session file's url to the control plane even though the PR contract and module doc state only {name, tools, connector_uuid} leave the device — expanding disclosure of private MCP endpoint metadata the backend never requested.
Fix: Remove url from the report payload to match the documented contract, or explicitly extend the PR/backend scope and treat url as sensitive data end-to-end.
Flagged by: Greptile, Claude, Lead
🟡 TRIAGE — Conflicting duplicate UUIDs merged without identity checks
scripts/coding_discovery_tools/sweep_connectors.py:86-95
Impact: When the same UUID appears in multiple session files, merge logic keeps the first name/URL and unions tools from later entries — a stale or conflicting file can report connector A's identity with connector B's tools, folding the UUID into the wrong grouped fingerprint on the control plane.
Fix: Skip or split on name/URL mismatches before unioning tools (e.g., only merge when name and URL agree, or prefer the newest session file).
Flagged by: Greptile, Cursor
🤖 consensus review · reviewers: Cursor,Claude,Semgrep,Gitleaks · head 23ea63a2 · 2026-06-26T21:32Z
- don't send the session url (not needed; keeps name-based grouping) - read session files newest-first; union tools only across same-name entries - raise on curl failure so DNS/TLS/timeout reasons surface - normalize UUIDs (lower+strip) on both the needed list and local entries
🛡️ Automated Security Review (consensus)0 findings — 0 high-confidence, 0 to triage. Reviewers: Cursor, Claude, Semgrep, Gitleaks. ✅ Security consensus: no issues found. (reviewers: Cursor, Claude, Semgrep, Gitleaks) Previously acknowledged (not re-flagged)
🤖 consensus review · reviewers: Cursor,Claude,Semgrep,Gitleaks · head |

What
Adds a device-side sweep that resolves bare Claude connector UUIDs to their real names so the control plane can group/policy them. Companion backend change: ai-gateway-data PR (
vv/backfill-uuid-mcp-connectors).Claude desktop OAuth remote connectors are named by a per-registration UUID at runtime. The real display name only exists in the local Claude session files on the device — the backend can't resolve it alone.
How (
sweep_connectors.py)GET /api/v1/ai-tools/unresolved-connector-uuids/— the opaque list of UUIDs the backend still needs resolved.claude-code-sessions= Claude Code,local-agent-mode-sessions= CoWork) →remoteMcpServersConfig→{uuid, name, tools}, de-duped across folders.POSTthe realname+tools+ originatingconnector_uuidto/api/v1/ai-tools/mcp-server-scan/.Only UUIDs the backend explicitly requested ever leave the device — nothing else from the session files is sent. HTTP uses
curlper the Zscaler constraint (nourllib).Notes
🤖 Generated with Claude Code
Note
Medium Risk
The script reads local Claude session data and posts connector metadata to the control plane using a bearer API key; scope is limited to backend-requested UUIDs and omits session URLs.
Overview
Adds a standalone
sweep_connectors.pyscript so devices can backfill bare Claude OAuth connector UUIDs with human-readable names and tool lists the control plane cannot infer from gateway traffic alone.The sweep
GETs/api/v1/ai-tools/unresolved-connector-uuids/, parsesremoteMcpServersConfigfrom Claude Code and CoWork session JSON (newest files first, tools merged only when the UUID shares the same name), thenPOSTs each backend-requested match to/api/v1/ai-tools/mcp-server-scan/withconnector_uuid, displayname,claude-connectorscope, and scan tools. Sessionurlis not included in the payload. HTTP is done viacurl --config(aligned withscan_single_mcp_server.pyand Zscaler constraints), withUNBOUND_API_KEY/--api-keyauth.Not wired into the main discovery scan cycle yet; intended as a companion to the ai-gateway-data backfill work.
Reviewed by Cursor Bugbot for commit cb932fd. Bugbot is set up for automated code reviews on this repo. Configure here.
Greptile Summary
This PR adds a standalone sweep for resolving Claude connector UUIDs. The main changes are:
Confidence Score: 5/5
This looks safe to merge.
Important Files Changed
Reviews (2): Last reviewed commit: "Address review feedback in connector swe..." | Re-trigger Greptile