# nLight.fit sandbox

```
POST https://nlight.fit/api/sandbox
```

No account. No token. The same MCP protocol and the same eighteen tool schemas as the production server, answered from a member record that was generated rather than lived.

## Why it exists

Signup is open, so an agent evaluating this integration *could* register. It should not have to, and mostly it should not want to.

An empty account is a bad place to develop against: nearly every interesting tool here answers from months of history, so a brand new record makes the whole surface look like it returns nothing. The alternative — pointing a half-built integration at somebody's real bloodwork — is worse. The sandbox gives you a populated record with no signup, no credential to manage, and no real person's data in the loop while you are still getting the request shapes right.

Everything a client needs in order to decide — the tool catalog, the argument schemas, the response shapes, the error behaviour, the rate-limit conventions — is reachable immediately, at the cost of the data being invented.

## Try it

```bash
curl -sS https://nlight.fit/api/sandbox \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json, text/event-stream' \
  -H 'MCP-Protocol-Version: 2026-07-28' \
  -H 'Mcp-Method: tools/list' \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'
```

Calling a tool:

```bash
curl -sS https://nlight.fit/api/sandbox \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json, text/event-stream' \
  -d '{"jsonrpc":"2.0","id":2,"method":"tools/call",
       "params":{"name":"get_recovery_context","arguments":{"days_back":14}}}'
```

To connect an MCP client, use `https://nlight.fit/api/sandbox` as the server URL and leave authentication empty. [Client setup](/docs/clients) covers the per-client configuration; the only difference is that no OAuth step happens.

## What is the same as production

- **The tool catalog.** `tools/list` returns the same eighteen tools with the same names, descriptions and input schemas. They are read from the production catalog, not copied, so the two cannot drift apart.
- **Argument validation.** Arguments are checked against the same schemas, so a call the production server would reject is rejected here with the same message.
- **The transport.** Streamable HTTP, stateless JSON-RPC 2.0 over POST, the same `MCP-Protocol-Version` negotiation, the same `405` on `GET`.
- **The rate-limit policy.** The same quota, reported in the same `RateLimit` and `RateLimit-Policy` headers, keyed by source address instead of by member.
- **The response envelope.** `content[].text` carrying JSON, `isError` set the same way.

## What is different

- **The data is synthetic.** Roughly 180 days of a generated ledger across ten metrics and four habits, plus a fixed lab panel, methylation profile, supplement regimen and Mission Statement. It is deterministic — the same request returns the same numbers — and anchored to today, so the most recent day is always yesterday or today.
- **Every response says so.** Each tool result carries `"sandbox": true` and a `notice` field stating in words that the values are generated and belong to no real person. The server instructions delivered at `initialize` say the same thing, so a model connected to the sandbox is told before it reads a single number.
- **The analysis is simpler.** Correlations are raw pairwise Pearson over the generated series. The production engine applies partial correlation with covariate controls and Benjamini-Hochberg correction before it will call anything a finding, and assigns a tier accordingly. The sandbox computes its correlations honestly over its own data but claims no tier, and says so in the payload.
- **There is no account.** `get_profile` returns a fixed synthetic Mission Statement and constraint list. Nothing is writable and nothing persists. The endpoint never opens a database handle and never resolves a credential, so there is no call by which a sandbox request could reach a real member record.

## The synthetic member

Ten continuous metrics — weight, sleep, HRV, resting heart rate, WHOOP recovery and strain, steps, protein, water and mood — and four binary habits: workout, reading, vitamins and no alcohol.

The series are shaped rather than random. There is a weekend dip in the behaviour metrics, a slow downward weight trend, and a recovery score derived from that night's sleep, so the correlation the tools report between sleep and recovery is genuinely present in the data rather than asserted over noise. A client that cross-checks a reported correlation against the raw series it also fetched will find the two agree.

## When to stop using it

Switch the URL to `https://nlight.fit/api/mcp` and add a Bearer token once a member has connected their account. Nothing else in your client changes — that is the property the sandbox exists to give you.

See [MCP server](/docs/mcp) for the production endpoint and [authentication](/docs/authentication) for how tokens are obtained.
