MCP Servers

模型上下文协议服务器、框架、SDK 和模板的综合目录。

MCP server for creating, updating, and querying posts on Micropub-compatible blogs via IndieAuth

创建于 3/2/2026
更新于 about 6 hours ago
Repository documentation and setup instructions

micropub-mcp

MCP server that lets AI agents (Claude Code, Cursor, etc.) create, update, delete, and query posts on any Micropub-compatible blog. Authenticates via IndieAuth with PKCE.

Built with Bun + TypeScript.

Quick Start

1. Install

git clone https://github.com/rmdes/micropub-mcp.git
cd micropub-mcp
bun install

2. Add to Claude Code

Add to your .mcp.json (project or global):

{
  "mcpServers": {
    "micropub": {
      "command": "bun",
      "args": ["run", "/path/to/micropub-mcp/src/index.ts"]
    }
  }
}

3. Authenticate

Tell Claude: "Authenticate with my blog at https://yourblog.com"

This calls micropub_auth, which:

  1. Discovers your blog's IndieAuth endpoints
  2. Opens your browser to the authorization page
  3. You approve access, the callback server catches the token
  4. Token is saved to ~/.config/micropub-mcp/<domain>.json

Authentication persists across sessions. You only need to do this once.

4. Start Posting

"Create a note saying Hello from my MCP client!"
"Write an article titled 'My Setup' about my development environment"
"Syndicate a note to Bluesky and Mastodon about the IndieWeb"

Tools

micropub_auth

Authenticate with a Micropub-compatible blog via IndieAuth + PKCE.

| Parameter | Type | Required | Description | |-----------|------|----------|-------------| | site_url | string | Yes | Your blog URL (e.g., https://yourblog.com) | | scope | string | No | OAuth scopes (default: create update delete media) |

micropub_create

Create a new post (note, article, photo, bookmark, etc.).

| Parameter | Type | Required | Description | |-----------|------|----------|-------------| | content | string | No | Post content (text or HTML) | | type | string | No | Post type: entry (default), event | | name | string | No | Title (makes it an article) | | summary | string | No | Post summary | | category | string[] | No | Tags/categories | | syndicate_to | string[] | No | Syndication target UIDs | | in_reply_to | string | No | URL being replied to | | like_of | string | No | URL being liked | | repost_of | string | No | URL being reposted | | photo | string[] | No | Photo URLs | | slug | string | No | URL slug | | post_status | string | No | published or draft | | published | string | No | ISO 8601 date |

Examples:

Create a note: { content: "Hello world" }
Create an article: { name: "My Title", content: "Article body..." }
Create a bookmark: { like_of: "https://example.com/post" }
Create a reply: { in_reply_to: "https://example.com/post", content: "Great post!" }
Syndicate: { content: "Cross-posted!", syndicate_to: ["https://brid.gy/publish/bluesky"] }

micropub_update

Update an existing post.

| Parameter | Type | Required | Description | |-----------|------|----------|-------------| | url | string | Yes | URL of the post to update | | replace | object | No | Properties to replace (values are arrays) | | add | object | No | Properties to add | | delete_properties | string[] | No | Property names to remove |

Example: { url: "https://blog.com/notes/abc", replace: { content: ["Updated text"] }, add: { category: ["new-tag"] } }

micropub_delete

Delete a post.

| Parameter | Type | Required | Description | |-----------|------|----------|-------------| | url | string | Yes | URL of the post to delete |

micropub_undelete

Restore a previously deleted post.

| Parameter | Type | Required | Description | |-----------|------|----------|-------------| | url | string | Yes | URL of the post to restore |

micropub_query

Query the Micropub server for configuration, posts, or metadata.

| Parameter | Type | Required | Description | |-----------|------|----------|-------------| | q | string | Yes | Query type (see below) | | url | string | No | Post URL (for source queries) | | properties | string[] | No | Properties to return | | limit | number | No | Max results | | offset | number | No | Pagination offset |

Query types:

  • config — Server capabilities, syndication targets, post types
  • source — Get a post's properties (requires url)
  • syndicate-to — Available syndication targets
  • post-types — Supported post types
  • category — Available categories/tags
  • channel — Available channels

micropub_upload

Upload a media file to the server's media endpoint.

| Parameter | Type | Required | Description | |-----------|------|----------|-------------| | file_path | string | Yes | Absolute path to the file |

Returns the uploaded file's URL, which can be used in photo, video, or audio parameters of micropub_create.

How Authentication Works

┌─────────┐     ┌──────────────┐     ┌─────────────┐     ┌──────────┐
│  Claude  │────>│  MCP Server  │────>│   Browser    │────>│   Blog   │
│  Code    │     │  (this tool) │     │              │     │  Server  │
└─────────┘     └──────────────┘     └─────────────┘     └──────────┘
     │                │                     │                    │
     │  micropub_auth │                     │                    │
     │───────────────>│                     │                    │
     │                │  discover endpoints │                    │
     │                │────────────────────────────────────────>│
     │                │  start callback     │                    │
     │                │  server :19750      │                    │
     │                │  open browser ──────>│                    │
     │                │                     │  authorize ────────>│
     │  "open browser"│                     │                    │
     │<───────────────│                     │<── redirect with   │
     │                │                     │    auth code       │
     │                │<── callback ────────│                    │
     │                │  exchange code ─────────────────────────>│
     │                │<── access token ────────────────────────│
     │                │  save token         │                    │
     │                │  ~/.config/...      │                    │

The callback server runs on localhost:19750 and is a process-level singleton — it persists across MCP tool calls and shuts down after receiving the callback.

Token Storage

Tokens are saved to ~/.config/micropub-mcp/<domain>.json and include:

  • Access token
  • Refresh token (if provided)
  • Expiration time
  • Discovered endpoints (micropub, media, token)

Expired tokens are automatically refreshed if a refresh token is available.

Requirements

Indiekit-Specific Notes

If your blog runs Indiekit behind nginx, ensure:

  1. CSP form-action: The /auth location must allow form-action * (or at minimum http://localhost:*) so the OAuth consent form can redirect to the local callback server. Without this, clicking "Allow" does nothing (HTTP 499 in logs).

  2. Redirect validation: Indiekit's upstream redirect regex (/^\/[\w&/=?]*$/) rejects hyphens in paths like /auth/new-password. If you hit ForbiddenError: Invalid redirect attempted, patch lib/indieauth.js with an expanded regex.

Development

# Run tests
bun test

# Start the MCP server (stdio)
bun run src/index.ts

Architecture

src/
├── index.ts        Entry point — creates MCP server, connects stdio transport
├── tools.ts        7 MCP tool definitions with Zod schemas
├── auth.ts         IndieAuth + PKCE flow, token storage, non-blocking callback server
├── client.ts       Micropub HTTP client (create/update/delete/query/upload)
└── discovery.ts    Endpoint discovery from Link headers + HTML + indieauth-metadata

License

MIT

快速设置
此服务器的安装指南

安装包 (如果需要)

npx @modelcontextprotocol/server-micropub-mcp

Cursor 配置 (mcp.json)

{ "mcpServers": { "rmdes-micropub-mcp": { "command": "npx", "args": [ "rmdes-micropub-mcp" ] } } }