# Connect an agent to Brava

Brava's agent API is the existing MCP endpoint at
[https://mcp.brava.cards/mcp](https://mcp.brava.cards/mcp).
It uses JSON-RPC over Streamable HTTP. It is not a REST API: initialise an MCP
client, discover tools with `tools/list`, and call them with `tools/call`.
The main-domain `/mcp` endpoint is retired; use the MCP subdomain directly.

## Discovery

- [OpenAPI 3.1 specification](/openapi.json)
- [Authorization server metadata](/.well-known/oauth-authorization-server)
- [Protected resource metadata](/.well-known/oauth-protected-resource)
- [Site guide](/llms.txt)
- [Sitemap](/sitemap.xml)

Discovery links on brava.cards return live copies of the canonical server metadata
without a redirect. Clients must use the canonical issuer for OAuth discovery
and issuer validation, rather than treating the main-domain copy as an issuer.
The issuer remains `https://jynzkzucubcmhmidsgki.supabase.co/auth/v1`.
Brava does not operate a second authorization server on its main domain.

## OAuth connection

Use the authorization code flow with PKCE `S256` and a random `state`.
Read the issuer's metadata for authorization, token, registration and JWKS URLs.
Include `resource=https://mcp.brava.cards/mcp` in the authorization request.
Send the resulting access token as `Authorization: Bearer <access_token>`.
Dashboard session tokens are not accepted by the production MCP endpoint.

Dynamic registration is supported by the authorization server, but Brava accepts
only clients with explicitly allowlisted redirect origins. Registration alone
does not grant access. Owners, active owner/manager staff and platform admins can
connect; ordinary staff accounts cannot. Existing supported assistant connection
flows use Brava's consent page at `/oauth/consent`. See the
[privacy policy](/privacy/) before connecting a business.

## Named OAuth scopes

The OpenAPI OAuth security scheme declares the issuer's supported scopes:

| Scope | Permission |
| --- | --- |
| `openid` | Identify the consenting user through OpenID Connect. |
| `profile` | Return profile claims in the ID token and UserInfo response. |
| `email` | Return email claims in the ID token and UserInfo response. |
| `phone` | Return phone claims in the ID token and UserInfo response. |
| `offline_access` | Request refresh access for continued authorised use. |

Request only what the client needs. These scopes govern identity claims and
refresh access. They do not grant or narrow business-data permissions. The MCP
operation intentionally declares no required identity scopes. Business access
is enforced by account roles, client allowlists and resource-bound tokens.
Separate customer-read, analytics-read or feedback-write OAuth scopes are not
implemented. Do not request invented Brava scopes.

## Available capabilities

- `brava_business_overview`: business profile, card rules and aggregate KPIs.
- `brava_activity_breakdown`: bounded activity, grouped by supported dimensions.
- `brava_list_customers`: bounded customer lists within permitted businesses.
- `brava_list_announcements`: recent broadcasts and response windows.
- `brava_data_definitions`: metric definitions and data limitations.
- `brava_list_businesses`: available only when the account can reach multiple businesses.
- `brava_draft_announcement`: a prefilled composer link for a human to review and send.
- `brava_report_missing_capability`: records a product-feedback request, not the requested business action.

Discover current input schemas and account-specific availability using
`tools/list`. Business/customer data tools do not write data. The feedback tool
writes only feature-request records. Announcement drafts do not send messages.

## HTTP errors

Unauthenticated MCP calls return HTTP 401 with a `WWW-Authenticate` challenge
pointing to protected-resource metadata. Refused clients or accounts return 403.
For unknown website paths, send `Accept: text/markdown` to receive a Markdown
error body with HTTP 404 and links back to documentation.
Send `Accept: application/json` for a JSON 404 containing
`error.code`, `error.message`, `error.resolution` and `error.documentation`.
Clients requesting `application/problem+json` receive RFC 9457 problem details
with `type`, `title`, `status` and `detail`, plus recovery fields. The URL and its
query parameters are not echoed into either error body. Existing API errors and
their status codes are preserved; MCP protocol errors continue to use JSON-RPC.

## Read the homepage

Send `Accept: text/markdown` to `/` for the product overview as Markdown.
Send `Accept: text/html` for the interactive website and its server-delivered
overview for browsers without JavaScript. Both representations include
`Vary: Accept`. Quality values and explicit exclusions are honoured; clients
requesting only unsupported homepage formats receive HTTP 406 with the available
types. HEAD returns the same negotiated headers without a response body.
