MCP server
The MCP endpoint, in full
MCP (Model Context Protocol) lets an AI agent enumerate and call tools over a standard wire format. FounderReply exposes its agent at a single endpoint — POST /api/mcp — speaking JSON-RPC 2.0 over one HTTP request and one response.
Wire contract
The whole contract, transcribed from source
- Endpoint
- POST /api/mcp
- Protocol
- JSON-RPC 2.0 over one HTTP request/response
- Methods
- tools/list · tools/call
- Auth
- Authorization: Bearer fr_live_… — missing or revoked → HTTP 401
- Scope
- The key resolves to one workspace; params never carry a workspace id
- Errors
- −32700 parse · −32600 request · −32601 method · −32602 params · −32603 internal — all at HTTP 200
- Not shipped
- SSE / streamable-HTTP transport: server-push, notifications, sessions
curl -s https://founderreply.com/api/mcp \
-H "Authorization: Bearer fr_live_…" \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'{
"jsonrpc": "2.0",
"id": 2,
"method": "tools/call",
"params": {
"name": "set_autonomy",
"arguments": { "action": "reply", "mode": "approve" }
}
}{
"jsonrpc": "2.0",
"id": 2,
"result": {
"content": [
{ "type": "text",
"text": "{\"ok\":true,\"action\":\"reply\",\"mode\":\"approve\"}" }
],
"structuredContent": {
"ok": true, "action": "reply", "mode": "approve"
},
"isError": false
}
}A key is bound to one workspace and the tools take no workspace id, so a key can only ever operate its own. And set_autonomy records exactly what you set — decide() reports any gap against a platform’s own policy at decision time, so no call arriving over this endpoint can push an action past what a platform allows.
Tool registry
Every MCP tool, and what it actually does
The whole registry — 36 tools, in the order tools/list returns them. Nothing below is a roadmap item.
| Tool | What it does |
|---|---|
| Persona & strategy | |
| create_persona | Generate and persist a brand persona / content strategy from a company-focus brief, and update the workspace brand voice. |
| bootstrap_focus | Infer that brief from a connected account’s own recent posts instead of typing it. |
| get_persona | The workspace’s latest persona, or null if none exists yet. |
| Content | |
| generate_content_plan | Build a rolling calendar of planned posts from the persona over the next horizonDays. |
| plan_news_posts | Find recent news in the brand’s field and schedule one planned post per item on the news template. |
| generate_blog_posts | Research SEO topics and generate finished, ready-to-publish articles in the brand voice. |
| list_blog_posts | Generated articles with bodies omitted, optionally filtered by status. |
| get_blog_post | One article by id, including its full markdown body. |
| list_templates | The available post formats — news, release, personal-update, tip, story, question, announcement. |
| list_scheduled_posts | Scheduled posts, optionally filtered by status. |
| Autonomy & analytics | |
| set_autonomy | Set the mode (auto | approve | off) for an action type. It is applied as written; decide() reports when it exceeds a platform’s own policy. |
| get_analytics | Engagement overview over a trailing window, with a per-content-pillar rollup. |
| Growth | |
| find_growth_opportunities | Discover public conversations the brand could add value to, and persist them. |
| list_opportunities | Engagement opportunities, optionally filtered by status. |
| Engagement — capability-gated per platform | |
| list_messages | Inbound DMs on one platform, normalised to { id, origin, sender, content, ts, threadId }. |
| list_mentions | Recent comments and mentions on the brand. |
| list_own_posts | The brand’s own recent posts, for persona and context. |
| draft_reply | Draft a reply in brand voice with cross-platform memory recall. Never sends. |
| send_reply | Enqueue a reply to the human approval queue. Does not dispatch. |
| publish_content | Enqueue an original post to the human approval queue. Does not publish. |
| SEO | |
| run_seo_audit | Fetch each page rendered, score it on discrete metrics plus PageSpeed Insights, and reconcile the issue register. |
| get_seo_overview | Site and page counts, average page score, open issues by severity, keyword coverage, average SERP position. |
| list_seo_issues | Open on-page issues across the workspace: error → warn → info. |
| track_keyword | Add or update a tracked keyword so its SERP position is sampled over time. |
| get_keyword_rankings | Sample current SERP positions and return the latest known position per keyword. |
| sync_search_console | Ingest Search Console’s authoritative impressions, clicks and average position. |
| add_seo_site | Register a website for SEO tracking. |
| generate_blog_from_seo_gaps | Find tracked keywords outside the top 10, read who outranks you, and write against the gap. |
| generate_conquest_posts | Mine a competitor’s surface and generate posts that capture the traffic it ranks for. |
| refresh_stale_blog_posts | Redraft published articles in place — same slug, honest updated_at, IndexNow ping when configured. |
| Browser | |
| browse_page | Read any page as markdown by driving a real browser. The cheapest read. |
| extract_from_page | Pull structured fields out of a page — pricing, contact details, a product list. |
| screenshot_page | Capture a page as a base64 image. Rides a stored session, so it can shoot logged-in pages. |
| list_browser_connections | Which sites this workspace has a usable sign-in for, and which are still waiting on the user. |
| connect_browser_account | Mint a one-time connect_url to hand the user. Never asks anyone to type a password to the agent. |
| run_on_page | Drive a goal in a real browser until a success condition holds. Not a posting path — those go through approvals. |