Cursor and Claude Code are the two AI coding agents most companies already run, usually both, usually on the same laptops, and usually without anyone in security having compared what each one can reach. Every comparison on the first page of Google is about which writes better code. This one is about the other question: where each agent keeps its permissions, how a developer turns the asking off, what each loads from files a repository can write, and what a security team should lock down first. It is written for the CISO or security architect who has just learned the count is two, not one, and it draws on the vendors' own documentation for every claim.
What each one is, in one paragraph
Cursor is an editor. It is a fork of VS Code with an agent built in, so it owns the window the developer works in, the terminal inside it, and the files in the open workspace. Claude Code is a command-line program. It runs in any terminal, inside any editor, on any machine with Node, and it works in whatever directory it was started in. Both read code, edit files, run shell commands and call tools over MCP. Both act with the developer's own account. That last fact is the whole reason a security team should care: whatever the developer can read, the agent can read, and on a real laptop that was forty-six credentials.
Where the configuration lives
Claude Code keeps its settings in JSON files with a documented order of precedence. From lowest to highest: the user file at ~/.claude/settings.json, the shared project file at .claude/settings.json (committed to the repository), the project-local file at .claude/settings.local.json, flags passed on the command line, and managed settings. Managed settings come from a managed-settings.json file at /Library/Application Support/ClaudeCode/ on macOS, /etc/claude-code/ on Linux or C:\ProgramData\ClaudeCode\ on Windows, from an MDM policy, or from the claude.ai console, and nothing set lower overrides them apart from a few exceptions where a stricter lower value still counts. A fifth file, ~/.claude.json, is written by the program itself and holds the sign-in session, MCP server configurations and per-project trust decisions.
Cursor keeps its settings in the editor's own settings, in .cursor folders and in hooks.json files. Project rules live in .cursor/rules as .mdc files, and Cursor also reads AGENTS.md, including nested ones in subdirectories. MCP servers are configured in .cursor/mcp.json in a project or ~/.cursor/mcp.json for everything. Hooks are in ~/.cursor/hooks.json for the user, .cursor/hooks.json in a project, and, for an enterprise, /Library/Application Support/Cursor/hooks.json, /etc/cursor/hooks.json or C:\ProgramData\Cursor\hooks.json.
The pattern is the same on both: a user layer, a repository layer, and an organisation layer. The repository layer is the one to watch, because a file in a cloned repository is written by whoever committed it.
How each one asks, and how developers stop it asking
Claude Code has named permission modes. In default mode it prompts on first use of each tool. acceptEdits auto-accepts file edits and common filesystem commands in the working directory. plan reads and explores but does not edit. auto approves tool calls after a background check that the action matches the request. dontAsk denies anything that would have prompted. bypassPermissions skips prompts except for a short list of actions no mode auto-approves. Beyond modes there are rules: an allow list, a deny list and an ask list, written as patterns such as Bash(npm run *), Read(./.env) or WebFetch(domain:example.com). When a developer answers a prompt with "Yes, and don't ask again", Claude Code saves the rule to .claude/settings.local.json at the root of the repository, and it applies to every future session in that repository.
That saved file is the standing-permissions story in one path. Each entry was a prompt somebody was tired of. Months later it is still there, and a rule like Bash(git push *) or Bash(rm *) removes the person from the loop for good.
Cursor asks for approval before running terminal commands and before using MCP tools by default, and lets the developer change that through run modes. There are three. Allowlist runs the actions on the developer's list without approval. Auto-review runs allowlisted calls immediately, runs other shell commands in a sandbox when it can, and sends the rest to a classifier that decides. Run Everything runs every tool call automatically. Cursor's documentation says plainly that auto-review is not a security boundary and that the classifier can allow a call the developer would have blocked. The same page describes run modes as best-effort guardrails.
The difference for a security team: Claude Code's off switches are keys in files with fixed paths, and a managed file can pin them. Cursor's are editor settings and, for enterprises, hooks the organisation deploys.
MCP servers
Both agents load MCP servers from files, and both load them from a repository.
Claude Code has three MCP scopes. Local and user servers are stored in ~/.claude.json. Project servers are in .mcp.json at the repository root, shared through version control. A project .mcp.json prompts for approval in an interactive session before its servers load, and since v2.1.196 the approval only takes effect in a trusted workspace. Non-interactive runs load them without prompting. The settings keys enableAllProjectMcpServers, enabledMcpjsonServers and disabledMcpjsonServers switch that per server. Transports are stdio for a local process, HTTP for a remote server, SSE, and WebSocket.
Cursor reads .cursor/mcp.json and ~/.cursor/mcp.json, supports stdio, SSE and streamable HTTP, asks for approval on each MCP tool call by default, and lets the developer pre-approve tools with an allowlist. Secrets go in through environment variables, referenced as ${env:NAME} in the config, which is the right advice and also the reason the sensor flags a token written directly into the file.
A stdio server is a program the agent starts on the machine with the developer's account. An HTTP server is a destination the agent talks to. Either one is a supply chain entry, and the MCP server security piece covers what to check on each. The point for this comparison is that a repository can add one to both agents, and only Claude Code's project scope has a documented approval step tied to workspace trust.
Hooks and rules as persistence
Both agents run hooks: shell commands or scripts that fire at points in the agent's lifecycle, with the developer's permissions. Claude Code's hook events include SessionStart, UserPromptSubmit, PreToolUse, PostToolUse, Stop and SessionEnd among more than thirty, configured in ~/.claude/settings.json, .claude/settings.json, .claude/settings.local.json, managed settings, plugins, skill frontmatter and subagent frontmatter. Cursor's include sessionStart, beforeShellExecution, beforeMCPExecution, beforeReadFile, afterFileEdit and stop, in the hooks.json files listed above. Cursor's documentation describes them as spawned processes that talk over stdio in JSON.
For a security team, a hook is two things. It is the mechanism ZYBE's own sensor uses to see the agent at all: the sensor installs into Claude Code's settings and into ~/.cursor/hooks.json, and the same script handles both contracts. And it is the cleanest persistence a malicious component could want: a command that runs on every session start, written to a file in a folder most people never open. The rule hook_persistence exists for that second case.
Rules files are the softer version of the same thing. Cursor's .cursor/rules and AGENTS.md, and Claude Code's CLAUDE.md, are instructions the agent follows every session. A repository can carry them. The rule unreviewed_components covers components that arrived without review, and the OWASP LLM04 mapping treats these files as the poisoning surface they are.
What each can read
Claude Code reads files in the working directory and any additional directories without asking, and prompts for paths outside them. Read rules such as Read(./.env) deny the Read tool, and a separate Bash rule is needed for the shell, because a deny on one does not cover the other; the documentation also notes that a Bash deny does not match the same program by path or inside sh -c, and points to the sandbox network allowlist when a restriction must hold.
Cursor's agent sees the open workspace. .cursorignore blocks files from the Agent, Tab, Inline Edit and @ mentions, and .env files are ignored by default. Cursor's documentation states that the terminal and MCP server tools used by Agent cannot block access to code governed by .cursorignore. The agent that cannot @ mention .env can still cat it.
On both, then, the honest statement is that the agent can read anything the developer can read, and the file-level controls narrow what it does by accident, not what it can do on instruction. That is why the sensor reports credentials in reach of each agent, readable_credential, rather than trusting either ignore mechanism. Network is the same story: Cursor's documentation limits the agent's requests to GitHub, direct links and web search by default, Claude Code governs WebFetch by domain rule, and on both a shell command or an HTTP MCP server reaches whatever the machine can.
Side by side
| Claude Code | Cursor | |
|---|---|---|
| Runs as | CLI in any terminal | Editor with a built-in agent |
| User config | ~/.claude/settings.json, ~/.claude.json | Editor settings, ~/.cursor/ |
| Repository config | .claude/settings.json, .claude/settings.local.json, .mcp.json, CLAUDE.md | .cursor/rules, AGENTS.md, .cursor/mcp.json, .cursor/hooks.json |
| Organisation config | managed-settings.json, MDM, claude.ai console | System hooks.json, Enterprise team hooks |
| Stops asking via | Permission modes, allow rules saved to settings.local.json | Run modes: Allowlist, Auto-review, Run Everything |
| MCP approval | Project .mcp.json prompts, tied to workspace trust | Each tool call asks, allowlist to pre-approve |
| Hooks | 30+ events, JSON settings files | 20+ events, hooks.json |
| Credential file guard | Read deny rules; Bash needs its own | .cursorignore; terminal and MCP not covered |
| Network default | Rules per domain, sandbox allowlist | GitHub, links and search only |
What to lock down first
For Claude Code:
- Deploy managed settings with permissions.disableBypassPermissionsMode set to disable, and a deny list that at least covers Read(./.env), Read(~/.aws/**) and the shell equivalents.
- Read every .claude/settings.local.json the sensor finds. That file is the list of things the agent no longer asks about.
- Hold project .mcp.json servers for review before they load, and treat a hook in a repository's .claude/settings.json as code that runs on every machine that clones it.
For Cursor:
- Deploy a system hooks.json and use beforeShellExecution and beforeMCPExecution to see, and if needed stop, what the agent runs.
- Find every workspace on Run Everything. The sensor's shell_auto_allowed rule reports it.
- Inventory .cursor/mcp.json and ~/.cursor/mcp.json on every machine, and look for tokens written into them instead of ${env:NAME}.
For both: know they are there. The shadow estate is the one nobody configured, and every control above applies only to the agents you know about.
A worked example: one laptop, both agents
A senior developer runs Cursor for daily work and Claude Code for longer tasks. Cursor is on Run Everything, set during a week of refactoring. Claude Code has Bash(git push *) and Bash(npm *) in the repository's settings.local.json from two "don't ask again" answers in March. The repository has a .cursor/mcp.json committed by a contractor, pointing at an HTTP server nobody in security has heard of, and a .env with a production database URL.
The sensor reports, grouped by cause: shell_auto_allowed for Cursor, permissive_agent for Claude Code, an unreviewed MCP server from the repository, and readable_credential for the .env in reach of both agents. The console shows one attack path: a file the agent reads, a server it talks to, a credential it can carry. The fix is one run-mode change, two lines removed from a settings file, one server held for review, and one file moved. Four findings, a few minutes, and the same evidence lines up under Article 14 of the EU AI Act and LLM06 of the OWASP list.
Frequently asked questions
Is Cursor or Claude Code more secure? Neither is secure or insecure on its own. Both run with the developer's account, both can be told to stop asking before they act, and both load MCP servers, rules and hooks from files a developer or a repository can write. The difference is where those switches live. Claude Code keeps them in JSON settings files with a documented precedence and a managed tier an organisation can enforce. Cursor keeps them in the editor's own settings, .cursor folders and hooks.json files. A security team can govern either. The one it cannot govern is the one it does not know is installed.
Can a company enforce permission rules on Claude Code and Cursor? Claude Code: yes, through managed settings, a managed-settings.json file in a system directory, an MDM policy or the claude.ai console. Nothing a user or a repository sets overrides a managed key, apart from a few exceptions where a stricter lower value still counts. Cursor: hooks.json can be deployed system-wide from /Library/Application Support/Cursor, /etc/cursor or C:\ProgramData\Cursor, and Enterprise teams can distribute hooks from the dashboard. Cursor's own run modes are described in its documentation as best-effort guardrails, not a security boundary.
Which files should a security team inventory for Cursor and Claude Code? For Claude Code: ~/.claude/settings.json, .claude/settings.json and .claude/settings.local.json in each repository, ~/.claude.json for MCP servers and trust decisions, .mcp.json in each repository, and managed-settings.json. For Cursor: ~/.cursor/mcp.json and .cursor/mcp.json, .cursor/rules and AGENTS.md, ~/.cursor/hooks.json and .cursor/hooks.json, and .cursorignore. Every one of those is a place a permission, a server or a script can be added without anyone in security seeing it.
Does .cursorignore stop Cursor's agent from reading a .env file? Only in part. Cursor's documentation says .cursorignore blocks code from the Agent, Tab and Inline Edit and from @ mentions, and that .env files are ignored by default. It also says the terminal and MCP server tools used by Agent cannot block access to code governed by .cursorignore. An agent that runs cat .env in the terminal reads it. The same holds for Claude Code: a Read deny rule covers the Read tool, and a Bash deny rule has to be written separately for the shell.