Introducing Ghost-MCP: A Model Context Protocol Server for Ghost CMS
Introducing Ghost-MCP, a groundbreaking integration between Ghost and Claude through (MCP) revolutionizes blog management. Now you can control your entire Ghost blog—from content creation to member management—using simple conversational commands. Transform your blogging workflow with AI.
![Introducing Ghost-MCP: A Model Context Protocol Server for Ghost CMS](/content/images/2025/02/IntroducingGHOST-MCP.jpg)
Introduction & Motivation
When Anthropic introduced the Model Context Protocol (MCP), it opened up exciting new possibilities for integrating AI models like Claude with external systems. The protocol provides a standardized way for AI models to interact with data and functionality from any source, transforming them from isolated systems into powerful tools that can work directly with your applications and services.
![](https://fanyangmeng.blog/content/images/thumbnail/1aef864f9b246c740fe3cef6e1068f2220995d5e-2400x1260.png)
As someone who has been actively blogging and working with Ghost CMS, I noticed an interesting opportunity. Looking through the official MCP servers repository, I discovered that no one had yet implemented an MCP server for Ghost. This seemed like the perfect chance to contribute something valuable to both the Ghost and AI communities.
The goal was clear: create a bridge between Claude and Ghost that would allow the AI to directly interact with all aspects of a Ghost blog. This meant not just reading and writing posts, but managing members, handling newsletters, working with tiers and offers – essentially providing programmatic access to everything you can do through Ghost's Admin API.
Technical Implementation
The project's architecture draws inspiration from two main sources: the Ghost Admin API documentation and the MCP Python SDK. By studying both, I was able to design a structure that maintains the elegance of the MCP protocol while providing comprehensive coverage of Ghost's functionality.
![](https://fanyangmeng.blog/content/images/thumbnail/ghost-docs-3.png)
Here's the complete project structure:
- Server Structure: The main server is built using FastMCP, providing a clean interface for defining resources and tools. The structure follows a modular design:
ghost-mcp/
├── README.md
├── ghost-admin-api.md # Local copy of Ghost API docs
├── mcp-python-sdk.md # MCP SDK reference
├── pyproject.toml # Project dependencies and metadata
├── uv.lock # Dependency lock file
└── src/
├── main.py # Entry point
└── ghost_mcp/
├── __init__.py
├── api.py # Ghost API interaction layer
├── config.py # Configuration management
├── exceptions.py # Custom error handling
├── models.py # Data models for Ghost resources
├── resources.py # MCP resource implementations
├── server.py # Main MCP server setup
└── tools/ # Individual tool implementations
├── __init__.py # Dynamically import everything
├── invites.py
├── members.py
├── newsletters.py
├── offers.py
├── posts.py
├── tags.py
├── roles.py
├── tiers.py
├── users.py
└── webhooks.py
The structure reflects several key design decisions:
- Clean Separation of Concerns: The project separates Ghost API interaction (
api.py
) from MCP protocol handling (server.py
), making it easier to maintain and update either aspect independently. - Modular Tool Organization: Each Ghost functionality area has its own module in the
tools/
directory, mirroring the organization of the Ghost Admin API documentation. This makes it easy to find and modify specific features. - Resource-First Design: The
resources.py
module implements MCP resources that map directly to Ghost entities, following the RESTful nature of Ghost's API while adapting it to MCP's resource paradigm.
Implementation Details
The implementation carefully bridges the gap between Ghost's REST API and MCP's protocol requirements:
- Authentication Flow: The
api.py
module handles Ghost's JWT-based authentication:
async def generate_token(staff_api_key: str, audience: str = "/admin/") -> str:
"""Generate a JWT token for Ghost Admin API authentication.
Keys are split and converted following Ghost's requirements while keeping
the implementation details hidden from the MCP layer.
"""
key_id, secret = staff_api_key.split(":")
secret_bytes = bytes.fromhex(secret)
# ... token generation logic
- Resource Mapping: Ghost entities are exposed as MCP resources with intuitive URIs:
@mcp.resource("post://{post_id}")
async def handle_post_resource(post_id: str) -> str:
"""Map Ghost posts to MCP resources while handling format conversion
and error cases appropriately."""
# ... implementation
- Tool Implementation: Each tool module provides specific Ghost functionality:
# tools/posts.py
async def create_post(
post_data: dict,
ctx: Context = None
) -> str:
"""Create a new blog post with comprehensive error handling and
format validation."""
# ... implementation
The Development Journey and Challenges
One of the most interesting challenges in developing an MCP server comes from its unique runtime environment. Unlike traditional Python applications where you can set breakpoints and step through code line by line, debugging an MCP server requires a different approach.
The server runs as a subprocess of the Claude Desktop client, which means standard debugging techniques aren't available. Instead, I developed a systematic approach to troubleshooting:
- Contextual Logging: Implemented detailed logging that respects the MCP protocol:
async def handle_error(error: Exception) -> None:
"""Structured error handling that maintains protocol integrity while
providing meaningful feedback."""
if isinstance(error, GhostError):
mcp.log.error(f"Ghost API Error: {str(error)}")
else:
mcp.log.error(f"Server Error: {str(error)}")
- Error Propagation: Created a custom
GhostError
class that properly surfaces API issues without breaking the MCP connection:
class GhostError(Exception):
"""Custom exception for Ghost API errors that can be safely
handled within the MCP protocol."""
pass
What You Can Do With It
The Ghost MCP server enables Claude to perform a wide range of blog management tasks. I have included them all in the GitHub repo's README.md
Here are some examples, not all of them, just a part of it:
- Content Management
- Write and edit blog posts with natural language
- Search through existing content
- Schedule posts for publication
- Manage tags and categories
- Member Management
- Create and update member profiles
- Handle newsletter subscriptions
- Manage membership tiers
- Newsletter Operations
- Create and configure newsletters
- Manage subscriber lists
- Schedule email campaigns
- System Integration
- Set up webhooks for automation
- Monitor blog statistics
- Handle user roles and permissions
Getting Started
Using the Ghost MCP server requires just a few steps:
- Install the package:
git clone git@github.com/your-username/ghost-mcp.git
cd ghost-mcp
uv venv
source .venv/bin/activate # On Windows: .venv\Scripts\activate
uv pip install -e .
- To use this with Claude Desktop, add the following to your
claude_desktop_config.json
:
{
"mcpServers": {
"ghost": {
"command": "/Users/username/.local/bin/uv",
"args": [
"--directory",
"/path/to/ghost-mcp",
"run",
"src/main.py"
],
"env": {
"GHOST_API_URL": "your_ghost_api_url",
"GHOST_STAFF_API_KEY": "your_staff_api_key"
}
}
}
}
Future Possibilities
This implementation opens up exciting possibilities for AI-assisted blog management. Some potential future enhancements could include:
- Automated content scheduling based on engagement analytics
- AI-driven newsletter personalization
- Intelligent member segmentation and targeting
- Automated content auditing and optimization
I am excited of being the first one who integrate Ghost CMS with MCP, and I am really exciting on exploring how much more I can do in the future to utlize it.
Conclusion
Building an MCP server for Ghost has been an enlightening journey into the future of AI-assisted content management. The project requires me to carefully study both the target API (Ghost) and the integration protocol (MCP), leads to a clean, maintainable architecture that serves as a bridge between these two powerful systems.
The challenges of debugging and error handling in the MCP environment pushed me to develop more robust solutions, ultimately resulting in a more reliable system. As we continue to explore the possibilities of AI integration, projects like this show how standardized protocols like MCP can make complex integrations more accessible and maintainable.
I encourage other developers to explore building MCP servers for their favorite platforms. The challenges are interesting, the learning experience is valuable, and the resulting tools can make a real difference in how we interact with AI systems.
The complete source code and documentation for this project are available on GitHub. If you're interested in contributing or using it with your Ghost blog, feel free to check out the repository and share your thoughts and suggestions.
Related Update:
![](https://fanyangmeng.blog/content/images/thumbnail/ImprovingCodeStructureforGhostMCP.jpg)
Discussion