Poplar/MCP45 tools
Generate a key
Model Context Protocol

Poplar, from inside your AI.

Poplar is an MCP server. Connect Claude, Cursor, Codex or an agent you wrote yourself, and it can run a customer's publishing end to end: draft in their voice, attach media, send a post for review, put it on the calendar. The writer, the brand voice and the learned preferences stay on Poplar's side, so the result sounds like the customer rather than like the model that asked.

One endpoint
https://usepoplar.com/api/mcp

Streamable HTTP. Sign in with OAuth in one click, or paste an API key. Nothing to install on Poplar's side.

01Section

Connect a client

Every client below talks to the same endpoint. Prefer signing in with OAuth where the client supports it: you approve the scopes once and no key is stored in a file. An API key works everywhere, including scripts and agents you wrote yourself.

Claude and Claude Desktop

Settings, then Connectors, then Add custom connector. Name it Poplar, paste the URL, and click Add. Then Connect, and Allow on the Poplar page that opens. Nothing to paste and no keys. Custom connectors need a paid Claude plan.

connector url
https://usepoplar.com/api/mcp

Claude Code

Add it once for every project with -s user, then authenticate from inside Claude Code: /mcp, pick poplar, Authenticate, and approve in the browser.

bash
claude mcp add --transport http poplar https://usepoplar.com/api/mcp -s user

Prefer a key? Add --header "Authorization: Bearer pop_live_YOUR_KEY" instead of signing in.

Cursor

Put this in .cursor/mcp.json, or ~/.cursor/mcp.json for every project. Leave headers out to sign in with OAuth from Settings, then MCP.

json
{
  "mcpServers": {
    "poplar": {
      "url": "https://usepoplar.com/api/mcp",
      "headers": { "Authorization": "Bearer pop_live_YOUR_KEY" }
    }
  }
}

Codex

Add it, then log in. Approve on the Poplar page that opens.

bash
codex mcp add poplar --url https://usepoplar.com/api/mcp
codex mcp login poplar

To use a key instead, set bearer_token_env_var on the server in ~/.codex/config.toml and put the key in that environment variable.

Gemini CLI

Add it, then run /mcp auth poplar.

bash
gemini mcp add --transport http poplar https://usepoplar.com/api/mcp

Hermes Agent

A key is the dependable choice: Hermes's OAuth sign-in needs a browser on the same machine, which a bot or gateway install does not have. Add this to ~/.hermes/config.yaml, then /reload-mcp in the chat.

yaml
mcp_servers:
  poplar:
    url: "https://usepoplar.com/api/mcp"
    headers:
      Authorization: "Bearer pop_live_YOUR_KEY"

On a laptop install you can sign in instead: set auth: oauth in place of the headers and run hermes mcp login poplar.

OpenClaw

Add it with a key, or sign in with OAuth from the Gateway.

bash
openclaw mcp add poplar --url https://usepoplar.com/api/mcp --transport streamable-http --header "Authorization: Bearer pop_live_YOUR_KEY"

To sign in instead: --auth oauth in place of the header, then openclaw mcp login poplar and approve on the Poplar page that opens.

Anything else

Most clients take the same shape: a URL and an Authorization header.

json
{
  "mcpServers": {
    "poplar": {
      "url": "https://usepoplar.com/api/mcp",
      "headers": { "Authorization": "Bearer pop_live_..." }
    }
  }
}

A client that only speaks stdio can bridge to the remote server:

bash
npx mcp-remote https://usepoplar.com/api/mcp --header "Authorization: Bearer pop_live_..."
Coding agents: install the skill first
It teaches the agent the whole workflow, the two-step scheduling and the house style, before its first call, so it does not spend a turn discovering them.
bash
npx skills add Poplar-AI/agent-mcp-skills
02Section

Authentication

Both methods work on the same endpoint, and both end up at the same permission checks.

OAuth, for a client that supports it

OAuth 2.1 with PKCE (S256) and dynamic client registration, so there is nothing to pre-register. Discovery starts at /.well-known/oauth-protected-resource, which points at the authorization server metadata. An unauthenticated call returns 401 with a WWW-Authenticate header naming that document, which is how a client finds the login on its own.

An API key, for everything else

Send a Poplar key as a Bearer token. Keys look like pop_live_<prefix>_<secret>. Generate one under Settings, then API keys, on the Pro and Agency plans. Treat it like a password.

Scopes

A key holds scopes; each tool names the one it needs, and the check happens before any work. The reference below prints the scope for every tool.

  • workspaces:read, workspaces:create, workspaces:update, members:invite
  • knowledge:write, analytics:read, usage:read
  • identity:read, identity:write. Learned preferences stay read only over MCP.
  • posts:read, posts:write, posts:schedule
  • agent:run, for the tools that spend AI credit.
Why scheduling has its own scope
posts:schedule is separate from posts:write because it is the first capability whose effect leaves the product: a scheduled post goes out without anyone looking at it again. There is deliberately no posts:publish.
03Section

Workspaces

The REST API takes a workspace in the X-Workspace-Id header. MCP does not. One connection sends the same headers to every call, which would pin an agent to a single workspace for the life of the connection, so here workspace_id is a tool argument instead.

Omit it and Poplar resolves it when there is only one possibility. When there is more than one, the tool returns the list so the agent can ask by name. The server is told never to show a UUID to a customer or ask them to type one.

A key inherits the workspace memberships of the user who made it, and an optional allow-list on the key can narrow that further. Every call checks the allow-list, the membership and the role the tool requires.

04Section

What an agent may do

An outside model is driving a real customer's publishing, so the boundaries are part of the product rather than a setting.

  • There is no publish tool. Scheduling is as far as an outside agent can go. Publishing immediately is not exposed at any scope.
  • Scheduling takes two calls. schedule_post changes nothing. It validates and returns a preview with a confirmation_id and the publish time in the workspace's own timezone. Nothing moves until confirm_action is called with that id.
  • A proposal cannot be swapped. The arguments that run are the ones stored when the preview was made, not whatever arrives with the confirm. Each proposal is single use, bound to the key that made it, and expires.
  • An owner can switch it off. Scheduling from connected apps has a switch in Poplar under Settings, then Workspace. The check fails closed: a missing row or an unreadable setting counts as off.
  • It stays reversible. unschedule_post takes a post back off the calendar, with its content and media intact, right up until it sends.
  • Intelligence is read only. Ideas, the strategy report and learned preferences can be read over MCP and never written.
Every call is scoped, rate limited, budgeted and logged
Each tool runs through one wrapper in a fixed order: check the scope, apply the rate limit, resolve the workspace, check membership and role, reserve any spend, run, then settle the reservation and write the audit log. A tool author cannot skip a step, because they never write the sequence.
05Section

Writing in their voice

start_draft runs Poplar's own writer, with the workspace's brand voice, its learned preferences and its strategy report, rather than asking the calling model to write. That is the difference between a post that sounds like the customer and one that sounds like whichever model happened to be connected.

A turn takes 12 to 60 seconds, longer than most MCP clients will hold a call open, so it returns a ticket and you poll. get_draft waits up to about 20 seconds before answering, so a short post usually needs one call.

flow
start_draft { workspace_id, brief: "why small releases beat big rewrites" }
  -> { run_id, status: "queued", poll_after_ms: 3000 }

get_draft { run_id }
  -> { status: "running" }            # wait poll_after_ms, ask again
  -> { status: "done", text: "..." }  # the finished post

Pass post_id to write into an existing post instead of returning loose text. To keep the result as a new draft, save it with create_draft and pass the run_id, so the draft is recorded as written by Poplar's writer rather than by the calling model.

If the agent writes the text itself
Anything a reader will see and that did not go through start_draft, a post body, a poll question, image alt text, should still follow the workspace's own style. Read list_learned_preferences and get_brand_identity first and apply them. The server tells connected models to say plainly when text did not go through Poplar's writer.

Every run counts against the workspace's AI allowance. get_usage reports spent, reserved and remaining in whole cents, plus when each window resets. Call it before a long batch.

06Section

Tool reference

All 45 tools the server advertises, generated from the same registry the endpoint runs, so this list cannot drift from the product. Open any tool for its full description and arguments.

45 tools

Workspaces and people

Provision workspaces, read and change their settings, invite the people who work in them.

Voice and knowledge

The material Poplar's writer draws on: who the customer is, how they sound, what they have taught the product by correcting it.

Writing

Run Poplar's own writer, then read and edit what came out.

Media

Images, uploads and video transcripts attached to a post.

Post options

Network features that live on the post itself.

Scheduling

The only capability whose effect leaves the product, so it is the only one that takes two calls.

Approvals

Send a post for review, see what is waiting on you, record a decision.

Team comments

The internal review thread on a post. Not social-platform comments.

Intelligence

What Poplar knows about the account. Read only over MCP.

Budget

What a run will cost against the workspace's allowance.

Everything else

Advertised by the server and not yet filed under a heading above.

07Section

Limits and errors

100 requests per minute per key. Over that you get RATE_LIMITED with a retry_after_seconds. Tools that spend AI credit reserve it before running and settle the true figure afterwards, so a failed run does not hold your budget.

Errors come back as a JSON body with a stable code, which is the thing to branch on. Common ones:

  • UNAUTHORIZED. Missing, malformed or revoked token.
  • MISSING_SCOPE, WORKSPACE_NOT_IN_ALLOWLIST, NOT_MEMBER, INSUFFICIENT_ROLE. The key lacks the scope, the workspace is outside its allow-list, or the user's role is too low for this tool.
  • MENTION_INVALID, MEDIA_NOT_ALLOWED, CONTENT_TOO_LONG, UPLOAD_MISSING. A draft write or an attachment was refused; the body says what to change (a mention token Poplar did not resolve, media the network does not take, an X post over its limits, a file that was never uploaded).
  • RATE_LIMITED. Too many calls this minute.
  • SPEND_LIMIT. The workspace's AI allowance is spent. Check get_usage.
08Section

Troubleshooting

The client connects but lists no tools

Almost always the token. An unauthenticated call still returns 200 at the transport layer for some clients, and the tool list comes back empty. Check the key is present, is not revoked, and carries the scopes for the tools you expect.

Scheduling is refused

Either the key lacks posts:schedule, or an owner has turned off scheduling from connected apps under Settings, then Workspace. The check fails closed, so a workspace whose migration has not run yet also reads as off.

The connection drops on a long call

There is no SSE stream and no session to pin, which is what lets the server run without a persistent process. Long work returns a ticket instead. If a call is timing out, you are probably waiting on start_draft when you should be polling get_draft.

Transcription tools are missing

transcribe_video and get_transcript are behind a deployment flag and are not advertised by default. A tool that is off is absent from the tool list and unknown to the caller, rather than present and failing.

Prefer plain HTTP?

The REST API covers provisioning, knowledge and analytics with the same keys and the same scopes. See the API reference, or take the OpenAPI spec.

Something missing or wrong here? Write to support@usepoplar.com.