@misarblog/mcp
v1.0.4
Published
MCP server for Misar.Blog — publish blog posts, manage drafts, generate AI cover images, and access analytics from Claude Code, Cursor & Windsurf.
Maintainers
Readme
Misar.Blog MCP Server
Connect Claude Code, Cursor, Windsurf, or any MCP-compatible AI assistant to your Misar.Blog account. Publish articles, manage drafts, generate cover images, and pull analytics — all from your AI coding environment.
Two runtimes are available — choose based on what you already have installed:
| Runtime | Requires | Best for | | ------- | -------- | -------- | | Python (recommended) | Python 3.11+ · stdlib only | Claude Code, any lightweight setup | | npm / npx | Node.js 18+ | Node-first workflows, CI/CD |
Contents
- Quick Start
- Option A — Python
- Option B — npm / npx
- Client Setup
- Authentication
- Tools reference
- Usage examples
- Self-hosted Misar.Blog
- Troubleshooting
Quick Start
Fastest path — Python + Claude Code:
# 1. Copy the server script
cp packages/mcp/misarblog-mcp.py ~/.claude/scripts/misarblog-mcp.py
chmod +x ~/.claude/scripts/misarblog-mcp.py
# 2. Add to Claude Code MCP settings (see below)
# 3. Run misarblog_login in Claude Code to authenticate via browserFastest path — npx + any MCP client:
# No install needed — just add the config below and run misarblog_loginOption A — Python (no dependencies)
Uses Python's standard library only. No pip install required. Works on macOS, Linux, and Windows (with Python 3.11+).
1 · Download the script
If you cloned the MisarBlog repo:
cp packages/mcp/misarblog-mcp.py ~/.claude/scripts/misarblog-mcp.py
chmod +x ~/.claude/scripts/misarblog-mcp.pyDirect download (one-liner):
mkdir -p ~/.claude/scripts
curl -fsSL https://www.misar.blog/mcp/misarblog-mcp.py -o ~/.claude/scripts/misarblog-mcp.py
chmod +x ~/.claude/scripts/misarblog-mcp.py2 · Verify Python version
python3 --version # must be 3.11 or laterIf you're on macOS with an older system Python, use Homebrew: brew install python.
3 · Add to your MCP client config
{
"mcpServers": {
"misarblog": {
"command": "python3",
"args": ["~/.claude/scripts/misarblog-mcp.py"],
"env": {
"MISARBLOG_API_KEY": "mbk_your_key_here"
}
}
}
}You can omit
MISARBLOG_API_KEYif you plan to use themisarblog_loginbrowser flow.
Option B — npm / npx
Uses Node.js 18+ with the @modelcontextprotocol/sdk. npx fetches and caches the package on first run — no manual install needed.
Option B1 — Zero-install via npx (recommended)
{
"mcpServers": {
"misarblog": {
"command": "npx",
"args": ["-y", "@misarblog/mcp"],
"env": {
"MISARBLOG_API_KEY": "mbk_your_key_here"
}
}
}
}Option B2 — Global install
npm install -g @misarblog/mcpThen use misarblog-mcp as the command:
{
"mcpServers": {
"misarblog": {
"command": "misarblog-mcp",
"env": {
"MISARBLOG_API_KEY": "mbk_your_key_here"
}
}
}
}Option B3 — pnpm / yarn
pnpm add -g @misarblog/mcp
# or
yarn global add @misarblog/mcpVerify Node version
node --version # must be v18 or laterClient Setup
Claude Code
Claude Code stores MCP server config in ~/.claude/settings.json.
Edit the file:
# Open in your editor
code ~/.claude/settings.jsonAdd the mcpServers block (create settings.json if it doesn't exist):
{
"mcpServers": {
"misarblog": {
"command": "python3",
"args": ["~/.claude/scripts/misarblog-mcp.py"],
"env": {
"MISARBLOG_API_KEY": "mbk_your_key_here"
}
}
}
}Reload Claude Code — MCP servers start automatically on the next session. You'll see
misarblog listed when you run /mcp in any Claude Code session.
Verify the connection:
> call misarblog_get_profileClaude Code should return your username, display name, and account status.
Cursor
Cursor stores MCP config at ~/.cursor/mcp.json (global) or .cursor/mcp.json inside a
project (project-scoped, takes priority).
Global config (~/.cursor/mcp.json):
{
"mcpServers": {
"misarblog": {
"command": "npx",
"args": ["-y", "@misarblog/mcp"],
"env": {
"MISARBLOG_API_KEY": "mbk_your_key_here"
}
}
}
}Alternative — via Cursor Settings UI:
- Open Cursor → Settings → MCP
- Click + Add new MCP server
- Fill in:
- Name:
misarblog - Command:
npx - Args:
-y @misarblog/mcp - Env:
MISARBLOG_API_KEY=mbk_your_key_here
- Name:
- Click Save — Cursor restarts the MCP daemon automatically.
Verify: open Cursor Agent mode → type use misarblog_get_profile — the tool card should appear.
Windsurf
Windsurf reads MCP config from ~/.codeium/windsurf/mcp_config.json.
{
"mcpServers": {
"misarblog": {
"command": "npx",
"args": ["-y", "@misarblog/mcp"],
"env": {
"MISARBLOG_API_KEY": "mbk_your_key_here"
}
}
}
}Reload Windsurf after saving. The MCP tools appear under the Cascade panel → Tools.
VS Code (Copilot)
VS Code reads MCP config from .vscode/mcp.json in the workspace root, or from
User Settings (settings.json) under "mcp".
Workspace config (.vscode/mcp.json):
{
"servers": {
"misarblog": {
"type": "stdio",
"command": "npx",
"args": ["-y", "@misarblog/mcp"],
"env": {
"MISARBLOG_API_KEY": "mbk_your_key_here"
}
}
}
}User settings (settings.json):
{
"mcp": {
"servers": {
"misarblog": {
"type": "stdio",
"command": "npx",
"args": ["-y", "@misarblog/mcp"],
"env": {
"MISARBLOG_API_KEY": "mbk_your_key_here"
}
}
}
}
}Restart VS Code after saving. The misarblog_* tools appear in GitHub Copilot Chat when
you enable Agent mode (the @ icon in the chat panel).
Any other MCP client
Any MCP-compatible client that supports stdio servers works with the same pattern:
- Command:
python3(Python) ornpx(npm) - Args:
["~/.claude/scripts/misarblog-mcp.py"]or["-y", "@misarblog/mcp"] - Transport:
stdio - Env:
MISARBLOG_API_KEY=mbk_...(or usemisarblog_loginafter connecting)
Authentication
API Key (recommended)
- Go to Misar.Blog → Dashboard → Settings → API Keys
- Click Generate API Key — your key starts with
mbk_ - Copy it and paste into the
MISARBLOG_API_KEYenv var in your MCP config
Keys have a 100 req/min rate limit. You can revoke and regenerate at any time from the settings page.
Precedence order:
MISARBLOG_API_KEY env var → ~/.misarblog/config.json → prompt to run misarblog_loginBrowser login (no copy-paste)
If you'd rather not handle the key manually, omit MISARBLOG_API_KEY from the config and run
misarblog_login as your first tool call. The flow:
- The MCP server starts a temporary HTTP listener on
127.0.0.1(random port 9001–9099) - Your default browser opens to
https://www.misar.blog/dashboard/settings/api?mcp_port=<port> - You click Authorize MCP Access — you must be logged in to Misar.Blog
- The page sends your API key directly to the local listener
- The key is saved to
~/.misarblog/config.json— no clipboard involved - All subsequent tool calls use this saved key automatically
The listener accepts connections from 127.0.0.1 only and shuts down after 120 seconds.
Example prompt:
Connect my Misar.Blog account using misarblog_loginClaude will call the tool, open your browser, and confirm once you've authorized.
Tools reference
| Tool | Description | Required params |
| ---- | ----------- | --------------- |
| misarblog_login | Browser-based auth — saves key to ~/.misarblog/config.json | — |
| misarblog_get_profile | Username, display name, bio, subscriber count, Stripe status | — |
| misarblog_list_articles | List your articles by status | — |
| misarblog_get_article | Fetch a single article with full body | slug |
| misarblog_publish_article | Publish now or schedule via ISO 8601 datetime | title, body_markdown |
| misarblog_create_draft | Save a draft for review in the web editor | title, body_markdown |
| misarblog_upload_image | Upload a local file to the Misar.Blog CDN | file_path |
| misarblog_generate_image | Generate an AI cover image from a text prompt | prompt |
| misarblog_list_series | List all article series on your account | — |
| misarblog_create_series | Create a new series | title |
| misarblog_add_to_series | Add an article to a series at a given position | series_slug, article_slug |
| misarblog_get_analytics | Views, revenue, and subscriber trends (up to 365 days) | — |
Tool parameters
misarblog_login
| Param | Type | Default | Description |
| ----- | ---- | ------- | ----------- |
| port | number | random 9001–9099 | Local callback port |
| base_url | string | https://www.misar.blog | Override for self-hosted instances |
misarblog_list_articles
| Param | Type | Default | Description |
| ----- | ---- | ------- | ----------- |
| status | string | published | One of: draft · published · scheduled · archived |
| limit | number | 20 | Max results, 1–100 |
misarblog_publish_article
| Param | Type | Required | Description |
| ----- | ---- | -------- | ----------- |
| title | string | yes | Article title (max 250 chars) |
| body_markdown | string | yes | Full article content in Markdown |
| tags | string[] | no | Up to 10 tags |
| cover_image_url | string | no | HTTPS URL of cover image |
| schedule_at | string | no | ISO 8601 datetime to publish later (e.g. 2025-06-01T09:00:00Z) |
| visibility | string | no | public · subscribers · paid · private (default: public) |
misarblog_create_draft
| Param | Type | Required | Description |
| ----- | ---- | -------- | ----------- |
| title | string | yes | Draft title |
| body_markdown | string | yes | Content in Markdown |
| tags | string[] | no | Up to 10 tags |
misarblog_upload_image
| Param | Type | Required | Description |
| ----- | ---- | -------- | ----------- |
| file_path | string | yes | Absolute local path (jpg, png, webp, gif, svg) |
misarblog_generate_image
| Param | Type | Default | Description |
| ----- | ---- | ------- | ----------- |
| prompt | string | — | Image description (max 1000 chars) |
| size | string | 1024x1024 | 1024x1024 · 1792x1024 · 1024x1792 |
misarblog_create_series
| Param | Type | Required | Description |
| ----- | ---- | -------- | ----------- |
| title | string | yes | Series name |
| description | string | no | Short description |
misarblog_add_to_series
| Param | Type | Required | Description |
| ----- | ---- | -------- | ----------- |
| series_slug | string | yes | URL slug of the series |
| article_slug | string | yes | URL slug of the article |
| position | number | no | 1-indexed position; appends to end if omitted |
misarblog_get_analytics
| Param | Type | Default | Description |
| ----- | ---- | ------- | ----------- |
| days | number | 30 | Look-back window, 1–365 |
Usage examples
These are prompts you can send directly in Claude Code or Cursor Agent mode:
Publish a new article:
Write a 1000-word article about "Why AI-first blogging changes SEO forever"
and publish it on my Misar.Blog with tags ["AI", "SEO", "blogging"].Draft with a generated cover image:
Generate a dark, futuristic cover image for an article titled "Building with MCP".
Then create a draft with that image as the cover.Check performance:
Show me my analytics for the last 90 days.Publish on a schedule:
Write a short announcement post and schedule it to publish tomorrow at 9am UTC.Organize a series:
List my articles with status "published", then create a series called "AI Writing Guide"
and add the last 3 articles to it in chronological order.Self-hosted Misar.Blog
If you run your own Misar.Blog instance, set MISARBLOG_BASE_URL to your domain:
{
"mcpServers": {
"misarblog": {
"command": "python3",
"args": ["~/.claude/scripts/misarblog-mcp.py"],
"env": {
"MISARBLOG_API_KEY": "mbk_your_key_here",
"MISARBLOG_BASE_URL": "https://blog.yourdomain.com"
}
}
}
}MISARBLOG_BASE_URL can also be stored in ~/.misarblog/config.json (written by misarblog_login):
{
"api_key": "mbk_...",
"username": "yourname",
"base_url": "https://blog.yourdomain.com"
}Troubleshooting
"Not configured" on every tool call
The server can't find your API key. Either:
- Set
MISARBLOG_API_KEYin the MCP config env block, or - Run
misarblog_loginonce to save it to~/.misarblog/config.json
"API key invalid or expired"
Your key was revoked. Go to Dashboard → Settings → API Keys and generate a new one,
or run misarblog_login again to get a fresh key via the browser flow.
"Rate limited (100 req/min)"
You've exceeded the API rate limit. Wait 60 seconds and retry. If you're running automated pipelines, add a short delay between tool calls.
Browser doesn't open during misarblog_login
The server prints the URL to stderr when webbrowser.open() fails. Copy and open it manually:
Open this URL in your browser:
https://www.misar.blog/dashboard/settings/api?mcp_port=9042You have 120 seconds from when the tool runs to click Authorize MCP Access.
python3: command not found
- macOS:
brew install pythonor install from python.org - Linux:
sudo apt install python3/sudo dnf install python3 - Windows: Install from python.org and ensure
python3is inPATH
Alternatively, switch to the npm/npx option — it only requires Node.js.
npx is slow on first run
npx -y @misarblog/mcp downloads the package on first run and caches it locally. Subsequent
starts are instant. If startup time matters, use npm install -g @misarblog/mcp instead.
MCP server doesn't appear in Claude Code
Run /mcp in a Claude Code session to list active servers. If misarblog is missing:
Check
~/.claude/settings.json— ensure themcpServers.misarblogblock is valid JSONVerify the script path:
ls -la ~/.claude/scripts/misarblog-mcp.pyTest the server directly:
printf '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}\n' \ | MISARBLOG_API_KEY=mbk_test python3 ~/.claude/scripts/misarblog-mcp.pyYou should see a JSON response listing 12 tools.
Connection refused on misarblog_login callback
The local HTTP server binds to 127.0.0.1. If your browser opens on a different machine
(e.g. remote VS Code over SSH), the callback won't reach the MCP server. In that case,
use the API Key method instead.
Requirements
- Python runtime: Python 3.11+ · no external packages
- npm runtime: Node.js 18+ · package fetched automatically via npx
- Account: Misar.Blog creator account (sign up free)
