Docs
Run opentopost from an agent
Every step in opentopost works from an agent: find ideas, write and revise drafts, ask for review, schedule, and report results. Agents get the same access checks, review rules, and audit log as people in the app.
Quick start
Connect an agent in two minutes
- 01
Make an API key
Open Settings > API and agents. Choose a name and the scopes the agent needs. Copy the key. It starts withotp_and is shown once. - 02
Add the MCP server
Point any MCP client athttps://opentopost.com/mcpand send the key as a Bearer token. - 03
Ask for something
For example: "List this week's ideas and draft the best one for me."
MCP
MCP server
opentopost runs a remote MCP server over Streamable HTTP at https://opentopost.com/mcp. It answers initialize, tools/list, and tools/call with JSON. Use it with Claude Code, Claude Desktop, Cursor, or any client that supports remote servers.
Claude Code:
claude mcp add --transport http opentopost https://opentopost.com/mcp \
--header "Authorization: Bearer otp_..."Cursor and other clients that read an mcp.json file:
{
"mcpServers": {
"opentopost": {
"url": "https://opentopost.com/mcp",
"headers": { "Authorization": "Bearer otp_..." }
}
}
}REST
REST API
Each tool is also one endpoint. Send a POST to https://opentopost.com/api/v1/<tool> with the tool's input as a JSON body. A GET to https://opentopost.com/api/v1 lists every tool with its scope and input schema.
curl -X POST https://opentopost.com/api/v1/list_ideas \
-H "Authorization: Bearer otp_..." \
-H "Content-Type: application/json" \
-d '{"limit": 5}'A good call returns { "data": ... }. An error returns { "error": "..." } with status 400 for a bad input, a missing scope, or a rule that stopped the action, 401 for a missing or revoked key, and 404 for an unknown tool.
Drafts take about 20 seconds to write. Tools that start a draft return its draftId at once. Call get_draft until status is ready, or listen for the draft.ready webhook.
Keys
API keys and scopes
A key acts as the member who made it. It can only do what that member can do in the app, and only inside the scopes it has.
readRead ideas, moments, drafts, and recaps.draftClaim ideas, write and revise drafts, and add voice samples.publishApprove, schedule, and publish posts.adminStart scans and manage sources. Owners and admins only.
opentopost stores only a SHA-256 hash of each key. Every call is written to the audit log with the key's name. Revoke a key in Settings > API and agents, and it stops working at once.
Tools
The 18 tools
| Tool | Scope | What it does |
|---|---|---|
| whoami | read | The workspace, the member the key acts as, their role, and the key's scopes. |
| list_ideas | read | Post ideas, highest score first, with who each idea suits and its source facts. |
| list_moments | read | Things the team did, each with the quotes that prove it. |
| list_drafts | read | The member's drafts, newest first, with status and schedule. |
| get_draft | read | One draft with hooks, body, claims and their sources, review state, and schedule. |
| get_recap | read | The latest weekly recap: posts, clicks, signups, and top posts. |
| claim_idea | draft | Claims an idea and starts a draft in the member's voice. |
| draft_from_moment | draft | Starts a draft from one moment, for any channel. |
| draft_from_brief | draft | Starts a draft from your own description of what happened. |
| revise_draft | draft | Rewrites a draft with one change, keeping the voice and the facts. |
| edit_draft | draft | Replaces the hook, the body, or both with your own text. |
| add_voice_sample | draft | Adds writing by the member so drafts sound more like them. |
| request_review | draft | Sends a ready draft to the workspace's reviewers. |
| review_draft | publish | Approves a draft, or returns it with a comment. |
| schedule_draft | publish | Puts a draft on the calendar. Publishes or sends a reminder. |
| cancel_schedule | publish | Removes a draft from the calendar. |
| mark_posted | publish | Records the link to the live post, so clicks and signups count toward it. |
| start_scan | admin | Scans the connected sources for new moments and ideas. |
Drafting tools take an optional channel: linkedin, x, changelog, investor_update, or newsletter. The default is linkedin.
Webhooks
Webhooks
Add an https endpoint in Settings > API and agents and choose the events to send. Each delivery is a POST with a JSON body:
{
"event": "draft.ready",
"workspaceId": "...",
"at": "2026-10-14T09:00:00.000Z",
"data": { "draftId": "...", "title": "...", "channel": "linkedin" }
}idea.createdA scan found new ideas.draft.readyA draft finished writing.draft.approvedA reviewer approved a draft.draft.scheduledA draft was put on the calendar.post.publishedA post went live, or someone recorded its link.conversion.createdA signup, demo, or other conversion was recorded from a tracked link.
Each request has an X-Opentopost-Event header and an X-Opentopost-Signature header in the form t=<unix seconds>,v1=<hex>. The v1 value is the HMAC-SHA256 of <t>.<raw body> with your signing secret. Check it, and refuse requests where t is more than five minutes old.
import crypto from "node:crypto";
function verify(rawBody, header, secret) {
const parts = Object.fromEntries(header.split(",").map((p) => p.split("=")));
const expected = crypto.createHmac("sha256", secret).update(`${parts.t}.${rawBody}`).digest("hex");
const fresh = Math.abs(Date.now() / 1000 - Number(parts.t)) < 300;
return fresh && crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(parts.v1));
}If your endpoint does not return a 2xx status, opentopost tries again up to five times, with a longer wait each time.
Rules
What agents cannot skip
- Review rules apply. If the workspace needs review, an agent cannot schedule or post a draft before a reviewer approves it.
- A member key only changes that member's own drafts. Company page drafts need an owner or admin key.
- Every fact in a draft still comes from a source, and claims without a source are flagged.
- Every action is in the audit log, marked as coming from the API.
Questions or a missing tool? Open an issue on GitHub.
Getting started
Give your agents the distribution job
Make a key, connect the MCP server, and ask for this week's best post.