Atif Ali 32246a99c1
feat(cursor-cli): add Cursor CLI module (#309)
Closes #305

## Summary
- Add new module `registry/coder-labs/modules/cursor-cli` to run Cursor
Agent CLI directly (no AgentAPI)
- Interactive chat by default; supports non-interactive mode (-p) with
output-format
- Supports model (-m) and force (-f) flags, initial prompt, and
CURSOR_API_KEY
- Merges MCP settings into ~/.cursor/settings.json
- Installs via npm, bootstrapping Node via NVM if missing (mirrors
gemini approach)
- Adds Terraform-native tests (.tftest.hcl); all pass locally

## Test plan
- From module dir:
  - terraform init -upgrade
  - terraform test -verbose
- Expect 4 tests passing covering defaults, flag plumbing, and MCP
settings injection
- Basic smoke run: ensure `cursor-agent` is on PATH or set
install_cursor_cli=true

---------

Co-authored-by: DevCats <christofer@coder.com>
Co-authored-by: 35C4n0r <work.jaykumar@gmail.com>
Co-authored-by: 35C4n0r <70096901+35C4n0r@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-08-18 13:08:48 -05:00

3.6 KiB

display_name icon description verified tags
Cursor CLI ../../../../.icons/cursor.svg Run Cursor CLI agent in your workspace (no AgentAPI) true
agent
cursor
ai
cli

Cursor CLI

Run the Cursor Coding Agent in your workspace using the Cursor CLI directly.

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


data "coder_parameter" "ai_prompt" {
  type        = "string"
  name        = "AI Prompt"
  default     = ""
  description = "Build a Minesweeper in Python."
  mutable     = true
}

module "coder-login" {
  count    = data.coder_workspace.me.start_count
  source   = "registry.coder.com/coder/coder-login/coder"
  version  = "1.0.31"
  agent_id = coder_agent.main.id
}

module "cursor_cli" {
  source   = "registry.coder.com/coder-labs/cursor-cli/coder"
  version  = "0.1.0"
  agent_id = coder_agent.example.id
  folder   = "/home/coder/project"

  # Optional
  install_cursor_cli = true
  force              = true
  model              = "gpt-5"
  ai_prompt          = data.coder_parameter.ai_prompt.value

  # 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
  }
}

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

References

  • 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/.

Troubleshooting

  • Ensure the CLI is installed (enable install_cursor_cli = true or preinstall it in your image)
  • Logs are written to ~/.cursor-cli-module/