Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
node_modules/
dist/
packages/*/dist
coverage/
*.tgz
.env
Expand Down
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
# Changelog

## 0.3.0

- Split into three packages: `cursor-cloud-core`, `openclaw-plugin-cursor-cloud`, and `cursor-cloud-mcp`.
- MCP is a standalone stdio binary (`cursor-cloud-mcp`). The OpenClaw plugin remains the gateway door.

## 0.2.0

- `cursor_cloud_launch` accepts `effort` (`low|med|high|xhigh`) and `fast` and sends them as `model.params`. `med` maps to Cursor `medium`; Grok 4.7 uses `reasoning_effort`.
Expand Down
30 changes: 13 additions & 17 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,13 @@

| Path | Role |
| --- | --- |
| `src/client.ts` | Cursor Cloud Agents API v1 |
| `src/registry.ts` | Env ids → `env` payload; base vs project allocation |
| `src/ledger.ts` | Local `agents.json` of launched `bc-…` |
| `src/env-catalog.ts` | Harvest named envs from `GET /v1/agents` |
| `src/harvest.ts` | Gateway init harvest service |
| `src/placement.ts` | Fresh vs reuse; session-bound agents |
| `src/actions.ts` | Shared launch/reply/status/cancel/watch |
| `src/plugin.ts` | OpenClaw tools |
| `src/cli.ts` / `src/mcp.ts` | Other surfaces |
| `src/setup.ts` | One-command gateway install |
| `skills/cursor-cloud/` | Agent door and first-proof |
| `examples/gateway-plugin.json` | Gateway plugin config |
| `examples/cli-config.json` | CLI config |
| `packages/core` | `cursor-cloud-core` — API client, harvest, actions, CLI |
| `packages/plugin` | `openclaw-plugin-cursor-cloud` — OpenClaw tools, skill, setup |
| `packages/mcp` | `cursor-cloud-mcp` — stdio MCP server |
| `packages/core/src/client.ts` | Cursor Cloud Agents API v1 |
| `packages/core/src/actions.ts` | launch/reply/status/cancel/watch |
| `packages/plugin/src/plugin.ts` | `defineToolPlugin` |
| `packages/mcp/src/mcp.ts` | JSON-RPC tools/list + tools/call |

Re-read [Cursor Cloud Agents API](https://cursor.com/docs/cloud-agent/api/endpoints) when changing the client. Do not copy community MCP source into this tree.

Expand All @@ -25,19 +19,20 @@ Re-read [Cursor Cloud Agents API](https://cursor.com/docs/cloud-agent/api/endpoi
```bash
npm install
npm test
npm run build
npm run plugin:build
npm run plugin:validate
```

Commit the generated `openclaw.plugin.json` when tool names or config schema change.
Commit `packages/plugin/openclaw.plugin.json` when tool names or config schema change.

## Release

1. `./scripts/release.sh <semver>`
2. Commit the version bump (`chore: release <semver>`).
3. Tag `v<semver>` and push the tag (publishes npm when `NPM_TOKEN` is set).
4. `clawhub package publish .` when the ClawHub owner is ready.
5. After ClawHub exists, set `package.json#openclaw.install.clawhubSpec`.
3. Tag `v<semver>` and push the tag.
4. Publish **core**, then **mcp**, then **plugin** (`npm publish --access public` in each package).
5. `clawhub package publish packages/plugin` when the ClawHub owner is ready.

## Rules that should not regress

Expand All @@ -48,3 +43,4 @@ Commit the generated `openclaw.plugin.json` when tool names or config schema cha
5. Do not add archive/delete/artifact tools to the default set.
6. Operator and skill first proof stay `cursor_cloud_me` then a `bc-…`.
7. Launched-agent JSON stays off git (`agents.json` / `state/`).
8. Core has no OpenClaw or MCP dependency. Plugin and MCP both depend on core only.
117 changes: 50 additions & 67 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,106 +1,89 @@
# openclaw-plugin-cursor-cloud
# cursor-cloud-agent

OpenClaw plugin that delegates coding work to **Cursor Cloud Agents on named saved environments**. Also a CLI and stdio MCP server.
Three packages, one coordinator. Coding work runs on **Cursor Cloud Agents** (`bc-…`), not on the host.

**Door:** `cursor_cloud_*` tools and the `cursor-cloud` skill.
**Implementer:** a Cloud agent (`bc-…`).
**Not the door:** `agent -p` (runs here), or `repos` together with a named cloud env.
| Package | npm | Role |
| --- | --- | --- |
| `packages/core` | `cursor-cloud-core` | API client, harvest, launch/reply/status/watch, `cursor-cloud` CLI |
| `packages/plugin` | `openclaw-plugin-cursor-cloud` | OpenClaw `cursor_cloud_*` tools + skill |
| `packages/mcp` | `cursor-cloud-mcp` | Stdio MCP server for the same tools |

Official API: [Cloud Agents API v1](https://cursor.com/docs/cloud-agent/api/endpoints). Host pin: `https://api.cursor.com`. Key: `CURSOR_API_KEY` on the gateway environment, never in git.
**Not the door:** `agent -p` on the coordinator, or `repos` together with a named cloud env.

Official API: [Cloud Agents API v1](https://cursor.com/docs/cloud-agent/api/endpoints). Host pin: `https://api.cursor.com`. Key: `CURSOR_API_KEY`, never in git.

## You are done when

1. `cursor_cloud_me` (or `openclaw-cursor-cloud me`) returns `ok: true` and a key name.
2. A **new** chat can see `cursor_cloud_launch`.
3. `cursor_cloud_envs` lists a **base** env (clone the target) and any **project** envs (repos already loaded).
4. `cursor_cloud_launch` with a listed id returns `agent.id` (`bc-…`) and `agent.url`. A later chat reads `cursor_cloud_agents` and replies on that id.
1. `cursor_cloud_me` (or `cursor-cloud me`) returns `ok: true` and a key name.
2. A **new** OpenClaw chat can see `cursor_cloud_launch`, **or** an MCP client lists the same tools.
3. `cursor_cloud_envs` lists a **base** env and any **project** envs.
4. Launch returns `agent.id` (`bc-…`) and `agent.url`. Follow-ups use `cursor_cloud_reply`.
5. A finished run is judged by `proof.prUrls` (or an exact blocker). `IDLE` only means follow-ups are accepted.

## Install

One command after npm publish:

```bash
npx -y openclaw-plugin-cursor-cloud@0.2.0 setup
```

From this checkout:
## OpenClaw plugin

```bash
npx -y openclaw-plugin-cursor-cloud@0.3.0 setup
# from this checkout:
./scripts/install-gateway.sh
```

`setup` installs the plugin, enables it, enables the `cursor-cloud` skill, and adds `cursor-cloud` to `tools.alsoAllow`. It does not write keys.

Then:
`setup` links **this repo’s `packages/plugin`**, enables the plugin and `cursor-cloud` skill, and adds `cursor-cloud` to `tools.alsoAllow`. It does not write keys.

```bash
# gateway EnvironmentFile — not openclaw.json
CURSOR_API_KEY=...
CURSOR_API_KEY=... # gateway EnvironmentFile — not openclaw.json
```

Restart the gateway. Open a new chat. Run the first proof above.

Pinned install without `npx` (still needs the key, env registry, restart, new chat):
Restart the gateway. Open a **new** chat.

```bash
openclaw plugins install npm:openclaw-plugin-cursor-cloud@0.2.0 --force --accept-capabilities
openclaw plugins install npm:openclaw-plugin-cursor-cloud@0.3.0 --force --accept-capabilities
```

After a ClawHub publish, use `clawhub:<org>/openclaw-plugin-cursor-cloud` the same way.

## Register an environment

The model passes a **registry id** (`env: "payments"`), never an invented `{ type, name }`.

- **base** — bootstrap env. Clone the target when it is not the env primary.
- **project** — repos already loaded and prepared. Set `allowRepos` to those URLs and a `project` key.
Gateway config: merge `packages/plugin/examples/gateway-plugin.json` into `plugins.entries.cursor-cloud`.

Plugin init (gateway startup service) harvests named environments from documented `GET /v1/agents` + `GET /v1/agents/{id}` into `~/.local/state/openclaw-cursor-cloud/envs.json`. Official v1 has no environment-list route. Unnamed dashboard fallbacks cannot be launched by `env.name` and are skipped. `cursor_cloud_envs` reads that catalog; `refresh: true` only forces a new harvest.
## MCP server

`cursor_cloud_launch` is the placement operation. OpenClaw gives the plugin `sessionId` (new on `/new` and `/reset`, kept across compact). If this chat is already bound to a `bc-…`, launch reuses it. If the user was not explicit, launch returns `phase: choose` — ask that tree, then recall with the option's `recall` fields. The CLI skips the ask and uses `defaultEnv`.

Gateway: merge `examples/gateway-plugin.json` into `plugins.entries.cursor-cloud`.
CLI: copy `examples/cli-config.json` to `~/.config/openclaw-cursor-cloud/config.json`.
Allowlist only: `examples/instance-enable.batch.json`.

Named `cloud` envs omit `repos` on the wire even when `allowRepos` lists a URL.

Launched `bc-…` ids are written to `~/.local/state/openclaw-cursor-cloud/agents.json` (or `$XDG_STATE_HOME/...`). That file is not git. Override with `ledgerPath` (for example `state/agents.json` in a checkout — `state/` is gitignored).

## Tools

Always on: `cursor_cloud_launch`, `cursor_cloud_reply`, `cursor_cloud_status`, `cursor_cloud_cancel`, `cursor_cloud_watch`, `cursor_cloud_me`, `cursor_cloud_envs`, `cursor_cloud_agents`, `cursor_cloud_models`.

Optional until `setup` / `tools.alsoAllow`: `cursor_cloud_list`.

`cursor_cloud_status` returns final/partial result, `messages[]`, and short-lived artifact download refs. It does not download artifact bytes onto the coordinator.
```json
{
"mcpServers": {
"cursor-cloud": {
"command": "cursor-cloud-mcp",
"env": { "CURSOR_API_KEY": "${CURSOR_API_KEY}" }
}
}
}
```

Not shipped: archive, delete, GitHub repository listing.
See `packages/mcp/examples/mcp.json`. Same config file as the CLI: `CURSOR_CLOUD_CONFIG` or `~/.config/openclaw-cursor-cloud/config.json` (`packages/core/examples/cli-config.json`).

When to call which: `skills/cursor-cloud/SKILL.md`.
`openclaw-cursor-cloud mcp` still delegates to `cursor-cloud-mcp`.

## CLI and MCP
## CLI

```bash
export CURSOR_API_KEY=...
openclaw-cursor-cloud me
openclaw-cursor-cloud envs --refresh
openclaw-cursor-cloud agents
openclaw-cursor-cloud launch --env base --prompt "Smoke the env, then stop."
openclaw-cursor-cloud reply --agent-id bc-… --prompt "Continue on the same branch."
openclaw-cursor-cloud mcp
cursor-cloud me
cursor-cloud envs --refresh
cursor-cloud launch --env base --prompt "Smoke the env, then stop."
cursor-cloud reply --agent-id bc-… --prompt "Continue on the same branch."
```

MCP (`examples/mcp.json`) uses the same CLI config as above unless `CURSOR_CLOUD_CONFIG` is set.
Launch: `model` plus optional `effort` and `fast`. Effort spellings go through one alias table; the table's preferred value is what the catalog receives (`med` prefers `medium`). Omit both to keep the model's own variant. Reply cannot change those (`model_locked`).

## Environments and tools

The model passes a **registry id** (`env: "payments"`), never an invented `{ type, name }`. Harvest (plugin init or `envs --refresh`) fills named envs from `GET /v1/agents`. Unnamed dashboard envs are skipped.

Always-on tools: launch, reply, status, cancel, watch, me, envs, agents, models. Optional: list.

Watch notify: the waiter injects `openclaw agent --session-key` / `--session-id` for the originating chat. Override with `watch.notifyCommand`. Safe placeholders: `{agentId} {runId} {runStatus} {url} {prUrl}`. Result text stays in `CURSOR_CLOUD_RESULT`, not the command line. Watch is not the transcript — poll `cursor_cloud_status`.
`cursor_cloud_status` returns final/partial result, `messages[]`, and short-lived artifact download refs. Watch is not the transcript.

Launch: `model` plus optional `effort` and `fast`. Effort spellings go through one alias table; the table's preferred value is what the catalog receives (`med` prefers `medium`). Reply cannot change those (`model_locked`). Default when `effort`/`fast` are omitted: the model's own variant (often fast).
Skill: `packages/plugin/skills/cursor-cloud/SKILL.md`.

## Versioning

`package.json` and `openclaw.plugin.json` share the semver. Authors: `CONTRIBUTING.md`.
Workspace packages share the semver. `./scripts/release.sh <semver>` bumps all three. Authors: `CONTRIBUTING.md`.

## License

Expand Down
2 changes: 1 addition & 1 deletion SECURITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ auth bypass, or host-pinning failure.

## Default blast radius

Default tools: launch, reply, status, cancel, watch, me, envs, agents, models.
Packages: `cursor-cloud-core`, `openclaw-plugin-cursor-cloud`, `cursor-cloud-mcp`. Same default tools on plugin and MCP.

Optional tools (must be allowlisted): list.

Expand Down
83 changes: 70 additions & 13 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading