---
title: MCP server
description: Connect Claude, ChatGPT, Cursor, Codex, and other MCP clients to the hosted BrainyShorts MCP server.
sidebar:
  label: MCP server
  icon: plug
---

BrainyShorts runs a hosted Model Context Protocol server. Your client signs in with OAuth, so there's no API key to paste.

| | |
| --- | --- |
| URL | `https://www.brainyshorts.com/api/mcp` |
| Transport | Streamable HTTP (stateless) |
| Auth | OAuth 2.1, PKCE (S256), dynamic client registration |
| Scopes | `brainy:read`, `brainy:write` |
| Discovery | `https://www.brainyshorts.com/.well-known/mcp.json` |

## Connect a client

**Claude Code**

```bash
claude mcp add --transport http brainy-shorts https://www.brainyshorts.com/api/mcp
```

Then run `/mcp` inside Claude Code and choose **Authenticate**.

**Claude.ai / Desktop**

Open **Settings → Connectors → Add custom connector**, name it BrainyShorts, and paste `https://www.brainyshorts.com/api/mcp`. Claude opens the sign-in page when you first connect.

**ChatGPT**

With developer mode enabled, open **Settings → Apps & Connectors → Create**, paste `https://www.brainyshorts.com/api/mcp`, and choose OAuth authentication.

**Codex**

Add this to `~/.codex/config.toml`:

```toml
[mcp_servers.brainy-shorts]
url = "https://www.brainyshorts.com/api/mcp"
```

Then run `codex mcp login brainy-shorts`.

**Cursor**

Add this to `~/.cursor/mcp.json`. The `mcp-remote` bridge runs the OAuth flow on a local callback:

```json
{
  "mcpServers": {
    "brainy-shorts": {
      "command": "npx",
      "args": ["-y", "mcp-remote", "https://www.brainyshorts.com/api/mcp"]
    }
  }
}
```

**VS Code**

Add this to `.vscode/mcp.json`:

```json
{
  "servers": {
    "brainy-shorts": { "type": "http", "url": "https://www.brainyshorts.com/api/mcp" }
  }
}
```

## Tools

The server has 26 tools. It has no resources or prompts.

### Read (`brainy:read`)

| Tool | What it does |
| --- | --- |
| `brainy_list_accounts` | Connected social and article accounts |
| `brainy_list_posts` | Posts and their per-platform delivery status |
| `brainy_get_post_batch` | Status of a bulk batch |
| `brainy_get_analytics` | Metrics by platform, account, or post |
| `brainy_list_skills` | Available skills and versions |
| `brainy_get_skill` | One skill's instructions |
| `brainy_list_automations` | Scheduled automations |
| `brainy_list_articles` | Long-form articles |
| `brainy_get_article` | One article and its destinations |

### Write (`brainy:write`)

| Tool | What it does |
| --- | --- |
| `brainy_reserve_media_upload` | Reserve a managed upload and get a presigned URL |
| `brainy_complete_media_upload` | Verify and finish the upload |
| `brainy_create_post` | Create a draft or scheduled post; it never publishes immediately |
| `brainy_create_posts_bulk` | Up to 100 drafts or schedules, idempotent by `batch_id` and `item_key` |
| `brainy_update_scheduled_post` | Edit caption, time, or targets |
| `brainy_update_posts_bulk` | Update up to 100 scheduled posts |
| `brainy_cancel_scheduled_post` | Return a scheduled post to draft |
| `brainy_publish_post` | Publish now; requires `confirmation: "USER_REQUESTED_PUBLISH_NOW"` |
| `brainy_create_article` | Create or schedule an article |
| `brainy_publish_article` | Publish an article to its destinations |
| `brainy_delete_article` | Delete an article |
| `brainy_register_executor` | Register a local runner for scheduled runs |
| `brainy_create_automation` | Create a scheduled automation from a skill |
| `brainy_update_automation` | Change an automation |
| `brainy_pause_automation` / `brainy_resume_automation` | Pause or resume one |
| `brainy_delete_automation` | Delete one |

:::note
Immediate publishing is gated on purpose. An agent should call `brainy_publish_post` only when the person has asked for it in so many words. Everything else creates drafts or schedules that a person can review in the dashboard.
:::

## Typical flow

1. `brainy_list_accounts` to find target account ids.
2. `brainy_reserve_media_upload` with the file's type, byte length, SHA-256, and MD5. PUT the bytes to `upload_url` with exactly the returned `upload_headers`. Skip the upload when the response says `already_uploaded: true`.
3. `brainy_complete_media_upload` to verify the upload.
4. `brainy_create_post` with `action: "schedule"` and a future `scheduled_at`.

## OAuth details

For client authors: an unauthenticated request returns `401` with

```
WWW-Authenticate: Bearer resource_metadata="https://www.brainyshorts.com/.well-known/oauth-protected-resource/api/mcp"
```

- Authorization server metadata: `/.well-known/oauth-authorization-server`
- Registration: `POST /oauth/register`, public clients only (`token_endpoint_auth_method: none`)
- Redirect URIs must be HTTPS, or HTTP on `localhost`, `127.0.0.1`, or `[::1]`
- The authorize request must include `resource=https://www.brainyshorts.com/api/mcp` and an S256 `code_challenge`
- Access tokens last 1 hour; refresh tokens last 30 days and rotate on every use
