# Connect Claude Code

> Let Claude Code and other MCP clients work in nexxus as the signed-in person. How an administrator allows it, how each person connects their own client, what the client may do, how changes are confirmed and how to disconnect.

nexxus is an MCP server. Claude Code, and other clients that speak the Model Context Protocol, can connect to it and work with your data the way the AI Assistant does in the app: look up a customer, read a project with its rates, find the documents of a case, create a holiday or change a record. The client signs in as you in the browser and from then on has exactly your rights. It never sees your password.

A developer who already works in Claude Code all day can ask it, without leaving the terminal, which projects of a customer are still open, and have it book a correction. Before an action of the app changes a record, Claude Code shows the change as nexxus describes it, and nothing happens until the developer accepts.

## Before you start

- An administrator allows external AI clients for the organisation (step 1 below). Until then every client is refused.
- Claude Code installed on your computer. Other MCP clients work too if they support the Streamable HTTP transport and OAuth sign-in; see [What the client needs](#what-the-client-needs).
- Your nexxus account. If it has an authenticator app, keep it at hand: confirming the connection asks for a code.

## Connect a client

<Steps>

1. **Administrator, once:** open <MenuPath to="Administration > Operations > System configuration" />. In the section <Ui>External AI clients (MCP)</Ui>, switch on <Ui>Allow external AI clients</Ui> and click <Ui>Save</Ui>. Below the switch, <Ui>Address for MCP clients</Ui> shows the address clients connect to.

2. Open <MenuPath to="My profile > AI clients" />. Under <Ui>Command for Claude Code</Ui>, copy the command. It looks like this, with your address:

   ```bash
   claude mcp add --transport http nexxus https://<your nexxus address>/api/mcp
   ```

3. Run the command in a terminal, then start Claude Code. It reports that the server needs authentication. Type `/mcp`, select `nexxus` and choose <Ui>Authenticate</Ui>. Claude Code opens your browser.

4. Sign in on the nexxus login page as usual. If you are already signed in to nexxus in that browser, this step is skipped.

5. nexxus shows the consent page. It names the client as it calls itself, your account, where the answer goes (`localhost` and a port for Claude Code) and what the client may do. Enter the code from your authenticator app, or your password if your account has no app, and click <Ui>Verbinden</Ui>.

6. The browser returns to Claude Code, which reports that it is connected. Ask it something, for example "Which record types can you read in nexxus?".

</Steps>

The consent page only ever appears in German. Confirm it only if you started the connection yourself a moment ago.

### Other clients

claude.ai and Claude Desktop add remote MCP servers as custom connectors with the same address. nexxus accepts claude.ai's sign-in callback (`https://claude.ai/api/mcp/auth_callback` and `https://claude.com/api/mcp/auth_callback`). This page has been checked with Claude Code; the claude.ai screens are not described here.

#### What the client needs

| Requirement | Why |
|---|---|
| Streamable HTTP transport (protocol `2025-03-26`, `2025-06-18` or `2025-11-25`) | nexxus offers no other transport to external clients |
| OAuth with PKCE (S256) and dynamic client registration (RFC 7591) | The client registers itself at `/oauth2/register` and signs the person in |
| A redirect address on the person's own computer (`http://localhost:<port>/...`, `127.0.0.1` or `[::1]`), or one the operator has allowed | nexxus refuses to send sign-in codes anywhere else |
| Elicitation (questions from the server to the person) | Without it, nexxus refuses every action that needs your confirmation |

## What the client may do

The client gets the same tools as your assistant in the app, as far as your organisation has switched them on, with your rights inside every tool. Tools that need the app's chat are left out, for example opening a page in your browser or creating a file inside a conversation. Three things are added:

| Tool | What it does |
|---|---|
| `nx_record_types`, `nx_record_search`, `nx_record_get` | Read records of every area you can open in the app, with the filters of the list view and the access check of the detail view. These are also available to the AI Assistant in the app. |
| `nx_action_execute` | Run an action of the app: create, change, delete, or a module's own action. Only for external clients. |
| `nx_mcp_connections` | Show your connected clients and the address to connect a new one |

The two permission keys behind the new tools, `RECORD_READ` and `ACTION_EXECUTE`, come with the built-in connector „Aktionen in der App“ (In-app actions).

### Actions are confirmed first

Before `nx_action_execute` changes anything, nexxus checks the input as the preview card in the app does. If a check fails, the client gets the reason and nothing is asked. If all checks pass, nexxus asks you through the client. Claude Code shows a dialog that starts with "MCP server "nexxus" requests your input", followed by the change as nexxus describes it, for example:

```text
Feiertag ändern
Datensatz: MCP-Testtag
- Name: MCP-Testtag-neu
```

<Ui>Accept</Ui> runs the change, <Ui>Decline</Ui> or <Ui>Esc</Ui> leaves everything as it was. A deletion is not ticked in advance. If nobody answers within 10 minutes, nothing happens. A client that cannot ask questions gets a refusal and changes nothing. Write tools of connectors and modules ask the same way.

Every other tool that changes something asks too, for example saving a note about you, a knowledge item or a skill. There the question names the tool and lists its inputs, and nothing is ticked in advance. Claude Code's own permission rules for MCP tools apply on top.

## Disconnect

<MenuPath to="My profile > AI clients" /> lists every connected client with <Ui>connected since</Ui>, <Ui>last used</Ui> and where it runs. <Ui>Disconnect</Ui> withdraws its access at once: its next request is refused, and Claude Code asks you to authenticate again under `/mcp`. To use the client again, connect it anew.

An administrator who switches off <Ui>Allow external AI clients</Ui> cuts every connection of the organisation at once. The connections come back when the switch is turned on again, as long as their sign-in has not expired.

## What happens behind the scenes

<Sequence
  actors={[
    { name: 'Claude Code', icon: 'terminal' },
    { name: 'Browser', icon: 'monitor' },
    { name: 'nexxus', icon: 'server' },
  ]}
  steps={[
    { from: 0, to: 2, label: 'POST /api/mcp without a token: 401 with the metadata address' },
    { from: 0, to: 2, label: 'Read the metadata, register at /oauth2/register' },
    { from: 0, to: 1, label: 'Open /oauth2/authorize with a PKCE challenge' },
    { from: 1, to: 2, label: 'Sign in, consent with code or password' },
    { from: 2, to: 0, label: 'Code to http://localhost:<port>/callback' },
    { from: 0, to: 2, label: 'Exchange the code at /oauth2/token' },
    { from: 0, to: 2, label: '/api/mcp with the access token' },
  ]}
  caption="The client finds everything on its own. All it needs is the MCP address."
/>

- **Discovery.** A request without a token gets `401` with `WWW-Authenticate: Bearer resource_metadata="..."`. The metadata (`/.well-known/oauth-protected-resource/api/mcp`) names nexxus as the authorization server, whose metadata names the registration endpoint and the scope `mcp`.
- **Tokens.** The access token is valid for 1 hour, the refresh token for 30 days. Every refresh replaces the refresh token, and the old one stops working. nexxus stores both only as a SHA-256 hash and looks the access token up on every request. That is why disconnecting and switching off take effect at once, and why a restart of nexxus does not sign anyone out.
- **Rights.** Every request runs as the person behind the token. Actions and record reads run the same checks as the app's own pages.
- **Results.** Dates come as ISO strings, for example `2026-12-28`.

| Address | Purpose |
|---|---|
| `/api/mcp` | The MCP endpoint (POST; DELETE ends a session) |
| `/.well-known/oauth-protected-resource/api/mcp` | Which authorization server and scope the MCP endpoint uses (RFC 9728) |
| `/.well-known/oauth-authorization-server` | The authorization server's metadata (RFC 8414) |
| `/oauth2/register` | Self-registration of the client (RFC 7591) |
| `/oauth2/authorize`, `/oauth2/consent`, `/oauth2/token` | Sign-in, consent, tokens |

## When something goes wrong

| What you see | Cause and fix |
|---|---|
| The consent page says „Externe KI-Clients sind in dieser Organisation nicht freigeschaltet.“ and offers no <Ui>Verbinden</Ui> | External AI clients are switched off. An administrator switches them on, see step 1. |
| A connected client suddenly gets every request refused with the same sentence | An administrator switched external AI clients off. |
| „Das Passwort ist falsch.“ or „Der Code ist ungültig oder es gab zu viele Versuche.“ on the consent page | The proof for the connection was wrong. Enter it again. |
| Claude Code shows `nexxus` under `/mcp` as needing authentication | The connection was disconnected, or the refresh token expired after 30 days. Choose <Ui>Authenticate</Ui> again. |
| The client reports „Diese Aktion braucht die Bestätigung der Person, aber dieser MCP-Client kann keine Rückfragen stellen (MCP elicitation).“ | The client cannot ask you, so nexxus did not run the change. Use a client with elicitation, or make the change in the app. |
| Registration fails with `invalid_redirect_uri` | The client wants to send the sign-in code to an address that is neither on your computer nor allowed by the operator. |

:::note[For self-hosters]
| Setting | Purpose |
|---|---|
| `NEXXUS_SSO_ISSUER` | The public HTTPS address of the backend. The MCP address is this value plus `/api/mcp`, and tokens are bound to it. Set it on every deployed installation. |
| `nexxus.mcp.oauth.redirect-uris` | Redirect addresses besides the person's own computer that clients may register, matched exactly. Default: the two claude.ai callbacks above. |
| `nexxus.mcp.oauth.access-token-ttl` | Lifetime of access tokens. Default `PT1H` |
| `nexxus.mcp.oauth.refresh-token-ttl` | Lifetime of refresh tokens. Default `P30D` |
:::

## Next steps

<CardGrid>
  <LinkCard title="Work with Claude Code" description="What to ask once connected, how changes are confirmed, and the limits." href="/mcp/usage/" />
  <LinkCard title="MCP tools" description="The tools a connected client gets, by area." href="/mcp/tools/" />
  <LinkCard title="Sign-in and OAuth" description="How people sign in, and the other meanings of OAuth in nexxus." href="/setup/sign-in/" />
  <LinkCard title="Security" description="Two-factor authentication, sessions and personal API tokens." href="/setup/security/" />
</CardGrid>