Cursor’s Config Surface: .cursorrules, MCP, and Extension Drift on the Endpoint
Cursor leaves a surprising amount of itself on the endpoint. Behavior rules, MCP server definitions, and installed extensions live as files in the home directory and in each project, and once a developer has used Cursor for a few months, that set looks nothing like what anyone reviewed on day one. This is a research-findings piece about that config surface: where each artifact lives, how it changes who the agent talks to and what it can run, and why it drifts off any allowlist you thought you had.
We have written about Cursor's sharper edges elsewhere, the MCP prompt-injection path in CurXecute (CVE-2025-54135) and the trust bypass in MCPoison (CVE-2025-54136). Those are specific bugs. The drift below is not a bug; it is the ordinary state of a tool that reads config from many places and lets each developer change it. Every behavior we describe is documented in Cursor's own docs and security page.
The three artifact families Cursor writes locally
Cursor's local footprint splits into three families that answer different security questions. Rules shape what the agent is told to do. MCP servers define what external systems and local processes it can reach. Extensions are the code running inside the editor alongside all of it. The broad inventory problem from securing AI coding agents and CLIs applies here, except Cursor spreads its state across more files and a registry-backed extension surface.
| Family | Where it lives | What it changes |
|---|---|---|
| Project rules | .cursor/rules/*.mdc (version-controlled) | Agent behavior, always or by glob/relevance |
| Legacy rules | .cursorrules in project root | Same, but older single-file form |
| User rules | Cursor Settings → Rules | Global behavior across every project |
| MCP servers | ~/.cursor/mcp.json, .cursor/mcp.json | External systems and local commands the agent can call |
| Extensions | Open VSX installs, manual VSIX | Code running inside the editor |
Rules: .cursorrules, .cursor/rules/, and the silent layers
Cursor's docs describe project rules living in .cursor/rules as .mdc files that are version-controlled. A format detail matters for inventory: a plain .md file dropped in that directory is ignored because it has no frontmatter, while AGENTS.md is recognized as a simpler markdown form. The older .cursorrules file in the project root still works as a single-file rule. So a repo can carry rules in at least three shapes, and only the .mdc files and AGENTS.md are picked up by the structured system.
Each .mdc rule declares how it applies through frontmatter. The documented types are Always Apply, loaded into every chat session; Apply Intelligently, pulled in when the agent decides the description is relevant; Apply to Specific Files, triggered on a glob match; and Apply Manually, invoked only when @-mentioned. That distinction is the one audits miss: an Always Apply rule is part of the agent's standing context, while a Manual rule is dormant until called. Counting rule files tells you little; you have to read the frontmatter to know which ones shape output.
Above the repo sit more layers. Cursor documents User Rules as global preferences set in Settings, applied across all projects but not to Inline Edit, and Team Rules from the dashboard with enforcement options. The documented precedence is Team Rules, then Project Rules, then User Rules. The consequence mirrors what we found with Claude Code's settings precedence: reading rules out of a Git repo shows team intent, not the effective context on the endpoint, because the user's Settings layer is untracked and lives only on their machine.
MCP: where the agent's reach actually expands
Rules steer the agent; MCP servers extend what it can touch. Cursor reads two MCP config locations, documented as project-level .cursor/mcp.json and global ~/.cursor/mcp.json in the home directory. A project file travels with the repo and is reviewable; the global file follows the developer into every project they open and is where the quiet additions land. We covered why this layer deserves its own inventory in the MCP server security complete guide, and the stdio launch surface in Anthropic's MCP stdio RCE by design.
The config format is the security story. Cursor's docs define each server with a command, args, env, and an optional envFile for stdio servers, or a url and headers for remote ones, across stdio, SSE, and Streamable HTTP transports. A stdio entry is simply a command Cursor launches on the endpoint, so the inventory question is concrete: which executables does the agent start, with which arguments, reading which environment. A representative global config:
{
"mcpServers": {
"internal-tools": {
"command": "npx",
"args": ["-y", "@acme/mcp-internal"],
"envFile": "~/.config/acme/mcp.env"
},
"db-admin": {
"command": "/usr/local/bin/mcp-db",
"args": ["--profile", "prod"],
"env": { "DB_TOKEN": "…" }
}
}
}
On approval, Cursor's docs state it asks before using MCP tools by default, and that Auto-review mode, the default in recent versions, runs allowlisted tools listed in permissions.json immediately while routing the rest through a safety classifier. That allowlist is where drift concentrates: every tool a developer marks to stop the prompts becomes a no-approval path no central policy sees. The documented guidance to only install MCP servers from trusted developers is sound advice and also an admission that trust is decided per endpoint, the same gap MCPoison turned into a trust bypass.
Extensions: a registry-backed surface that no one diffs
The third family is the one teams forget is part of the agent's blast radius. Cursor pulls extensions from the Open VSX Registry rather than the Microsoft Marketplace, and Anysphere publishes its own builds of several popular extensions. Developers also sideload extensions the catalog does not carry, installing a .vsix through the command palette or via cursor --install-extension. Each extension is code running inside the editor with the editor's access, next to whatever the agent is doing, and the sandbox-escape class of issue we traced in the Cursor Git hooks RCE (CVE-2026-26268) is a reminder that local execution context inside the editor is a real boundary.
Extensions drift the way browser extensions do: installed once for a task, never removed, occasionally replaced by a same-named build from a different publisher. Because some come from a registry, some are sideloaded VSIX files, and some are Anysphere's own forks, which publisher's code runs on a given laptop has no single answer until you enumerate it per machine. A package scanner reading a lockfile never sees this; the extension set is not in the dependency manifest.
What to check, and what existing controls miss
Pulling the families together, here is the per-endpoint reconciliation we run when we inventory Cursor, and what each line answers:
- Effective rules. Which
.mdcrules are Always Apply versus Manual, whether a legacy.cursorrulesorAGENTS.mdis also present, and which User and Team rules layer on top, in the documented Team, Project, User order. - MCP server set. Every entry in
~/.cursor/mcp.jsonand each project.cursor/mcp.json, the command and arguments for stdio servers, the URL for remote ones, and whether the global file has grown servers no project reviewed. - Approval allowlist. What sits in the Auto-review
permissions.jsonallowlist, since those tools run without a prompt. - Extension inventory. Which extensions are installed, their publisher (Open VSX, Anysphere fork, or sideloaded VSIX), and what changed since last seen.
Now walk the controls you already own. EDR sees a signed Cursor process making expected syscalls and a few child processes it launched, all trusted software behaving normally. A network proxy or DLP tool sees TLS to Cursor's backend, documented as requests for API, indexing, update, and marketplace functionality, and for a stdio MCP server it sees no network at all because the server is a local subprocess. Package scanners read the project manifest and never touch the untracked global mcp.json, the user's rules in Settings, or the extension set. GRC tooling captures policy intent, not the merged on-disk reality, and Cursor's SOC 2 Type II attestation, available on request, speaks to Cursor's own controls, not to what each developer has accumulated locally. Each control is correct in its frame and blind to the same editor running different rules, servers, and extensions on every laptop.
That reconciliation is the layer Anomity makes visible. On every managed endpoint we inventory eight AI artifact types, AI agents, MCP servers, extensions, skills, plugins, secrets, hooks, and CLIs, and classify them, so the fleet inventory shows Cursor's effective rules, the servers in each mcp.json, the approval allowlist, and the installed extensions as they resolve per machine rather than as the repo claims. Where an agent exposes a hook, Anomity returns allow, deny, or log on each tool call before it runs, and keeps a queryable 90-day audit trail routed to your SIEM, Slack, email, or Jira. It complements EDR, DLP, and GRC rather than replacing them. To see what your fleet's Cursor configuration looks like once it is reconciled across endpoints, request early access.