Cursor — the AI-native VS Code fork — added first-class support for Model Context Protocol (MCP) in early 2025, and it has quickly become one of the most powerful ways to extend an AI coding assistant. Configure an MCP server once and Cursor's agent can read your database, manage your repo, query your design tool, or hit any internal API directly from inside your editor.
This guide walks through everything: where Cursor stores its MCP config, how to add servers, how to switch between project and global setups, and the small differences from Claude Desktop that catch developers off guard.
Two config files, two scopes
Cursor reads MCP server definitions from one of two locations:
| Scope | File path | When to use |
|---|---|---|
| Global (all projects) | ~/.cursor/mcp.json |
Personal tools like GitHub, filesystem, weather |
| Project (this workspace only) | <project-root>/.cursor/mcp.json |
Project-specific tools like a custom internal server, project database |
Project-level config takes precedence over global. If both define a server with the same name, the project one wins.
The shape of both files is identical — same JSON, same keys as Claude Desktop. Cursor was deliberately designed to be compatible.
Adding your first server (global)
Open Cursor settings: Cmd+Shift+J (macOS) or Ctrl+Shift+J (Windows/Linux), then go to MCP & Integrations. Click Add new global MCP server. Cursor opens ~/.cursor/mcp.json for you.
For a working example, add the filesystem server:
{
"mcpServers": {
"filesystem": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-filesystem", "/Users/you/code"]
}
}
}
Save the file. Go back to the MCP & Integrations settings tab — you should see filesystem listed with a green dot. Click the refresh icon next to it if it does not appear immediately.
No full app restart needed (unlike Claude Desktop). Cursor reloads MCP servers when the config file changes.
Project-scoped servers
For team projects where you want everyone to share the same MCP setup — for example, a custom internal MCP server that wraps your company's API — put the config inside the repo:
my-project/
├── .cursor/
│ └── mcp.json ← project-scoped MCP
├── src/
└── package.json
The file is the same shape:
{
"mcpServers": {
"internal-api": {
"command": "node",
"args": ["./tools/internal-mcp-server/dist/server.js"]
}
}
}
Commit .cursor/mcp.json to your repo. Every teammate who opens the project in Cursor automatically gets the same MCP server.
Note on relative paths: unlike Claude Desktop, Cursor resolves relative paths in args from the project root when the config is project-scoped. That makes project configs portable across machines without absolute paths.
Using the MCP server inside Cursor
MCP tools become available to Cursor's Agent mode (the chat panel with the "Agent" toggle). They are not used by tab-completion or inline AI.
To invoke:
- Open the chat panel: Cmd+L (macOS) / Ctrl+L (Windows/Linux).
- Switch the dropdown to Agent (not Ask).
- Type a request that needs the tool. The agent picks tools autonomously.
A tool call appears as a collapsible card showing the tool name, arguments, and the response — same UX as Claude Desktop.
Auto-run vs ask-for-permission
Cursor has two modes for tool execution:
- Auto-run — the agent runs tool calls without confirmation. Fast, but risky for write operations.
- Ask for permission — every tool call surfaces a Yes/No prompt. Safe, but slows iteration.
Set the default in Settings → MCP & Integrations → Auto-run. You can also override per-tool with the "Always allow" checkbox that appears the first time a tool is invoked.
A sensible policy: enable auto-run for read-only servers (filesystem, GitHub search, web search) and keep ask-for-permission on for anything with side effects (database writes, file modifications, creating PRs).
Environment variables and secrets
Use the env field exactly like in Claude Desktop:
{
"mcpServers": {
"github": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-github"],
"env": { "GITHUB_PERSONAL_ACCESS_TOKEN": "ghp_..." }
}
}
}
For team-shared project configs, do not commit secrets. Either reference an env var the user must set themselves, or document the requirement in your project's README:
{
"mcpServers": {
"linear": {
"command": "npx",
"args": ["-y", "@linear/mcp-server"],
"env": { "LINEAR_API_KEY": "${LINEAR_API_KEY}" }
}
}
}
Cursor expands ${VAR_NAME} from your shell environment at server-launch time — so LINEAR_API_KEY in your shell flows through transparently.
Working with a TypeScript server in development
While iterating on your own MCP server, run it via tsx so you do not have to rebuild on every change:
{
"mcpServers": {
"my-server": {
"command": "npx",
"args": ["tsx", "./src/server.ts"],
"cwd": "/Users/you/code/my-mcp-server"
}
}
}
When you save changes to server.ts, click the refresh button in MCP & Integrations to reload — Cursor restarts the subprocess with your new code.
Verifying everything works
Three quick checks after adding a server:
- Green dot next to the server name in MCP & Integrations = process started successfully.
- Tools tab under the server entry should list every tool with its description.
- Test invocation: open the agent chat, ask a question that uses the server. Watch for the tool-call card.
If the server is red or missing tools, click on it to expand the log panel. Cursor shows the subprocess's stderr inline — which is where almost every startup error surfaces.
Cursor-specific quirks
A few things that differ from Claude Desktop:
| Behaviour | Claude Desktop | Cursor |
|---|---|---|
| Restart required after config edit | Yes (full quit) | No — hot reloads |
Relative paths in args |
Not supported (use absolute) | Supported in project configs |
| Auto-run by default | No (always asks) | Configurable per server |
| Project-scoped config | Not supported | Native via .cursor/mcp.json |
| Number of servers shown in UI | Hidden in dev panel | Top-level setting, always visible |
The project-scoped config alone is reason to use Cursor over Claude Desktop for team workflows — you ship the MCP setup with the codebase.
Common issues
| Symptom | Likely cause | Fix |
|---|---|---|
| Server appears greyed out | Process exited at startup | Click the server entry to see stderr |
| Tools list is empty | Server connected but registered zero tools | Check your server.tool() calls compile and run |
npx: command not found |
Cursor launched from a context where Node is not on PATH | Use the full path to Node (/usr/local/bin/node) |
| Changes to server.ts not reflected | Cached subprocess | Click the refresh icon next to the server in settings |
| Agent never calls the tool | Tool description too vague | Rewrite the description to include intent examples |
That last one bites everyone. Cursor's agent (like any LLM) chooses tools based on their descriptions. A description like "file utility" is useless; "Search the contents of files matching a pattern" gets called constantly. Spend an extra minute on each description.
A complete team setup
A realistic .cursor/mcp.json for a real project — checked into the repo, secrets in shell env vars:
{
"mcpServers": {
"filesystem": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-filesystem", "."]
},
"github": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-github"],
"env": { "GITHUB_PERSONAL_ACCESS_TOKEN": "${GITHUB_TOKEN}" }
},
"db": {
"command": "npx",
"args": [
"-y",
"@modelcontextprotocol/server-postgres",
"${DATABASE_URL}"
]
},
"internal": {
"command": "node",
"args": ["./tools/mcp-server/dist/server.js"],
"env": { "INTERNAL_API_TOKEN": "${INTERNAL_API_TOKEN}" }
}
}
}
Every teammate cloning the repo gets filesystem, GitHub, database, and the project's custom internal server — provided they set GITHUB_TOKEN, DATABASE_URL, and INTERNAL_API_TOKEN in their shell. Document those three env vars in your README and onboarding becomes trivial.
Conclusion
Cursor's MCP integration is, in many ways, more developer-friendly than Claude Desktop's. Project-scoped configs, hot reload, ${VAR} expansion, and per-server auto-run policies all add up to a smoother experience for the kind of fast iteration that defines coding.
The two-rule starter pack:
- Put team-relevant servers in
.cursor/mcp.jsonand commit it. - Put personal servers in
~/.cursor/mcp.jsonand never commit your secrets.
Do that and the Cursor agent becomes a meaningfully more capable coding partner — one that can read your repo, query your database, and search your tickets without ever leaving the editor.
Try it yourself
With Cursor's project-scoped GitHub + Postgres servers active, a refactor conversation looks like this:
orders.status column. Which open PRs touch that column?describe_table then search_issuesConfirmed: orders.status is a text column. 3 open PRs reference it:• #412 Add status transition validation
• #398 Migrate status enum to lookup table
• #374 Fix race condition on bulk status update
PR #398 is the most relevant — it is already changing how status is stored. You may want to coordinate the rename with that author before merging anything else.
Project-scoped MCP is what makes that one-shot answer possible — Cursor knows your database schema and your GitHub repo because both servers are wired up in the workspace config.