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.