The Problem

Developers need a language‑agnostic way to drive Cursor agents without pulling in the full TypeScript or Python SDKs. The bridge protocol (sdk.v1 protobuf) offers a thin, local gRPC‑Web server that exposes the full SDK surface, but creating an adapter requires a concrete reference implementation and clear wiring.

What This Does

The repository publishes the stable protobuf contract under proto/sdk/v1/ and a minimal Python adapter in examples/python-adapter/. The adapter spawns the bridge binary (fetch-bridge.sh) and talks to it via the generated _transport module, which issues HTTP‑based RPCs (unary, server_stream). Core logic lives in the cursor_adapter package:

  • __init__.py exposes prompt – the public entry for scripts.
  • _client.py, _agent.py, _run.py implement high‑level client, agent, and streaming‑run objects.
  • _transport.py handles low‑level HTTP calls (_post, unary).
  • _bridge.py starts the bridge process (start) and monitors its readiness.

Documentation in docs/ explains the protocol, services, error model, and a curl‑based smoke test.

How It Is Wired

Execution begins at examples/python-adapter/demo.py:34 in the main function. The call chain is:

  1. mainversion (calls unary_post) – performs a network request to the bridge (urllib.request.Request).
  2. mainprompt (from cursor_adapter/__init__.py) – constructs a Client (_client.py).
  3. Client.__init__ creates a _transport._post session and stores bridge endpoint info.
  4. Clientstart (_bridge.py) – runs fetch-bridge.sh via subprocess.Popen, launching the local bridge binary (external command).
  5. start calls _await_ready_line then scan, both of which invoke TransportError handling paths (4 callers).
  6. Streaming runs use Client._run (_run.py) which iterates over server_stream_transport.server_stream_read_exactTransportError on read failures.

The internal call graph shows 89 intra‑repo edges; the most widely used symbols are unary, TransportError, and BridgeProcessError. The hub modules (_client.py, _agent.py, _run.py) form a circular import cycle (3 files), increasing the risk of refactor breakage because any change propagates through the cycle.

External effects are limited to:

  • One subprocess launch (fetch-bridge.sh) from _bridge.start.
  • One outbound HTTP request from _transport.unary/_post.

No file currently touches a database or filesystem beyond spawning the bridge.

How To Use It

# Clone the repo
git clone https://github.com/moses-y/sdk-bridge.git
cd sdk-bridge

# Install the Python example adapter dependencies
pip install -r examples/python-adapter/requirements.txt
# (or use a PEP‑517 build: pip install .[example] if a pyproject extra existed)

# Verify the bridge binary is present (download from the latest release)
# e.g., curl -L -o cursor-sdk-bridge.tar.gz \
#   https://github.com/cursor/sdk-bridge/releases/latest/download/cursor-sdk-bridge-standalone-linux-x64.tar.gz
# tar -xzf cursor-sdk-bridge.tar.gz && chmod +x cursor-sdk-bridge

# Run the demo script (spawns the bridge, prints version, runs a simple prompt)
python examples/python-adapter/demo.py

The demo prints the bridge version, then calls prompt which uses the Client API to talk to the bridge. Adjust fetch-bridge.sh if you place the binary elsewhere.

Real‑World Use

A microservice written in Go could embed the same binary, generate Go stubs from proto/sdk/v1/, and use the same sdk.v1 contract to drive agents. The Python adapter serves as a reference for spawning the bridge, handling RPC transport, and translating errors—mirroring the pattern any new language adapter would follow.

Code Health & Issues

  • Measured findings (static analysis)
  • HIGH – Import cycle in examples/python-adapter/cursor_adapter/_client.py, _agent.py, _run.py. Break the cycle by extracting shared types or deferring imports.
  • MEDIUM – Deep nesting (max indent 6) in _transport.py and demo.py. Refactor with early returns or helper functions.
  • Repository hygiene
  • HIGH – Unpinned GitHub Action (.github/workflows/proto-check.yml uses bufbuild/buf-setup-action@v1). Pin to a commit SHA to avoid supply‑chain risk.
  • LOW – Missing job timeout in the same workflow; add timeout-minutes to prevent overlapping runs.
  • No lockfile for Python dependencies (pyproject.toml/requirements.txt), making reproducible builds non‑deterministic.
  • Tests exist (tests/ folder) but only one file; coverage may be insufficient for production use.

The Bottom Line

The repo supplies a solid, version‑controlled protobuf contract and a working Python adapter that clearly demonstrates how to spawn and communicate with the Cursor bridge. However, the import cycle and deep nesting hinder maintainability, and CI configuration lacks pinning and timeouts. It is suitable as a reference implementation for building adapters in other languages, provided the consumer addresses the noted structural and CI hygiene concerns.