# Authenticate MCP calls with OAuth or API keys

> Let AI clients sign in to a Bonnard app through OAuth, and connect scripts and agents with an API key that Bonnard shows one time.

Updated: 2026-10-15

AI clients connect to a Bonnard app when a person signs in through OAuth. Scripts and agents that cannot open a
browser send an API key instead.

Table: OAuth sign-in and API keys compared

| | OAuth sign-in | API key |
| --- | --- | --- |
| For | Claude, ChatGPT and other AI clients | Scripts, CI jobs and agents |
| Setup | Install, then sign in | An admin creates a key |
| Connects as | The person who signs in | You, or a customer's user |
| Lasts | 30 days, then sign in again | Until revoked |

## Requirements

- An app. Its production URL answers after you [publish it](https://bonnard.ai/docs/apps/publish-and-staging.md).
- The Admin role in your Bonnard workspace, to create API keys.

## Sign in through OAuth

An AI client finds the sign-in details at the app's URL and registers itself, with no client ID to copy. Who signs in
depends on the app's [audience](https://bonnard.ai/docs/apps/audience.md):

- **Your customers' users** sign in on the production URL with their work email and a 6-digit code, or with their
  company's single sign-on. WorkOS works today, and other providers are available on
  request.
- **Members of your workspace** sign in with their Bonnard account, on the staging URL and on **Internal** apps.

**Authorize access** then names the client and what it can do. Select **Authorize** or **Deny**.

[Image: The Authorize access page: claude.ai wants to connect to your Bonnard account, with a Verified origin badge, what it will be able to do, and the Deny and Authorize buttons]

**Verified origin** names the domain that the client proved it comes from, for example `claude.ai`. Otherwise the page
shows **Unverified identity**: approve only if you recognise the redirect host that the page names.

A sign-in is for one app URL, so production and staging each need their own.

### Details for client developers

Table: Bonnard's OAuth endpoints and settings

| Item | Value |
| --- | --- |
| Authorization server metadata | `https://app.bonnard.ai/.well-known/oauth-authorization-server` |
| Protected resource metadata | `https://app.bonnard.ai/.well-known/oauth-protected-resource/mcp/<slug>` |
| Client registration | Dynamic and open, at `https://app.bonnard.ai/reg`, or a client ID metadata document |
| Grant types | `authorization_code` with PKCE (`S256`), and `refresh_token`, rotated on each use |
| Scopes | `openid`, `profile`, `email`, `offline_access` |
| Tokens | For one app URL (RFC 8707). Access tokens last 15 minutes |

A request with no token gets `401` and this header:

```text
WWW-Authenticate: Bearer resource_metadata="https://app.bonnard.ai/.well-known/oauth-protected-resource/mcp/<slug>", scope="openid"
```

## Create an API key

Your own key connects as you and reads the whole database. It works only on apps whose audience is **Internal** or
**All customers**, on a **No tenancy** database. Other apps need a customer user's key. Bonnard shows each key one time.

### Create your own key

1. In the console at `app.bonnard.ai`, select **Apps**, then your app, or **Open app details** in the setup steps,
   then **Settings**.
2. In the **API keys** card, enter an optional name, for example `laptop`.
3. Select **Generate API key**. Then copy the key.

The key works for that app only. For one key for all those apps, select **Settings** in the console menu, then
**API keys**, then **+ Create key**, and set **Scope** to **Any server (unscoped)**.

### Create a key for a customer's user

1. In the console, select **Customers**, then the customer.
2. In the user's row menu, select **API keys**, then **+ Create key**.
3. Enter a **Label**, for example `Nightly sync`.
4. Optional: in **Server scope**, select one app.
5. Select **Create key**. Then copy the key.

The key connects as that user, with their role and their customer's tenant (the value that marks the customer's data in
your database).

## Send the key

Send the key in an `Authorization` header to the [app's URL](https://bonnard.ai/docs/apps/publish-and-staging.md#production-and-staging-urls). Keys start with `bmk_`.

```text
Authorization: Bearer <key>
```

For example, in [Claude Code](https://code.claude.com/docs/en/mcp):

```bash
claude mcp add --transport http <name> https://app.bonnard.ai/mcp/<slug> \
  --header "Authorization: Bearer <key>"
```

A key gets the same tools as a sign-in. That includes `save_chart` and `save_dashboard` when the app has them on.

## Revoke a key

A revoke is immediate and final.

1. Find the key. Your own keys are under **Settings**, then **API keys**. A customer user's keys are in their
   **API keys** panel.
2. Select **Revoke**, then **Revoke key**.

To end a customer user's sign-ins and keys immediately, select **Sign out & revoke keys** in their row menu. A deactivated
member loses their keys.

## Related

- [Install in AI clients](https://bonnard.ai/docs/apps/install-in-ai-clients.md): install an app in Claude, ChatGPT or Cursor.
- [Audience](https://bonnard.ai/docs/apps/audience.md): who can connect to an app.
- [Publish and staging](https://bonnard.ai/docs/apps/publish-and-staging.md): the production and staging URLs.
