Key facts
- permissions.json lives at ~/.cursor/permissions.json. It is a global per-user file: Cursor's reference states there is no per-project override, so a repo-level .cursor/permissions.json is not read.
- autoRun.allow_instructions and autoRun.block_instructions are arrays of plain-English sentences that steer the Auto-review classifier. They are steering, not enforcement: allowed shapes still pass the safety check and blocked shapes are held for review, not banned.
- mcpAllowlist (server:tool patterns) and terminalAllowlist (command prefixes) are deterministic. When a key is present it fully replaces the in-app allowlist for that type - including an empty array, which yields an empty allowlist rather than falling back.
- Precedence is strict: team admin dashboard controls override permissions.json, which overrides the IDE settings UI.
- None of this is a security boundary. Cursor's own docs say allowlists are best-effort convenience. Treat the file as a productivity control and put deterministic gates around irreversible actions.
The full schema at a glance
permissions.json configures two different mechanisms that both act on agent tool calls: deterministic allowlists that let matching MCP tools and terminal commands auto-run without approval, and natural-language instructions that steer the Auto-review classifier. All fields are optional and unknown keys are ignored.
{
// ~/.cursor/permissions.json (JSONC: comments are allowed)
// Steers the Auto-review classifier (natural language, not patterns)
"autoRun": {
"allow_instructions": [
"Read-only inspections of build artifacts under ./dist are fine."
],
"block_instructions": [
"Always pause delete operations so I get a chance to review them."
]
},
// Deterministic allowlists for auto-run (override the in-app lists)
"mcpAllowlist": [
"github:*",
"linear:list_issues"
],
"terminalAllowlist": [
"git",
"npm",
"cargo build",
"cargo test"
]
}| Key | Type | What it does |
|---|---|---|
autoRun.allow_instructions | string[] | Natural-language call shapes the Auto-review classifier should lean toward allowing. |
autoRun.block_instructions | string[] | Natural-language call shapes the classifier should hold for human review. |
mcpAllowlist | string[] | server:tool patterns that may auto-run without approval. Overrides the in-app MCP allowlist when present. |
terminalAllowlist | string[] | Command prefixes that may auto-run without approval. Overrides the in-app terminal allowlist when present. |
The allowlist keys are documented in Cursor's permissions.json reference; the autoRun instruction fields are documented in the June 4, 2026 SDK changelog. That split is why the schema is hard to find with one search.
File location and load behavior
The file lives in your Cursor data folder: ~/.cursor/permissions.json. It is global and per-user, applies to all workspaces, and per Cursor's reference there is no per-project override - a .cursor/permissions.json checked into a repo is not read. It is loaded on startup and re-read automatically whenever it changes. JSONC comments are supported, and non-string entries inside the allowlist arrays are silently dropped.
The allowlists only matter when auto-run is enabled ("Auto-Run in Sandbox" or "Run Everything"). In "Ask Every Time" mode they are not consulted. The autoRun instruction fields matter when Auto-review is the active run mode - in the IDE via Run Mode settings, or headless in the SDK via local.autoReview.
autoRun.allow_instructions and autoRun.block_instructions
Auto-review, introduced with Cursor 3.6 on May 29, 2026, routes Shell, MCP, and Fetch tool calls through an LLM classifier that decides which calls run automatically and which are held back. The June 4, 2026 SDK release brought the same gate to headless runs via local.autoReview. Both are steered by the autoRun object: allow_instructions describes call shapes the classifier should lean toward allowing, and block_instructions describes the ones to hold for review. Entries are free-form sentences, written the way you would brief a teammate.
{
"autoRun": {
"allow_instructions": [
"Read-only inspections of build artifacts under ./dist are fine."
],
"block_instructions": [
"Always pause delete operations so I get a chance to review them."
]
}
}Treat both fields as steering, not enforcement. The classifier is probabilistic: an allowed shape still passes through the safety check, a blocked shape is held rather than banned, and a misclassified allow on a destructive call still causes harm. Our Cursor SDK 3.7 PSF assessment covers what this means for unattended CI and cron automation.
mcpAllowlist patterns
Each entry is a server:tool string, matched case-insensitively. The server name is the key from your mcp.json. Entries without a : are ignored.
| Pattern | Matches |
|---|---|
my-server:my_tool | Exactly my_tool from the server named my-server |
my-server:* | All tools from my-server |
*:my_tool | my_tool from any server |
*:* | All tools from all servers |
my-server:list_* | Glob inside names: list_issues, list_users, ... |
{
"mcpAllowlist": [
"github:*", // all tools from the github server
"linear:list_issues" // one tool from the linear server
]
}terminalAllowlist patterns
Each entry is a command or command-prefix string. Matching is case-sensitive and uses prefix semantics: git matches git status but not gitk.
| Pattern | Matches |
|---|---|
git | Any command starting with git (git status, git diff) - but not gitk |
git status | Only git status and anything starting with "git status " |
npm:install* | npm install, npm install express, ... (the : separates base command from an args glob) |
{
"terminalAllowlist": [
"git", // any command starting with git
"git status", // only git status (prefix match)
"npm:install*" // npm install, npm install express, ...
]
}Precedence and the gotchas that bite in production
Allowlists can come from three places, in strict priority order: team admin dashboard controls, then permissions.json, then the IDE settings UI. When the file defines an allowlist key, that key's value fully replaces the corresponding in-app allowlist - entries from Cursor Settings are not merged in, and the in-app editor becomes read-only for that type.
Three behaviors are easy to get wrong. First, the empty-array trap: a key set to [] means an empty allowlist for that type, not a fallback to IDE settings; only a missing or unparseable key falls back. Second, the keys are independent - defining only mcpAllowlist leaves the terminal allowlist under IDE control. Third, none of this is a security boundary: Cursor's reference explicitly calls allowlists best-effort convenience.
For teams running agents against production systems, that last point is the whole game. Keep permissions.json in configuration management, audit it in CI, route block_instructions changes through change control, and gate irreversible actions with deterministic controls outside the agent - PR review, change tickets, and scoped credentials. The Production Safety Framework maps these controls, and our Cursor 3.6 Auto-review assessment rates how far the classifier gate actually gets you.
Relevant PSF domains
FAQ
Does <repo>/.cursor/permissions.json work per project?
No. Cursor's permissions.json reference documents a single global file at ~/.cursor/permissions.json that applies to all workspaces, and states there is no per-project override. Team-level control comes from the admin dashboard, which outranks the file.
Do allow_instructions guarantee a call runs without approval?
No. The June 4, 2026 changelog describes both fields as steering for the classifier: calls matching allow_instructions still go through the safety check, and the classifier can still hold them. If you need a guarantee, use the deterministic allowlists - and even those are documented as best-effort, not a security boundary.
What is the difference between the allowlists and autoRun instructions?
mcpAllowlist and terminalAllowlist are deterministic pattern matches that let calls run without approval in auto-run modes. autoRun.allow_instructions and block_instructions are natural-language guidance to the LLM classifier used by Auto-review. Patterns are predictable; instructions are probabilistic.
Does permissions.json apply to the Cursor CLI?
No. The CLI has a separate permissions system with its own reference documentation.
When does the file take effect?
It is read on startup and re-read automatically when it changes. The allowlists are only consulted when auto-run is enabled; in Ask-Every-Time mode they are ignored. JSONC comments are supported, unknown keys are ignored, and non-string array entries are silently dropped.
Sources
- Cursor Docs: permissions.json reference
- Cursor Changelog (June 4, 2026): auto-review and autoRun instructions for the SDK
- Cursor Docs: terminal Run Mode (Auto-review)
- Cursor Docs: CLI permissions (separate system)
- PAI: Cursor SDK 3.7 PSF assessment (headless auto-review in CI)
- PAI: Cursor 3.6 Auto-review PSF assessment (classifier run mode)
- Production AI Institute: Production Safety Framework
Turn the release into proof you can use.
Use the PSF to understand the control change, then choose the proof path that matches your role. Most readers should start with a personal credential; buyers and MSPs can branch from there.
Use the foundation credential when this change exposes a judgement gap in production AI work.
For agent operations, monitoring, escalation, and workflow-control responsibility.
Use the MSP pack or team programme when the release creates a client or organisation conversation.