No description
  • JavaScript 99.6%
  • Dockerfile 0.4%
Find a file
Kenzi Marcel f7edb25aca
All checks were successful
Container Build / build (push) Successful in 40s
SonarQube / sonarqube (push) Successful in 1m7s
feat: add forgejo CI for docker and sonarqube
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-02 01:37:41 -07:00
.forgejo/workflows feat: add forgejo CI for docker and sonarqube 2026-06-02 01:37:41 -07:00
archive/v1-bridge feat: promote persistent bridge and add live UI 2026-06-02 00:42:37 -07:00
tests feat: promote persistent bridge and add live UI 2026-06-02 00:42:37 -07:00
.dockerignore feat: add forgejo CI for docker and sonarqube 2026-06-02 01:37:41 -07:00
.env.example feat: promote persistent bridge and add live UI 2026-06-02 00:42:37 -07:00
.gitignore feat: promote persistent bridge and add live UI 2026-06-02 00:42:37 -07:00
cursor-invocation.mjs feat: promote persistent bridge and add live UI 2026-06-02 00:42:37 -07:00
Dockerfile feat: add forgejo CI for docker and sonarqube 2026-06-02 01:37:41 -07:00
openclaw.provider.example.json feat: promote persistent bridge and add live UI 2026-06-02 00:42:37 -07:00
package.json feat: promote persistent bridge and add live UI 2026-06-02 00:42:37 -07:00
README.md feat: add forgejo CI for docker and sonarqube 2026-06-02 01:37:41 -07:00
server.mjs feat: promote persistent bridge and add live UI 2026-06-02 00:42:37 -07:00
sonar-project.properties feat: add forgejo CI for docker and sonarqube 2026-06-02 01:37:41 -07:00

cursor-openai-bridge

Local OpenAI-compatible bridge that lets OpenClaw use Cursor (cursor-agent) as a model provider.

This is the v2 persistent-agent bridge promoted to the repo root:

  • Reuses persistent Cursor chats (no cursor-agent spawn per request)
  • Stores session_id -> cursorChatId on disk (sessions.json by default)
  • OpenAI-style tool calling support (via tools, tool_choice, tool_calls, and role:"tool" messages)
  • Windows-safe spawning (full prompt is written to .openclaw/tasks/<run-id>.md so argv stays small)

Endpoints

  • GET /health
  • GET /v1/models
  • POST /v1/chat/completions (streaming and non-streaming)

Web UI (localhost-only)

  • GET /ui (live dashboard)
  • GET /admin/stream (SSE: status/sessions/logs)
  • GET /admin/status
  • GET /admin/sessions
  • POST /admin/default-model
  • GET /admin/logs?tail=N

Requirements

  • Node.js 20+
  • Cursor headless CLI available as one of:
    • cursor-agent
    • cursor-agent.cmd
    • full path to cursor-agent.cmd
  • Valid CURSOR_API_KEY (or an already authenticated local Cursor CLI session)

Running in Docker (and Cursor auth)

This repo ships a Dockerfile for packaging the bridge server. It does not include cursor-agent.

You have two practical options:

  • Run the bridge on the host where Cursor CLI is installed, and dont containerize it.
  • Run the bridge in a container, but bind-mount cursor-agent into the container and provide auth:
    • Auth option A (recommended): set CURSOR_API_KEY as an environment variable (via your orchestrator secrets).
    • Auth option B: mount the Cursor CLIs local auth/session state into the container (host-dependent; only do this on trusted hosts).

Minimal example (Linux host with cursor-agent installed on host):

docker run --rm -p 32124:32124 \
  -e CURSOR_API_KEY="cursor_..." \
  -e CURSOR_AGENT_BIN="/usr/local/bin/cursor-agent" \
  -v /usr/local/bin/cursor-agent:/usr/local/bin/cursor-agent:ro \
  -v "$PWD:/workspace" \
  -e CURSOR_BRIDGE_WORKSPACE="/workspace" \
  <your-registry>/<owner>/openclaw-cursor:latest

Quick start (PowerShell)

cd C:\openclaw-cursor

$env:CURSOR_API_KEY="cursor_..."
$env:CURSOR_AGENT_BIN="cursor-agent"
$env:CURSOR_BRIDGE_DEFAULT_MODEL="auto"
$env:CURSOR_BRIDGE_WORKSPACE="C:\dev\ai-test"
$env:CURSOR_BRIDGE_DEBUG="true"

node .\server.mjs

Environment variables

See .env.example:

  • CURSOR_API_KEY=cursor_...
  • CURSOR_BRIDGE_HOST=127.0.0.1
  • CURSOR_BRIDGE_PORT=32124
  • CURSOR_AGENT_BIN=cursor-agent
  • CURSOR_BRIDGE_DEFAULT_MODEL=auto
  • CURSOR_BRIDGE_WORKSPACE=C:\dev\ai-test
  • CURSOR_BRIDGE_TIMEOUT_MS=600000
  • CURSOR_BRIDGE_MAX_CONCURRENCY=2
  • CURSOR_BRIDGE_DEBUG=true
  • CURSOR_BRIDGE_TRUST=true
  • CURSOR_BRIDGE_PERSISTENT_STORE=./sessions.json
  • CURSOR_BRIDGE_SESSION_TTL_MS=21600000
  • CURSOR_BRIDGE_CLEANUP_INTERVAL_MS=300000

Endpoint tests

Open a second PowerShell after starting the server.

Health and models

Invoke-RestMethod http://127.0.0.1:32124/health
Invoke-RestMethod http://127.0.0.1:32124/v1/models

Non-streaming completion

$body = @{
  model = "auto"
  messages = @(
    @{
      role = "user"
      content = "Say exactly OPENCLAW_BRIDGE_OK"
    }
  )
} | ConvertTo-Json -Depth 10

Invoke-RestMethod `
  -Uri "http://127.0.0.1:32124/v1/chat/completions" `
  -Method Post `
  -ContentType "application/json" `
  -Body $body

Streaming completion

$body = @{
  model = "sonnet-4.5"
  stream = $true
  messages = @(
    @{
      role = "user"
      content = "Count from 1 to 10, one number per line."
    }
  )
} | ConvertTo-Json -Depth 10

curl.exe -N `
  -H "Content-Type: application/json" `
  -d $body `
  http://127.0.0.1:32124/v1/chat/completions

You should see data: chunks arrive progressively, ending in:

  • final chunk with finish_reason: "stop"
  • data: [DONE]

OpenClaw provider config

Use openclaw.provider.example.json and merge its cursor-bridge block into your OpenClaw providers config.

Expected provider settings:

  • baseUrl: http://127.0.0.1:32124/v1
  • api: openai-completions
  • apiKey: any local placeholder (for example "local")

Notes

  • This is the persistent-agent bridge (v2 promoted). The archived v1 lives in archive/v1-bridge/.