# MCP Server

DailyPlay exposes a remote **MCP (Model Context Protocol)** server so AI agents — Cursor, Claude,
and other MCP clients — can create games, manage streams, generate assets, and mint play sessions
on behalf of your organization.

:::note[Business Tier Required]
MCP access uses organization API keys, which are available on the **Business tier** or higher.
:::

## Endpoint

| | |
| --- | --- |
| **URL** | `https://app.dailyplay.ai/api/mcp` |
| **Transport** | Streamable HTTP |
| **Auth** | Bearer API key (`dpk_…`) |

Discovery metadata is published at:

```
https://app.dailyplay.ai/.well-known/oauth-protected-resource
```

## Before You Start

1. Create an [API key](/api/api-keys/) in **Connect → API Keys**
2. Enable the **MCP scopes** your agent needs (leave empty for session-token minting only)
3. Copy the key value shown once at creation time (`dpk_…`)

DailyPlay authenticates with a **Bearer API key**, not OAuth. In clients that offer both, choose
header / API-key auth and skip the sign-in flow.

## Client Setup

### Claude Desktop, Claude.ai, and Cowork

Use a **custom connector** (remote MCP). Claude reaches the server from Anthropic's cloud — the
endpoint must be publicly reachable.

1. Open **Customize → Connectors** (Team/Enterprise owners: **Organization settings → Connectors**)
2. Click **Add custom connector** (or **Add → Custom → Web**)
3. Set:
   - **Name:** `DailyPlay` (or any label)
   - **MCP server URL:** `https://app.dailyplay.ai/api/mcp`
4. Under authentication, choose **No sign-in** (DailyPlay does not use OAuth yet)
5. Add a **request header**:
   - Header: `Authorization`
   - Value: `Bearer dpk_YOUR_KEY` (include the `Bearer ` prefix and the space)
6. Save, then enable the connector for the chat via the **+** menu → **Connectors**

:::note[Request headers availability]
Request-header auth for custom connectors is rolling out and may not appear for every plan or
organization. If you do not see **Request headers**, use the [stdio bridge](#claude-desktop-local-config)
below, or set up [Claude Code](#claude-code) / [Cursor](#cursor) instead.
:::

#### Claude Desktop local config

`claude_desktop_config.json` only accepts **stdio** servers. To point Desktop at DailyPlay's remote
URL, bridge with [`mcp-remote`](https://www.npmjs.com/package/mcp-remote) (requires Node.js 18+):

**macOS:** `~/Library/Application Support/Claude/claude_desktop_config.json`  
**Windows:** `%APPDATA%\Claude\claude_desktop_config.json`

```json
{
  "mcpServers": {
    "dailyplay": {
      "command": "npx",
      "args": [
        "-y",
        "mcp-remote",
        "https://app.dailyplay.ai/api/mcp",
        "--header",
        "Authorization:${AUTH_HEADER}"
      ],
      "env": {
        "AUTH_HEADER": "Bearer dpk_YOUR_KEY"
      }
    }
  }
}
```

Restart Claude Desktop after saving. Do not put a bare `url` field in this file — Desktop ignores
remote HTTP entries there.

### Claude Code

```bash
claude mcp add --transport http dailyplay https://app.dailyplay.ai/api/mcp \
  --header "Authorization: Bearer dpk_YOUR_KEY"
```

Prefer `claude mcp add` (user or local scope) over hand-editing `.mcp.json` so headers are applied
on every request. Equivalent JSON:

```json
{
  "mcpServers": {
    "dailyplay": {
      "type": "http",
      "url": "https://app.dailyplay.ai/api/mcp",
      "headers": {
        "Authorization": "Bearer dpk_YOUR_KEY"
      }
    }
  }
}
```

### Cursor

1. Open **Cursor Settings → MCP** (or edit the config file)
2. Add a remote server entry:

**Project:** `.cursor/mcp.json`  
**Global:** `~/.cursor/mcp.json`

```json
{
  "mcpServers": {
    "dailyplay": {
      "url": "https://app.dailyplay.ai/api/mcp",
      "headers": {
        "Authorization": "Bearer dpk_YOUR_KEY"
      }
    }
  }
}
```

You can keep the key out of the file with env interpolation:

```json
"Authorization": "Bearer ${env:DAILYPLAY_API_KEY}"
```

Enable the server under **Available Tools**, then ask the agent to list templates or games to
confirm the connection.

### Other MCP clients

Any client that supports **Streamable HTTP** remote MCP works the same way:

| Setting | Value |
| --- | --- |
| URL | `https://app.dailyplay.ai/api/mcp` |
| Auth header | `Authorization: Bearer dpk_…` |
| Alternative header | `x-api-key: dpk_…` |

If the client only supports stdio, use the [`mcp-remote`](#claude-desktop-local-config) bridge
pattern from the Claude Desktop section.

## Verify the Connection

After connecting, ask the agent something that requires a tool, for example:

- “List DailyPlay game templates”
- “List games in my organization”

If tools are missing or every call fails with `401` / scope errors:

- Confirm the key starts with `dpk_` and was copied in full
- Confirm the needed [MCP scopes](#mcp-scopes) are enabled on the key
- Confirm the connector or MCP server is **enabled** for the current chat
- Restart the client after editing config files

## Authentication

MCP tools authenticate with the same organization API keys used for [session tokens](/api/session-tokens/).

| Header | Value |
| --- | --- |
| `Authorization` | `Bearer dpk_…` |
| or `x-api-key` | `dpk_…` |

The organization is taken from the key — clients never supply `org_id` for mutations.

:::caution[Scopes are deny-by-default]
API keys with **no MCP scopes** can only mint play-session tokens via the REST API. They cannot
call MCP tools until you enable the scopes you need.
:::

## MCP Scopes

Enable scopes when creating or editing a key:

| Scope | What it unlocks |
| --- | --- |
| `mcp:templates:read` | List and inspect game templates |
| `mcp:games:read` | List and read games and prizes |
| `mcp:games:write` | Create/update games, status, and prizes |
| `mcp:streams:read` | List and read streams |
| `mcp:streams:write` | Create and update streams |
| `mcp:connections:read` | List org integrations (no raw credentials) |
| `mcp:connections:write` | Create integrations and link them to streams |
| `mcp:ai` | Brand extract, funnel suggestions, image generation |
| `mcp:sessions:write` | Mint one-time play session tokens |

See the full [MCP tools reference](/api/mcp-tools/) for every tool and its required scope.

## Typical Agent Workflow

A common flow for branding a new game from a template:

1. `list_templates` / `get_template` — read asset schemas (`name`, size, `transparent`, `promptWrapper`)
2. `generate_image` — create each prompt-image asset (transparent assets are chroma-keyed)
3. `create_game` — pass a **flat** `config` that merges `baseGameConfig` with asset URLs keyed by `asset.name` (e.g. `character`, `obstacle`)
4. `set_game_prizes` — optional prize table (chances must total 100% per `min_score` tier)
5. `set_game_status` — publish when ready

:::tip[Flat config keys]
Do **not** nest image URLs under `config.assets`. Use the template asset `name` as a top-level key
on `config`. `update_game` shallow-merges `config`, so you can patch one asset without wiping the rest.
:::

## Braze / Connections Example

Connection tools require an **admin** (or owner) role on the key's organization.

1. `create_stream` (`mcp:streams:write`)
2. `create_connection` with `provider: "braze"` and `credentials: { api_key, rest_endpoint }`
3. `link_stream_connection` with the new `stream_id` and `connection_id`

Credential values are write-only — list/get responses never return raw secrets.

## Security Notes

- Prefer **least-privilege scopes** — enable only the tools your agent needs
- Combine MCP scopes with [game/stream allowlists](/api/api-keys/#key-scoping) to limit which resources a key can touch
- Rotate or revoke keys from the dashboard if a key is exposed
- Rate limits on the API key also apply to MCP tool calls

## Next Steps

- [MCP Tools Reference](/api/mcp-tools/) — every tool, scope, and role
- [API Keys](/api/api-keys/) — create keys and manage MCP scopes
- [Session Tokens](/api/session-tokens/) — one-time play access without MCP