Connect AI clients
How to set up MCP servers in Cursor
Cursor has no command for adding MCP servers. They all go in a JSON file called mcp.json, either in your home directory or in the project.
New to MCP? What is an MCP server? covers the basics first.
You'll give Cursor's agent two servers: a local one Cursor starts on your machine, and a remote one at a URL. Getting them working is mostly a matter of what goes in mcp.json.
Prerequisites
- Cursor, recent enough to have the Customize sidebar, which is where MCP servers are switched on and off.
- Node.js 20 or later, for the local server example, which runs through
npx. - A project open in Cursor, if you want project-level servers.
Step 1: Pick global or project config
Cursor looks for mcp.json in two places:
| File | Applies to | Good for |
|---|---|---|
~/.cursor/mcp.json | Every project you open | Servers you want everywhere, with keys that are yours |
.cursor/mcp.json in the project | That project only | Servers the whole team should get from the repository |
Both files have the same shape: one top-level mcpServers object, with one entry per server, keyed by the name you want Cursor to show. Create the file if it does not exist:
{
"mcpServers": {}
}A project file usually ends up in version control, so keep keys out of it. Step 4 shows how.
Step 2: Add a local server
A local server, also called stdio, is a program Cursor starts and talks to over standard input and output. The entry names the command and its arguments:
{
"mcpServers": {
"everything": {
"type": "stdio",
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-everything"]
}
}
}server-everything is the MCP project's reference server. Its tools exist for testing, which makes it a safe way to check the setup before you add a server that touches real data.
command is the program, and args is a list with one item per argument. If the server needs environment variables, add an env object next to args.
Step 3: Add a remote server
A remote server runs somewhere else and you reach it at a URL. The entry needs only the url:
{
"mcpServers": {
"everything": {
"type": "stdio",
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-everything"]
},
"deepwiki": {
"url": "https://mcp.deepwiki.com/mcp"
}
}
}DeepWiki answers questions about public GitHub repositories and needs no key. Cursor supports the Streamable HTTP transport current remote servers use, plus the older SSE transport for servers that haven't moved yet.
Step 4: Keep keys out of the file
The quick way to give a server its key is to paste it into env or a header. Cursor can read it from your environment instead, which keeps it out of the file.
For a remote server that takes an API key, reference an environment variable in headers:
{
"mcpServers": {
"my-api": {
"url": "https://example.com/mcp",
"headers": {
"Authorization": "Bearer ${env:MY_API_KEY}"
}
}
}
}For a local server, do the same in env:
{
"mcpServers": {
"my-tool": {
"type": "stdio",
"command": "node",
"args": ["tool.js"],
"env": {
"TOKEN": "${env:MY_TOKEN}"
}
}
}
}Cursor fills these in when it starts the server. The syntax is ${env:NAME}, and it works in command, args, env, url and headers. For paths that differ between machines there are also ${workspaceFolder} (the project root) and ${userHome}.
Local servers can also load a whole file of variables with envFile, for example "envFile": "${workspaceFolder}/.env". That option is only for stdio servers. Keep the .env file out of version control.
For a remote server that supports OAuth, you may not need a key at all. Cursor runs the login flow and stores the token. If the provider wants a pre-registered client, add an auth object with its CLIENT_ID (and CLIENT_SECRET if it is a confidential client).
Step 5: Turn the servers on and check them
Open Customize in the sidebar. Your servers are listed there, and you can switch each one on or off without editing the file. If one you just added is missing, quit and reopen Cursor. It reads its MCP config at startup, so an open window may not have seen the change.
Then ask the agent something that needs one of the tools. Cursor uses MCP tools when they are relevant, and by default it asks for your approval before each call. You can let allowlisted tools run without asking, through the same run modes that govern terminal commands. I would leave the prompt on until you know what each tool does.
When a server fails to start, open the Output panel and pick MCP Logs from the dropdown. The error there is usually a wrong path in command or a variable that wasn't set.
Step 6: Put the servers behind Statio
As set up here, the key sits on every laptop that uses the server, and Cursor sees every tool the server offers.
With Statio, you install servers once in the dashboard, from the catalog or your own, add the upstream key there, and grant tools one at a time to people and agents. Cursor then points at the Statio desktop app's local proxy instead of at each server. The desktop app writes ~/.cursor/mcp.json for you and keeps it current as your access changes. By hand, the entry is just a URL:
{
"mcpServers": {
"github": {
"url": "http://127.0.0.1:7777/github/mcp"
}
}
}There is no header because the proxy attaches your sign-in to each request, and no key because the GitHub token stays in Statio, encrypted. If the agent calls a tool you were not granted, the gateway refuses it, and the refusal lands in the audit log next to the calls that went through. The client docs cover agents and other clients.
Conclusion
Both servers now live in mcp.json, and their keys come from your environment.
Where to go next:
- Add MCP servers to Claude Code covers the same servers from the terminal.
- Build an MCP server in Python or in TypeScript if the server you want does not exist.
- Turn an OpenAPI spec into an MCP server if you already have an API.
- Give an AI agent read-only GitHub access for a first real server with a safe set of tools.