# MCP for AI agents

> Connect Cursor, Claude, or another MCP client to Postless. Create drafts, generate images, and schedule posts without opening the dashboard.

- HTML: https://postless.app/guides/mcp
- Published: 2026-09-11
- Author: Postless
- Category: Product
- Tags: founders, creators, agencies, teams, api, mcp

Postless exposes a remote [Model Context Protocol](https://modelcontextprotocol.io) server so an AI
client can create drafts, generate images, and schedule posts on your brands.

The dashboard stays the place you review and publish. MCP is the agent-facing adapter around the
same [public API](https://postless.app/guides/public-api). It does **not** publish immediately.

Typical flow:

```
create_post (draft)
        ↓
generate_post_media
        ↓
poll get_media_generation_status
        ↓
schedule_post
```

## What you need

- An active Postless subscription and a verified email
- At least one **finished** brand (incomplete and archived brands are unreachable)
- An API key from **Settings → API keys**
- An MCP client that can call a remote Streamable HTTP server with a Bearer token

## Create a key for MCP

1. Open **Settings → API keys**.
2. Name the key (for example `Cursor` or `Claude`).
3. Turn on the permissions the agent should have. For the demos below, use:

   | Permission    | Why                                                    |
   | ------------- | ------------------------------------------------------ |
   | `brands:read` | List brands and read voice, audience, pillars          |
   | `posts:read`  | List posts and poll media generation                   |
   | `posts:write` | Create drafts, generate image/video/carousel, schedule |
   | `plans:read`  | Read the content calendar                              |

   Leave **Publish posts** off. MCP has no `publish_post` tool even if the key has `posts:publish`.

4. Optionally limit the key to specific brands.
5. Click **Create key** and copy the secret. It is shown **once**.

The key is `pl_…`. Treat it like a password. Do not commit it to git.

Same subscription, media quotas, and **60 requests per minute** as the public API apply.

## Endpoint

```
https://dashboard.postless.app/mcp
```

Transport: **Streamable HTTP**. Auth:

```
Authorization: Bearer pl_YOUR_KEY
```

`x-api-key: pl_YOUR_KEY` also works. On your own host, replace the domain with that host.

## Tools

| Tool                          | Permission    | What it does                                                                 |
| ----------------------------- | ------------- | ---------------------------------------------------------------------------- |
| `list_brands`                 | `brands:read` | List onboarded brands the key can access                                     |
| `get_brand`                   | `brands:read` | Name, voice, audience, pillars                                               |
| `list_posts`                  | `posts:read`  | Filter by `status` (`draft`, `queued`, `published`, `failed`) and date range |
| `create_post`                 | `posts:write` | Create a **draft** (or schedule if you pass `scheduledAt`). Finished copy    |
| `generate_post_media`         | `posts:write` | Start image, video, or carousel generation from a prompt. Async              |
| `get_media_generation_status` | `posts:read`  | Poll until `succeeded` or `failed`                                           |
| `get_content_calendar`        | `plans:read`  | Current plan slots (day, topic, format, time, linked `postId`)               |
| `schedule_post`               | `posts:write` | Set `scheduledAt` on a **draft**. Highest-impact tool in v1                  |

`create_post` is not AI generation. The client writes the caption. Use `get_brand` or the voice
resource so the copy matches the brand.

`generate_post_media` does not invent a prompt. Pass `type` (`image`, `video`, or `carousel`) and a
prompt (10–3000 characters). Then poll. Video and carousel can take minutes. Brand `aiImagesEnabled`
/ `aiVideosEnabled` and weekly media quota still apply.

`schedule_post` is the step that puts something on the public calendar. The post must be a draft
with a body that is ready to schedule (connected accounts, caption, platform media rules). It does
not publish now.

## Resources

Read-only context:

```
postless://brands/{brandId}/voice
```

Tone, audience, and pillars for that brand. An agent can write in the brand’s style without a custom
integration per model.

## How agents should work

1. `list_brands` / `get_brand` (or read the voice resource) before writing.
2. `create_post` with finished copy. Omit `scheduledAt` to keep a draft while media generates.
3. `generate_post_media` if the post needs a still, video, or carousel. Poll
   `get_media_generation_status` until it settles.
4. `schedule_post` only after the draft is ready.
5. Do not ask the user to “publish now.” There is no publish tool. They approve or publish in the
   dashboard if they want it live immediately.

## Connect Cursor

1. Create an API key as above.
2. Open Cursor **Settings → MCP** (or add a project file `.cursor/mcp.json`).
3. Add a Streamable HTTP server:

```json
{
  "mcpServers": {
    "postless": {
      "url": "https://dashboard.postless.app/mcp",
      "headers": {
        "Authorization": "Bearer pl_YOUR_KEY"
      }
    }
  }
}
```

If your Cursor build supports env interpolation, keep the secret out of the file:

```json
{
  "mcpServers": {
    "postless": {
      "url": "https://dashboard.postless.app/mcp",
      "headers": {
        "Authorization": "Bearer ${env:POSTLESS_API_KEY}"
      }
    }
  }
}
```

4. Restart MCP or reload Cursor. You should see tools such as `list_brands` and `create_post`.
5. Try: “List my Postless brands, then draft a LinkedIn post for the first one about this week’s
   shipping notes. Save it as a draft — don’t schedule yet.”

Do not put `.cursor/mcp.json` with a raw `pl_` secret in a shared repo.

## Connect Claude Code

```bash
claude mcp add --transport http postless https://dashboard.postless.app/mcp \
  --header "Authorization: Bearer pl_YOUR_KEY"
```

Then in a Claude Code session:

> Turn the changes in this working tree into a LinkedIn announcement for my Postless brand. Save it
> as a draft, generate a 1:1 image from a prompt that matches the caption, and wait until the image
> is attached.

Claude Code can inspect git locally and call Postless for distribution.

## Connect Claude Desktop

Claude Desktop often speaks stdio, not remote HTTP. Bridge with `mcp-remote`:

```json
{
  "mcpServers": {
    "postless": {
      "command": "npx",
      "args": [
        "-y",
        "mcp-remote",
        "https://dashboard.postless.app/mcp",
        "--header",
        "Authorization: Bearer pl_YOUR_KEY"
      ]
    }
  }
}
```

Config path is usually **Claude → Settings → Developer → Edit Config**
(`claude_desktop_config.json`). Restart Claude Desktop after saving.

If a later Claude Desktop build supports Streamable HTTP URLs natively, use the same URL and Bearer
header as Cursor.

## Connect VS Code (Copilot / agent)

Add `.vscode/mcp.json` (workspace) or a user MCP config:

```json
{
  "servers": {
    "postless": {
      "type": "http",
      "url": "https://dashboard.postless.app/mcp",
      "headers": {
        "Authorization": "Bearer pl_YOUR_KEY"
      }
    }
  }
}
```

Reload the window. In agent chat, ask it to list Postless brands or create a draft.

## ChatGPT, Claude.ai, and other hosted connectors

Hosted products that only offer **OAuth MCP connectors** are not a fit yet. Postless MCP
authenticates with an API key, not an OAuth consent screen.

Until OAuth exists:

- Use Cursor, Claude Code, Claude Desktop (`mcp-remote`), or VS Code with the key.
- Or call the [public API](https://postless.app/guides/public-api) from a Custom GPT / Action (HTTP Bearer), which is a
  different integration than MCP.

## Sample use cases

### 1. Cursor: ship notes → LinkedIn draft

You just merged a release. In Cursor:

> Turn the changes in this release into a LinkedIn announcement for Postless. Match our brand voice.
> Save it as a draft and generate a simple product still. Do not schedule.

The agent should:

1. Read the diff or changelog locally
2. `list_brands` / `get_brand` (or `postless://brands/{id}/voice`)
3. `create_post` with a LinkedIn caption
4. `generate_post_media` (`type: image`) and poll until attached

You open **Posts** in Postless to edit, then schedule or publish.

### 2. Fill gaps in next week’s calendar

> Look at next week’s Postless calendar. For empty days, draft LinkedIn posts in our voice and leave
> them as drafts.

The agent should:

1. `get_content_calendar`
2. `get_brand`
3. `create_post` for each gap (no `scheduledAt` until you say so)

If you want them on the calendar: “Schedule those drafts for 10:00 on each empty day.” That is
`schedule_post` — confirm the times before it runs.

### 3. Repurpose what you already posted

> List my LinkedIn posts from this month. Draft three new posts that continue the same themes. Save
> drafts only.

Uses `list_posts` (filter by date / status). There is no analytics tool yet, so the agent cannot
rank “top performing” posts. It can read recent copy and write variations.

### 4. Founder agent with GitHub

An agent with GitHub MCP **and** Postless MCP:

> We shipped 2.4 today. Read the GitHub release, write LinkedIn and X drafts in our voice, attach a
> generated image to LinkedIn, and schedule LinkedIn for tomorrow 9:00.

GitHub supplies facts. Postless is distribution: voice, draft, image, schedule. You still own
publish.

### 5. Image for an existing draft

> Generate a 1:1 image for post POST_ID: a quiet laptop on a desk, no text on the image. Poll until
> it’s attached.

Needs `posts:write` and `posts:read`. If generation is disabled on the brand or the weekly image
quota is used, the tool returns an error — fix that in brand settings or wait for the week to reset.

## Limits and safeguards

- **No publish from MCP.** Immediate publish stays on HTTP `posts:publish` and the dashboard.
- **`schedule_post` only accepts drafts.** Queued or published posts return `409`.
- **Media generation** uses the same providers, brand toggles, and weekly caps as the dashboard.
- **Tenant isolation** is the API key: one Postless user (and optional brand allowlist), not every
  account on the server.
- **Idempotency and validation** are the same as `/api/v1`.

## Troubleshooting

| What you see                                         | What to do                                                                |
| ---------------------------------------------------- | ------------------------------------------------------------------------- |
| `401` Unauthorized                                   | Missing or wrong key. Use `Authorization: Bearer pl_…`                    |
| `403` `missing_permission`                           | Turn on the permission on the key (for example `plans:read` for calendar) |
| `403` `brand_not_allowed`                            | The key is limited to other brands                                        |
| `402` `subscription_required`                        | No active subscription                                                    |
| `404`                                                | Unknown brand/post, or the brand is unfinished or archived                |
| `409` `media_generation_in_progress`                 | Poll; don’t start a second generate on the same post                      |
| `409` `media_generation_disabled`                    | Enable AI images or videos on the brand                                   |
| `409` `post_not_draft`                               | Only drafts can be scheduled from MCP                                     |
| `429` `media_quota_exceeded` / `rate_limit_exceeded` | Weekly media cap or 60 req/min                                            |
| `503` `media_provider_not_configured`                | Image/video provider isn’t configured on the server                       |
| Client never lists tools                             | Confirm Streamable HTTP (not stdio), Accept headers, and a reload/restart |

## Related

- [Public API](https://postless.app/guides/public-api)
- [Scheduling](https://postless.app/guides/scheduling)
- [Set up your brand profile](https://postless.app/guides/brand-setup)
- [Getting started](https://postless.app/guides/getting-started)
