# Client setup

There are two ways in. Claude connects over OAuth: you paste one URL, sign in, and approve — no token, no config file. Everything else takes a bearer token against `https://nlight.fit/api/mcp` over HTTP.

If you are using Claude, start below. For the token path, mint one first — see [token management](/docs/token-scripts).

## Claude — Desktop, web, and mobile

Open **Settings → Connectors → Add custom connector**, paste:

```
https://nlight.fit/api/mcp
```

Claude sends you to nlight.fit, you sign in if you aren't already, and a screen tells you exactly what it will be able to read. Approve it and you land back in Claude with the tools loaded.

The connection is **read-only** and there is no way to change that from this flow — the server will not issue a write scope to a connector at all, so nothing you approve here can add, edit, or delete an entry. To end it, revoke the connector's token under Settings → API tokens in nlight; it appears under the name of the application that asked.

This is the same flow on Desktop, on claude.ai in a browser, and in the mobile apps. There is no config file to edit and nothing to keep in sync across devices.

## Claude Code

```bash
claude mcp add --transport http nlight https://nlight.fit/api/mcp \
  --header "Authorization: Bearer rt_ro_your_token_here"
```

Confirm it connected:

```bash
claude mcp list
```

## Claude Desktop with a token

Only needed if you want Desktop pinned to a specific token rather than an OAuth connection — for a shared machine, or to hold a credential you rotate yourself. Otherwise use the connector above.

Desktop's config file understands stdio servers only. It has no field for a remote URL, and it does not ignore one it cannot parse — it rewrites the file without that entry, taking every other server in `mcpServers` with it. Bridge the endpoint through `mcp-remote` instead, which Desktop launches as an ordinary local process.

Open Settings → Developer → Edit Config and add:

```json
{
  "mcpServers": {
    "nlight": {
      "command": "npx",
      "args": ["-y", "mcp-remote", "https://nlight.fit/api/mcp", "--header", "Authorization:${AUTH_HEADER}"],
      "env": { "AUTH_HEADER": "Bearer rt_ro_your_token_here" }
    }
  }
}
```

Restart Claude Desktop. The tools appear under the server name `nlight`.

Two details in that snippet are load-bearing. The credential sits in `env` because Desktop mangles arguments containing spaces, and `Authorization: Bearer rt_ro_...` has two. And there is no space after `Authorization:` — `mcp-remote` splits the header at the first colon, so the space that belongs to `Bearer ` lives in the environment variable, where nothing will strip it.

## Cursor

Add the server to `.cursor/mcp.json` in a project, or to `~/.cursor/mcp.json` for every project:

```json
{
  "mcpServers": {
    "nlight": {
      "url": "https://nlight.fit/api/mcp",
      "headers": {
        "Authorization": "Bearer rt_ro_your_token_here"
      }
    }
  }
}
```

## A custom client

The endpoint is ordinary HTTP, so any language works. Nothing MCP-specific is required beyond setting the headers correctly.

```bash
curl -sX POST https://nlight.fit/api/mcp \
  -H "Authorization: Bearer $NLIGHT_TOKEN" \
  -H "Content-Type: application/json" \
  -H "MCP-Protocol-Version: 2026-07-28" \
  -H "Mcp-Method: tools/call" \
  -H "Mcp-Name: get_streak" \
  -d '{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "tools/call",
    "params": { "name": "get_streak", "arguments": { "metric": "vitamins" } }
  }'
```

Three rules to build against:

- Send one JSON-RPC message per request. Arrays are rejected.
- From protocol revision `2026-07-28`, `Mcp-Method` is required and must match the body. `Mcp-Name` is required for `tools/call` and must match `params.name`.
- Do not send an `Origin` header. Requests carrying one are refused as browser traffic.

## Verifying the connection

Ask your client to list the available tools. You should get sixteen. If you would rather check directly:

```bash
curl -sX POST https://nlight.fit/api/mcp \
  -H "Authorization: Bearer $NLIGHT_TOKEN" \
  -H "Content-Type: application/json" \
  -H "Mcp-Method: tools/list" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}' | jq '.result.tools | length'
```

## Troubleshooting

| Symptom | Cause |
| --- | --- |
| `401` with `WWW-Authenticate: Bearer` | No token, or one that is unknown, revoked or expired. Mint a new one. |
| `403 Insufficient scope` | The token lacks `read`. Mint one with `--scopes read`. |
| `403 Requests from browser origins are not accepted` | Your client is sending an `Origin` header. Remove it. |
| `405 Method not allowed` | Something issued a `GET`. The endpoint is POST-only; there is no event stream. |
| `-32020 Header mismatch` | `Mcp-Method` or `Mcp-Name` disagrees with the body, or is missing on protocol `2026-07-28`. |
| `400 Unsupported protocol version` | Pick one from `error.data.supported` in the response. |
| `429` | Rate limited at 120 requests per minute. Honour `Retry-After`. |
| Claude stops at "you started connecting but didn't finish" | The approval never completed. Reopen the connector and approve it; if the screen never appeared, check that you pasted `https://nlight.fit/api/mcp` with no trailing path. |
| The approval screen says the connection can't be completed | The application asked to be sent somewhere it never registered, so the server refused rather than redirect. Nothing was shared. Remove the connector in Claude and add it again. |
| Claude reconnects but the tools are gone | The connector's token was revoked in nlight. Remove the connector and add it again to approve a new one. |
| Claude Desktop lost every server in its config | The config contained a `url` or `headers` field. Desktop validates stdio entries only and rewrites the file without the ones it rejects. Restore the block and use the `mcp-remote` form above — or drop the config entry entirely and use the connector. |

## Good first questions

Your client may already offer these. The server publishes four workflows over `prompts/list` — a morning readiness check, a weekly review, a hypothesis test over any two metrics, and a single-metric explainer — and clients that render prompts show them as pickable entries, so you can run a multi-tool analysis without typing one. See [the MCP server page](/docs/mcp#orientation) for what each does.

Typed from scratch, these exercise different parts of the tool surface:

- "What's my current vitamins streak?"
- "Pull my recovery context for the last two weeks and tell me if I'm overreaching."
- "What correlates with my HRV? Use the correlation edges, not the narrative."
- "Get my daily features for the last 90 days for sleep hours and recovery, and check whether the relationship holds at a one-day lag."

The last one is what the warehouse tools exist for: the client does the analysis itself rather than reading a conclusion.

## Related

- [MCP server](/docs/mcp) — transport, methods and access rules
- [MCP tool reference](/docs/mcp-tools) — all sixteen tools
- [Errors and limits](/docs/errors) — full status code table
