MCP and agents
MCP is available at /blog/mcp, using the same Bearer authentication as the API. Send JSON-RPC requests by POST. Notifications return 202 without a body; GET and DELETE return 405. Browser origins must match the request origin or configured public origin, including the port. Set config.mcp.enabled = false to disable the endpoint. Each HTTP request uses the shared actor rate limit once.
curl -s -X POST https://example.com/blog/mcp \
-H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'
The result lists 31 tools with their titles, descriptions, and input schemas. Call one with tools/call:
curl -s -X POST https://example.com/blog/mcp \
-H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"blog_save_draft","arguments":{"title":"Pruning","body":"When to prune.","external_id":"prune-1"}}}'
{
"jsonrpc": "2.0",
"id": 2,
"result": {
"isError": false,
"content": [{"type": "text", "text": "{\"post\":{\"id\":229,\"slug\":\"pruning\",\"status\":\"draft\", ...}"}],
"structuredContent": {"post": {"id": 229, "slug": "pruning", "status": "draft", "...": "..."}, "created": true,
"records": {"revision": null, "publication": null, "approval": null}, "label": "ai_unknown", "findings": ["..."]}
}
}
Tool results contain the same JSON object in text content and structured content. A typed refusal, such as a missing scope or a missing change type, returns isError: true with the API error object as the structured content. The HTTP status stays 200.
| MCP tools | Purpose |
|---|---|
blog_list_posts, blog_search_posts, blog_get_post |
Find and read stored articles |
blog_get_post_records, blog_check_post, blog_doctor |
Inspect history, findings, and setup |
blog_save_draft, blog_get_preview_link |
Save unpublished content and obtain its preview |
blog_publish_post, blog_update_post, blog_correct_post, blog_approve_revision |
Release, revise, correct, or record a review |
blog_declare_connections, blog_unpublish_post, blog_remove_post |
Declare relationships, withdraw, or remove content |
blog_upload_image |
Import a URL or upload base64 bytes with filename and content type |
blog_list_categories, blog_save_category, blog_list_tags |
Manage post classification |
blog_list_authors, blog_save_author, blog_list_series, blog_save_series |
Manage authors and series |
blog_list_redirects, blog_save_redirect |
Inspect or create URL moves and removals |
blog_extract_faq, blog_adopt_post |
Prepare FAQ extraction and import existing articles |
blog_get_site_page, blog_save_site_page |
Read or edit a policy page by kind |
blog_get_page_views |
Read daily article counts or top articles |
blog_get_surface_report |
Inspect fetched reader pages and publishing records |
Tools use the fields in the JSON API reference. Pass id for a specific post; publish accepts an optional ID, and draft saves use slug or external-ID upsert. Category, author, and series saves use an optional numeric ID to select an update. Redirect save creates a new record. Correction always selects the correction change type and requires a note. Image upload takes either {url} or {base64, filename, content_type}. MCP list sizes are additionally capped by config.mcp.max_page_size (default 50).
Embedding in a host MCP server
Hosts can add the tools to their own MCP::Server, supplying actor and optionally base_url in the server context:
server = MCP::Server.new(
name: "journal",
tools: OpenBlog::Mcp.tools,
server_context: { actor: OpenBlog::Actor.new(name: "Agent", scopes: %w[read write]), base_url: "https://example.com" }
)
OpenBlog::Mcp.definitions exposes each tool’s name, title, description, schema, annotations, scope, and call(arguments, actor:, base_url: nil) method. Direct Ruby calls retain validation and permission checks; the embedding host manages its own request rate limiting.
Packaged agent workflows
The gem ships six agent workflows in OpenBlog::Engine.root.join("skills"): install, publish, update, adopt, policy pages, and reports. They describe approval and evidence handling and check tool availability for features added by later versions.
Publishing instructions
Every tool description already tells an agent to show the final version and ask for approval before blog_publish_post, blog_update_post, or blog_correct_post. The full instruction text an agent must follow, and the provenance rule, are in the publishing guide.
Import instructions
Before blog_adopt_post, an agent must ask about historical evidence and declarations as described in the adoption guide.