> ## Documentation Index
> Fetch the complete documentation index at: https://docs.lucenthq.com/llms.txt
> Use this file to discover all available pages before exploring further.

# MCP quickstart

> Connect Claude, Cursor, Claude Desktop, or any MCP-compatible client to your Lucent data.

Lucent exposes a [Model Context Protocol](https://modelcontextprotocol.io)
server so any MCP-compatible client — claude.ai, Claude Desktop, Claude
Code, Cursor, Windsurf, Codex, VS Code — can query your organization's
signals, issues, and insights directly.

The server runs at `https://app.lucenthq.com/api/mcp`. Tokens are
read-only by default: agents can list and fetch data. The one write
operation, [`update_issue`](/mcp/tools#update-issue), requires the
`write:issues` scope — grant it by checking **Allow issue status
updates** when creating an API key.

## Two ways to connect

Lucent supports both authentication methods MCP clients use today.

| Method                  | Best for                                                                                                                                                                                 | How it works                                                                                                                                |
| ----------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- |
| **OAuth (recommended)** | Hosted MCP clients that auto-discover OAuth — claude.ai custom connectors and Claude Desktop via remote MCP today. Other clients can adopt it as their MCP transports add OAuth support. | The client redirects you to Lucent's consent screen, you approve once, and it gets a refreshing access token automatically — no copy/paste. |
| **Static bearer token** | Clients without OAuth support, CI scripts, smoke tests, or anything that needs a stable long-lived credential.                                                                           | Mint a `luc_mcp_…` token in **Organization settings → MCP** and paste it into the client's config.                                          |

Both methods hit the same endpoint and return the same tools. The MCP
endpoint dispatches by token prefix (`luc_oat_…` for OAuth, `luc_mcp_…`
for static), so existing static-token integrations keep working
unchanged. Pick OAuth if your client supports it.

## Option A — OAuth flow

Use this for any client that supports remote MCP with OAuth (claude.ai
"custom connectors", Claude Desktop's remote-MCP support, etc.).

<Steps>
  <Step title="Add Lucent as a custom connector">
    In your MCP client, add a new server pointing at
    `https://app.lucenthq.com/api/mcp`. The client will discover Lucent's
    OAuth endpoints automatically via
    `/.well-known/oauth-protected-resource` and
    `/.well-known/oauth-authorization-server`.
  </Step>

  <Step title="Approve the connection">
    Your browser opens to Lucent's consent screen. Sign in if you aren't
    already, then review:

    * The client name (every DCR-registered app is shown with a
      **Third-party** badge — verify the redirect URL matches the tool
      you actually opened).
    * The requested scopes (`read:lucent`, plus `write:issues` if the
      client asked for issue-update access).
    * The redirect URL the auth code will be returned to.

    Leave **Remember this choice** ticked (default) so future requests
    from the same client don't prompt again. Click **Approve**.
  </Step>

  <Step title="Tokens are minted automatically">
    The client gets an access token (1 hour TTL) and a refresh token (30
    days). It rotates them transparently — you don't see or copy
    anything. As long as the client refreshes at least once every 30 days
    and you don't revoke the consent, it stays connected indefinitely.
  </Step>

  <Step title="Manage authorized apps">
    Under **Organization settings → MCP → Connected apps**, you can see
    every OAuth client that has authorized your org and revoke any of
    them with one click. Revoke immediately invalidates all of that
    client's outstanding tokens.
  </Step>
</Steps>

<Note>
  Lucent uses RFC 7591 Dynamic Client Registration with PKCE (S256) and
  rotating refresh tokens. See the [OAuth reference](/mcp/oauth) for
  protocol-level details.
</Note>

### Currently allowed origins

Lucent's OAuth surface only redirects back to a vetted set of origins,
to defend against open-redirect and auth-code injection. Hosted MCP
clients are accepted from:

* `https://claude.ai`
* `https://claude.com`

Native MCP clients can register loopback redirect URIs
(`http://127.0.0.1:<port>`, `http://[::1]:<port>`,
`http://localhost:<port>`).

If you'd like another hosted client added, email
[support@lucenthq.com](mailto:support@lucenthq.com).

## Option B — Static bearer token

Use this for CLI clients and editors that don't speak OAuth, or for
scripts that need a stable token.

<Steps>
  <Step title="Open Organization settings">
    Open [**Organization settings → MCP**](https://app.lucenthq.com/organization?tab=mcp) in your Lucent Dashboard.
  </Step>

  <Step title="Click Create token">
    Give the token a name so you can identify it later (e.g. `my laptop`,
    `cursor-prod`). Names are free text up to 64 characters.
  </Step>

  <Step title="Copy the plaintext token">
    The token is shown **once** in a dialog and starts with `luc_mcp_…`.

    <Warning>
      This is the only time the plaintext is visible. Lucent stores a SHA-256
      hash, not the original token. If you lose it, revoke it and create a new
      one.
    </Warning>
  </Step>
</Steps>

### Configure your client

The dashboard auto-fills the snippets below with your real token until
you navigate away — copy whichever one matches your client.

<Tabs>
  <Tab title="Claude Code CLI">
    Register the server once for the current project:

    ```bash theme={null}
    claude mcp add --transport http lucent https://app.lucenthq.com/api/mcp \
      --header "Authorization: Bearer luc_mcp_..."
    ```

    Claude Code stores this in `~/.claude.json` and sends the bearer header
    on every request. Run `/mcp` inside Claude Code to confirm the connection
    and list the tools.
  </Tab>

  <Tab title="Cursor">
    Cursor speaks streamable HTTP natively — no proxy needed. Open
    **Settings → MCP → Add new server** and paste:

    ```json theme={null}
    {
      "mcpServers": {
        "lucent": {
          "url": "https://app.lucenthq.com/api/mcp",
          "headers": { "Authorization": "Bearer luc_mcp_..." }
        }
      }
    }
    ```
  </Tab>

  <Tab title="Claude Desktop">
    Edit `~/Library/Application Support/Claude/claude_desktop_config.json`
    (macOS) or the equivalent on your platform, then restart the app:

    ```json theme={null}
    {
      "mcpServers": {
        "lucent": {
          "command": "npx",
          "args": [
            "-y",
            "mcp-remote",
            "https://app.lucenthq.com/api/mcp",
            "--header",
            "Authorization: Bearer luc_mcp_..."
          ]
        }
      }
    }
    ```

    `mcp-remote` proxies streamable HTTP for clients that haven't
    implemented it natively.
  </Tab>

  <Tab title="Codex CLI">
    Add to `~/.codex/config.toml` and restart the CLI:

    ```toml theme={null}
    [mcp_servers.lucent]
    command = "npx"
    args = ["-y", "mcp-remote", "https://app.lucenthq.com/api/mcp", "--header", "Authorization: Bearer luc_mcp_..."]
    ```
  </Tab>

  <Tab title="VS Code">
    Add to `.vscode/mcp.json` in your workspace (requires GitHub Copilot
    with MCP support):

    ```json theme={null}
    {
      "servers": {
        "lucent": {
          "type": "http",
          "url": "https://app.lucenthq.com/api/mcp",
          "headers": { "Authorization": "Bearer luc_mcp_..." }
        }
      }
    }
    ```
  </Tab>

  <Tab title="Windsurf">
    Add to `~/.codeium/windsurf/mcp_config.json` and reload Windsurf:

    ```json theme={null}
    {
      "mcpServers": {
        "lucent": {
          "command": "npx",
          "args": [
            "-y",
            "mcp-remote",
            "https://app.lucenthq.com/api/mcp",
            "--header",
            "Authorization: Bearer luc_mcp_..."
          ]
        }
      }
    }
    ```
  </Tab>

  <Tab title="Smoke test (curl)">
    Verify the endpoint and token work end-to-end:

    ```bash theme={null}
    curl -sS -X POST https://app.lucenthq.com/api/mcp \
      -H "Authorization: Bearer luc_mcp_..." \
      -H "Content-Type: application/json" \
      -H "Accept: application/json, text/event-stream" \
      -d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'
    ```

    An OAuth access token (`luc_oat_...`) works in the same `Authorization`
    header — the MCP endpoint accepts both prefixes.
  </Tab>
</Tabs>

## Try a tool

Once the client is connected, ask your agent a question that needs your
Lucent data:

* *"What are my most critical unresolved issues right now?"* → `list_issues`
* *"Show me issue 87b3a6b6-5af5-438b-a39c-eff148a68ccb."* → `get_issue`
* *"What signals have I configured and which are matching most?"* → `list_signals`
* *"Summarize the last week of insights."* → `list_insights`

See the [tool reference](/mcp/tools) for the full set of arguments and
return shapes.

## Security model

* **Read-only.** The MCP server exposes no write tools. Agents cannot
  create, update, or delete data in your org.
* **Organization-scoped.** Every tool query compiles to `WHERE org_id = ?`
  where `org_id` comes exclusively from the token's auth context.
  There is no way for a client to override it.
* **192-bit token entropy.** All tokens (`luc_mcp_`, `luc_oat_`,
  `luc_ort_`, `luc_oac_`) are 24 random bytes from a CSPRNG, encoded
  with `base64url`. The prefix lets you spot them in configs.
* **SHA-256 hashed at rest.** Plaintext tokens are never stored on disk
  or in logs — only the hex digest.
* **PKCE (S256) is required** for the OAuth code grant — no `plain`
  challenges, no implicit grant.
* **Refresh-token rotation.** Each refresh issues a new pair and
  invalidates the previous refresh. Reuse of a rotated refresh token
  revokes the entire chain (RFC 6819 §5.2.1.1).
* **Auth-code single-use.** Authorization codes expire in 60 seconds and
  are bound to a `redirect_uri`. Reusing a code revokes any tokens
  previously issued from it.
* **Per-token usage timestamps.** The `Last used` columns in the
  dashboard show recent activity for both static tokens and OAuth
  clients. Revoke and rotate if anything looks off.
* **Instant revocation.** Revoking either a static token or a connected
  OAuth app sets `revoked_at`; the next request returns `401`
  immediately.

## Troubleshooting

<AccordionGroup>
  <Accordion title="Failed to parse JSON / SDK auth failed">
    Your client likely couldn't reach the OAuth discovery endpoint. Confirm
    you can `GET https://app.lucenthq.com/.well-known/oauth-protected-resource`
    and it returns valid JSON (not an HTML page). If it's blocked by a
    corporate proxy, add an exception.
  </Accordion>

  <Accordion title="401 Unauthorized on every request">
    Check that your client is sending the `Authorization: Bearer ...` header.
    Confirm the token wasn't revoked in the dashboard (Organization
    settings → MCP). Static tokens start with `luc_mcp_`; OAuth access
    tokens start with `luc_oat_`. Token comparison is exact — no trailing
    whitespace, full prefix required.
  </Accordion>

  <Accordion title="OAuth consent screen says 'Authorization request rejected'">
    Lucent returns a single opaque error for every authorize-time failure
    (unknown `client_id`, mismatched `redirect_uri`, malformed PKCE
    parameters) so an attacker can't enumerate registered clients. The
    most common cause is a `redirect_uri` whose origin isn't in our
    allowlist (`https://claude.ai`, `https://claude.com`, or loopback).
    Re-register the connector in your MCP client and try again.
  </Accordion>

  <Accordion title="Tools work, then suddenly start returning 401">
    Likely the connected app was revoked from **Organization settings →
    MCP → Connected apps** — that nukes its outstanding access and
    refresh tokens. The next request from the client should trigger a
    fresh OAuth flow (consent screen included, since the prior consent
    record was also revoked).
  </Accordion>

  <Accordion title="500 Internal Server Error">
    The streamable HTTP transport is the only supported transport. If your
    client is trying to fall back to legacy SSE (`/api/sse` or
    `/api/message`), upgrade to a client that supports streamable HTTP or
    use `mcp-remote` as a proxy.
  </Accordion>

  <Accordion title="I lost my plaintext token">
    Static tokens are only visible once, at creation time. Revoke the
    token in **Organization settings → MCP** and create a new one. OAuth
    clients don't have this problem — re-authorize from the client and a
    new token is minted.
  </Accordion>
</AccordionGroup>
