# MCP

Faceless ships a Model Context Protocol (MCP) server so agent runtimes (Claude Code, Claude Desktop, Cursor and any other MCP client) can call the API as tools. There are two ways to connect: the remote server over streamable HTTP, or a local stdio server. Both need an API key from your team settings at https://faceless.so/team.

## Remote server (nothing to install)

The remote server lives at `https://faceless.so/api/v1/mcp` and speaks the streamable HTTP transport. Authenticate with the same `Authorization` header as the REST API.

Claude Code:

```bash
claude mcp add --transport http faceless https://faceless.so/api/v1/mcp \
  --header "Authorization: Bearer fl_live_..."
```

Any MCP client that supports streamable HTTP works the same way: point it at the URL and send `Authorization: Bearer fl_live_...` with every request.

## Local server (stdio)

For clients that only speak stdio, run the server locally. Two equivalent ways: `npx -y faceless-mcp`, or `faceless mcp` if the [CLI](/developers/docs/cli) is installed. Both read the key from the `FACELESS_API_KEY` environment variable.

Claude Code:

```bash
claude mcp add faceless --env FACELESS_API_KEY=fl_live_... -- npx -y faceless-mcp
```

Claude Desktop (Settings > Developer > Edit Config, `claude_desktop_config.json`):

```json
{
  "mcpServers": {
    "faceless": {
      "command": "npx",
      "args": ["-y", "faceless-mcp"],
      "env": { "FACELESS_API_KEY": "fl_live_..." }
    }
  }
}
```

Cursor (`.cursor/mcp.json` in your project, or the global `~/.cursor/mcp.json`):

```json
{
  "mcpServers": {
    "faceless": {
      "command": "npx",
      "args": ["-y", "faceless-mcp"],
      "env": { "FACELESS_API_KEY": "fl_live_..." }
    }
  }
}
```

Use the remote server when you want zero install and always-current tools; use the local one when your client only speaks stdio or your network policy prefers a locally spawned process.

## Tools

All 27 API operations are exposed as tools named `faceless_*`, and each respects the key's scopes (a missing scope surfaces as a `forbidden_scope` error). The core ones an agent reaches for:

- `faceless_get_me`, `faceless_get_credits`: identity, scopes and budget
- `faceless_list_voices`, `faceless_list_options`: catalogs to choose voices, styles and models
- `faceless_create_video`, `faceless_get_video_status`, `faceless_render_video`, `faceless_get_render`: the create, poll, render, poll lifecycle
- `faceless_create_caption_video`: caption existing footage
- `faceless_update_video`, `faceless_publish_post`, `faceless_schedule_post`, `faceless_cancel_post`, `faceless_get_calendar`: publishing and scheduling
- `faceless_create_series`, `faceless_list_series`, `faceless_get_series`, `faceless_update_series`, `faceless_delete_series`, `faceless_generate_series_episode`, `faceless_list_series_episodes`: automated series
- `faceless_list_videos`, `faceless_get_video`, `faceless_delete_video`, `faceless_list_accounts`, `faceless_create_asset`, `faceless_get_analytics`: the rest of the surface

Mutating tools accept an optional `idempotencyKey` argument with the same semantics as the REST `Idempotency-Key` header: retries with the same key and arguments replay the stored result instead of re-running (and re-charging). Pass one when a tool call might be retried.

Tool results use the same envelope and error types as the REST API; see [errors and rate limits](/developers/docs/errors-and-rate-limits). Rate limits also apply per key, so a busy agent should back off on `rate_limited`.

## Related

- Prefer commands over tools? The [CLI](/developers/docs/cli) covers the same surface.
- A packaged Claude Skill with ready-made workflows: `npx skills add Side-Products/faceless-skill` (https://github.com/Side-Products/faceless-skill).
- The machine-readable surface: https://faceless.so/llms.txt and https://faceless.so/api/v1/openapi.json.
