# Troubleshooting

Find your symptom below. Each section says what the error means and what to do
about it.

## My AI app can't reach Lune

If the connection fails outright, with a timeout or "couldn't reach the
server":

1. Check the URL. The server is `https://mcp.luneresearch.com`. The older
   `https://mcp.luneresearch.com/mcp` and `https://mcp.luneresearch.com/v1/mcp`
   still work.
2. Check that your network reaches it. From a terminal:

   ```sh
   curl -sS -o /dev/null -w "%{http_code}\n" \
     https://mcp.luneresearch.com/.well-known/oauth-protected-resource
   ```

   You should see `200`. A `5xx` means Lune is having trouble. Try again in a
   few minutes, and email support if it doesn't clear. No answer at all points
   to a network or DNS problem on your side.

3. Open the [status page](https://luneresearch.com/status). It checks from your browser whether the MCP
   server responds. It doesn't post incident reports.

## Test the connection by hand

List the tools with an access key. This call doesn't count as a request.

```sh
curl -sS https://mcp.luneresearch.com \
  -H "Authorization: Bearer lune_your_access_key" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'
```

A working key gets the tool list back as an event stream: an `event: message`
line, then a `data:` line holding the JSON-RPC response. Other answers mean:

- `401`: the key is wrong or revoked. See the next section.
- `405`: the request went out as `GET`. The server takes `POST` only. A browser
  that opens the URL is sent to [Connect Lune to your AI app](https://luneresearch.com/docs/mcp)
  instead.
- `406`: the `Accept` header is missing one of its two types.
- `415`: the `Content-Type` header isn't `application/json`.
- `400`: the body isn't valid JSON, or a JSON-RPC batch had more than 50
  messages. Fix the JSON or split the batch.
- `403` with "origin not allowed": the request came from a web page. Call the
  server from a backend or a native app.

## I get "401 unauthorized" or "invalid_token"

The server didn't accept the credential.

- **Apps you connected by signing in (OAuth).** The app renews its access token
  on its own. If the error keeps coming back, the sign-in has ended. Someone
  revoked it on the Credentials page, it went unused for 90 days, or a reused
  refresh token ended it. Disconnect Lune in the app and connect again.
- **Access keys.** The key is mistyped, revoked, or past an expiry date set when
  it was created. Create a new key on the
  [Credentials page](https://luneresearch.com/dashboard/settings/credentials)
  and replace the old one. Members can revoke only their own keys; owners and
  admins can revoke any key in the team.
- **Suspended accounts.** The hosted server answers a suspended account with the
  same `401` as a bad credential, and the local stdio server returns an error
  that says the account is suspended. If reconnecting never clears the `401`,
  or you see that message, email
  [appeal@luneresearch.com](mailto:appeal@luneresearch.com). New credentials
  won't help.

### If you're building the connector

OAuth discovery starts with a request that has no credential:

1. `POST` to the server without an `Authorization` header. The `401` response
   carries
   `WWW-Authenticate: Bearer resource_metadata="https://mcp.luneresearch.com/.well-known/oauth-protected-resource", scope="papers:read guidance:read account:read"`.
   An expired or unverifiable token gets the same header with
   `error="invalid_token"` added, which tells the client to refresh it.
2. Fetch that resource metadata. Its `authorization_servers` entry is
   `https://api.luneresearch.com`.
3. Fetch `https://api.luneresearch.com/.well-known/oauth-authorization-server`
   for the endpoints. Then register, authorize, and exchange the code as
   [auth.md](https://luneresearch.com/auth.md) shows.

When the token endpoint refuses a form-encoded request, it answers `400` with a
flat body, `{"error": "...", "error_description": "..."}`. A body that isn't
form-encoded, or that lacks `grant_type`, gets `422` with a `{"detail": [...]}`
list instead. Registration answers `422` when `redirect_uris` is missing and
`400` when the list is empty or holds a URI it refuses. The common `error`
values:

| `error`                | Cause                                                                                                                                                                          | Fix                                                            |
| ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------- |
| `invalid_grant`        | The code expired after 10 minutes, was already used, or doesn't match the client ID, redirect URI, or PKCE verifier. Or the refresh token expired, was revoked, or was reused. | Start the authorization again.                                 |
| `invalid_target`       | `resource` differs from the value on the authorization request or on the refresh token.                                                                                        | Send `resource=https://mcp.luneresearch.com` on every request. |
| `invalid_redirect_uri` | Registration refused a redirect URI: `http` on a host other than loopback, a fragment, or an unsafe scheme.                                                                    | Register an `https`, loopback, or private-use URI.             |

An authorization request fails with `400` when its `redirect_uri` isn't one of
the registered URIs (character for character, except the port of an `http`
loopback URI), and with `422` when `scope` is missing.
[auth.md](https://luneresearch.com/auth.md) lists the errors a client usually
meets.

## I get "403" or a missing-scope error

The credential works but lacks the scope a tool needs. The tool list shows
every tool whatever the scopes; only the call fails.

- **OAuth.** The server answers `403` with a `WWW-Authenticate` header whose
  `error` is `insufficient_scope` and whose `scope` names the missing scope.
  Disconnect Lune in the app and connect again. A client should authorize again
  with the full set, `papers:read guidance:read account:read`, because a new
  grant carries only the scopes its request names.
- **Access keys.** The tool returns an error that names the missing scope.
  Create a key that includes it. [Permissions](https://luneresearch.com/docs/concepts/scopes) lists
  which tools need which scope.

## I'm out of requests, or I get "429"

These are two different limits.

**Out of requests.** When neither the daily allowance nor credits can cover a
call, the tool returns an error whose last line carries `http_status=402` and
a `quota_reason`:

- `no_capacity`: the daily allowance and credits are both used up. Wait for the
  reset at midnight UTC, buy credits, or upgrade on the
  [Billing page](https://luneresearch.com/dashboard/settings/billing). A
  credit pack is $0.99 for 300 extra requests.
- `batch_too_large`: a batch tool asked for more items than your remaining
  allowance covers, and more than your credits cover. A call is paid from one
  or the other, never both. Retry with fewer queries, papers, or claims.
- `retry_now`: capacity came back while the call was in flight. Retry it once.

**429.** A short per-second burst guard stops runaway scripts. It has nothing to
do with your daily allowance. Wait the number of seconds in
`retry_after_seconds`, retry the same call, and have the app make fewer calls
at once.

[Plans, requests & credits](https://luneresearch.com/docs/concepts/quotas-and-billing) explains the
allowance and how calls are counted.

## My AI app connects but the tools don't show up

- Restart the AI app. Most clients fetch the tool list only at startup.
- In a web AI app, remove the connector and add it again.
- In Claude Desktop, quit fully (closing the window isn't enough) and reopen it.

Tips for each kind of app are in [Local AI agents](https://luneresearch.com/docs/mcp/stdio) and
[Web AI apps](https://luneresearch.com/docs/mcp/remote).

## Requests count against the wrong team

Apps you connected by signing in always bill your personal team. An access key
bills the team it was created in. To use a shared team's plan, create an access
key in that team and connect with it.
[Teams & access keys](https://luneresearch.com/docs/concepts/orgs-and-keys) has the details.

## Search results look wrong, missing, or outdated

- **Coverage.** Lune indexes top-tier peer-reviewed venues. The
  [Venues page](https://luneresearch.com/conferences) and the
  `list_conferences` tool list the venues whose main-track papers are all
  indexed. Search also finds papers from venues Lune is still completing. A
  paper from any other venue isn't in the corpus.
- **Freshness.** Lune adds a venue's new papers when it next crawls that venue.
  Crawls run by hand, not on a schedule, so a recent paper can take weeks to
  appear.
- **Phrasing.** A full natural-language query ("methods for retrieval-augmented
  generation that reduce hallucination on long-form QA") finds more than a
  keyword list ("RAG hallucination").
- **Venue filters.** A `conference` name Lune doesn't know returns an error, not
  unfiltered results. A `venues` list keeps the names Lune knows and drops the
  rest, and fails if it knows none of them. An ambiguous name returns the
  candidates to choose from. Ask the agent to check `list_conferences` for the
  exact short names.

## I'm still stuck

Email [support@luneresearch.com](mailto:support@luneresearch.com) with:

- the AI app you use (Claude, Cursor, and so on)
- the tool name, if the error came from a tool call
- when it happened, in UTC
- the exact error text
- whether it's a new setup or one that used to work

We usually reply the same day.
