Proposal: First-party MCP (Model Context Protocol) server for the Admin API

Summary

I’d like to propose adding native Model Context Protocol support to Ghost, exposing a curated subset of the Admin API as MCP tools. This would let any MCP client (Claude Desktop, Cursor, Zed, etc.) author posts, manage members, and inspect newsletters in a Ghost site through natural language — without each user wiring up a custom Admin API integration.

Before I open a PR, I wanted to surface the idea here and get a maintainer signal on direction.

Motivation

Ghost is a writing tool, and writing is one of the most natural fits for LLM-assisted workflows. The Admin API already exposes everything a publishing agent would need; what’s missing is a standard protocol bridge so users don’t have to build that bridge themselves. MCP has become the de-facto standard for that bridge over the last year, and shipping first-party support feels well-aligned with Ghost’s positioning around independent publishers and creator tooling.

I checked the codebase — there are no existing MCP dependencies in any product package.json today, only some references in CI tooling.

Proposed approach

In-process service inside ghost/core, mounted on the Admin API router under /ghost/api/admin/mcp, transported over streamable HTTP.

Key properties:

  • No new auth path. The MCP endpoint sits behind the existing Admin API auth middleware (staff API key JWT). Clients use the same key they already use for the Admin API.

  • No HTTP round-trips inside Ghost. Tools call the existing endpoint controllers directly via the @tryghost/api-framework frame, reusing all validation, permissions, and serialization.

  • Permissions inherited. Each tool runs in the role/permission context of the authenticated staff user or integration — no parallel permission model to maintain.

  • Curated tool surface, not a full API mirror. Exposing all ~70 endpoints would drown the LLM’s context. v1 is ~18 well-named tools across the resources users actually want to drive from an agent.

v1 tool surface

  • Posts: list_posts, get_post, create_post (markdown input), update_post, publish_post

  • Pages: list_pages, create_page, update_page

  • Tags: list_tags, create_tag

  • Members: list_members, get_member, create_member, add_member_to_newsletter

  • Newsletters: list_newsletters, send_newsletter_preview

  • Tiers: list_tiers, create_tier

create_post would accept markdown (the natural format for an LLM), convert to HTML in the tool handler, and use the existing ?source=html path on the posts endpoint — so no new content-conversion code.

Scope of the change

  • New service: ghost/core/core/server/services/mcp/ (~6-8 files, mostly tool definitions + a thin frame-builder)

  • One new dependency: @modelcontextprotocol/sdk

  • One mount point added to the Admin API router

  • Tests under ghost/core/test/unit/ and ghost/core/test/integration/

No changes to models, the Admin API endpoints themselves, or any other part of core.


Happy to open a draft PR for the spike (list_posts as a canary, proving the in-process frame-construction works end-to-end) once there’s directional alignment.

Have you seen this?