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
186 changes: 99 additions & 87 deletions registry/coder-labs/modules/cursor-cli/README.md
Original file line number Diff line number Diff line change
@@ -1,136 +1,148 @@
---
display_name: Cursor CLI
icon: ../../../../.icons/cursor.svg
description: Run Cursor Agent CLI in your workspace for AI pair programming
description: Install and configure the Cursor Agent CLI in your workspace.
verified: true
tags: [agent, cursor, ai, tasks]
tags: [agent, cursor, ai]
---

# Cursor CLI

Run the Cursor Agent CLI in your workspace for interactive coding assistance and automated task execution.
Install and configure the [Cursor Agent CLI](https://cursor.com/docs/cli/overview) in your workspace.

```tf
module "cursor_cli" {
source = "registry.coder.com/coder-labs/cursor-cli/coder"
version = "0.3.1"
version = "1.0.0"
agent_id = coder_agent.main.id
folder = "/home/coder/project"
api_key = var.cursor_api_key
}
```

## Basic setup
> [!WARNING]
> If upgrading from v0.x.x of this module: v1 is a major refactor that drops support for Coder Tasks and AgentAPI. The module now only installs and configures Cursor CLI; launch it with your own `coder_app`. `folder` is renamed to `workdir` and is optional. `model`, `force`, and `ai_prompt` are removed in favor of CLI flags in your launcher. MCP servers are now written to the user-level `~/.cursor/mcp.json` instead of `<folder>/.cursor/mcp.json`. Keep using v0.x.x if you depend on Coder Tasks.

A full example with MCP, rules, and pre/post install scripts:
## Examples

```tf
### Standalone mode with a launcher app

data "coder_parameter" "ai_prompt" {
type = "string"
name = "AI Prompt"
default = ""
description = "Build a Minesweeper in Python."
mutable = true
```tf
locals {
cursor_workdir = "/home/coder/project"
}

module "coder-login" {
count = data.coder_workspace.me.start_count
source = "registry.coder.com/coder/coder-login/coder"
version = "1.0.31"
module "cursor_cli" {
source = "registry.coder.com/coder-labs/cursor-cli/coder"
version = "1.0.0"
agent_id = coder_agent.main.id
workdir = local.cursor_workdir
api_key = var.cursor_api_key
}

resource "coder_app" "cursor_cli" {
agent_id = coder_agent.main.id
slug = "cursor-cli"
display_name = "Cursor CLI"
icon = "/icon/cursor.svg"
open_in = "slim-window"
command = <<-EOT
#!/usr/bin/env bash
set -e
cd "${local.cursor_workdir}"
exec cursor-agent --model gpt-5 --force
EOT
}
```

When `workdir` is set, the module creates it if missing and marks it as a trusted workspace, so Cursor CLI does not show the trust prompt there. Pass `--model`, `--force`, `--approve-mcps`, or any other [CLI flag](https://cursor.com/docs/cli/reference/parameters) in the launcher command.

> [!NOTE]
> The `coder_app` command re-executes on every pane reconnect. This works for interactive `cursor-agent`, but one-shot commands like `cursor-agent -p` will re-run each time. For one-shot prompts, use a `coder_script` (runs once at startup) and a `coder_app` that attaches to the existing session (for example, with tmux).

### MCP servers and rules

```tf
module "cursor_cli" {
source = "registry.coder.com/coder-labs/cursor-cli/coder"
version = "0.3.1"
version = "1.0.0"
agent_id = coder_agent.main.id
folder = "/home/coder/project"

# Optional
install_cursor_cli = true
force = true
model = "gpt-5"
ai_prompt = data.coder_parameter.ai_prompt.value
api_key = "xxxx-xxxx-xxxx" # Required while using tasks, see note below
workdir = "/home/coder/project"
api_key = var.cursor_api_key

# Minimal MCP server (writes `folder/.cursor/mcp.json`):
mcp = jsonencode({
mcpServers = {
playwright = {
command = "npx"
args = ["-y", "@playwright/mcp@latest", "--headless", "--isolated", "--no-sandbox"]
}

desktop-commander = {
command = "npx"
args = ["-y", "@wonderwhy-er/desktop-commander"]
}
}
})

# Use a pre_install_script to install the CLI
pre_install_script = <<-EOT
#!/usr/bin/env bash
set -euo pipefail
curl -fsSL https://deb.nodesource.com/setup_20.x | bash -
apt-get install -y nodejs
EOT

# Use post_install_script to wait for the repo to be ready
post_install_script = <<-EOT
#!/usr/bin/env bash
set -euo pipefail
TARGET="$${FOLDER}/.git/config"
echo "[cursor-cli] waiting for $${TARGET}..."
for i in $(seq 1 600); do
[ -f "$TARGET" ] && { echo "ready"; exit 0; }
sleep 1
done
echo "timeout waiting for $${TARGET}" >&2
EOT

# Provide a map of file name to content; files are written to `folder/.cursor/rules/<name>`.
rules_files = {
"python.mdc" = <<-EOT
---
description: RPC Service boilerplate
globs:
alwaysApply: false
---

- Use our internal RPC pattern when defining services
- Always use snake_case for service names.

@service-template.ts
EOT

"frontend.mdc" = <<-EOT
---
description: RPC Service boilerplate
globs:
alwaysApply: false
---

- Use our internal RPC pattern when defining services
- Always use snake_case for service names.

@service-template.ts
EOT
---
description: Python conventions
alwaysApply: true
---

- Use type hints on public functions.
EOT
}
}
```

`mcp` is merged into the user-level `~/.cursor/mcp.json`, so the servers apply to every Cursor CLI session in the workspace. Servers already in that file win on duplicate names, so edits made inside the workspace are never overwritten. `rules_files` are written to `<workdir>/.cursor/rules/` and require `workdir`.

> [!NOTE]
> A `.cursor` directory will be created in the specified `folder`, containing the MCP configuration, rules.
> To use this module with tasks, please pass the API Key obtained from Cursor to the `api_key` variable. To obtain the api key follow the instructions [here](https://docs.cursor.com/en/cli/reference/authentication#step-1%3A-generate-an-api-key)
> The official installer ships a self-contained binary and does not install Node.js. MCP servers whose `command` is `npx` or `uvx` need that runtime available in the workspace image, or installed with `pre_install_script`.

## References
### Serialize a downstream `coder_script` after the install pipeline

- See Cursor CLI docs: `https://docs.cursor.com/en/cli/overview`
- For MCP project config, see `https://docs.cursor.com/en/context/mcp#using-mcp-json`. This module writes your `mcp_json` into `folder/.cursor/mcp.json`.
- For Rules, see `https://docs.cursor.com/en/context/rules#project-rules`. Provide `rules_files` (map of file name to content) to populate `folder/.cursor/rules/`.
The module exposes the `scripts` output: an ordered list of `coder exp sync` names for the scripts this module creates (pre_install, install, post_install). Scripts that were not configured are absent.

```tf
module "cursor_cli" {
source = "registry.coder.com/coder-labs/cursor-cli/coder"
version = "1.0.0"
agent_id = coder_agent.main.id
}

resource "coder_script" "post_cursor_cli" {
agent_id = coder_agent.main.id
display_name = "Run after Cursor CLI install"
run_on_start = true
script = <<-EOT
#!/usr/bin/env bash
set -euo pipefail
trap 'coder exp sync complete post-cursor-cli' EXIT
coder exp sync want post-cursor-cli ${join(" ", module.cursor_cli.scripts)}
coder exp sync start post-cursor-cli

cursor-agent --version
EOT
}
```

## Configuration

When `api_key` is set, it is exported as `CURSOR_API_KEY` and is not rendered into the install script. To create a key, see [Cursor CLI authentication](https://cursor.com/docs/cli/reference/authentication). Without a key, run `cursor-agent login` in the workspace.

When `cursor_config_dir` is set, it is exported as `CURSOR_CONFIG_DIR`, which moves Cursor CLI's [`cli-config.json`](https://cursor.com/docs/cli/reference/configuration). When empty (the default), the module leaves `CURSOR_CONFIG_DIR` untouched. Cursor CLI still reads the user-level `mcp.json` from `~/.cursor`, so the module always merges `mcp` there.

The module always installs the latest Cursor CLI with the [official installer](https://cursor.com/install) and skips the install when `cursor-agent` is already on `PATH`. If `install_cursor_cli = false`, a working `cursor-agent` must already be available on `PATH`, or workspace startup fails.

## Troubleshooting

- Ensure the CLI is installed (enable `install_cursor_cli = true` or preinstall it in your image)
- Logs are written to `~/.cursor-cli-module/`
Check the log files in `~/.coder-modules/coder-labs/cursor-cli/logs/` for detailed information.

```bash
cat ~/.coder-modules/coder-labs/cursor-cli/logs/install.log
cat ~/.coder-modules/coder-labs/cursor-cli/logs/pre_install.log
cat ~/.coder-modules/coder-labs/cursor-cli/logs/post_install.log
```

## References

- [Cursor CLI documentation](https://cursor.com/docs/cli/overview)
- [Cursor CLI MCP](https://cursor.com/docs/cli/mcp)
- [Cursor rules](https://cursor.com/docs/context/rules)
152 changes: 0 additions & 152 deletions registry/coder-labs/modules/cursor-cli/cursor-cli.tftest.hcl

This file was deleted.

Loading
Loading