> Source: https://wexa.ai/docs/surfaces/mcp/cursor

# Cursor

Cursor configures servers in a file called `mcp.json`, and where you put that file decides who gets
the connection. This matters more for Wexa than for most servers, because a Wexa connection
carries a project identifier and often a credential, and a repository is shared.

## Choose the file first

**`.cursor/mcp.json` in the repository root** applies to that project only. It is the right choice
when a repository maps to one Wexa project and you want every developer on the repository to get
the same connection — which is usually what you want, since the Wexa project holding the context
for a codebase is a property of the codebase.

**`~/.cursor/mcp.json` in your home directory** applies to every project you open. Use it when you
work across several repositories that share one Wexa project, or when you would rather keep the
configuration out of version control entirely.

## With an API key

A remote server in Cursor is an entry with a `url` and a `headers` block — no `command`, no `args`,
no `type`, which are for local servers launched as processes.

```json
{
  "mcpServers": {
    "fabric": {
      "url": "https://fabric.wexa.ai/mcp/proj_abc123",
      "headers": {
        "Authorization": "Bearer ${env:FABRIC_API_KEY}"
      }
    }
  }
}
```

`${env:NAME}` reads from the environment Cursor was launched with, so export `FABRIC_API_KEY` from
your shell profile and the file holds no secret. Cursor also resolves `${userHome}` and
`${workspaceFolder}` in both `url` and `headers`, which is occasionally useful for pointing a local
development gateway at the right place.

The project identifier belongs in the path, not in a header. Wexa refuses a credential used
against a URL naming a different project than the credential's own, which is deliberate: it turns a
copy-paste mistake into an error rather than into one project's data showing up under another
project's name.

## With OAuth instead

If you would rather not manage a key, give Cursor an `auth` block and let it run the authorization
flow:

```json
{
  "mcpServers": {
    "fabric": {
      "url": "https://fabric.wexa.ai/mcp/proj_abc123",
      "auth": {
        "CLIENT_ID": "${env:FABRIC_CLIENT_ID}",
        "CLIENT_SECRET": "${env:FABRIC_CLIENT_SECRET}",
        "scopes": ["fabric:query.read", "fabric:docs.read"]
      }
    }
  }
}
```

Registering a client by hand, to get identifiers to put in that block, is one request against
Wexa and needs no credential:

```bash
curl -sS -X POST https://fabric.wexa.ai/oauth/register \
  -H 'Content-Type: application/json' \
  -d '{"client_name":"cursor","redirect_uris":["http://127.0.0.1:9876/callback"]}'
```

```json
{
  "client_id": "fab_client_Z6R3UrscnP5HLdkFA0MB4NV3",
  "client_secret": "fab_secret_4UCnz3b76ess8OjyC1qOg1qg",
  "client_name": "cursor",
  "redirect_uris": ["http://127.0.0.1:9876/callback"]
}
```

The `scopes` list above asks for read access only. Wexa offers seven grants —
`fabric:query.read`, `fabric:ontology.write`, `fabric:docs.read`, `fabric:codesync.write`,
`fabric:agent.run`, `fabric:orchestrate.read` and `fabric:orchestrate.write` — and a consent that
names none of them falls back to `query.read` and `docs.read`. Ask for what the editor actually
needs: an agent that should be able to write context needs `fabric:ontology.write`, and one that
should run process flows needs the two `orchestrate` grants.

## Turn it on and check it

Cursor lists configured servers under **Customize** in the sidebar, where each one has a toggle.
Enable Wexa there; a server present in the file but switched off is the commonest reason for a
configuration that looks right and does nothing.

Once it is on, the tool list should appear beside the server's name: 62 tools, on every deployment.
A tool whose backing service the deployment has not configured is still listed and answers with a
not-configured error — the [overview](/docs/surfaces/mcp/overview) explains what that looks like.

Then ask the agent something that has to go through Wexa. The two tools worth trying first are
[`search-code`](/docs/tools/search-code) and [`fetch-code`](/docs/tools/fetch-code), because they
read the code graph your repository is synced into and work on every deployment:

> Use Wexa to find where the retry policy is implemented, then show me that function.

If the agent answers from the open editor buffer instead, the server is not connected — Cursor falls
back to its own search silently.

## Fixing a connection

**Nothing appears and there is no error.** The server is disabled under **Customize**, or the JSON
is malformed. Cursor is quiet about a file it could not parse.

**`410 Gone`.** The URL has no project in it. `https://fabric.wexa.ai/mcp` is permanently retired
and will not return; the working form is `/mcp/{projectId}`.

**`401 invalid_token`.** `${env:FABRIC_API_KEY}` resolved to nothing, most often because Cursor was
launched from the desktop rather than from a shell and never saw your profile. Launch it from a
terminal once to confirm, then set the variable somewhere the desktop session reads.

**`403`, different project.** The credential and the URL name different projects.

## Where to go next

**Concepts — Code sync**
How a repository reaches the code graph the code tools read.

**Surfaces — Custom clients**
The authorization flow Cursor runs for you, in full.

**Reference — All tools**
Every tool an editor agent can reach, and what each one refuses.
