Browse documentation
Cursor: connect unlob as an MCP server
One JSON file, project or global.
Configuration
Cursor reads mcp.json. Put it in the project at .cursor/mcp.json, or globally at
~/.cursor/mcp.json.
{
"mcpServers": {
"unlob": {
"url": "https://api.unlob.com/mcp",
"headers": { "x-api-key": "ulb_…" }
}
}
}
Then Settings → MCP (or Tools & Integrations, depending on your version), where
unlob should appear with a green indicator and its tools. Toggle it on if it is not
already.
Keep the key out of the repository
.cursor/mcp.json is a project file, and project files get committed. Either add it to
.gitignore, or use the global ~/.cursor/mcp.json and share only the fact that the
server exists.
Cursor’s environment-variable expansion in this file has varied between versions; if
${UNLOB_API_KEY} arrives literally rather than expanded, that is why. A committed literal
key is not a disaster — rotate it in the console — but it is
better avoided.
If the remote form does not work
Older builds only spawn stdio servers. Bridge it:
{
"mcpServers": {
"unlob": {
"command": "npx",
"args": ["-y", "mcp-remote", "https://api.unlob.com/mcp",
"--header", "x-api-key:ulb_…"]
}
}
}
No space after the colon — argument splitting eats it.
Using it
Cursor’s agent picks tools from the task. Being explicit helps:
Use unlob to find corroborated reporting on this, then tell me which sources are independent.
Add the habits to .cursorrules if you use it often:
When using unlob: prefer assemble_context for open questions, web_search for
specific pages. Run corroborate before stating something as established.
The 429 you should not retry
Cursor’s agent retries a failed tool call on its own in some cases, and a 429 looks the
same to it whether it is a per-minute rate limit or a hard-capped key out of credits. Only
the first is worth a retry:
retry-after: 23 → rate limit, retry after that many seconds
(no header) → out of monthly credits, retrying will not help
The header is the real wait — the seconds left in the current minute — so an agent that sleeps a flat second retries into the same window and is refused again.
Add the distinction to .cursorrules alongside the corroboration habit, so the agent does
not loop against a key that has run out of credits:
If a search tool call fails with 429 and no retry-after header, this key is out
of monthly credits — tell me rather than retrying. With retry-after
present, one retry after the given number of seconds is fine.
A 402 is a different failure again — the account itself is suspended, not rate limited or
out of credits — and no retry fixes it. See Rate limits and credits for the
full table of which status means which, and whether it is worth a retry at all.
Project config versus global config, in practice
The choice between .cursor/mcp.json and ~/.cursor/mcp.json is really a question of who
else needs the server configured. A solo project with one contributor gets no benefit from
the project file over the global one — it is one more place to keep the key current, for no
sharing gain. A team repository is the opposite case: the project file, committed with the
key expanded from an environment variable rather than written literally, means every new
clone has unlob available with no manual setup step, which is worth the extra file. The
middle case is a monorepo with several unrelated services, where a project-scoped server
list that only appears in the packages that use it keeps the tool list an agent sees
relevant to what it is actually working on, rather than every server anyone on the team has
ever configured showing up everywhere.
If you work across several client projects that each talk to a different unlob account — common when you are building against your own key in one and a client’s in another — the project file is worth using even solo, specifically so a stray global config cannot point a throwaway prototype at a production key by accident. That is a real enough failure mode to plan around: the global file applies everywhere with nothing in a given repository to show it is in effect, so a key mix-up here tends to surface as unexplained usage on the wrong account rather than as an error.