Connect Claude Desktop to Your REST API with MCP
A practical guide to giving Claude Desktop access to your REST API through an MCP server — the config file, the two connection methods, and the mistakes that waste an afternoon.
There's a specific moment that sells people on MCP: you ask Claude a question, and instead of guessing, it goes and calls your actual API to answer. The first time you watch it pull a real record out of your own system, the whole thing stops feeling abstract.
This post gets you to that moment with Claude Desktop. I'll assume you already have an MCP server URL and access token — if you don't, the no-code walkthrough covers producing one from an OpenAPI spec. Here we're focused on the client side: wiring that server into Claude Desktop and dealing with the handful of things that trip people up.
Two ways to connect
Claude Desktop can reach a remote MCP server two ways, and it's worth knowing both because they suit different situations.
The Connectors UI is the newer, friendlier path. In Claude Desktop's settings there's a Connectors section where you add a custom connector by URL. If your MCP server uses OAuth, this is the path that handles the sign-in flow for you: you click connect, a browser window opens, you authenticate, and you're done. No tokens to copy by hand.
The config file is the direct path, and it's what most people use for a server they created themselves. You edit a JSON file and Claude picks up the server on restart. This is the method I'll spend most of the post on, because it's explicit and you can see exactly what's happening.
Finding the config file
Claude Desktop keeps its MCP configuration in claude_desktop_config.json. Where that lives depends on your OS:
- macOS:
~/Library/Application Support/Claude/claude_desktop_config.json - Windows:
%APPDATA%\Claude\claude_desktop_config.json
The fastest way to open it is from inside the app — Settings, then Developer, then "Edit Config." That drops you at the right file and creates it if it doesn't exist yet. Opening it through the app beats hunting through folders, and it guarantees you're editing the file Claude actually reads (I've watched someone edit a copy in the wrong directory and spend twenty minutes wondering why nothing changed).
The configuration
Here's a complete, working entry. Replace the URL and token with the ones from your MCP server:
{
"mcpServers": {
"my-api": {
"url": "https://api.api2mcp.io/mcp/<your-server-id>",
"headers": {
"Authorization": "Bearer <your-access-token>"
}
}
}
}
A few things about this that matter:
"my-api"is just a label. Name it something you'll recognize when Claude shows you which server a tool came from. It doesn't have to match anything on the server side.- The
urlis the server URL you got when you wrapped your provider — not your API's base URL. This is the API2MCP endpoint, which then proxies to your API. - The
Authorizationheader carries the access token for the MCP server. This authorizes Claude to use the server. It is not your upstream API key — that key stays on the server and never comes near this file. (That distinction is the whole security model, and it's the reason this setup is safe to put in a config file at all.)
If you already have other servers in the mcpServers object, add yours as another key alongside them — don't create a second mcpServers block.
Restart, then verify
Claude reads this file at startup, so quit and reopen the app — not just close the window, actually quit it. On restart, open a new conversation and look for the tools indicator (the little tool/plug icon in the input area). Your server's tools should be listed there. If they are, you're connected.
Now test it with a question that only your API can answer. Vague is fine — the model is good at matching intent to the right tool. If you wrapped a weather API, "what's the weather in Denver right now?" is enough. If it's your CRM, ask about a customer you know exists. Claude will call the tool, the server will proxy to your API with the real credentials attached, and the answer comes back grounded in live data instead of a guess.
When it doesn't work
It usually comes down to one of four things, in rough order of frequency:
The tools don't show up. Almost always a JSON syntax error — a trailing comma, a missing brace, smart quotes pasted from somewhere. Run the file through any JSON validator; Claude silently ignores a malformed config rather than erroring loudly. And confirm you actually quit and relaunched.
Every call returns unauthorized. The access token is wrong, expired, or you pasted it with a stray space. Regenerate it from the server's page and paste it clean. Remember there are two layers of auth here — the token in this file (client → MCP server) and the upstream key on the server (MCP server → your API). A 401 in Claude is the first layer; a 401 that shows up in the tool's response is the second.
The tool call times out. Your upstream API is slow or the endpoint is heavy. MCP calls have finite patience, and so does the proxy. If a particular endpoint is genuinely long-running, that's worth knowing before you rely on it in a conversation.
Claude has the tools but won't use them. This is a description problem, not a connection problem. If the tool's summary is vague, the model can't tell it's relevant. Better descriptions in your source spec fix this — which is one more reason the spec quality conversation matters more than it seems.
What you've got now
Once this works, Claude Desktop can reach your API any time it's relevant to what you're doing — pulling real records into a conversation, taking actions through endpoints you've exposed, all with your credentials kept server-side. It stops being a chatbot that talks about your systems and becomes one that can actually use them.
Cursor is the natural next setup if you live in an editor — connecting Cursor to the same server takes about two minutes once you've done this once. And if you haven't created a server yet, the free tier is enough to wrap one and try this end to end.