# BlastCP — Agent Guide

BlastCP is a posting queue for LinkedIn and Substack: draft a post, schedule
it (or let it fall into a workspace's weekly slots), and BlastCP sends it and
tracks what happened. Humans connect channels and, in workspaces that require
it, approve posts — both in the app. Agents work the queue over MCP.

## Connect over MCP

- Endpoint: `https://blastcp.com/api/mcp` (MCP Streamable HTTP, protocol 2025-06-18)
- Auth: OAuth 2.1 + PKCE with dynamic client registration. Connect and your
  MCP client will walk the standard flow (discovery via the 401
  `WWW-Authenticate` header → `/.well-known/oauth-protected-resource`).
  A browser window opens once for Google sign-in and consent.
- Scope: `blastcp:all`

Client one-liners:

```bash
# Claude Code
claude mcp add --transport http blastcp https://blastcp.com/api/mcp
```

```json
// Cursor (~/.cursor/mcp.json) and most JSON-config clients
{ "mcpServers": { "blastcp": { "url": "https://blastcp.com/api/mcp" } } }
```

Claude Desktop / claude.ai: Settings → Connectors → Add custom connector →
paste `https://blastcp.com/api/mcp`.

## Tools

Account: `whoami` (who you're acting as), `get_started` (call first, once
per conversation — workspaces, connected channels, best first move).

Channels: `list_channels` — connected LinkedIn/Substack channels, status,
and connect_url. Connecting a channel is a human action, done in the app —
no tool here does it.

Posts: `create_post` (a draft, or with `intent` schedule / queue /
publish_now in one call), `schedule_post` (a time, or `queue: true` for
the next free slot; also how you MOVE a scheduled post), `publish_post`
(synchronous — the reply is the outcome), `list_posts`, `get_post`,
`update_post`, `cancel_post`, `mark_post_published` (record a manual
post — one BlastCP has no channel for — as published elsewhere).

Schedule: `get_posting_schedule`, `set_posting_schedule` — the workspace's
weekly posting slots (timezone, weekday/hour/minute, paused).

## Approval

Your token IS an account. `schedule_post`, `publish_post`, and a
`create_post` intent approve as that account: the post goes out under the
name the token belongs to, and `approved_by` records it. Read the draft back
before you send it. Two things stop you: you must be a member of the
workspace, and the workspace may require a PERSON to approve every post
(Settings → General). There the tools refuse, the draft is kept, and the
error carries `review_url` — send the user there rather than retrying.
Editing a scheduled post's body, link, or time drops it back to draft
(approval was of those words); `schedule_post` again to re-approve.

## Platform notes

- LinkedIn channel tokens last 60 days with no refresh and are never renewed
  automatically — a channel can expire on its own. Check `list_channels`
  before assuming a post will go through.
- A Substack post through a connected channel becomes a DRAFT in the
  author's own Substack — BlastCP never emails subscribers or hits publish
  for them.
- A manual post (platform `other`, or linkedin/substack with no usable
  channel) is never sent by BlastCP. Paste it in yourself, then call
  `mark_post_published`.

## For humans

Setup instructions: https://blastcp.com/mcp
