From 97b40d1b7d1e36ac4ca7ed259f7aba8e9a5b5f01 Mon Sep 17 00:00:00 2001 From: Brett Chien <1193046+brettchien@users.noreply.github.com> Date: Tue, 14 Apr 2026 02:56:06 +0800 Subject: [PATCH 01/10] feat: add Cursor Agent CLI support Add Cursor Agent CLI as a new agent backend using native ACP support (`cursor-agent acp`). Includes Dockerfile with pinned version download, CI matrix entries, Helm chart config, and documentation. Co-Authored-By: Claude Opus 4.6 --- .github/workflows/build.yml | 3 ++ Dockerfile.cursor | 42 ++++++++++++++++ README.md | 1 + RELEASING.md | 4 +- charts/openab/templates/NOTES.txt | 3 ++ charts/openab/values.yaml | 23 +++++++++ config.toml.example | 6 +++ docs/cursor.md | 81 +++++++++++++++++++++++++++++++ 8 files changed, 162 insertions(+), 1 deletion(-) create mode 100644 Dockerfile.cursor create mode 100644 docs/cursor.md diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index c2dcf678..9b130e93 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -70,6 +70,7 @@ jobs: - { suffix: "-claude", dockerfile: "Dockerfile.claude", artifact: "claude" } - { suffix: "-gemini", dockerfile: "Dockerfile.gemini", artifact: "gemini" } - { suffix: "-copilot", dockerfile: "Dockerfile.copilot", artifact: "copilot" } + - { suffix: "-cursor", dockerfile: "Dockerfile.cursor", artifact: "cursor" } platform: - { os: linux/amd64, runner: ubuntu-latest } - { os: linux/arm64, runner: ubuntu-24.04-arm } @@ -131,6 +132,7 @@ jobs: - { suffix: "-claude", artifact: "claude" } - { suffix: "-gemini", artifact: "gemini" } - { suffix: "-copilot", artifact: "copilot" } + - { suffix: "-cursor", artifact: "cursor" } runs-on: ubuntu-latest permissions: contents: read @@ -179,6 +181,7 @@ jobs: - { suffix: "-claude" } - { suffix: "-gemini" } - { suffix: "-copilot" } + - { suffix: "-cursor" } runs-on: ubuntu-latest permissions: contents: read diff --git a/Dockerfile.cursor b/Dockerfile.cursor new file mode 100644 index 00000000..7330754b --- /dev/null +++ b/Dockerfile.cursor @@ -0,0 +1,42 @@ +# --- Build stage --- +FROM rust:1-bookworm AS builder +WORKDIR /build +COPY Cargo.toml Cargo.lock ./ +RUN mkdir src && echo 'fn main() {}' > src/main.rs && cargo build --release && rm -rf src +COPY src/ src/ +RUN touch src/main.rs && cargo build --release + +# --- Runtime stage --- +FROM debian:bookworm-slim +RUN apt-get update && apt-get install -y --no-install-recommends ca-certificates curl && rm -rf /var/lib/apt/lists/* + +# Install Cursor Agent CLI (pinned version) +ARG CURSOR_VERSION=2026.04.08-a41fba1 +RUN ARCH=$(dpkg --print-architecture) && \ + if [ "$ARCH" = "arm64" ]; then ARCH=arm64; else ARCH=x64; fi && \ + curl -fSL "https://downloads.cursor.com/lab/${CURSOR_VERSION}/linux/${ARCH}/agent-cli-package.tar.gz" \ + -o /tmp/cursor.tar.gz && \ + mkdir -p /opt/cursor-agent && \ + tar xzf /tmp/cursor.tar.gz -C /opt/cursor-agent && \ + ln -s /opt/cursor-agent/cursor-agent /usr/local/bin/cursor-agent && \ + rm /tmp/cursor.tar.gz + +# Install gh CLI (for auth and token management) +RUN curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg \ + -o /usr/share/keyrings/githubcli-archive-keyring.gpg && \ + echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" \ + > /etc/apt/sources.list.d/github-cli.list && \ + apt-get update && apt-get install -y --no-install-recommends gh && \ + rm -rf /var/lib/apt/lists/* + +RUN useradd -m -s /bin/bash -u 1000 node +ENV HOME=/home/node +WORKDIR /home/node + +COPY --from=builder --chown=node:node /build/target/release/openab /usr/local/bin/openab + +USER node +HEALTHCHECK --interval=30s --timeout=5s --retries=3 \ + CMD pgrep -x openab || exit 1 +ENTRYPOINT ["openab"] +CMD ["/etc/openab/config.toml"] diff --git a/README.md b/README.md index 6ad1dbcd..9231afa7 100644 --- a/README.md +++ b/README.md @@ -69,6 +69,7 @@ The bot creates a thread. After that, just type in the thread — no @mention ne | Codex | `codex-acp` | [@zed-industries/codex-acp](https://github.com/zed-industries/codex-acp) | [docs/codex.md](docs/codex.md) | | Gemini | `gemini --acp` | Native | [docs/gemini.md](docs/gemini.md) | | Copilot CLI ⚠️ | `copilot --acp --stdio` | Native | [docs/copilot.md](docs/copilot.md) | +| Cursor ⚠️ | `cursor-agent acp` | Native | [docs/cursor.md](docs/cursor.md) | > 🔧 Running multiple agents? See [docs/multi-agent.md](docs/multi-agent.md) diff --git a/RELEASING.md b/RELEASING.md index 8e2f35d6..7aa8594a 100644 --- a/RELEASING.md +++ b/RELEASING.md @@ -140,13 +140,15 @@ release-pr.yml 在 Release PR 中自動更新以下檔案的版本: ## Image Variants -每次 build 產出 4 個 multi-arch image (linux/amd64 + linux/arm64): +每次 build 產出 6 個 multi-arch image (linux/amd64 + linux/arm64): ``` ghcr.io/openabdev/openab # default (kiro-cli) ghcr.io/openabdev/openab-codex # codex ghcr.io/openabdev/openab-claude # claude ghcr.io/openabdev/openab-gemini # gemini +ghcr.io/openabdev/openab-copilot # copilot +ghcr.io/openabdev/openab-cursor # cursor ``` Image tags 依 release 類型不同: diff --git a/charts/openab/templates/NOTES.txt b/charts/openab/templates/NOTES.txt index 37f1c709..ca292b6f 100644 --- a/charts/openab/templates/NOTES.txt +++ b/charts/openab/templates/NOTES.txt @@ -24,6 +24,9 @@ Agents deployed: {{- else if eq $cfg.command "gemini" }} Authenticate: kubectl exec -it deployment/{{ include "openab.agentFullname" (dict "ctx" $ "agent" $name) }} -- gemini +{{- else if eq $cfg.command "cursor-agent" }} + Authenticate: + kubectl exec -it deployment/{{ include "openab.agentFullname" (dict "ctx" $ "agent" $name) }} -- cursor-agent login {{- end }} Restart after auth: diff --git a/charts/openab/values.yaml b/charts/openab/values.yaml index 0e4f6e7a..7087afa1 100644 --- a/charts/openab/values.yaml +++ b/charts/openab/values.yaml @@ -48,6 +48,29 @@ agents: # tolerations: [] # affinity: {} # image: "ghcr.io/openabdev/openab-claude:latest" + # cursor: + # command: cursor-agent + # args: + # - acp + # discord: + # botToken: "" + # allowedChannels: + # - "YOUR_CHANNEL_ID" + # allowedUsers: [] + # workingDir: /home/node + # env: {} + # envFrom: [] + # pool: + # maxSessions: 10 + # sessionTtlHours: 24 + # reactions: + # enabled: true + # removeAfterReply: false + # persistence: + # enabled: true + # storageClass: "" + # size: 1Gi + # image: "ghcr.io/openabdev/openab-cursor:latest" image: "" command: kiro-cli args: diff --git a/config.toml.example b/config.toml.example index 6b377e5f..4e4d27c5 100644 --- a/config.toml.example +++ b/config.toml.example @@ -32,6 +32,12 @@ working_dir = "/home/agent" # working_dir = "/home/agent" # env = {} # Auth via: kubectl exec -it -- gh auth login -p https -w +# [agent] +# command = "cursor-agent" +# args = ["acp"] +# working_dir = "/home/agent" +# env = {} # Auth via: kubectl exec -it -- cursor-agent login + [pool] max_sessions = 10 session_ttl_hours = 24 diff --git a/docs/cursor.md b/docs/cursor.md new file mode 100644 index 00000000..7007cdbc --- /dev/null +++ b/docs/cursor.md @@ -0,0 +1,81 @@ +# Cursor Agent CLI — Agent Backend Guide + +How to run OpenAB with [Cursor Agent CLI](https://www.cursor.com/) as the agent backend. + +## Prerequisites + +- A paid [Cursor](https://www.cursor.com/pricing) subscription (**Pro or Business** — Free tier does not include Agent CLI access) +- Cursor Agent CLI with native ACP support + +## Architecture + +``` +┌──────────────┐ Gateway WS ┌──────────────┐ ACP stdio ┌──────────────────────┐ +│ Discord │◄─────────────►│ openab │──────────────►│ cursor-agent acp │ +│ User │ │ (Rust) │◄── JSON-RPC ──│ (Cursor Agent CLI) │ +└──────────────┘ └──────────────┘ └──────────────────────┘ +``` + +OpenAB spawns `cursor-agent acp` as a child process and communicates via stdio JSON-RPC. No intermediate layers. + +## Configuration + +```toml +[agent] +command = "cursor-agent" +args = ["acp"] +working_dir = "/home/agent" +# Auth via: kubectl exec -it -- cursor-agent login +``` + +## Docker + +Build with the Cursor-specific Dockerfile: + +```bash +docker build -f Dockerfile.cursor -t openab-cursor . +``` + +The Dockerfile installs a pinned version of Cursor Agent CLI via direct download from `downloads.cursor.com`. The version is controlled by the `CURSOR_VERSION` build arg. + +## Authentication + +Cursor Agent CLI uses its own login flow. In a headless container: + +```bash +# 1. Exec into the running pod/container +kubectl exec -it deployment/openab-cursor -- bash + +# 2. Authenticate via device flow +cursor-agent login + +# 3. Follow the device code flow in your browser + +# 4. Restart the pod (token is persisted via PVC) +kubectl rollout restart deployment/openab-cursor +``` + +The auth token is stored under `~/.cursor-agent/` and persisted across pod restarts via PVC. + +## Helm Install + +> **Note**: The `ghcr.io/openabdev/openab-cursor` image is not published yet. You must build it locally first with `docker build -f Dockerfile.cursor -t openab-cursor .` and push to your own registry, or use a local image. + +```bash +helm install openab openab/openab \ + --set agents.kiro.enabled=false \ + --set agents.cursor.discord.botToken="$DISCORD_BOT_TOKEN" \ + --set-string 'agents.cursor.discord.allowedChannels[0]=YOUR_CHANNEL_ID' \ + --set agents.cursor.image=ghcr.io/openabdev/openab-cursor:latest \ + --set agents.cursor.command=cursor-agent \ + --set 'agents.cursor.args={acp}' \ + --set agents.cursor.persistence.enabled=true \ + --set agents.cursor.workingDir=/home/node +``` + +## Known Limitations + +- Cursor Agent CLI is a separate distribution from Cursor Desktop — they are not the same binary +- No official apt/yum package; the Dockerfile downloads a pinned tarball directly +- `cursor-agent login` requires an interactive terminal for the device flow +- Auth token persistence requires a PVC mount at the user home directory From 5e9133ff339b5d4fad7bd97567e567fbdd599c76 Mon Sep 17 00:00:00 2001 From: Brett Chien <1193046+brettchien@users.noreply.github.com> Date: Tue, 14 Apr 2026 02:56:07 +0800 Subject: [PATCH 02/10] fix: use 'agent' user and cp install in Dockerfile.cursor Align with kiro Dockerfile conventions: - Rename user from 'node' to 'agent' (uid 1000) - Use cp instead of symlink for cursor-agent binary - Pre-create ~/.cursor/ directory - Fix docs/cursor.md token path from ~/.cursor-agent/ to ~/.cursor/ Co-Authored-By: Claude Opus 4.6 --- Dockerfile.cursor | 21 ++++++++++++--------- docs/cursor.md | 2 +- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/Dockerfile.cursor b/Dockerfile.cursor index 7330754b..799b20d3 100644 --- a/Dockerfile.cursor +++ b/Dockerfile.cursor @@ -16,10 +16,11 @@ RUN ARCH=$(dpkg --print-architecture) && \ if [ "$ARCH" = "arm64" ]; then ARCH=arm64; else ARCH=x64; fi && \ curl -fSL "https://downloads.cursor.com/lab/${CURSOR_VERSION}/linux/${ARCH}/agent-cli-package.tar.gz" \ -o /tmp/cursor.tar.gz && \ - mkdir -p /opt/cursor-agent && \ - tar xzf /tmp/cursor.tar.gz -C /opt/cursor-agent && \ - ln -s /opt/cursor-agent/cursor-agent /usr/local/bin/cursor-agent && \ - rm /tmp/cursor.tar.gz + mkdir -p /tmp/cursor-agent && \ + tar xzf /tmp/cursor.tar.gz -C /tmp/cursor-agent && \ + cp /tmp/cursor-agent/cursor-agent /usr/local/bin/ && \ + chmod +x /usr/local/bin/cursor-agent && \ + rm -rf /tmp/cursor-agent /tmp/cursor.tar.gz # Install gh CLI (for auth and token management) RUN curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg \ @@ -29,13 +30,15 @@ RUN curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg \ apt-get update && apt-get install -y --no-install-recommends gh && \ rm -rf /var/lib/apt/lists/* -RUN useradd -m -s /bin/bash -u 1000 node -ENV HOME=/home/node -WORKDIR /home/node +RUN useradd -m -s /bin/bash -u 1000 agent +RUN mkdir -p /home/agent/.cursor && \ + chown -R agent:agent /home/agent +ENV HOME=/home/agent +WORKDIR /home/agent -COPY --from=builder --chown=node:node /build/target/release/openab /usr/local/bin/openab +COPY --from=builder --chown=agent:agent /build/target/release/openab /usr/local/bin/openab -USER node +USER agent HEALTHCHECK --interval=30s --timeout=5s --retries=3 \ CMD pgrep -x openab || exit 1 ENTRYPOINT ["openab"] diff --git a/docs/cursor.md b/docs/cursor.md index 7007cdbc..9584bb74 100644 --- a/docs/cursor.md +++ b/docs/cursor.md @@ -55,7 +55,7 @@ cursor-agent login kubectl rollout restart deployment/openab-cursor ``` -The auth token is stored under `~/.cursor-agent/` and persisted across pod restarts via PVC. +The auth token is stored under `~/.cursor/` and persisted across pod restarts via PVC. ## Helm Install From 17813e07a655f009263246e487a5b924e36cd127 Mon Sep 17 00:00:00 2001 From: Brett Chien <1193046+brettchien@users.noreply.github.com> Date: Tue, 14 Apr 2026 02:56:07 +0800 Subject: [PATCH 03/10] fix: remove unnecessary ~/.cursor/ pre-creation cursor-agent creates the directory on first run. Co-Authored-By: Claude Opus 4.6 --- Dockerfile.cursor | 2 -- 1 file changed, 2 deletions(-) diff --git a/Dockerfile.cursor b/Dockerfile.cursor index 799b20d3..401f4b40 100644 --- a/Dockerfile.cursor +++ b/Dockerfile.cursor @@ -31,8 +31,6 @@ RUN curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg \ rm -rf /var/lib/apt/lists/* RUN useradd -m -s /bin/bash -u 1000 agent -RUN mkdir -p /home/agent/.cursor && \ - chown -R agent:agent /home/agent ENV HOME=/home/agent WORKDIR /home/agent From 94ed603425adfd3fd0b68273c706fd4719fad628 Mon Sep 17 00:00:00 2001 From: Brett Chien <1193046+brettchien@users.noreply.github.com> Date: Tue, 14 Apr 2026 02:56:07 +0800 Subject: [PATCH 04/10] fix: simplify Dockerfile.cursor install and add model docs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Extract tarball directly to /opt, rename dist-package to cursor-agent - Remove preview warning from README agent table - Add Model Selection section to docs/cursor.md - Fix workingDir in Helm example (/home/node → /home/agent) Co-Authored-By: Claude Opus 4.6 --- Dockerfile.cursor | 9 ++++----- README.md | 2 +- docs/cursor.md | 24 +++++++++++++++++++++++- 3 files changed, 28 insertions(+), 7 deletions(-) diff --git a/Dockerfile.cursor b/Dockerfile.cursor index 401f4b40..251077a2 100644 --- a/Dockerfile.cursor +++ b/Dockerfile.cursor @@ -16,11 +16,10 @@ RUN ARCH=$(dpkg --print-architecture) && \ if [ "$ARCH" = "arm64" ]; then ARCH=arm64; else ARCH=x64; fi && \ curl -fSL "https://downloads.cursor.com/lab/${CURSOR_VERSION}/linux/${ARCH}/agent-cli-package.tar.gz" \ -o /tmp/cursor.tar.gz && \ - mkdir -p /tmp/cursor-agent && \ - tar xzf /tmp/cursor.tar.gz -C /tmp/cursor-agent && \ - cp /tmp/cursor-agent/cursor-agent /usr/local/bin/ && \ - chmod +x /usr/local/bin/cursor-agent && \ - rm -rf /tmp/cursor-agent /tmp/cursor.tar.gz + tar xzf /tmp/cursor.tar.gz -C /opt && \ + mv /opt/dist-package /opt/cursor-agent && \ + ln -s /opt/cursor-agent/cursor-agent /usr/local/bin/cursor-agent && \ + rm /tmp/cursor.tar.gz # Install gh CLI (for auth and token management) RUN curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg \ diff --git a/README.md b/README.md index 9231afa7..fa49fd0c 100644 --- a/README.md +++ b/README.md @@ -69,7 +69,7 @@ The bot creates a thread. After that, just type in the thread — no @mention ne | Codex | `codex-acp` | [@zed-industries/codex-acp](https://github.com/zed-industries/codex-acp) | [docs/codex.md](docs/codex.md) | | Gemini | `gemini --acp` | Native | [docs/gemini.md](docs/gemini.md) | | Copilot CLI ⚠️ | `copilot --acp --stdio` | Native | [docs/copilot.md](docs/copilot.md) | -| Cursor ⚠️ | `cursor-agent acp` | Native | [docs/cursor.md](docs/cursor.md) | +| Cursor | `cursor-agent acp` | Native | [docs/cursor.md](docs/cursor.md) | > 🔧 Running multiple agents? See [docs/multi-agent.md](docs/multi-agent.md) diff --git a/docs/cursor.md b/docs/cursor.md index 9584bb74..e6a3912e 100644 --- a/docs/cursor.md +++ b/docs/cursor.md @@ -70,9 +70,31 @@ helm install openab openab/openab \ --set agents.cursor.command=cursor-agent \ --set 'agents.cursor.args={acp}' \ --set agents.cursor.persistence.enabled=true \ - --set agents.cursor.workingDir=/home/node + --set agents.cursor.workingDir=/home/agent ``` +## Model Selection + +List available models: + +```bash +cursor-agent --list-models +# or +cursor-agent models +``` + +To specify a model, pass `--model` as an arg: + +```toml +[agent] +command = "cursor-agent" +args = ["acp", "--model", "auto"] +``` + +In ACP mode, `--model` can be appended after `acp`. If omitted, the account default is used. + +To verify which model is active, ask the agent "who are you" — the underlying model will typically self-identify (e.g. "I am Gemini, a large language model built by Google."). + ## Known Limitations - Cursor Agent CLI is a separate distribution from Cursor Desktop — they are not the same binary From 38628bf2911e8d682a27c4705f004357293af91a Mon Sep 17 00:00:00 2001 From: Brett Chien <1193046+brettchien@users.noreply.github.com> Date: Wed, 15 Apr 2026 18:37:20 +0800 Subject: [PATCH 05/10] =?UTF-8?q?fix(chart):=20cursor=20example=20workingD?= =?UTF-8?q?ir=20/home/node=20=E2=86=92=20/home/agent?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cursor uses debian:bookworm-slim base with `agent` user (uid 1000, home /home/agent), not node:22 like other agents. The example comment in values.yaml was copy-pasted from node-based agents. Addresses review comment on PR #301 from @masami-agent. --- charts/openab/values.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/charts/openab/values.yaml b/charts/openab/values.yaml index 7087afa1..441b3acd 100644 --- a/charts/openab/values.yaml +++ b/charts/openab/values.yaml @@ -57,7 +57,7 @@ agents: # allowedChannels: # - "YOUR_CHANNEL_ID" # allowedUsers: [] - # workingDir: /home/node + # workingDir: /home/agent # env: {} # envFrom: [] # pool: From 654b7435c3deaa951b099ecf6a9768377c050df9 Mon Sep 17 00:00:00 2001 From: Brett Chien <1193046+brettchien@users.noreply.github.com> Date: Wed, 15 Apr 2026 18:37:26 +0800 Subject: [PATCH 06/10] fix(docker): add procps to Dockerfile.cursor for pgrep healthcheck HEALTHCHECK uses `pgrep -x openab`, which requires procps. Debian slim does not ship with it, so the healthcheck was silently failing (command not found) and the pod would enter Unhealthy state. Same fix pattern as pending PR #234 for the other Dockerfiles. Addresses review comment on PR #301 from @masami-agent. --- Dockerfile.cursor | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile.cursor b/Dockerfile.cursor index 251077a2..e0d6cbe8 100644 --- a/Dockerfile.cursor +++ b/Dockerfile.cursor @@ -8,7 +8,7 @@ RUN touch src/main.rs && cargo build --release # --- Runtime stage --- FROM debian:bookworm-slim -RUN apt-get update && apt-get install -y --no-install-recommends ca-certificates curl && rm -rf /var/lib/apt/lists/* +RUN apt-get update && apt-get install -y --no-install-recommends ca-certificates curl procps && rm -rf /var/lib/apt/lists/* # Install Cursor Agent CLI (pinned version) ARG CURSOR_VERSION=2026.04.08-a41fba1 From eeb122e7c0f2c06f9d6a868748d2c48f7799ac79 Mon Sep 17 00:00:00 2001 From: Brett Chien <1193046+brettchien@users.noreply.github.com> Date: Wed, 15 Apr 2026 18:42:32 +0800 Subject: [PATCH 07/10] docs(docker): document Cursor tarball URL source in Dockerfile.cursor MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a comment explaining the Cursor tarball URL pattern (downloads.cursor.com/lab//linux//...) and that it's scraped from the official downloads page — there's no apt/yum package. If Cursor changes the URL scheme, the build will fail with a curl 404 at build time, so future maintainers have a hint of where to check. Addresses non-blocking review comment on PR #301 from @masami-agent. --- Dockerfile.cursor | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Dockerfile.cursor b/Dockerfile.cursor index e0d6cbe8..b6969f65 100644 --- a/Dockerfile.cursor +++ b/Dockerfile.cursor @@ -11,6 +11,10 @@ FROM debian:bookworm-slim RUN apt-get update && apt-get install -y --no-install-recommends ca-certificates curl procps && rm -rf /var/lib/apt/lists/* # Install Cursor Agent CLI (pinned version) +# Tarball source: https://downloads.cursor.com/lab//linux//agent-cli-package.tar.gz +# URL scheme scraped from Cursor's official downloads page — no apt/yum package exists. +# If Cursor changes this pattern, the build fails with curl 404. Monitor +# https://cursor.com/cli or https://docs.cursor.com/cli for version/URL updates. ARG CURSOR_VERSION=2026.04.08-a41fba1 RUN ARCH=$(dpkg --print-architecture) && \ if [ "$ARCH" = "arm64" ]; then ARCH=arm64; else ARCH=x64; fi && \ From 20fcd10ffa9f3869dd32c90cd6843a0816d7553c Mon Sep 17 00:00:00 2001 From: Brett Chien <1193046+brettchien@users.noreply.github.com> Date: Wed, 15 Apr 2026 18:42:39 +0800 Subject: [PATCH 08/10] docs(config): add --model auto to cursor example args Align config.toml.example with docs/cursor.md and the Helm example in PR #301, both of which use `--model auto`. `auto` is Cursor CLI's built-in classifier router and is the safest default (users can override via helm values). Addresses non-blocking review comment on PR #301 from @masami-agent. --- config.toml.example | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config.toml.example b/config.toml.example index 4e4d27c5..d5d1208b 100644 --- a/config.toml.example +++ b/config.toml.example @@ -34,7 +34,7 @@ working_dir = "/home/agent" # [agent] # command = "cursor-agent" -# args = ["acp"] +# args = ["acp", "--model", "auto"] # working_dir = "/home/agent" # env = {} # Auth via: kubectl exec -it -- cursor-agent login From 146a2f2351de197c4456cb07e73c37bf16c06334 Mon Sep 17 00:00:00 2001 From: Brett Chien <1193046+brettchien@users.noreply.github.com> Date: Wed, 15 Apr 2026 18:53:56 +0800 Subject: [PATCH 09/10] docs(config): align cursor example args with runtime defaults Add `--workspace /home/agent` to cursor example args in both charts/openab/values.yaml and config.toml.example. Rationale: pinning the workspace explicitly makes cursor-agent use /home/agent for .cursor/ config/approvals lookup. Without it, cursor-agent auto-detects from cwd, which also lands on /home/agent in containers but can differ in interactive/local runs. Explicit is safer and matches the runtime config used in production deployments. Part of PR #301 polish. --- charts/openab/values.yaml | 4 ++++ config.toml.example | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/charts/openab/values.yaml b/charts/openab/values.yaml index 441b3acd..ae724af0 100644 --- a/charts/openab/values.yaml +++ b/charts/openab/values.yaml @@ -52,6 +52,10 @@ agents: # command: cursor-agent # args: # - acp + # - --model + # - auto + # - --workspace + # - /home/agent # discord: # botToken: "" # allowedChannels: diff --git a/config.toml.example b/config.toml.example index d5d1208b..2b3199c9 100644 --- a/config.toml.example +++ b/config.toml.example @@ -34,7 +34,7 @@ working_dir = "/home/agent" # [agent] # command = "cursor-agent" -# args = ["acp", "--model", "auto"] +# args = ["acp", "--model", "auto", "--workspace", "/home/agent"] # working_dir = "/home/agent" # env = {} # Auth via: kubectl exec -it -- cursor-agent login From 2a1167f70e5d532f372d4ee515d61dc7a1a98454 Mon Sep 17 00:00:00 2001 From: Brett Chien <1193046+brettchien@users.noreply.github.com> Date: Wed, 15 Apr 2026 18:54:04 +0800 Subject: [PATCH 10/10] docs(cursor): add MCP usage and --workspace / approval quirks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Document how MCP servers are configured in cursor-agent ACP mode: - The `--workspace` flag determines which `.cursor/mcp.json` is loaded and which approvals slug is used — explicit is safer than relying on cwd auto-detection. - `--approve-mcps` does NOT apply in ACP mode (interactive CLI only); MCP load gating uses an approval file at .cursor/projects//mcp-approvals.json. - Two paths to approve: pre-create the file, or approve once interactively so Cursor persists it. - openab auto-replies session/request_permission with allow_always, so once loaded, subsequent tool calls pass without prompting. - Verify with `cursor-agent mcp list`. Part of PR #301 polish. --- docs/cursor.md | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/docs/cursor.md b/docs/cursor.md index e6a3912e..94490817 100644 --- a/docs/cursor.md +++ b/docs/cursor.md @@ -95,6 +95,60 @@ In ACP mode, `--model` can be appended after `acp`. If omitted, the account defa To verify which model is active, ask the agent "who are you" — the underlying model will typically self-identify (e.g. "I am Gemini, a large language model built by Google."). +## MCP Usage (ACP mode caveats) + +Cursor Agent CLI supports MCP servers configured via `.cursor/mcp.json` in the active workspace directory. **Which directory counts as the workspace is determined by the `--workspace` flag** — if omitted, cursor-agent auto-detects from `cwd`, which is usually `/home/agent` in OpenAB containers via the Dockerfile `WORKDIR` directive but can drift in interactive or local runs. For reproducible MCP loading, pass `--workspace` explicitly: + +```toml +[agent] +command = "cursor-agent" +args = ["acp", "--model", "auto", "--workspace", "/home/agent"] +``` + +This anchors: +- **MCP config lookup**: `/home/agent/.cursor/mcp.json` +- **Approval file path**: `/home/agent/.cursor/projects/home-agent/mcp-approvals.json` (slug = URL-safe workspace path) + +Without `--workspace`, a different cwd would produce a different slug and cursor-agent would not find previously saved approvals. + +### Example MCP config + +```json +{ + "mcpServers": { + "playwright": { + "command": "/usr/bin/npx", + "args": ["-y", "@playwright/mcp@latest"] + } + } +} +``` + +### Approval quirk in ACP mode + +Cursor's `--approve-mcps` flag **does not apply in ACP mode** — it only affects the interactive CLI. In ACP mode, MCP servers are gated by an approval file. Two options: + +1. **Pre-create the approvals file** at `/.cursor/projects//mcp-approvals.json`: + ```json + ["-"] + ``` + Hash is derived from workspace path + server config. + +2. **Approve once interactively**, then let Cursor persist the approval: + ```bash + kubectl exec -it deployment/openab-cursor -- cursor-agent + # invoke an MCP tool, approve the prompt; approval is saved + ``` + +OpenAB itself auto-responds to ACP `session/request_permission` with `allow_always` (see `src/acp/connection.rs`), so once an MCP server is *loaded*, subsequent tool calls pass without prompting. The approval file only gates the initial load. + +### Verifying MCP is loaded + +```bash +kubectl exec deployment/openab-cursor -- cursor-agent mcp list +# Expected: ": ready" +``` + ## Known Limitations - Cursor Agent CLI is a separate distribution from Cursor Desktop — they are not the same binary