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

# MCP authorization reference

> OAuth 2.1 reference for the Wavix MCP server: discovery endpoints, dynamic client registration, PKCE, scope values, token lifetimes, and revocation.

The Wavix MCP server is an OAuth 2.1 protected resource. Wavix operates the authorization server. For what a grant binds and how permissions behave at runtime, see the [MCP server overview](/mcp/overview).

## Identifiers

|                             |                             |
| --------------------------- | --------------------------- |
| Protected resource          | `https://mcp.wavix.com/mcp` |
| Authorization server issuer | `https://app.wavix.com`     |
| Token audience (`aud`)      | `https://mcp.wavix.com/mcp` |
| Access token format         | JWT, signed by the issuer   |

## Discovery and endpoints

An unauthenticated request returns `401` with an [RFC 9728](https://www.rfc-editor.org/rfc/rfc9728.html) `WWW-Authenticate` challenge naming the protected resource metadata document, which names the authorization server.

| Purpose                                  | URL                                                            |
| ---------------------------------------- | -------------------------------------------------------------- |
| Protected resource metadata (RFC 9728)   | `https://mcp.wavix.com/.well-known/oauth-protected-resource`   |
| Authorization server metadata (RFC 8414) | `https://app.wavix.com/.well-known/oauth-authorization-server` |
| OpenID Connect discovery                 | `https://app.wavix.com/.well-known/openid-configuration`       |
| JSON Web Key Set                         | `https://app.wavix.com/.well-known/jwks.json`                  |
| Authorization                            | `https://app.wavix.com/oauth/authorize`                        |
| Token                                    | `https://app.wavix.com/oauth/token`                            |
| Revocation (RFC 7009)                    | `https://app.wavix.com/oauth/revoke`                           |
| Client registration (RFC 7591)           | `https://app.wavix.com/oauth/register`                         |

The step from `mcp.wavix.com` to `app.wavix.com` is a metadata pointer the client resolves itself, not an HTTP redirect.

## Client registration

Dynamic Client Registration ([RFC 7591](https://www.rfc-editor.org/rfc/rfc7591.html)) is **enabled and open**: a client registers itself at `https://app.wavix.com/oauth/register` with no initial access token and no prior arrangement with Wavix. Clients that publish a client-ID metadata document are supported alongside it.

Registration alone grants nothing. Every token still requires a Wavix user to complete the consent screen, and mandatory PKCE plus exact `redirect_uri` matching bound what a registration can do. A client registering a plaintext `http://` loopback redirect URI is treated as a native application, so the callback matches on any port; every other component must match exactly.

## Authorization request

| Requirement                                                          |                                                                                                                                                             |
| -------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Grant type                                                           | `authorization_code`                                                                                                                                        |
| PKCE                                                                 | **Required on every request.** `code_challenge_method` must be `S256`; `plain` is rejected                                                                  |
| Client authentication                                                | None — public clients only                                                                                                                                  |
| `resource` ([RFC 8707](https://www.rfc-editor.org/rfc/rfc8707.html)) | Accepted and validated, never required. When omitted, `aud` defaults to `https://mcp.wavix.com/mcp`. A non-matching value is rejected with `invalid_target` |
| Refresh tokens                                                       | Request the `offline_access` scope                                                                                                                          |

## Token lifetimes

| Token               | Lifetime                            |
| ------------------- | ----------------------------------- |
| Access token        | 900 seconds (15 minutes)            |
| Refresh token       | 2,592,000 seconds (30 days)         |
| Authorization code  | 60 seconds, single use              |
| Consent interaction | 300 seconds (5 minutes), single use |

Refresh tokens rotate: each refresh invalidates the token presented. A replayed authorization code revokes the grant.

## Scopes

The Wavix MCP server advertises **27 scope values**: 13 permission groups, each with `:read` and `:write`, plus `offline_access`. A `:write` grant includes read access to the same group.

| Scope group   | Consent screen label | Covers                                            |
| ------------- | -------------------- | ------------------------------------------------- |
| `account`     | Account              | Profile details and account settings              |
| `billing`     | Billing              | Balance, invoices, and payment history            |
| `calls`       | Calls                | Placing calls, call history, and speech analytics |
| `campaigns`   | Campaigns            | Voice campaigns, 10DLC brands, and short links    |
| `embeddable`  | Embeddable           | Tokens for the in-browser calling widget          |
| `messages`    | Messages             | Sending and reading SMS and MMS                   |
| `numbers`     | Numbers              | Searching, buying, and managing phone numbers     |
| `recordings`  | Recordings           | Stored call recordings                            |
| `subaccounts` | Subaccounts          | Sub-organizations and their settings              |
| `trunks`      | Trunks               | Viewing and configuring SIP trunks                |
| `two_fa`      | 2FA and OTP          | Sending and verifying one-time passcodes          |
| `validator`   | Number validation    | Carrier and line-type lookups                     |
| `webhooks`    | Webhooks             | Call webhook endpoints                            |

`offline_access` is not a permission group and does not appear on the consent screen. It requests a refresh token.

### Permission levels

A grant assigns each group **No access**, **Read**, or **Write** — the same three levels a restricted API key uses. There is no higher level: an OAuth grant can never exceed write on any group.

### Scopes are bounded by the user's permissions

A scope is grantable only if the user's own account permissions allow it, and granted scopes are intersected with those permissions again on every request. Most groups map to one account permission. Three require several, and are grantable only when the user's role permits all of them:

| Scope group | Requires all of             |
| ----------- | --------------------------- |
| `numbers`   | `dids`, `buy`, `cart`       |
| `calls`     | `cdr`, `call_transcription` |
| `campaigns` | `voice_campaign`, `ten_dlc` |

`webhooks` and `embeddable` have no account permission counterpart and are grantable to any authenticated user.

## How scopes are enforced

1. **Tool listing.** A tool the granted scopes do not cover is omitted from `tools/list` and is not visible to the agent at all.
2. **Tool call.** A call from a stale tool list is refused with an MCP-level tool error inside a `200` response, not an HTTP status. The message names the missing scope.
3. **API gateway.** A request reaching the Wavix API without a covering scope is refused with `403`.

API-key management endpoints (`/v1/api-keys`) match no scope rule and are denied to every OAuth token by design, so their tools are hidden from all OAuth connections. A connection authenticated with a Wavix API key is not scope-filtered: it sees the full catalogue, and the Wavix API enforces that key's own scopes.

## Revocation

| Method                                    | Effect                                                                                                                                               |
| ----------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Connected apps** in the Wavix portal    | Revokes the grant. Any user manages their own; the master account and any sub-account whose role is **Admin** manages every grant across the account |
| `POST https://app.wavix.com/oauth/revoke` | RFC 7009. A client revokes its own tokens and the grant behind them                                                                                  |
| Account state change                      | Blocking or suspending a user, or removing their account level, revokes every grant that user created                                                |

Revocation is immediate. OAuth tokens bypass the gateway's authorization cache, so the grant's state is re-read on every request rather than at token expiry.

## Rate limits and network access

The Wavix MCP server applies no IP allowlisting, user-agent filtering, or bot protection. Rate limits on the OAuth endpoints are not yet defined.
