<!-- AvatarFactory Docs · https://avatarfactory.in/docs/ai/mcp-reference · Full map: https://avatarfactory.in/llms.txt -->

# MCP & OAuth reference

The AvatarFactory MCP server for client builders and coding agents: transport, OAuth discovery, endpoints, token lifetimes and tool schemas.

Everything an MCP client needs to connect to AvatarFactory. If you only want to use
the connector in Claude, the [text-to-video connector](/docs/ai/text-to-video) page is
all you need.

## Server

| Property | Value |
| --- | --- |
| Endpoint | https://www.avatarfactory.in/api/mcp |
| Transport | Streamable HTTP, stateless. POST JSON-RPC; responses are JSON (no SSE stream, no Mcp-Session-Id). |
| Auth | OAuth 2.1 bearer token on every request (Authorization: Bearer …). |
| Server name | avatarfactory |
| Server info | title AvatarFactory, a one-line description, websiteUrl, and the AvatarFactory icon at 192×192 and 32×32 (PNG). |
| Capabilities | tools, with server instructions |
| CORS | Any origin; Authorization is the only credential, never cookies. |

Requests must send `Accept: application/json, text/event-stream`. The server sends no
notifications of its own, so clients need no standalone `GET` stream.

## Authorization

The server follows the MCP authorization spec. AvatarFactory is its own authorization
server, and users sign in with their normal AvatarFactory account.

### Discovery

An unauthenticated request gets `401` with a pointer to the resource metadata:

```http
HTTP/1.1 401 Unauthorized
WWW-Authenticate: Bearer resource_metadata="https://www.avatarfactory.in/.well-known/oauth-protected-resource/api/mcp"
```

| Document | URL |
| --- | --- |
| Protected resource (RFC 9728) | /.well-known/oauth-protected-resource |
| Authorization server (RFC 8414) | /.well-known/oauth-authorization-server |

Both documents also answer with any path suffix, e.g.
`/.well-known/oauth-protected-resource/api/mcp`.

### Endpoints

| Endpoint | URL | Notes |
| --- | --- | --- |
| Registration (RFC 7591) | /api/oauth/register | Open dynamic client registration. Public clients only. |
| Authorization | /connect/authorize | The user signs in and approves in the browser. |
| Token | /api/oauth/token | authorization_code and refresh_token grants. |
| Revocation (RFC 7009) | /api/oauth/revoke | Revoking any token ends the whole connection. |

### Rules

- **Public clients only.** Register with `token_endpoint_auth_method: "none"`. There are
  no client secrets.
- **PKCE with S256 is required** on every authorization request.
- **Redirect URIs** must be `https`, or `http` on a loopback host (`localhost`,
  `127.0.0.1`, `[::1]`). A loopback URI may use a different port than the one registered
  (RFC 8252), since desktop and CLI clients pick a free port each run.
- **Scope:** the only scope is `videos`. Omitting it grants `videos`.
- **Resource:** if you send a `resource` parameter (RFC 8707), it must be this server's
  MCP endpoint.

| Credential | Lifetime | Notes |
| --- | --- | --- |
| Authorization code | 5 minutes | Single use. A failed exchange still burns it. |
| Access token | 1 hour | Bearer token for /api/mcp. |
| Refresh token | 30 days | Rotates: each use returns a new pair and spends the old one. |

> Registration is rate-limited to 20 clients per IP address per hour. Register once and
>   reuse the client ID.

## Tools

The server sends instructions on `initialize` that tell the model to ask for the
avatar, the orientation and the background when the user has not given them. Every tool acts as the signed-in
user.

### list_avatars

Lists the avatars that can star in a video: the user's published avatars and the public
library. Read-only. No arguments.

Returns text with one line per avatar: its name and `avatarId`, with library avatars that
need a paid plan marked `[paid plans only]`.

### create_video

Makes an MP4 of an avatar speaking the script, then waits up to 45 seconds for it.

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `avatarId` | `string` | — | The avatar the user chose, from list_avatars or an ID they gave. When omitted, no video is made: the result lists the user's avatars and asks the model to let the user choose. |
| `text` **(required)** | `string` | — | The exact words spoken. 1–2000 characters. |
| `aspect` | `"16:9" \| "9:16" \| "1:1"` | `"9:16"` | Frame shape. Vertical unless the user asks otherwise. |
| `resolution` | `720 \| 1080` | `720` | The short side in pixels. |
| `background` | `string` | `"#FFFFFF"` | "#RRGGBB", "#RRGGBBAA", "rgba(r, g, b, a)" or "transparent". Opaque gives an MP4; any transparency gives a WebM with an alpha channel. |

When the video is ready, the result has a text block with the link, the speech length,
the frame size and the link's expiry, plus a `resource_link` to the MP4
(`mimeType: video/mp4`). If it is still rendering after 45 seconds, the text names the
`videoId` to pass to `get_video`.

### get_video

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `videoId` **(required)** | `string` | — | From create_video. |

Returns the same shape as `create_video`: the link once ready (with a fresh 24-hour
expiry), the current status while rendering, or the failure reason.

### Errors

Failures come back as a tool result with `isError: true` and a message the model can
relay to the user.

| Situation | Message (abridged) |
| --- | --- |
| Unknown or unpublished avatar | Avatar not found |
| Three videos already rendering | At most 3 videos can render at once |
| Plan minutes used up | The plan's limit message |
| Voice generation failed | The voice couldn't be generated… |
| Render service unavailable | The video renderer is unavailable right now… |
| Render exceeded its time limit | The render took too long and was stopped… |

## Example session

```bash
# 1. Initialize
curl -s https://www.avatarfactory.in/api/mcp \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18","capabilities":{},"clientInfo":{"name":"my-client","version":"1.0.0"}}}'

# 2. Make a video
curl -s https://www.avatarfactory.in/api/mcp \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -d '{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"create_video","arguments":{"avatarId":"4HY925aPdlVmRKpfPmaf","text":"Hello! I was made with AvatarFactory.","aspect":"9:16"}}}'
```
