The customization reference, not another tour of the chat box. Write rules the agent actually follows, package your playbooks as skills, delegate to subagents, enforce policy with hooks, pick a run mode that will not run rm on your repo, connect MCP servers, drive the CLI headless in CI, and put Bugbot and cloud agents on review duty.
Cursor's Agent is not a chat box with autocomplete bolted on: it is a loop that reads your repo, edits files, runs your test command and drives a browser, and it will keep calling tools until the task is done. This tab covers what that loop is made of, and the approval model that decides how much of it happens without you.
Cursor for QA
Rules, skills, subagents, hooks, MCP and the CLI
Cursor is not just a chat box bolted onto an editor. It is an agent you can ground with rules, teach with skills, delegate from with subagents, fence in with hooks and run modes, and run headless in CI. Almost everything on this page is a file you commit to the repo.
Scoped by glob, loaded at the top of context
Playbooks, plus delegation in its own context
Block a command before the agent runs it
agent -p with a committed allowlist
How a grounded Cursor setup comes together
.cursor/rules/*.mdcConventions the agent reads before it touches your suite.
permissions.jsonAuto-review, plus the actions in .cursor/ you always want to approve.
SKILL.mdYour triage playbook, version controlled and reusable.
readonly: trueIndependent verification that cannot edit a thing.
.cursor/hooks.jsonDeny destructive commands before they ever run.
agent -pOne shot in CI, then schedule the recurring work.
Describe the task → the right rule, skill or subagent loads → you review the diff
What the agent loads
AGENTS.mdrules.cursor/rules/4.cursor/skills/3.cursor/agents/2.cursor/hooks.json6.cursor/mcp.json2Run mode
Chat mode
plan mode › rule match › skill match › review
tests/**.flaky-test-triage skill from your description, no slash needed.beforeShellExecution hook.Loaded from
.cursor/rules/playwright.mdcglob.cursor/skills/flaky-test-triage/SKILL.mdmatch.cursor/agents/verifier.mdreadonly.cursor/hooks.jsondenyWhat you commit
*.mdcProject rules
SKILL.mdTeam playbooks
hooks.jsonLifecycle gates
mcp.jsonExternal tools
.cursor/BUGBOT.mdReview rules
cli.jsonCI permissions
Key capabilities
.cursor/BUGBOT.mdQuickstart (local)
# 1. in your shell (macOS, Linux, WSL) curl https://cursor.com/install -fsS | bash agent # 2. at the prompt /create-rule # write your first rule /plan # scope before editing # 3. in CI (PowerShell: $env:CURSOR_API_KEY = "...") # commit a .cursor/cli.json deny list first: --force is not read only export CURSOR_API_KEY=... agent -p --force --output-format json "triage the failing specs"
Your conventions, your triage playbook and your safety limits stop living in one senior tester's head. They become files in the repo that agents read instead of guessing, on your machine and in the cloud.
Cmd+I. Agent lives in the sidepane. The model picker sits at the top of the chat input, and Cmd+/ cycles models mid-conversation.These are first-party tools, present with no setup. Read the third column as the QA job each one does.
| Tool | What it does | Where it lands in a QA loop |
|---|---|---|
| Search files and folders | Search by name, read directory structures, find exact keywords or patterns inside files | Find the existing spec before writing a duplicate one |
| Read files | Reads file content, and reads image files (.png, .jpg, .gif, .webp, .svg) into context for vision-capable models | Drop a failure screenshot next to the spec and have both in context |
| Edit files | Suggests edits and applies them automatically | The step that writes the test, and the step you must review hardest |
| Run shell commands | Executes terminal commands and monitors output | Runs the suite, the linter, the migration |
| Browser | Navigates, clicks, types, scrolls, screenshots, with full access to console logs and network traffic | Reproduce the bug, then verify the fix, with no external tooling to install |
| Web | Generates search queries and performs web searches | Look up a library behaviour without leaving the loop |
| Fetch Rules | Retrieves specific rules based on type and description | How an "Apply Intelligently" rule gets pulled in (see the Rules tab) |
| Image generation | Generates images from text or reference images, saved to the project's assets/ folder by default and shown inline in chat | Fixture and placeholder assets for visual test data |
| Ask questions | Asks clarifying questions mid-task; while waiting it keeps reading, editing and running commands, then folds your answer in | Ambiguous acceptance criteria get challenged instead of guessed |
localStorage and sessionStorage, IndexedDB), so a logged-in session survives between agent runs, and different projects keep separate storage.Cmd/Ctrl+Shift+P) then "Terminal: Select Default Profile". Heavy prompt themes such as Powerlevel9k or Powerlevel10k can truncate or mangle inline terminal output; gate them on the CURSOR_AGENT environment variable in your shell config.Run Modes control how the agent runs tool calls and when Cursor interrupts you for approval. They govern shell commands, MCP tools, and Fetch calls. Pick one at Settings > Agents > Approvals & Execution. Cursor recommends Auto-review as "the safest useful setup for most people".
| Mode | What runs without asking | Sandbox | Classifier | Use it when |
|---|---|---|---|---|
| Auto-review | Allowlisted calls run immediately. Other shell commands run in the sandbox when possible. Calls that do not use the sandbox go to the Auto-review classifier. | Yes, for shell commands | Yes | You want fewer prompts with a safety review before higher-risk calls run |
| Allowlist | Actions in your allowlist run without approval. With sandboxing enabled, supported shell commands can run in the sandbox. | Optional, for shell commands | No | You want deterministic behavior with a small set of trusted repeat actions |
| Run Everything | Every tool call runs automatically. | No | No | You accept the risk and want zero prompts |
The order of checks inside Auto-review, in the order Cursor applies them:
permissions.json. Configuration is not required. Configure only the actions you always want to review manually. Files live at ~/.cursor/permissions.json (all projects on your machine) and <project-dir>/.cursor/permissions.json (one project, commit it to share). If both exist, Cursor merges them.autoRun.allow_instructions and autoRun.block_instructions. Each holds plain-English sentences, for example "Every command that modifies Kubernetes resources should go through approval first." The easiest setup is to ask the agent to write the file for you.Cursor's stated premise is that "AI can behave unexpectedly due to prompt injection, hallucinations, and other issues", so sensitive actions require manual approval by default and the docs recommend keeping those defaults on. The line between free and gated is not where most testers assume it is.
| Action | Default behavior | What a tester should do about it |
|---|---|---|
| Read files, search code | No approval required | Use .cursorignore to block agent access to files it should never see |
| Edit workspace files | No approval required, and changes save immediately to disk | Always work on a branch. Version control is your only undo that survives |
| Edit configuration files (for example workspace settings) | Approval required | This is the one file class the agent cannot silently rewrite |
| Terminal commands | Approval required by default; your Run Mode relaxes it | Allowlist your test and lint commands, nothing that publishes or deploys |
| MCP connections | Approval required | Approve the server once, deliberately |
| Each MCP tool call | Approval required after the connection is approved | Pre-approve individual tools with an MCP allowlist if the prompting is unbearable |
| Arbitrary network requests | Not possible with default settings | Cursor's tools reach only GitHub, direct link retrieval, and web search providers |
These sit on top of the mode and can force an approval even when the mode would otherwise auto-run.
| Protection | What it does |
|---|---|
| Browser Protection | Prevents the agent from automatically running Browser tools |
| File-Deletion Protection | Prevents the agent from automatically deleting files, including rm commands |
| External-File Protection | Prevents the agent from automatically creating, modifying or deleting files outside the workspace |
settings.json with "security.workspace.trust.enabled": true; organizations can enforce it through MDM.| Individual plan | Other Models usage included | Cursor Models |
|---|---|---|
| Start (India only, billed in INR via UPI, credit card or debit card) | None, the pool is not included | Generous included usage |
| Pro | Included allowance | Generous included usage |
| Pro Plus | Larger allowance | Generous included usage |
| Ultra | Largest allowance | Generous included usage |
Everything above is Cursor's default behavior. The rest of this page is about overriding it: the next tab starts with Rules, the cheapest and most portable way to change what the agent does before it does it.
Rules are persistent instructions that get inserted into the model context before the agent reads your prompt. For a QA team they are the place you encode the things you would otherwise repeat in every message: locator conventions, what a real assertion looks like, and the rule that a failing test is a finding, not a file to edit.
| Type | Where it lives | Scope |
|---|---|---|
| Project Rules | .cursor/rules in the repo | Version-controlled, scoped to that codebase. The default choice for a team |
| User Rules | Defined in Customize -> Rules, not on the file system | Global to your Cursor environment. Used by Agent (Chat) only |
| Team Rules | Cursor dashboard, https://cursor.com/dashboard/team-content | Org-wide, Team and Enterprise plans. Can be made mandatory |
AGENTS.md | Project root, and any subdirectory | Plain markdown, no frontmatter, no metadata. The zero-ceremony option |
@filename.ts, for example @service-template.ts or @component-template.tsx. Referencing keeps the rule short and prevents the rule from going stale when the template changes..mdc files and the frontmatter that decides everything.cursor/rules as .mdc files. The filename itself can be anything, and rules can be organized into subfolders.description, globs and alwaysApply. You can hand-edit them; the UI is writing the same three keys..cursor/rules/
react-patterns.mdc # Recognized as a project rule
api-guidelines.md # Ignored (wrong extension)
frontend/ # Organize rules in folders
components.mdc
.md file in .cursor/rules is silently ignored. No error, no warning in chat, no entry in Customize. It is ignored because it has no frontmatter for description, globs and alwaysApply. If your carefully written testing standards are having no effect, check the extension before you rewrite the prose.The frontmatter interaction table. This is the single thing to get right on this tab.
alwaysApply | description | globs | Behavior |
|---|---|---|---|
true | (any) | (any) | Always included. Globs and description are ignored. |
false | (omitted) | provided | Auto-attached when a matching file is in context. |
false | provided | (omitted) | Agent reads the description and pulls the rule in when relevant. |
false | (omitted) | (omitted) | Included only when you @-mention the rule in chat. |
The same four behaviors, named as the UI names them:
| Rule Type (UI label) | Trigger |
|---|---|
Always Apply | Applied to every chat session |
Apply Intelligently | When Agent decides it is relevant based on description |
Apply to Specific Files | When a file matches the specified pattern |
Apply Manually | When @-mentioned in chat, for example @my-rule |
Apply Intelligently, make sure a description actually exists, because that string is the only thing the agent has to judge relevance by. For Apply to Specific Files, make sure the glob really matches the files you are referencing.Separate multiple patterns with commas.
| Pattern | Matches |
|---|---|
* | Any single file name segment |
** | Any number of directories (recursive) |
*.ts | All .ts files in the root |
**/*.ts | All .ts files in any directory |
src/** | All files anywhere under src/ |
src/**/*.tsx | All .tsx files anywhere under src/ |
docs/**/*.md, docs/**/*.mdx | .md and .mdx files under docs/ (comma-separated) |
tailwind.config.* | tailwind.config with any extension |
AGENTS.md: rules with no frontmatter, nested by directory
.cursor/rules. If your repo already has one for another tool, Cursor reads it.AGENTS.md is automatically applied when working with files in that directory or its children.tests/e2e/AGENTS.md carries the Playwright specifics.project/
AGENTS.md # Global instructions
frontend/
AGENTS.md # Frontend-specific instructions
components/
AGENTS.md # Component-specific instructions
backend/
AGENTS.md # Backend-specific instructions
.mdc frontmatter to write.**/*.py. Without a glob, a Team Rule applies to every conversation. Scope your "all API tests must assert on the response schema" rule to the test globs, not to everything./create-rule in Agent and describe what you want. Agent writes the rule into .cursor/rules with the correct frontmatter, which removes the most common source of a rule that never fires.description, globs and alwaysApply for you.@filename.ts inside the rule body, for example @migration-template.sql. Referencing beats copying: shorter rule, and it cannot go stale..mdc files, then pulls and syncs them..cursor/rules/imported/<repoName>, preserving relative paths. Review them like any other dependency before you rely on them.@cursor on a GitHub issue or PR to have Agent update a rule.Cmd/Ctrl+K); they are used by Agent (Chat) only. If your personal rule seems to vanish, check which surface you are typing into.Three files, one per trigger style. Together they cover roughly 80 percent of what a test-automation team keeps repeating in chat.
1. Playwright conventions, scoped to the test tree (.cursor/rules/playwright-conventions.mdc). Globs with no description, so it auto-attaches whenever a spec or page object is in context.
---
globs: tests/**/*.spec.ts, tests/**/*.page.ts
alwaysApply: false
---
- Prefer role and label based locators. Use a test id only when nothing semantic is stable
- Never use nth-child, XPath, or locators that depend on CSS class names
- Every spec opens with a test.describe named after the feature under test
- Page objects live in tests/pages and use named exports. Follow @login.page.ts
- Wait on the condition the test cares about. Never add a fixed timeout to stabilise a test
2. Test integrity, always on (.cursor/rules/test-integrity.mdc). Short on purpose: it rides along with every single request, so every line is paying rent.
---
alwaysApply: true
---
- Never delete, skip, or weaken an assertion to make a test pass
- A failing test is a finding. Report the failure and the suspected cause before changing any test file
- Do not change production code and its test in the same step without saying so explicitly
- Never commit credentials or real customer data into fixtures
3. API contract test conventions, description-driven (.cursor/rules/api-test-conventions.mdc). No globs, so Agent pulls it in when the description matches what you asked for.
---
description: Conventions for API contract tests, fixtures and response assertions
alwaysApply: false
---
- Assert status code and response schema as separate assertions so schema drift is not reported as a status failure
- Request fixtures live in tests/fixtures and are named after the endpoint they exercise
- Every negative-path test asserts on the error body, not only the status code
- Follow the fixture shape in @checkout.fixture.ts
alwaysApply: true and the others are not. Test integrity is the rule you need most when the agent is not looking at a test file, for example when it decides the fastest way to green the suite is to edit the assertion. Scoping that rule to tests/** would remove it from exactly the moment it matters.Rules are text in front of the prompt, which makes them cheap and blunt. When you need instructions that carry scripts, templates and reference files, and that load only when relevant, you want Skills: that is the next tab.
A rule tells Agent how to behave. A skill gives it a capability: a folder of instructions, scripts and reference material that loads only when it is relevant. For a QA team this is where repeatable work (triage a flake, write a test plan, run a review pass) stops living in someone's head and starts living in the repo.
SKILL.md. A bare markdown file dropped in a skills root is not a skill.agentskills.io, so the same folder works across any agent that supports it./ in Agent chat and search for the skill name.| Location | Scope | What that means for a team |
|---|---|---|
.agents/skills/ | Project | Committed with the repo, applies to everyone who clones it |
.cursor/skills/ | Project | Same, and the directory /migrate-to-skills writes into |
~/.agents/skills/ | User (global) | Your machine only, available in every project, not shared |
~/.cursor/skills/ | User (global) | Same, good for personal habits you do not want to impose on the team |
.claude/skills/, .codex/skills/, ~/.claude/skills/ and ~/.codex/skills/, so a skill written for another agent is picked up without moving it..agents/
└── skills/
└── my-skill/
└── SKILL.md
| Field | Required | Constraints and behavior |
|---|---|---|
name | Yes | Lowercase letters, numbers and hyphens only, and it must match the parent folder name |
description | Yes | What the skill does and when to use it. This is the text Agent reads to decide relevance |
paths | No | Glob patterns scoping the skill to matching files. Accepts a comma-separated string or a list. When set, the skill is surfaced only while the agent works with matching files |
disable-model-invocation | No | When true, the skill is included only when you invoke /skill-name. Agent will not auto-apply it |
metadata | No | Arbitrary key-value mapping for extra metadata |
paths unset for an always-available skill. Patterns follow standard glob syntax. No paths means the skill can surface regardless of which files are open.globs is the legacy fallback. It is still accepted for older skills, but write paths in anything new.SKILL.md short. Move detail into references/. Agents load resources progressively, so a thin entry file plus fat references is cheaper than one long file.---
name: my-skill
description: Short description of what this skill does and when to use it.
---
# My Skill
Detailed instructions for the agent.
## When to Use
- Use this skill when...
## Instructions
- Step-by-step guidance for the agent
- Use the ask questions tool if you need to clarify requirements with the user
paths takes either a list or a comma-separated string:
---
name: react-component-patterns
description: Conventions for writing React components in this codebase.
paths:
- "**/*.tsx"
- "packages/ui/**/*.ts"
---
---
name: python-style
description: Style rules for Python files.
paths: "**/*.py, scripts/**/*.py"
---
name field (or use an underscore, a capital letter or a space), the skill is invalid. name must be lowercase letters, numbers and hyphens, and it must equal the folder that directly contains SKILL.md.SKILL.md. A folder like testing/ above your skills is purely organizational, it does not become part of the identity.SKILL.md names the skill..cursor/skills/ or .agents/skills/ folder anywhere in the repo is picked up, and skills in a nested project directory are automatically scoped to files inside that directory. You do not need paths for that case.my-monorepo/
├── .cursor/skills/ # repo-wide skills
│ └── land-it/SKILL.md
└── apps/
└── web/
└── .cursor/skills/ # scoped to apps/web automatically
└── deploy-web/SKILL.md
paths pattern that drifts from the folder structure.| Directory | Purpose |
|---|---|
scripts/ | Executable code that agents can run |
references/ | Additional documentation loaded on demand |
assets/ | Static resources such as templates, images or data files |
scripts/deploy.sh <environment> or python scripts/validate.py in SKILL.md. Agent reads the instruction and executes the script when the skill is invoked.These ship with Cursor, are managed by Cursor, and appear alongside your own. Run any of them by typing / in Agent chat. Agent may also use some automatically when a request clearly matches. The pills mark the ones a tester reaches for.
| Skill | What it does |
|---|---|
/create-skill QA pick | Creates Agent Skills, including their structure and SKILL.md files |
/create-rule QA pick | Creates Cursor rules with the appropriate scope and instructions |
/create-subagent QA pick | Creates custom subagents with focused roles and delegation instructions |
/create-hook QA pick | Creates Cursor hooks and updates hooks.json for agent lifecycle events |
/review QA pick | Selects and runs the appropriate code-review agent |
/review-bugbot QA pick | Reviews code for likely bugs and regressions with Bugbot |
/review-security QA pick | Reviews code for security vulnerabilities with Security Review |
/automate QA pick | Creates Cursor Automations triggered by schedules, Slack messages, GitHub events and other sources |
/babysit QA pick | Monitors a pull request and addresses feedback, conflicts, failing checks and follow-up work |
/loop QA pick | Runs a prompt or skill repeatedly at a specified interval |
/migrate-to-skills QA pick | Converts eligible dynamic rules and slash commands into Agent Skills |
/canvas | Creates interactive React artifacts that render alongside the conversation |
/cursor-blame | Investigates AI-authored changes and the prompts that produced them |
/sdk | Helps build applications and integrations with the Cursor SDK |
/shell | Runs the provided text as a literal shell command |
/split-to-prs | Splits large changes into smaller pull requests |
/statusline | Configures the Cursor CLI status line |
/update-cli-config | Updates Cursor CLI settings in ~/.cursor/cli-config.json |
/update-cursor-settings | Finds and updates the appropriate Cursor or VS Code setting |
/cursor-blame deserves a second look even though it is not on the QA list: when a regression lands in agent-authored code, it investigates the change and the prompt that produced it.
alwaysApply is false or undefined and there are no globs, become standard skills.disable-model-invocation: true, which preserves their explicit-invocation behavior.alwaysApply: true, rules with specific globs, and User Rules (they are not stored on the file system)..cursor/skills/.# --- in Agent chat, not a terminal ---
/migrate-to-skills
/create-skill a skill that triages a flaky Playwright spec
| Component | What it contributes |
|---|---|
| Rules | Persistent AI guidance and coding standards (.mdc files) |
| Skills | Specialized agent capabilities for complex tasks |
| Agents | Custom agent configurations and prompts |
| Commands | Agent-executable command files |
| MCP Servers | Model Context Protocol integrations |
| Hooks | Automation scripts triggered by events |
.cursor-plugin/plugin.json manifest plus its components. Only name is required. Components are discovered automatically from their default directories, or you can point at custom paths in the manifest.my-plugin/
├── .cursor-plugin/
│ └── plugin.json
├── rules/
│ └── coding-standards.mdc
├── skills/
│ └── code-reviewer/
│ └── SKILL.md
└── mcp.json
{
"name": "my-plugin",
"description": "Custom development tools",
"author": { "name": "Your Name" }
}
~/.cursor/plugins/local/my-plugin, with .cursor-plugin/plugin.json at the plugin root.cursor.com/marketplace/publish. For a repo holding several plugins, add a marketplace manifest at .cursor-plugin/marketplace.json.# --- shell, macOS and Linux ---
ln -s /path/to/my-plugin ~/.cursor/plugins/local/my-plugin
# --- PowerShell equivalent ---
# needs Developer Mode on, or an elevated shell. Otherwise copy the folder instead.
New-Item -ItemType SymbolicLink -Path "$env:USERPROFILE\.cursor\plugins\local\my-plugin" -Target "C:\path\to\my-plugin"
| Installation mode | Behavior | When a QA lead picks it |
|---|---|---|
Default Off | Developers find it and choose to install | Optional helpers, experiments, team-specific tooling |
Default On | Installed by default, developers can opt out | The house test conventions, review skills, most people should have them |
Required | Always installed, cannot be uninstalled | Safety hooks and compliance gates that are not negotiable |
Flaky-test triage is the ideal first skill: it is a procedure everyone already does badly, it needs a script, it needs a reference table, and it should only surface when someone is looking at specs.
.cursor/skills/
└── flaky-test-triage/
├── SKILL.md
├── scripts/
│ └── rerun.sh
└── references/
└── flake-taxonomy.md
---
name: flaky-test-triage
description: Triage an intermittent test failure. Use when a spec fails on CI but passes locally, when a spec fails only in a parallel run, or when someone asks whether a failure is a real bug or a flake.
paths:
- "tests/**/*.spec.ts"
- "e2e/**/*.spec.ts"
---
# Flaky Test Triage
## When to Use
- A spec failed on CI and passes on a local rerun
- The same spec fails only when the suite runs in parallel
- Someone asks whether a failure is a product bug or a flake
## Instructions
1. Re-run the single spec in isolation ten times: scripts/rerun.sh <spec-path> 10
2. If it passes every time, treat it as environment or ordering related. Check shared fixtures and seeded test data first.
3. If it fails intermittently, classify it against references/flake-taxonomy.md (wait, race, data, selector, network).
4. Never delete or skip the test. Either propose the fix, or quarantine it and open a ticket with the run log attached.
5. Report back: spec path, failure class, the evidence, the proposed fix, and whether it should block the release.
description is doing the real work. It names the situations, not the capability. That is what makes Agent pull the skill in without being told.paths entry keeps it quiet. The skill stays out of context entirely while someone works on application code.paths pointed at your spec directory, assets/test-plan-template.md, and instructions that require risk, scope and exit criteria in every plan.disable-model-invocation: true on any skill that has side effects (anything that pushes, files a ticket, or hits an environment) so it only ever runs when a human types /skill-name. Leave it off for advisory skills like triage.Skills give Agent new capabilities inside the same context window. When the work is large enough that it would flood that window, or when you want an independent second opinion, you hand it to a subagent instead, and you enforce the rules of engagement with hooks.
Subagents give a task its own clean context window and hand back only the result. Hooks are the opposite direction of control: spawned processes that sit in the agent loop and decide what the agent is allowed to do. Together they are how a QA team turns policy into something the tool enforces rather than something the tool is asked politely to respect.
| Type | Location | Scope |
|---|---|---|
| Project | .cursor/agents/ | Current project only |
| Project | .claude/agents/ | Current project only (Claude compatibility) |
| Project | .codex/agents/ | Current project only (Codex compatibility) |
| User | ~/.cursor/agents/ | All projects for the current user |
| User | ~/.claude/agents/ | All projects for the current user (Claude compatibility) |
| User | ~/.codex/agents/ | All projects for the current user (Codex compatibility) |
.cursor/ takes precedence over .claude/ or .codex/..cursor/agents/ belongs in version control, same as your rules and skills.explore (searches and analyzes codebases), bash (runs series of shell commands), browser (drives the browser through MCP tools). Each exists because its output is verbose and isolating it keeps the parent focused on decisions.| Field | Type | Default | Description |
|---|---|---|---|
name | string | Derived from filename | Display name and identifier. Use lowercase letters and hyphens |
description | string | (none) | Short description shown in Task tool hints. Agent reads this to decide delegation |
model | string | inherit | inherit for the parent model, or a specific model ID |
readonly | boolean | false | If true, runs with restricted write permissions: no file edits and no state-changing shell commands |
is_background | boolean | false | If true, runs in the background without blocking the parent |
readonly: true is the QA field. A reviewer that cannot edit files and cannot run state-changing commands can be pointed at anything without a second thought. Set it on every subagent whose job is to look and report.id=value pairs in square brackets to a model ID, comma-separated, for options like reasoning effort or context size. Empty brackets pin the base model and select the standard variant rather than the fast one.| Mode | Behavior | Best for |
|---|---|---|
| Foreground | Blocks until the subagent completes, returns the result immediately | Sequential tasks where you need the output before the next step |
Background (is_background: true) | Returns immediately, the subagent works independently | Long-running tasks or parallel workstreams |
A review subagent a QA team can commit as .cursor/agents/test-reviewer.md:
---
name: test-reviewer
description: Reviews test code for assertions that cannot fail, sleeps used as synchronization, and selectors bound to markup. Use proactively after any change under tests/ or e2e/.
model: inherit
readonly: true
---
You review test code. You never edit files and you never run the suite.
When invoked:
1. Read every changed spec file named in the prompt.
2. Flag assertions that cannot fail, fixed sleeps used instead of waits, selectors bound to markup rather than roles or test ids, and shared mutable fixtures.
3. For each finding give file, line, why it is unsafe, and the smallest fix.
4. End with a single verdict: safe to merge, or needs changes.
description encourage automatic delegation./name. The reliable path when you want a specific reviewer on a specific thing.# --- in Agent chat, not a terminal ---
/verifier confirm the auth flow is complete
/security-auditor review the payment module
/test-reviewer review the specs I changed on this branch
~/.cursor/subagents/, and the parent can read those files to check progress.cursor.com/agents, not your local ones./in-cloud makes the next task run as a cloud subagent on its own VM and branch. /babysit has a cloud subagent iterate on a pull request remotely.| Benefit | Trade-off |
|---|---|
| Context isolation | Startup overhead, each subagent gathers its own context from scratch |
| Parallel execution | Higher token usage, multiple contexts running at once |
| Specialized focus | Latency, often slower than the main agent for simple tasks |
| Use subagents when | Use skills when |
|---|---|
| You need context isolation for long research tasks | The task is single-purpose (generate changelog, format) |
| You are running multiple workstreams in parallel | You want a quick, repeatable action |
| The task requires specialized expertise across many steps | The task completes in one shot |
| You want an independent verification of work | You do not need a separate context window |
The docs are explicit about the failure mode: if you are creating a subagent for a simple single-purpose task like generating a changelog or formatting imports, make it a skill instead.
/create-subagent, then trim them. Use hooks if you need subagents to produce structured output files.hooks.json. At project or user level, or installed through plugins from Customize.| Source | Location | Working directory for relative paths |
|---|---|---|
| Enterprise (MDM, system-wide) | macOS /Library/Application Support/Cursor/hooks.json, Linux and WSL /etc/cursor/hooks.json, Windows C:\ProgramData\Cursor\hooks.json | The enterprise config directory |
| Team (Enterprise only) | Web dashboard at cursor.com/dashboard/team-content, section hooks, synced to all members | The managed hooks directory |
| Project | <project-root>/.cursor/hooks.json | The project root |
| User | ~/.cursor/hooks.json | ~/.cursor/ |
.cursor/hooks.json the simplest way to distribute a policy to the whole team..cursor/hooks/script.sh. Writing ./hooks/script.sh resolves to <project>/hooks/script.sh, which does not exist, and the hook silently does nothing. User hooks are the opposite: they run from ~/.cursor/, so ./hooks/script.sh or hooks/script.sh is correct there. Copying a snippet from one level to the other without fixing the path is the most likely cause of a hook that appears to be ignored..cursor/hooks/. Keep it beside the config it belongs to.chmod +x .cursor/hooks/format.sh on macOS and Linux. A non-executable script is a hook failure, and by default a hook failure lets the action through. On Windows there is no chmod: write the hook as a script your shell can run and point command at it..cursor/hooks.json with the project-root relative path. Save, and Cursor reloads.{
"version": 1,
"hooks": {
"afterFileEdit": [{ "command": ".cursor/hooks/format.sh" }]
}
}
"type": "prompt" and give a prompt expressing a natural language condition. It returns a structured { ok: boolean, reason?: string } response and uses a fast model for quick evaluation.$ARGUMENTS carries the input. In a prompt hook the placeholder is auto-replaced with the hook input JSON, and if $ARGUMENTS is absent the input is auto-appended.| Exit code | Result |
|---|---|
0 | Hook succeeded, Cursor uses the JSON output |
2 | Block the action, equivalent to returning permission: "deny" (matches Claude Code behavior for compatibility) |
| anything else | Hook failed and the action proceeds. Fail-open by default |
| Per-script option | Type | Default | Description |
|---|---|---|---|
command | string | required | Script path or command. Shell string, absolute path, or relative path |
type | "command" or "prompt" | "command" | Hook execution type |
timeout | number | platform default | Execution timeout in seconds |
loop_limit | number or null | 5 for Cursor hooks, null for hooks loaded from Claude Code | Per-script loop limit for stop and subagentStop hooks. null means no limit |
failClosed | boolean | false | When true, hook failures (crash, timeout, invalid JSON) block the action instead of allowing it through |
matcher | pattern | (none) | Filter criteria for when the hook runs. Every documented example passes a string regex pattern |
"failClosed": true, which makes a failure block instead. This is explicitly recommended for security-critical beforeMCPExecution hooks, and it applies just as much to a beforeShellExecution guard or a beforeReadFile secrets filter. A guard you have never seen fail is a guard you have never tested.The full catalog splits into agent hooks (Cmd+K and Agent Chat): sessionStart, sessionEnd, preToolUse, postToolUse, postToolUseFailure, subagentStart, subagentStop, beforeShellExecution, afterShellExecution, beforeMCPExecution, afterMCPExecution, beforeReadFile, afterFileEdit, beforeSubmitPrompt, preCompact, stop, afterAgentResponse, afterAgentThought; tab hooks (inline completions): beforeTabFileRead, afterTabFileEdit; and app lifecycle hooks: workspaceOpen. These are the ones worth your time first.
| Event | Fires | What a QA team uses it for |
|---|---|---|
beforeShellExecution | Before a terminal command runs. Input has command, cwd, sandbox | Block destructive commands and writes against shared environments. Can return allow, deny or ask |
beforeReadFile | Before Agent reads a file. Input has file_path, content, attachments | Keep credentials, prod dumps and customer fixtures out of the model. Returns allow or deny |
afterFileEdit | After Agent edits a file. Input has file_path and the edits array | Run the formatter or linter, and account for how much agent-written code landed |
preToolUse | Before any tool execution, for all tool types | Broad policy in one place, narrowed with a matcher. Can also return updated_input |
postToolUse | After a successful tool call. Input adds tool_output and duration | Audit trails, and injecting additional_context after a result |
subagentStart | Before a subagent spawns. Input has subagent_type, task, subagent_model | Allow or deny delegation, for example blocking cloud or write-capable subagents on a release branch |
subagentStop | When a subagent completes, errors or aborts. Input has status, summary, modified_files, agent_transcript_path | Record what a reviewer touched, and push a followup_message when it completed |
beforeSubmitPrompt | Right after send, before the backend request. Input has prompt and attachments | Stop a prompt that carries a secret or a customer record. Output continue decides submission |
stop | When the agent loop ends. Input has status and loop_count | The test-run gate. A non-empty followup_message is submitted as the next user message |
sessionStart | When a new composer conversation is created | Inject additional_context (the current branch, the environment) and set env variables available to every later hook in the session |
CURSOR_PROJECT_DIR and CURSOR_VERSION are always present, CURSOR_USER_EMAIL when logged in, CURSOR_TRANSCRIPT_PATH when transcripts are enabled, CURSOR_CODE_REMOTE is the string "true" in a remote workspace, and CLAUDE_PROJECT_DIR is an alias for the project dir.conversation_id (stable across turns), generation_id (changes with every user message), hook_event_name, workspace_roots, user_email and transcript_path.| Hook | The matcher is tested against |
|---|---|
preToolUse, postToolUse, postToolUseFailure | Tool type. Values include Shell, Read, Write, Grep, Delete, Task, and MCP tools as MCP:<tool_name> |
beforeShellExecution, afterShellExecution | The full shell command string |
beforeReadFile | Tool type (TabRead, Read, and so on) |
afterFileEdit | Tool type (TabWrite, Write, and so on) |
subagentStart, subagentStop | Subagent type (generalPurpose, explore, shell, and so on) |
beforeSubmitPrompt | The value UserPromptSubmit |
stop | The value Stop |
afterAgentResponse | The value AgentResponse |
afterAgentThought | The value AgentThought |
Every documented example passes a string pattern, so write it that way:
{
"hooks": {
"beforeShellExecution": [
{
"command": "./scripts/approve-network.sh",
"timeout": 30,
"matcher": "curl|wget|nc"
}
]
}
}
| Limit | Detail |
|---|---|
permission: "ask" on preToolUse | Accepted by the schema but not enforced. Only allow and deny take effect |
permission: "ask" on subagentStart | Not supported and treated as deny. Returning it silently blocks delegation |
postToolUseFailure, afterTabFileEdit, afterAgentThought | No output fields are currently supported. Observation only |
preCompact | Observational only. It cannot block or modify compaction. It can show a user_message |
sessionEnd | Fire and forget. The response is logged but not used |
sessionStart | Fire and forget. The loop does not wait for it, and session creation is not blocked even when continue is false |
stop and subagentStop follow-ups | Capped at 5 automatic follow-ups per script by default via loop_limit. Set it to null to remove the cap. A subagentStop follow-up is consumed only when status is "completed" |
.cursor/hooks.json in the repo), team hooks and enterprise hooks all apply.~/.cursor/hooks.json does not load, because cloud VMs have no access to your local home directory. If your safety net lives only in your home directory, it does not exist in the cloud.beforeShellExecution, afterShellExecution, beforeReadFile, afterFileEdit, preToolUse, postToolUse, postToolUseFailure, subagentStart, subagentStop, beforeSubmitPrompt, preCompact, afterAgentResponse, afterAgentThought, stop.sessionStart and sessionEnd, beforeMCPExecution and afterMCPExecution, beforeTabFileRead and afterTabFileEdit (Tab is an IDE feature), and workspaceOpen (an IDE lifecycle hook).One. Block a destructive command. The matcher narrows it to the commands you care about, and failClosed means a broken guard blocks instead of waving things through.
{
"version": 1,
"hooks": {
"beforeShellExecution": [
{
"command": ".cursor/hooks/block-destructive.sh",
"matcher": "rm -rf|drop table|truncate|db:reset",
"timeout": 10,
"failClosed": true
}
]
}
}
#!/bin/bash
json_input=$(cat)
echo "$json_input" >> /tmp/agent-audit.log
echo '{"continue": true, "permission": "deny", "user_message": "Destructive command blocked by the QA hook.", "agent_message": "That command was blocked. Use the seeded test database and the fixture reset task instead."}'
exit 0
{ "continue": true, "permission": "allow" }, the deny above, or { "continue": true, "permission": "ask", "user_message": "GitHub CLI command requires permission" }.agent_message earns its place. It is fed to the agent when the action is denied, so use it to point at the approved path rather than leaving the agent to guess and retry.exit 2 is the shortcut. Exiting with code 2 blocks the action and is equivalent to returning permission: "deny", which is handy for a one-line guard.chmod +x .cursor/hooks/block-destructive.sh.Two. Keep the agent away from secrets. beforeReadFile receives the absolute file_path and the full content, and its output decides whether the model ever sees the file.
{
"version": 1,
"hooks": {
"beforeReadFile": [
{ "command": ".cursor/hooks/guard-secrets.sh", "failClosed": true }
]
}
}
{ "permission": "deny", "user_message": "Blocked: this path is on the secrets list and is never sent to the model." }
The same idea as a release gate, using stop. When the loop ends without the suite having run, hand the agent its next instruction:
{
"version": 1,
"hooks": {
"stop": [
{ "command": ".cursor/hooks/test-gate.sh", "loop_limit": 2 }
]
}
}
{ "followup_message": "The test suite was not run for this change. Run it now and report pass or fail before you finish." }
loop_limit deliberately on any stop hook. The default of 5 means a badly written gate can push five automatic follow-ups before it gives up, and each one is a full turn you are paying for. Two is usually enough for a gate. Reserve null for loops you are actively watching.Subagents isolate context and hooks enforce policy. What decides how much rope the agent has in the first place is the mode it is running in, and what it can reach outside your repo is the MCP servers you connect. Both are next.
Plan Mode decides what gets built, Agent Review checks what got built, and checkpoints undo it when the agent gets it wrong. This tab covers those three, plus the context ring you should read before blaming the model, the browser tool that turns the agent into a manual tester, worktrees for running several agents on one repo, and MCP for wiring in the tools your team already runs.
Shift+Tab from the chat input to rotate into Plan Mode, or pick it from the mode dropdown. Cursor also suggests Plan Mode automatically when you type keywords that indicate a complex task.Available Tools when relevant, including in Plan Mode, so a plan can be informed by your tracker or log search before a single file changes.| Situation | Mode to use |
|---|---|
| Complex feature with multiple valid approaches | Plan Mode |
| Task touching many files or systems | Plan Mode |
| Unclear requirements that need exploration to understand scope | Plan Mode |
| Architectural decision you want to review first | Plan Mode |
| A quick change | Agent mode, skip planning |
| Something you have done many times already | Agent mode, skip planning |
Cursor Settings > Agents > Agent Review. If it is missing there, check Git & PRs > Pull Requests.BUGBOT.md files, which means the same rules your PR reviewer enforces are enforced on your machine first. Set those up once and both surfaces agree (see tab 7).| How to start it | What you get |
|---|---|
| Automatic, enabled in settings | Reviews run on their own with no action from you |
Slash command /agent-review in the agent window input | An on-demand review of the current work |
| Source Control tab | Compares all local changes against your main branch, catching issues across the full change set rather than only the latest edit |
| Depth | Speed | Cost | Best for |
|---|---|---|---|
| Quick | Fast | Low | Small diffs, formatting changes, a fast sanity check |
| Deep | Slow | High | Complex logic, security-sensitive code, large refactors |
Restore Checkpoint button on a previous request, or use the + button that appears when you hover over a message.| Ring category | What fills it |
|---|---|
| System prompt | Cursor's own instructions for the agent |
| Tools | Definitions of every available tool |
| Rules | Project and user rules (tab 2) |
| Skills | Skill descriptions injected into system context (tab 3) |
| MCP | Instructions and catalog from connected servers |
| Subagents | Documentation for the subagent types the agent can launch (tab 4) |
| Summarized conversation | Older turns that have already been compressed |
| Conversation | The live turns you are working in |
localStorage and sessionStorage) and IndexedDB content are retained between Agent sessions. The browser context is isolated per workspace, so projects keep separate storage and cookie state. Log in once, then keep testing the authenticated flows.| Capability | Detail |
|---|---|
| Navigate | Visit URLs, follow links, go back and forward in history, refresh pages |
| Click | Click, double-click, right-click and hover on any visible element |
| Type | Enter text into inputs, fill and submit forms, search boxes, text areas |
| Scroll | Reveal additional content, find elements, explore long documents |
| Screenshot | Capture page state to understand layout and verify visual elements |
| Console output | Read console messages, JavaScript errors, debugging output, network warnings |
| Network traffic | Monitor HTTP requests and responses, track API calls, analyze payloads, check status codes. Available in the Agent panel only |
| Browser approval mode | Behavior |
|---|---|
| Manual approval | Review and approve each browser action individually (recommended, and the default is that browser tools require approval) |
| Allow-listed actions | Actions matching your allow list run automatically, everything else needs approval |
| Auto-run | All browser actions execute immediately without approval, use with caution |
Allow list and block list live at Cursor Settings > Agents > Auto-Run. The browser itself runs as a secure web view controlled by an MCP server running as an extension, with a random authentication token generated before each session and a unique random ID per tab.
# in-chat prompts, typed into the Agent input (not shell)
@browser Check color contrast ratios, verify semantic HTML and ARIA labels, test keyboard navigation, and identify missing alt text
@browser Fill out forms with test data, click through workflows, test responsive designs, validate error messages, and monitor console for JavaScript errors
.cursor/worktrees.json when creating a worktree from the Agents Window, the IDE or the CLI. Lookup order: the worktree path first, then the root path of your project..cursor/worktrees.json. Put scripts in .cursor/ next to the config.$ROOT_WORKTREE_PATH points at the root checkout, which is how you carry an untracked .env or fixture file across. Windows cmd uses %ROOT_WORKTREE_PATH%, PowerShell uses $env:ROOT_WORKTREE_PATH. That is also why a cp line under the generic setup-worktree key breaks on Windows: put the Windows commands in setup-worktree-windows and leave the fallback for the commands that genuinely run everywhere.Worktrees Setup channel.Key in .cursor/worktrees.json | Applies to |
|---|---|
setup-worktree-unix | macOS and Linux. Takes precedence over setup-worktree on Unix |
setup-worktree-windows | Windows. Takes precedence over setup-worktree on Windows |
setup-worktree | Generic fallback for all operating systems |
{
"setup-worktree": [
"npm ci",
"cp $ROOT_WORKTREE_PATH/.env .env"
]
}
{
"setup-worktree-unix": "setup-worktree-unix.sh",
"setup-worktree-windows": "setup-worktree-windows.ps1",
"setup-worktree": [
"echo 'Using generic fallback. For better support, define OS-specific scripts.'"
]
}
# in-chat slash commands, typed into the Agent input (not shell)
/worktree fix the failing auth tests and update the login copy
/apply-worktree
/delete-worktree
/best-of-n sonnet,gpt,composer fix the flaky logout test
# shell
git worktree list
/worktree <task> runs the rest of that chat in a separate checkout. Good for experimental edits, for installs, builds and test runs that would disturb your current branch, and for risky refactors with a simple cleanup path. In many cases you can commit and push directly from the worktree./apply-worktree brings the changes into your main checkout so you can test them there. /delete-worktree cleans up when you are done./best-of-n <models> <task> runs the same task across multiple models at once, each in its own worktree so candidates stay isolated. Limit: it compares runs only and does not merge changes back into your main checkout. After picking a winner, commit and push from that worktree or run /apply-worktree.bun, pnpm or uv instead.git worktree add, are eligible for deletion. Do not leave a long-lived manual checkout there.{
"cursor.worktreeCleanupIntervalHours": 6,
"cursor.worktreeMaxCount": 25
}
stdout or serve an HTTP endpoint.mcp.json. Official plugins live in the Cursor Marketplace, community servers at cursor.directory.| Transport | Execution | Deployment | Users | Input | Auth |
|---|---|---|---|---|---|
stdio | Local | Cursor manages | Single user | Shell command | Manual |
SSE | Local or remote | Deploy as server | Multiple users | URL to an SSE endpoint | OAuth |
Streamable HTTP | Local or remote | Deploy as server | Multiple users | URL to an HTTP endpoint | OAuth |
| Scope | Path |
|---|---|
| Project | .cursor/mcp.json, project-specific tools, commit it for the team |
| Global | ~/.cursor/mcp.json, tools available everywhere |
A QA-shaped local server: run it over stdio so the credential never leaves your machine, and pull the token from the environment rather than hardcoding it.
{
"mcpServers": {
"server-name": {
"command": "npx",
"args": ["-y", "mcp-server"],
"env": {
"API_KEY": "${env:QA_TRACKER_TOKEN}"
}
}
}
}
A remote server, HTTP or SSE, uses url and headers instead of command and args:
{
"mcpServers": {
"server-name": {
"url": "https://api.example.com/mcp",
"headers": {
"Authorization": "Bearer ${env:MY_SERVICE_TOKEN}"
}
}
}
}
| STDIO field | Required | Description |
|---|---|---|
type | Listed as required | Server connection type, "stdio". The docs list it as required, yet none of their own mcp.json examples include it |
command | Yes | Command that starts the server. Must be on your system path or contain its full path |
args | No | Array of arguments passed to the command |
env | No | Environment variables for the server |
envFile | No | Path to an environment file, for example ".env" or "${workspaceFolder}/.env" |
envFile is STDIO only. Remote HTTP and SSE servers do not support it. For those, use config interpolation with environment variables set in your shell profile or system environment. Interpolation resolves in command, args, env, url, headers and auth values only, using ${env:NAME}, ${userHome}, ${workspaceFolder}, ${workspaceFolderBasename}, ${pathSeparator} and ${/}. Put a variable anywhere else in the file and it stays a literal string.Available Tools are used when relevant, including in Plan Mode. You can also ask for a tool by name or just describe what you need.Cmd+Shift+U) by selecting MCP Logs.stdio transport. "MCP servers can access external services and execute code on your behalf. Always understand what a server does before installation."That covers everything the desktop app gives you. The same rules, skills, MCP servers and worktrees also run from a terminal, which is where QA automation actually lives, so tab 6 takes the agent into CI.
The Cursor CLI is the same agent without the editor, and it is the piece a tester can put in a pipeline. This tab is the reference: install, modes, every flag you will use, subcommands, slash commands, headless output for CI, the permission tokens that stop it doing something stupid, and where the config actually lives.
agentagent, not cursor. The product is the Cursor CLI, the binary you type is agent.agent login for interactive use. For scripts, export CURSOR_API_KEY or pass --api-key <key>.# shell - macOS, Linux, WSL
curl https://cursor.com/install -fsS | bash
# shell - Windows PowerShell
irm 'https://cursor.com/install?win32=true' | iex
# shell - first run
agent
agent "refactor the auth module to use JWT tokens"
agent -p "find and fix performance issues"
.cursor/rules and are loaded and applied automatically based on their configuration. The CLI also reads AGENTS.md and CLAUDE.md at the project root, if present, and applies them as rules alongside .cursor/rules.mcp.json, from .cursor/mcp.json or ~/.cursor/mcp.json, so the servers you set up in tab 5 are already there.| Mode | What it does | How to enter |
|---|---|---|
| Agent | Full access to all tools for complex coding tasks | Default, no --mode value needed |
| Plan | Design your approach before coding, agent asks clarifying questions | Shift+Tab, /plan, --plan, --mode=plan |
| Ask | Read-only exploration without making changes | /ask, --mode=ask |
Shift+Tab rotates between Agent, Plan and Ask, the same gesture as the IDE./debug slash command. It is not a --mode value.Ctrl+R reviews changes, i adds follow-up instructions, arrow keys scroll and switch files. @ selects files and folders into context, /summarize frees context window space.Global options work with any command.
| Flag | Value | What it does |
|---|---|---|
-p, --print | none | Print responses to console, for scripts or non-interactive use. Has access to all tools, including write and shell |
--output-format | text, json, stream-json | Output format, only works with --print. Default text |
--stream-partial-output | none | Stream partial output as individual text deltas. Only works with --print plus stream-json |
--resume [chatId] | optional chat id | Resume a chat session |
--continue | none | Continue the previous session, alias for --resume=-1 |
--model <model> | model | Model to use |
--mode <mode> | plan, ask | Set agent mode. Agent is the default when no mode is specified |
--plan | none | Start in plan mode, shorthand for --mode=plan |
--list-models | none | List all available models |
-f, --force | none | Force allow commands unless explicitly denied |
--yolo | none | Alias for --force |
--sandbox <mode> | enabled, disabled | Set sandbox mode |
--approve-mcps | none | Automatically approve all MCP servers |
--trust | none | Trust the workspace without prompting. Headless mode only |
--workspace <path> | path | Workspace directory to use |
-w, --worktree [name] | optional name | Run in a new Git worktree under ~/.cursor/worktrees/<reponame>/<name>. A name is generated if you omit it |
--worktree-base <branch> | branch or ref | Branch or ref to base the new worktree on. Default is current HEAD |
--skip-worktree-setup | none | Skip running worktree setup scripts from .cursor/worktrees.json |
--api-key <key> | key | API key for authentication. CURSOR_API_KEY does the same job |
-H, --header <header> | Name: Value | Add a custom header to agent requests. Can be used multiple times |
--plugin-dir <path> | path | Load a local plugin directory. Can be specified multiple times |
-v, --version | none | Output the version number |
-h, --help | none | Display help for command |
--output-format only works with --print. --stream-partial-output only works with --print plus stream-json. --trust is headless mode only. If a CI job is silently producing plain text when you asked for JSON, check that -p is actually there.| Command | What it does | Usage |
|---|---|---|
login | Authenticate with Cursor | agent login |
status | View authentication status. whoami is an alias, both take --format text|json | agent status |
models | List available models for this account | agent models |
mcp | Manage MCP servers | agent mcp |
worker | Start a private cloud worker that runs agents in your environment | agent worker start |
ls | Open previous chats and resume one | agent ls |
resume | Resume the latest chat session | agent resume |
create-chat | Create a new empty chat and return its ID | agent create-chat |
generate-rule | Generate a new Cursor rule with interactive prompts. rule is an alias | agent generate-rule |
install-shell-integration | Install shell integration to ~/.zshrc | agent install-shell-integration |
update | Update Cursor Agent to the latest version | agent update |
agent mcp has its own subcommands, all useful before you trust a server in CI: login <identifier>, list, list-tools <identifier>, enable <identifier>, disable <identifier>. Run list-tools first so your permission tokens name real tools.agent create-chat returns an ID, which is what makes a scripted multi-step job resumable with --resume.uninstall-shell-integration removes it from ~/.zshrc again.These are typed inside an interactive session, never in your shell.
| Group | Commands |
|---|---|
| Mode and model | /model [filter] (press Tab to edit), /plan [prompt], /ask, /debug [prompt], /max-mode |
| Execution and safety | /run-everything [on|off|status] (alias /auto-run), /sandbox, /shell [command] (aliases /sh, /run) |
| Session control | /clear (aliases /new, /new-chat, /newchat), /resume, /fork, /rename <name>, /rewind |
| Context | /summarize (alias /compress), /copy, /copy-request-id, /copy-conversation-id |
| Tools and plugins | /mcp [list|list-tools] [identifier], /plugin [subcommand], /bedrock [subcommand] |
| Display | /vim, /line-numbers, /show-thinking, /status-indicators |
| Config and terminal | /config, /setup-terminal |
| Housekeeping | /logs, /update, /about, /help [command], /feedback <message>, /open (alias /cursor), /logout, /quit, /exit |
Shift+Enter inserts a newline instead of submitting, and works in iTerm2, Ghostty, Kitty, Warp and Zed. Under tmux, use Ctrl+J. Ctrl+J and Option+Enter are the universal alternatives that work in all terminals. Ctrl+D exits and requires a double press. ArrowUp cycles through previous messages. When a command needs sudo, Cursor shows a masked prompt and the password flows straight to sudo over a secure IPC channel, so the model never sees it.-p or --print. This prints the response to the console and is the documented path for scripts and CI pipelines.text for a human reading the job log, json when you want to pull the answer out with jq, stream-json when you want to watch tool calls as they happen.export CURSOR_API_KEY=your_api_key_here on macOS, Linux and WSL, or $env:CURSOR_API_KEY = "your_api_key_here" in PowerShell. You can also pass --api-key. Store it as a CI secret, never in the repo.--force as read only. The docs are inconsistent here: the headless page says that without --force changes are only proposed and not applied, while the parameter reference says -p, --print has access to all tools including write and shell. What is unambiguous is that combining --print with --force (or its alias --yolo) is the documented way to modify files in scripts. Until the docs reconcile the rest, get your read-only guarantee from a committed deny list, not from a flag you left off.--force still respects deny. The flag forces allow "unless explicitly denied", so the deny list in your permissions file is the real guardrail, not the flag.# commit this FIRST, at .cursor/cli.json. Without it, --force means write and shell.
{
"permissions": {
"allow": ["Read(reports/**)", "Read(tests/**)", "Write(reports/**)"],
"deny": ["Write(src/**)", "Write(tests/**)", "Shell(rm)", "Shell(git)", "WebFetch(*)"]
}
}
#!/bin/bash
# shell - triage-failures.sh, run this after the test job fails
# Safe only because the deny list above is committed. The prompt is not the guard.
echo "Triaging failing tests..."
agent -p --force --output-format text "Read every JUnit XML file under reports/ and the spec files each failure names. For each failing test, classify it as product bug, test bug or environment issue, quote the assertion that failed, and write the table to reports/triage.md. Do not modify any test or source file."
if [ $? -eq 0 ]; then
echo "Triage written to reports/triage.md"
else
echo "Triage failed"
exit 1
fi
# shell - other documented invocations
agent -p "What does this codebase do?"
agent -p --force "Refactor this code to use modern ES6+ syntax"
agent -p --output-format json "Analyze this image and provide a detailed description: $IMAGE_PATH" | jq -r '.result'
agent -p --force --output-format stream-json --stream-partial-output "Summarize the failing specs in reports/"
--force --trust to a pipeline. Print mode has access to all tools, including write and shell. --trust removes the workspace prompt and --approve-mcps automatically approves all MCP servers. That combination on a runner that checks out untrusted pull request branches is how a prompt injection becomes a shell command. Pair every one of those flags with a committed deny list.stream-json.type values are system, assistant, tool_call and result.system with .subtype == "init" carries .model, which is what you log so a flaky run can be traced back to a model choice.assistant events split two ways: streaming deltas have timestamp_ms and no model_call_id, while buffered flushes before tool calls and at end of turn carry model_call_id. Text sits at .message.content[0].text.tool_call has a .subtype of started or completed. Payloads include .tool_call.writeToolCall.args.path, .tool_call.writeToolCall.result.success.linesCreated, .tool_call.writeToolCall.result.success.fileSize, .tool_call.readToolCall.args.path and .tool_call.readToolCall.result.success.totalLines. Watching writeToolCall.args.path is a cheap audit of exactly which files a CI agent touched.result carries .duration_ms. With --output-format json instead, the final answer is at .result.Permissions are set as permission tokens in ~/.cursor/cli-config.json (global) or <project>/.cursor/cli.json (project-specific).
| Type | Format | Notes |
|---|---|---|
| Shell commands | Shell(commandBase) | commandBase is the first token in the command line. Supports glob patterns and an optional command:args syntax, for example Shell(curl:*) |
| File reads | Read(pathOrGlob) | Read access to files and directories, supports glob patterns |
| File writes | Write(pathOrGlob) | Write access to files and directories, supports glob patterns |
| Web fetch | WebFetch(domainOrPattern) | Which domains the agent may fetch with the web fetch tool |
| MCP tools | Mcp(server:tool) | server comes from mcp.json, tool is the tool name, * is a wildcard |
**, * and ?. Relative paths are scoped to the current workspace, absolute paths can target files outside the project.* matches all domains, *.example.com matches subdomains such as docs.example.com and api.example.com, and example.com matches that exact domain only.WebFetch allowlist entry, each fetch prompts for approval, which will hang a headless job.A permissions block a tester can commit: the agent may run the suite and read the code, but it can only write into reports/, and it can never touch secrets or delete anything.
{
"permissions": {
"allow": [
"Shell(ls)",
"Shell(git)",
"Shell(npm)",
"Read(src/**/*.ts)",
"Read(tests/**)",
"Read(reports/**)",
"Write(reports/**)",
"WebFetch(docs.github.com)",
"Mcp(*:search)"
],
"deny": [
"Shell(rm)",
"Read(.env*)",
"Write(**/*.key)",
"Write(**/.env*)",
"Write(src/**)"
]
}
}
| Type | Platform | Path |
|---|---|---|
| Global | macOS and Linux | ~/.cursor/cli-config.json |
| Global | Windows | $env:USERPROFILE\.cursor\cli-config.json |
| Project | All | <project>/.cursor/cli.json |
deny list travels with the repo, but the approval mode, the sandbox setting and the model do not: they are per machine, and per runner. Note also that the project file is cli.json while the global one is cli-config.json. They are not the same filename.version (number), editor.vimMode (boolean), permissions.allow (string array), permissions.deny (string array).approvalMode, sandbox.mode, sandbox.networkAccess, notifications, rewind, display.showThinkingBlocks, and the two attribution flags attribution.attributeCommitsToAgent and attribution.attributePRsToAgent, which add a "Made with Cursor" trailer to Agent commits and a footer to Agent PRs and default to true..bad and recreates them. If the CLI misbehaves on startup, move the file aside and restart: mv ~/.cursor/cli-config.json ~/.cursor/cli-config.json.bad on macOS and Linux, or rename the file at $env:USERPROFILE\.cursor\cli-config.json on Windows.CURSOR_CONFIG_DIR points at a custom directory. On Linux and BSD, XDG_CONFIG_HOME puts the config at $XDG_CONFIG_HOME/cursor/cli-config.json.HTTP_PROXY, HTTPS_PROXY and NODE_USE_ENV_PROXY=1 before running, plus NODE_EXTRA_CA_CERTS if the proxy does SSL inspection. Some enterprise proxies do not support HTTP/2 bidirectional streaming, and network.useHttp1ForAgent: true switches agent connections to HTTP/1.1 with Server-Sent Events.-w or --worktree [name] keeps the agent off your checkout. It runs in a new Git worktree created under ~/.cursor/worktrees/<reponame>/<name>, alongside worktrees created from the editor. Omit the name and Cursor generates one..cursor/worktrees.json and can be skipped with --skip-worktree-setup. --worktree-base <branch> bases the worktree on a branch or ref instead of current HEAD.--workspace <path> when you need an explicit repository root, otherwise the CLI uses the current working directory. --worktree only changes where the agent makes file edits inside that project.# shell
agent --worktree "upgrade the test runner and fix any broken snapshots"
agent --workspace ~/src/my-app --worktree auth-fix "fix the flaky auth test and open a PR"
# in-session message - prefix with & to hand off to a Cloud Agent
& refactor the auth module and add comprehensive tests
& prefix moves the conversation to the cloud. Prepend it to any message to push the conversation to a Cloud Agent mid-session, then pick it up on web or mobile at cursor.com/agents. Useful when a triage turns into a long refactor you do not want holding your terminal.y or reject with n. That prompt is exactly what --force removes, which is why the deny list matters more in CI than on your laptop./review and /review-bugbot are not available in the CLI. Run pre-push reviews from the desktop app or from cursor.com/agents.Which is the natural handoff: once the agent runs unattended, review has to become someone else's job. Tab 7 puts Bugbot, cloud agents and automations on review duty.
Everything up to here ran on your machine, at your pace, with you watching. This tab is the other half of the job: review that happens without you, agents that run in someone else's VM, and QA chores that fire on a schedule. Bugbot guards the pull request, cloud agents do the long jobs, automations put the recurring work on a timer.
cursor.com/agents.cursor.com/dashboard/bugbot. Supported providers: GitHub (including GitHub Enterprise Server), GitLab (including GitLab Self-Hosted), and Bitbucket (including Bitbucket Data Center).| Trigger | Where | Effect |
|---|---|---|
| Automatic | Nothing to type | Runs on every PR update once the repository is enabled |
cursor review | PR comment | Manually trigger a Bugbot review on any PR |
bugbot run | PR comment | Same as above, alternate phrasing |
cursor review verbose=true | PR comment | Trigger with verbose mode for detailed logs and a request ID |
bugbot run verbose=true | PR comment | Same, alternate phrasing. This is step one of the documented troubleshooting order |
@cursor remember [fact] | PR comment | Teach Bugbot a rule inline. It saves the fact as a learned rule and applies it to future reviews |
/review-bugbot | Agent session | Run Bugbot from your agent before you push the code |
/review | Agent session | Selects and runs the appropriate code review agent |
.cursor/BUGBOT.md. Bugbot always includes the root file, plus any additional BUGBOT.md files it finds while traversing upward from the changed files. A backend/.cursor/BUGBOT.md applies only when backend files are in the diff.eval() and exec(), blocking disallowed OSS licenses when dependency files change, flagging deprecated lifecycle methods, requiring tests for backend changes, and disallowing TODO and FIXME comments.BUGBOT.md files including nested ones, then User Rules.cursor.com/dashboard/bugbot/repository-rules. Cursor generates rules from your team's activity on that repository, or backfills from repository history, and enables or disables them as it learns. Manual rules live in the same dashboard with a Name, Rule content, and optional Scoped paths such as src/components/**.A QA-shaped rules file. Every clause below maps to a documented capability: blocking versus non-blocking, title and body, assignment, labels, autofix suggestions, auto-resolve.
# .cursor/BUGBOT.md
## Weakened assertions are blocking
If a diff replaces an exact assertion with a weaker one (a truthiness check in place of a
value check, a removed expect, an assertion moved inside a try block), raise a blocking Bug.
Title it "Assertion weakened" and quote the old and the new assertion in the body.
Assign it to the pull request author and apply the label "test-quality".
## Backend changes need tests
If any file under src/api/ or src/services/ changes and no file under tests/ changes in the
same pull request, raise a non-blocking Bug titled "Backend change with no test".
Suggest an autofix snippet containing a skeleton test for the changed function.
## No skipped or focused tests reach the base branch
Flag any added test.skip, test.only, it.only or xit as a blocking Bug.
Auto-resolve the finding once the line no longer appears in the diff.
## Hard waits are a smell, not a fix
Flag any added fixed-duration sleep or timeout inside tests/ as a non-blocking Bug.
Explain in the body which condition should be waited on instead. Apply the label "flaky-risk".
## No TODO or FIXME in shared test helpers
Raise a non-blocking Bug on any added TODO or FIXME comment under tests/helpers/.
Apply the label "cleanup" and assign it to the pull request author.
/review-bugbot reviews branch changes, not just the last edit. By default it covers every change relative to the base branch, committed and uncommitted. Ask it to review only uncommitted changes when you want narrower feedback./review-bugbot stores the git patch ID of the diff it reviewed. When Bugbot on your source control provider later sees a diff with the same patch ID, it skips the review and leaves a comment saying it already reviewed that diff. Run it locally, open the PR with the same diff, and the remote review does not repeat./review and /review-bugbot are available in Cursor desktop builds and at cursor.com/agents. CLI support is documented as not yet available. Plan your CI review step around the PR trigger or the review API, not around the slash command.Bugbot publishes a GitHub check named Cursor Bugbot and a Bitbucket build status with key cursor-bugbot. What that check reports is not what most people assume.
| Conclusion | When it is emitted |
|---|---|
success | No issues found, and no unresolved Bugbot comments from earlier runs |
neutral | Issues found, or the run was cancelled by a newer commit, or an internal error. This is the default conclusion when Bugbot reports findings. |
failure | Issues found and the check is configured to fail on unresolved issues |
skipped | Never. Bugbot does not emit this conclusion |
Cursor Bugbot to branch protection makes Bugbot run before merge. It does not make findings block the merge, because findings default to neutral and a neutral check is not a failing check. If you want unresolved findings to stop a merge, you have to enable fail-on-unresolved-issues behavior where it is available for your organization. A quality gate that always goes green is worse than no gate, because your team stops reading it. When Autofix is on, GitHub may also show a separate Cursor Bugbot Autofix check, which only ever reports success or neutral..cursor/environment.json. The dashboard shows which environment each agent used, with details and version history.| Start it from | How |
|---|---|
| Cursor Web | cursor.com/agents on any device. On Android, open it in Chrome and tap Install App for a PWA |
| Cursor Desktop | Select Cloud in the dropdown under the agent input |
| Cursor for iOS | Start and manage agents from the iOS app |
| Slack | Use the @cursor command |
| GitHub or Bitbucket | Comment @cursor on a GitHub PR or issue, or on a Bitbucket PR |
| Linear | Use the @cursor command |
| API | Kick off an agent programmatically |
| Cursor CLI | Prepend & to any message to hand the conversation off mid-flow, then pick it up on web or mobile |
# in an interactive CLI session, hand the rest of the job to the cloud
& run the full regression suite against staging and attach screenshots for every failure
.cursor/hooks.json (plus team and enterprise hooks on Enterprise plans), but user-level hooks from ~/.cursor/hooks.json never load because the VM cannot see your home directory, and hooks do not run during early read-only exploratory turns. Sharing an agent URL is view-only, and viewers must connect their own source control account and have verified access to the repository. Secrets are workspace and team scoped, added at cursor.com/dashboard/cloud-agents. Snapshots save the base environment. .env.local files are saved only if you include them at snapshot creation, so the Secrets tab is the recommended route for environment variables.cursor.com/automations, from a Cursor Marketplace template, or with the /automate skill in a local agent session, where you describe the workflow in plain language and Cursor configures the triggers, instructions, and tools for you.| Source | Triggers |
|---|---|
| Scheduled | Recurring schedule from preset options or a cron expression. A scheduled run may start late but never earlier than the indicated time |
| Source control core | Supported by every connected provider (GitHub, GitLab, and Bitbucket Cloud only, not Bitbucket Server or Data Center): Draft opened, Pull request opened, Pull request pushed, Pull request merged, Push to branch, Comment added |
| GitHub extras | Pull request label changed, Issue label changed, CI completed, Issue comment, PR review comment, PR review submitted, Review thread updated, Workflow run completed |
| GitLab extras | Pull request label changed, Pull request approved |
| Bitbucket extras | Pull request approved |
| Slack | New message in channel, Emoji reaction, Channel created |
| Webhook | A private HTTP endpoint you POST to. For internal systems, CI pipelines, and monitoring tools |
| Linear | Issue created, Status changed, End of cycle |
| Sentry | Issue created, Issue updated, Any issue event |
| PagerDuty | Incident triggered, Incident acknowledged, Incident resolved, Any incident event |
git, memory, and other tools to identify domain experts.MEMORIES.md by default) outside the working filesystem. Enabled by default, editable and deletable from the UI. Treat them as untrusted input: memories persist, so a poisoned note can steer future runs.cursor; team-scoped automations open PRs as cursor while private ones open PRs as your account; Slack messages come from the Cursor bot.BUGBOT.md rules: Bugbot judges the code, this one judges the coverage..cursor/environment.json, capture a screenshot or recording, and open a PR containing a failing regression test plus the artifact. You arrive in the morning to a red test that proves the bug instead of a paragraph describing it.Bugbot guards the PR, cloud agents do the heavy runs, and automations handle the recurring work. None of that matters until it is one continuous habit.
A login test in your Playwright suite has failed twice and passed on retry both times, so nobody filed it. Here is that test going from noticed to merged fix, using one artifact from every tab on this page, in the order you would actually touch them.
AGENTS.md at the root stating the framework, the runner command, the fixture conventions, and the assertion style, plus one scoped .cursor/rules/flaky-triage.mdc with globs: tests/**/*.spec.ts saying how this team handles waits and retries. Without this the agent invents your conventions from the first file it opens. See rules for the frontmatter that decides when each file loads.autoRun.block_instructions to .cursor/permissions.json in plain English ("Every command that drops or truncates a database table should go through approval first", "Every command that pushes or force-pushes should go through approval first"), and add a beforeShellExecution hook in .cursor/hooks.json for the destructive shapes you never want to argue about. Set failClosed: true on that hook, because hooks fail open by default and a crashed guard that lets the command through is not a guard. The run modes and hooks tabs have the exact shapes.Shift+Tab to Plan Mode and describe the symptom, not the fix: "the login spec passes on retry, find out why". The agent asks clarifying questions, researches the codebase, and produces a plan you can edit before a single line changes. Click Save to workspace so the plan is a reviewable artifact rather than a file in your home directory. If the build later goes sideways, revert and sharpen the plan; do not patch a wrong build with follow-up prompts./worktree reproduce the flaky login test gives the agent its own checkout with its own dependencies, so a half-finished experiment never blocks your main branch. Commit .cursor/worktrees.json with the setup commands (install, copy the env file from $ROOT_WORKTREE_PATH, run migrations) so every new worktree is usable on arrival. Do not symlink dependencies in; use a fast package manager instead.@browser plus the login URL, with instructions to run the flow ten times, watch the console and the network panel, and screenshot the state at the moment of failure. This is where flaky login tests usually confess: a race between a token refresh call and the first assertion, visible in network traffic and invisible in the test log..cursor/skills/flaky-test-triage/SKILL.md with paths scoped to your spec files, so the next person does not redo it. Remember the folder name must match the name in the frontmatter. See skills..cursor/agents/verifier.md with readonly: true runs in its own context window, cannot make file edits or run state-changing shell commands, and confirms the fix holds without any chance of quietly "helping" by adjusting the test. Give it everything it needs in the prompt: subagents start with a clean context and see none of your conversation./agent-review in the agent window, or the Source Control tab to compare all local changes against your main branch rather than only the latest edit. Pick Deep depth for logic changes, Quick for a formatting pass. Agent Review reads your BUGBOT.md files, so it enforces the same rules the PR gate will./review-bugbot before you push; the patch-id sync means the identical diff will not be reviewed twice on the PR. Your .cursor/BUGBOT.md is what catches the fix that "fixes" the flake by weakening the assertion. Configure fail-on-unresolved-issues if you want findings to actually stop a merge, because findings default to a neutral check..cursor/cli.json so the pipeline's allowances live in the repo and not in one engineer's head. Only permissions can be configured at the project level; every other CLI setting is global. See the CLI in CI.# shell (macOS, Linux, WSL): the headless verification step in your pipeline
# PowerShell: $env:CURSOR_API_KEY = "your_api_key_here"
# --force allows anything the committed .cursor/cli.json deny list does not block.
# Commit that deny list before this line, not after the first incident.
export CURSOR_API_KEY=your_api_key_here
agent -p --force --output-format text "Run the login spec ten times, and write every failure with its console and network context to flaky-report.txt"
# in-session slash commands, in the order this workflow uses them
/worktree reproduce the flaky login test and capture a trace
/verifier confirm the login spec passes ten consecutive runs without a retry
/agent-review
/review-bugbot
This is the whole page as a directory listing. If you copy one thing from here, copy this table.
| Path | What it does | Who it serves |
|---|---|---|
AGENTS.md | Plain markdown instructions, no frontmatter. Works at the root and in subdirectories, where nested files combine with their parents and the more specific one wins | Every agent that touches the repo, and every new joiner who reads it as onboarding |
.cursor/rules/*.mdc | Scoped rules with description, globs, and alwaysApply frontmatter deciding when each one loads. A .md file here is silently ignored | The reviewer who is tired of leaving the same comment |
.cursor/skills/<name>/SKILL.md | A packaged procedure with optional scripts/, references/, and assets/. The folder name must match the name field | The next tester who inherits the flow and should not rediscover it |
.cursor/agents/*.md | Subagent definitions with description, model, readonly, and is_background. The description is what decides whether delegation happens at all | Anyone who wants verification done by something that cannot edit the code |
.cursor/hooks.json | Lifecycle gates over the agent loop. Project hooks run from the project root, so paths look like .cursor/hooks/guard.sh | The QA lead who needs policy that does not depend on anyone remembering it |
.cursor/mcp.json | MCP servers for this project, in stdio, SSE, or Streamable HTTP form, with interpolation for secrets | Testers who need the tracker, the observability tool, or the test-data service in-session |
.cursor/permissions.json | autoRun.allow_instructions and autoRun.block_instructions, written in plain English. Merges with your personal file. A team dashboard configuration overrides both | Everyone sharing the repo, especially on the day someone runs an agent against production config |
.cursor/sandbox.json | What a sandboxed terminal command may reach: network domains, extra readable and writable paths. A different job from permissions.json, and neither is required to get started | Teams with an internal package registry or an air-gapped dependency mirror |
.cursor/worktrees.json | setup-worktree plus the OS-specific variants, as command arrays or script paths, with $ROOT_WORKTREE_PATH for copying files across | Anyone running more than one agent on the same repo at once |
.cursor/environment.json | The cloud agent environment: agent-led setup, a saved snapshot, or a Dockerfile | Cloud agents, automations, and the incident-to-repro pipeline |
.cursor/cli.json | Project-level CLI permission tokens such as Shell(npx), Write(tests/**), Read(.env*) under deny. Permissions are the only thing configurable per project | CI, and the reviewer of the pipeline that runs the agent |
.cursor/BUGBOT.md | Repository review rules. The root file always applies, and nested files apply when files under them change. Read by both Bugbot on the PR and Agent Review locally | Every reviewer, human or otherwise, on every pull request |
.cursorignore | Blocks agent access to specific files, and hides them inside the sandbox too | Anyone whose repo contains fixtures, dumps, or config the model has no business reading |
AGENTS.md and a Run Mode. That is the whole day-one setup. Auto-review is the recommended mode and needs no configuration file to work well..mdc file for the convention that actually got broken. Add an autoRun.block_instructions line for the command that actually scared you. Add two or three BUGBOT.md clauses for the review comments you actually keep leaving.readonly: true subagent. Start with two or three focused subagents, not a directory of them: fifty vague "helps with coding" agents are documented as ineffective, and running five subagents in parallel costs roughly five times the tokens.cli.json for CI, environment.json, and automations come after the manual loop is boring. Automating a workflow you have not yet stabilised just gives you a scheduled version of your confusion.Read the safety story on this page as risk reduction, not as a control. Run Modes are described in the docs as best-effort guardrails rather than a hard security boundary, and Auto-review is called out by name as not a security boundary: its classifier can allow a call you would have blocked, and it can block a call you would have allowed. Both directions are real failure modes, and the second one is the one that tempts people into Run Everything. Hooks fail open unless you set failClosed: true. The browser origin allowlist does not stop link clicks, redirects, or JavaScript navigation. Team Rules can be marked as enforced and used in compliance workflows, and the docs still say plainly that AI guidance should not be your only security control. A model asked to behave is not an access control, and a check that reports neutral is not a merge gate.
What all of this buys you is leverage: the agent grounds itself in your conventions, isolates its experiments, reproduces the failure, gates its own diff, and repeats the boring part on a schedule. What it does not buy you is the last decision. Bugbot finds a weakened assertion; whether the fix is acceptable is a judgement about your product, your users, and your risk. The tester still owns the acceptance decision, and nothing on this page should be built in a way that quietly takes it away.