How to Add an MCP Server to Claude Desktop and Cursor
To add a remote MCP server to Claude Desktop, open Customize > Connectors, click Add custom connector and enter the server URL. For Perceptlayer that's https://api.perceptlayer.com/mcp, with your API key sent as an Authorization: Bearer request header. If your app doesn't offer request headers yet, add the server to claude_desktop_config.json through the mcp-remote bridge instead. Cursor takes the same URL and header in mcp.json. Then ask a question that needs live data, and read the credits each call reports.
What do you need before you start?
You need an API key, a client that supports remote MCP servers, and a couple of minutes. Get a free API key; keys start with sk_live_, and verifying your email address gives you 1,000 free credits every month, with no credit card. For Claude Desktop, you need either the Request headers section in the custom connector dialog or Node.js on your machine for the mcp-remote bridge. Cursor needs nothing extra.
Keep the key out of shared files. A config file stores it in plain text, so don't commit a project-level mcp.json that contains it. The authentication docs cover key handling and revocation.
How do you add the server as a Claude Desktop custom connector?
Claude Desktop adds remote MCP servers as custom connectors, and an API key goes in as a request header. On a Free, Pro or Max plan you add it to your own account. On the Free plan you can add one custom connector. On Team and Enterprise plans an Owner adds it for the organization and members connect to it (Claude, 2026). Claude's docs mark request header authentication as a beta available to a limited set of organizations. If the section isn't in your dialog, use the config file route in the next section.
- Open Customize > Connectors and click Add custom connector.
- Enter a name, such as
Perceptlayer, and the server URLhttps://api.perceptlayer.com/mcp. - For authentication, choose No sign-in. The server uses an API key, not OAuth.
- Open Request headers, pick
authorizationfrom the list and enterBearer sk_live_...with your key. Mark it required. - Click Add.
Claude doesn't add a scheme to the header value. If you enter only the key, the server receives Authorization: sk_live_... and rejects it. You can't edit the header after saving. To change the key, remove the connector and add it again. These steps follow Claude's documentation; we haven't run them against our server for this article.
How do you add it through claude_desktop_config.json instead?
The config file runs local programs, so a remote server needs a small local bridge. The mcp-remote package is one: Claude Desktop starts it with npx, and it forwards each request to the remote URL with your header. Open the file from Settings > Developer > Edit Config, or directly at ~/Library/Application Support/Claude/claude_desktop_config.json on macOS and %APPDATA%\Claude\claude_desktop_config.json on Windows (mcp-remote, 2026).
{
"mcpServers": {
"perceptlayer": {
"command": "npx",
"args": [
"-y",
"mcp-remote",
"https://api.perceptlayer.com/mcp",
"--header",
"Authorization:${AUTH_HEADER}"
],
"env": {
"AUTH_HEADER": "Bearer sk_live_..."
}
}
}
}
Note Authorization:${AUTH_HEADER} with no space after the colon. The mcp-remote README explains that Claude Desktop on Windows and Cursor don't escape spaces inside args, so the value with a space goes in env, where spaces are fine. Save the file and restart Claude Desktop, then check that the server's three tools are listed in a new chat. We haven't run this config against https://api.perceptlayer.com/mcp ourselves, so if the tools don't appear, check the mcp-remote README for your version's options.
How do you add it to Cursor?
Cursor connects to remote servers directly, so it needs no bridge: the URL and the header go straight into mcp.json. Use ~/.cursor/mcp.json to make the server available in every project, or .cursor/mcp.json inside one project to scope it there (Cursor, 2026). The same file can hold other servers next to this one.
{
"mcpServers": {
"perceptlayer": {
"url": "https://api.perceptlayer.com/mcp",
"headers": { "Authorization": "Bearer sk_live_..." }
}
}
}
If you use Claude Code as well, one command registers the same server:
claude mcp add --transport http perceptlayer https://api.perceptlayer.com/mcp \
--header "Authorization: Bearer $API_KEY"
We haven't tested this Cursor config against the live server for this article; it follows the AI agents (MCP) docs, which also have the VS Code config, which asks for the key once and stores it.
What does the first tool call look like?
Ask a question the model can't answer from training data, and it goes through search, inspect, call. Try: "Use Perceptlayer to search Google for best restaurants in Berlin and give me the top two results." The model calls search_endpoints with a query such as google search and gets matches with their IDs, credits per call and required parameters. It may call get_endpoint on google-search.search to read the parameter list. Both lookups are free. Then it runs the search:
{
"endpoint": "google-search.search",
"params": { "query": "best restaurants in Berlin", "hl": "en", "safe": "off" }
}
The client usually asks you to approve a tool call. Approve call_endpoint once per call until you trust the setup, since it's the tool that spends credits.
These are the parameters the model will most often set on GET /v1/google-search/search. The Google Search API page lists the full set.
| Parameter | Type | Required | Notes |
|---|---|---|---|
query |
string | yes | The search terms |
hl |
string | no | Interface language, 2 characters |
gl |
string | no | Country, 2 characters |
location |
string | no | Up to 500 characters |
device |
string | no | desktop, tablet or mobile |
safe |
string | no | active or off |
page |
integer | no | Results page |
The result is the endpoint's JSON. This is our recorded response for that request, trimmed:
{
"search_information": {
"query_displayed": "best restaurants in Berlin",
"organic_results_count": 6
},
"organic_results": [
{
"position": 1,
"title": "The Best Restaurants in Berlin - Food Guide & Map",
"link": "https://andershusa.com/best-restaurants-berlin-germany-guide/",
"source": "Anders & Kaitlin",
…
},
{
"position": 2,
"title": "Restaurants - Berlin",
"link": "https://guide.michelin.com/us/en/berlin-region/berlin/restaurants",
"source": "MICHELIN Guide",
…
}
],
…
}
After the JSON, the tool result adds a line such as Credits used: 1. Credits remaining: … and a request ID.
How do you check that only successful calls cost credits?
Compare the balance across a good call and a bad one. Credits are debited only when a call succeeds, and every response says what it cost, so you can check this yourself in two requests. Inside the chat, each call_endpoint result reports Credits used and Credits remaining. Outside it, run the same search with cURL and print the response headers:
curl -s -D - -o /dev/null \
"https://api.perceptlayer.com/v1/google-search/search?query=best+restaurants+in+Berlin&hl=en&safe=off" \
-H "X-API-Key: $API_KEY" | grep -i '^x-credits'
A successful call returns X-Credits-Used: 1 and X-Credits-Remaining with the balance after the call. Now send a value the endpoint doesn't accept, such as safe=maybe (it allows only active or off). The call fails with invalid_parameters (422) and X-Credits-Used: 0, and X-Credits-Remaining is unchanged. Through MCP, the same failure comes back as Error invalid_parameters: …, and the next successful call's remaining balance shows nothing was taken. The credits docs explain the balance, and the errors docs list every code.
What goes wrong, and how do you fix it?
Most setup failures are a missing or malformed header, because searching and inspecting the catalogue work without a key. A client that lists the three tools but fails on call_endpoint almost always has a header problem. The error code in the tool result tells you which, and the table covers the common ones.
| Symptom | Cause | Fix |
|---|---|---|
call_endpoint returns invalid_api_key and says no key was sent |
The header isn't configured | Add Authorization: Bearer sk_live_... to the server config |
invalid_api_key with a key configured |
The value lacks Bearer , or the key was revoked |
Re-enter the value with the scheme, or create a new key |
| The header arrives cut off on Windows | A space inside args |
Use Authorization:${AUTH_HEADER} and put the value in env |
| Tools don't appear after editing the config file | The app hasn't reloaded it | Restart Claude Desktop |
rate_limited |
More than the account's per-second rate | Wait the Retry-After seconds; see the rate limits docs |
insufficient_credits (402) |
The balance is used up | Buy a pack on pricing; nothing is debited meanwhile |
To go further, Claude MCP Web Search builds a search agent on the same server. MCP Server Too Many Tools explains why the server has three tools rather than one per endpoint.
APIs in this post
Frequently asked questions
How much does a question cost through Claude Desktop?
Each successful call_endpoint costs the endpoint's credits, 1 for a Google search, and the lookups are free. A question that needs one search costs 1 credit, so 200 such questions a month is 200 × 1 = 200 credits, within the 1,000 free monthly credits. Failed calls cost nothing. The pricing page has what credit packs cost.
Can I use OAuth instead of an API key?
Not with Perceptlayer's server today. It authenticates with an API key in the Authorization: Bearer or X-API-Key header. In Claude Desktop, choose No sign-in and add the key as a request header if your dialog has the Request headers section (a beta), or use the mcp-remote bridge. Each person can use their own key, and all of an account's keys share one balance.
Does the connector work in the Claude web app too?
Custom connectors are added to your Claude account under Customize > Connectors, which the web app also shows. The config file route with mcp-remote is desktop only, since it starts a local program. Perceptlayer's server doesn't yet support MCP clients that run inside a web browser.
Is my API key safe in claude_desktop_config.json?
The file stores it in plain text on your machine, readable by anything running as your user. Don't sync or share the file, and revoke the key from your dashboard if it leaks. The request header route stores the value in your Claude account and doesn't show it again after saving.
Which other sources can Claude reach through this server?
All of them. The same three tools reach the whole catalogue of 248 websites and 1,659 endpoints. Ask for Zillow listings or Indeed jobs and the model finds the right endpoint with search_endpoints. Restricted endpoints, with social, personal or SEO data, need the restricted-endpoint terms accepted first.