Skip to main content
Glama

patreonmcp

CI License: MIT Python 3.10+

MCP server for the official Patreon API v2. Typed tools for campaigns, tiers, members, posts, webhooks, and early-access Lives, plus post creation and editing through Patreon's web editor API.

Python 3.10+.

Features

  • Typed MCP tools with structured JSON output.

  • Identity, campaigns, tiers, members, and posts through the official API.

  • Cursor pagination, explicit field selection, and opt-in PII fields.

  • Automatic OAuth refresh with rotated-token persistence.

  • Webhook CRUD (creation requires a host allowlist) and early-access Lives.

  • Text post creation, editing, publishing, scheduling, and deletion through Patreon's web editor API when a browser session cookie is configured.

  • No browser automation. The post client talks directly to Patreon's JSON:API routes.

Related MCP server: X MCP Server

API limits worth knowing

The official Patreon API v2 has no endpoints for creating, editing, or deleting posts:

  • Read: identity, campaigns, tiers, members, posts.

  • Write: webhooks and early-access Lives.

Patreon's own web app uses separate, undocumented JSON:API routes under /api/posts with a browser session and CSRF ticket. This server speaks to those routes directly for post management. They are not a public API, can change without notice, and currently support text posts only. Post write tools require PATREON_SESSION_COOKIE or PATREON_SESSION_COOKIE_FILE.

Member email, creator notes, and shipping addresses are opt-in tool parameters because they are sensitive; email and address also require extra OAuth scopes. They are also disabled unless the operator sets PATREON_ALLOW_PII=1.

Install

git clone https://github.com/andreanjos/patreonmcp.git
cd patreonmcp
uv sync

Verify the server starts and your credentials work:

PATREON_ACCESS_TOKEN=your_token uv run patreonmcp check

For post write tools, check also verifies the browser session when PATREON_SESSION_COOKIE is set.

Run it directly:

PATREON_ACCESS_TOKEN=your_token uv run patreonmcp serve

Authentication

Creator access token

Get your Creator Access Token from the Patreon Developer Portal. Creator tokens automatically carry all API v2 scopes for the creator's campaign.

export PATREON_ACCESS_TOKEN=...

OAuth refresh (optional)

If your token expires, provide the OAuth client credentials and refresh token so the server can renew it automatically:

export PATREON_CLIENT_ID=...
export PATREON_CLIENT_SECRET=...
export PATREON_REFRESH_TOKEN=...

Set PATREON_TOKEN_FILE to persist rotated tokens across restarts. The file is created with mode 0600; without it, refreshed tokens live only in memory. On POSIX, existing token and cookie files must already be 0600, regular files, owned by the current user, and not symlinks.

export PATREON_TOKEN_FILE="$HOME/.config/patreonmcp/tokens.json"

Web session (post write tools)

The create_post, update_post, publish_post, delete_post, get_managed_post, and list_drafts tools use Patreon's internal web API. They need a logged-in browser session, not an OAuth token.

  1. Sign in to https://www.patreon.com in a Chrome-family browser.

  2. Open DevTools → Network, reload the page, and select a www.patreon.com request.

  3. Copy its full Cookie request header. document.cookie is not enough because the session cookies are HttpOnly.

  4. Put the copied header in PATREON_SESSION_COOKIE, or save it to a file and point PATREON_SESSION_COOKIE_FILE at it.

export PATREON_SESSION_COOKIE='session_id=...; a_csrf=...; cf_clearance=...'
# or
chmod 600 ~/.config/patreonmcp/cookies.txt
export PATREON_SESSION_COOKIE_FILE="$HOME/.config/patreonmcp/cookies.txt"

The cookie grants full access to the account. Keep it local, never commit it, and log out of Patreon to invalidate it. The server fetches a CSRF ticket automatically and never prints the cookie.

patreonmcp check verifies both auth modes when both are configured.

Configuration reference

Variable

Required

Purpose

PATREON_ACCESS_TOKEN

One auth mode

Bearer token for API calls.

PATREON_REFRESH_TOKEN

OAuth mode

Refresh token.

PATREON_CLIENT_ID

OAuth mode

OAuth client ID.

PATREON_CLIENT_SECRET

OAuth mode

OAuth client secret.

PATREON_TOKEN_FILE

No

Persist refreshed tokens as JSON (0600).

PATREON_SESSION_COOKIE

Web post tools

Raw Cookie header from a logged-in patreon.com session.

PATREON_SESSION_COOKIE_FILE

Web post tools

File containing the raw Cookie header.

PATREON_API_BASE_URL

No

API base; defaults to https://www.patreon.com/api/oauth2/v2.

PATREON_TOKEN_URL

No

Token endpoint; defaults to https://www.patreon.com/api/oauth2/token.

PATREON_WEB_BASE_URL

No

Web API base; defaults to https://www.patreon.com.

PATREON_USER_AGENT

No

Browser User-Agent for the web session; match the browser that issued the cookie if Cloudflare rejects it.

PATREON_HTTP_BEARER_TOKEN

No

Require Authorization: Bearer <token> on streamable-HTTP requests. Minimum 16 characters.

PATREON_WEBHOOK_ALLOWED_HOSTS

No

Required to enable webhook creation. Comma-separated hostname allowlist; * explicitly allows any public host. Private/loopback IP targets are rejected.

PATREON_ALLOW_PII

No

Set to 1 to enable patron email, creator notes, and shipping addresses. Disabled by default.

PATREON_TIMEOUT_SECONDS

No

HTTP timeout; defaults to 30.

The server reads process environment variables only. .env.example documents the names; it is not loaded automatically. Use your shell, your MCP client's env block, or uv run --env-file .env ....

Setup helper

Generate a client config with absolute paths, then fill in the placeholder token:

uv run patreonmcp init
uv run patreonmcp init --output .mcp.json
uv run patreonmcp init --http --url http://127.0.0.1:8000/mcp

init never prints credentials; it uses explicit REPLACE_... placeholders. Written files are mode 0600.

Inspect the effective configuration with secrets redacted:

uv run patreonmcp config
uv run patreonmcp config --json

MCP client configuration

Use an absolute path to this checkout. Example for Claude Desktop, Claude Code, Cursor, or any client that accepts the standard mcpServers object:

{
  "mcpServers": {
    "patreon": {
      "command": "uv",
      "args": [
        "run",
        "--directory",
        "/absolute/path/to/patreonmcp",
        "patreonmcp",
        "serve"
      ],
      "env": {
        "PATREON_ACCESS_TOKEN": "your_token_here",
        "PATREON_SESSION_COOKIE": "session_id=...; a_csrf=..."
      }
    }
  }
}

Omit PATREON_SESSION_COOKIE if you only need the read tools. Add PATREON_SESSION_COOKIE_FILE instead when the cookie lives in a local file.

For HTTP transport instead of stdio:

PATREON_ACCESS_TOKEN=... uv run patreonmcp serve --transport streamable-http --host 127.0.0.1 --port 8000

The MCP endpoint is /mcp. Set PATREON_HTTP_BEARER_TOKEN to require a bearer token on every HTTP request; clients then send Authorization: Bearer <token>. Without it, loopback HTTP is unauthenticated. Binding beyond loopback requires both --allow-remote-http and a bearer token; --allow-unauthenticated-http is a second explicit opt-in for reverse-proxy deployments.

{
  "mcpServers": {
    "patreon-http": {
      "url": "http://127.0.0.1:8000/mcp",
      "headers": { "Authorization": "Bearer your-http-token" }
    }
  }
}

CLI post commands

The same post operations are available from the terminal, which is useful for checking a session before wiring up an MCP client:

# Published posts need an OAuth token; drafts need a web session.
uv run patreonmcp post list
uv run patreonmcp post list --drafts --campaign-id 42

uv run patreonmcp post create "Launch notes" --content "Hello patrons" --publish
uv run patreonmcp post create "Draft" --content-file post.html --allow-html
uv run patreonmcp post get POST_ID --content
uv run patreonmcp post update POST_ID --title "New title" --publish
uv run patreonmcp post update POST_ID --clear-tags
uv run patreonmcp post publish POST_ID
uv run patreonmcp post delete POST_ID --yes

uv run patreonmcp post list --json

post create defaults to a draft. --schedule accepts an ISO 8601 time and implies --publish. Deletion requires --yes.

Tools

Tool

What it does

Scope

get_identity

Authenticated creator profile, optionally with campaign.

identity (+ campaigns for the campaign)

list_campaigns

Campaigns visible to the token, optionally with tiers.

campaigns

get_campaign

One campaign with tiers and creator.

campaigns

list_members

Paginated patrons; optional tiers, profile, email, note, address.

campaigns.members

get_member

One patron by member UUID.

campaigns.members

list_posts

Paginated posts; content is opt-in and capped at 100,000 characters per post.

campaigns.posts

get_post

One post; HTML content is capped at 100,000 characters.

campaigns.posts

create_post

Create a text post, draft or published; public, paid, or tier-gated.

Web session

update_post

Edit content/audience, publish, or schedule a post.

Web session

publish_post

Publish an existing draft.

Web session

delete_post

Delete a post permanently.

Web session

get_managed_post

Read a draft, scheduled, or published post.

Web session

list_drafts

Paginated unpublished drafts.

Web session

list_webhooks

Webhooks created by this API client; signing secrets redacted by default.

w:campaigns.webhook

create_webhook

Create a webhook; response includes the signing secret.

w:campaigns.webhook

update_webhook

Change URI, triggers, or paused state; unpause to redeliver.

w:campaigns.webhook

delete_webhook

Delete a webhook.

w:campaigns.webhook

create_live

Schedule or immediately start a Live; stream key redacted by default.

w:campaigns.lives

get_live

Live state and RTMP connection details; stream key redacted by default.

campaigns.lives

update_live

Start or end a Live; stream key redacted by default.

w:campaigns.lives

Pagination

list_members and list_posts return next_cursor. Pass it back as cursor to fetch the next page. page_size accepts 1–1000; when post content is included, the maximum is 100.

Campaign resolution

Tools that need a campaign accept an optional campaign_id. If it is omitted and the token can see exactly one campaign, the server uses it. If several are visible, the tool fails with the visible IDs so the caller can choose.

Post write behavior

create_post defaults to a draft (publish=false). Set publish=true to publish immediately, or publish=true plus scheduled_for to schedule. Use visibility="tiers" with tier_ids for tier-gated posts; public and paid need no tier IDs. Only text_only posts are supported.

Post content and teaser text are escaped as plain text by default. Set allow_html=true to publish raw HTML; that is not sanitized and can include links, embeds, or tracking pixels.

update_post sends a partial update. publish=true publishes; omitting publish saves without changing publication state. delete_post is permanent.

These tools are built on Patreon's browser API (/api/posts/new and PATCH /api/posts/{id}) plus its CSRF ticket endpoint. They are not covered by Patreon's public API contract and can break when Patreon changes its web app.

Webhook triggers

members:create, members:update, members:delete, members:pledge:create, members:pledge:update, members:pledge:delete, posts:publish, posts:update, posts:delete.

Patreon signs webhook deliveries with X-Patreon-Signature, an HMAC-MD5 hex digest of the request body using the webhook secret. Verify it on your receiver.

Webhook creation is disabled unless PATREON_WEBHOOK_ALLOWED_HOSTS names the target host. Webhooks are a persistent data-export channel; approve URI changes and unpausing carefully.

Scopes

Scope

Needed for

identity

get_identity

identity[email]

get_identity(include_email=true)

campaigns

campaigns and tiers

campaigns.members

members

campaigns.members[email]

list_members / get_member with email

campaigns.members.address

shipping addresses

campaigns.posts

posts

w:campaigns.webhook

webhook CRUD

campaigns.lives

reading Lives

w:campaigns.lives

creating and updating Lives

Web session cookie

post create/edit/publish/delete and draft listing

Third-party OAuth clients must request these explicitly. During Patreon's OAuth flow, newly requested scopes are added to previously approved scopes.

Security defaults

  • Patron email, creator notes, and shipping addresses require PATREON_ALLOW_PII=1.

  • Webhook creation is disabled until PATREON_WEBHOOK_ALLOWED_HOSTS is set.

  • Webhook signing secrets and Live stream keys are redacted unless explicitly requested.

  • Post content and teaser text are escaped unless allow_html=true; post content is capped at 100,000 characters.

  • HTTP transport binds to loopback; remote exposure requires --allow-remote-http plus PATREON_HTTP_BEARER_TOKEN (or a second explicit --allow-unauthenticated-http opt-in for a reverse proxy).

  • On POSIX, token and cookie files must be regular files owned by the current user with no group/other permissions (chmod 600).

  • Base URLs are pinned to www.patreon.com (or loopback for tests), so a rogue environment cannot redirect bearer tokens, refresh tokens, or session cookies to another host.

Development

uv sync --all-groups
uv run pytest
uv run ruff check .
uv run ruff format --check .

Layout:

src/patreonmcp/
  api.py       # endpoint wrappers + JSON:API normalization
  client.py    # auth, token refresh, retries, rate-limit handling
  config.py    # environment, token-file, and session-cookie loading
  models.py    # typed structured-output models
  web_api.py   # undocumented /api post create/edit client + CSRF
  post_cli.py  # post list/get/create/update/publish/delete commands
  http_auth.py # bearer-token guard for streamable HTTP
  server.py    # MCP tool registration
  cli.py       # serve / check / init / config commands

Tests use httpx2.MockTransport; no network or real credentials are required.

Privacy

Patron names, pledge amounts, charge status, and any optional email, note, or address fields are sent to your MCP client and therefore to your model provider. PII fields are disabled unless PATREON_ALLOW_PII=1 is set. Enable optional fields only when the task needs them, and handle the data in accordance with Patreon's Creator Privacy Promise and applicable law.

PATREON_SESSION_COOKIE is a full account credential. Keep it in your local environment or a 0600 file; never commit it, paste it into a chat, or share it with the model provider.

Contributing

Development setup, test commands, and review guidelines are in CONTRIBUTING.md.

Security

Do not report vulnerabilities in public issues. See SECURITY.md. Never commit a Patreon token or session cookie.

License

MIT. See LICENSE.

Available Tools

20 tools
create_liveB
Destructive

Create an early-access Patreon Live livestream.

The stream key is redacted by default.

Inputs: state (required), title (required), description, scheduled_for, +2 more. Returns: id, state, title, rtmp_url, +3 more

create_postA
Destructive

Create a text post through Patreon's web editor API.

Requires PATREON_SESSION_COOKIE or PATREON_SESSION_COOKIE_FILE. This uses Patreon's undocumented browser API, not the official OAuth API, and can break when Patreon changes its web app. Only text posts are supported.

Inputs: title (required), tags, content, publish, +6 more. Returns: id, url, title, content, +16 more

create_webhookA
Destructive

Create a webhook. The response includes the HMAC signing secret.

Disabled unless PATREON_WEBHOOK_ALLOWED_HOSTS permits the target host. This is a persistent data-export channel; clients should require approval.

Inputs: uri (required), triggers (required), campaign_id. Returns: id, uri, paused, secret, +3 more

delete_postA
DestructiveIdempotent

Delete a post through Patreon's web editor API.

This is destructive and cannot be undone.

Inputs: post_id (required). Returns: id, deleted

delete_webhookB
DestructiveIdempotent

Delete a webhook created by this API client.

Inputs: webhook_id (required). Returns: id, deleted

get_campaignB
Read-onlyIdempotent

Get one campaign with its tiers and optionally its creator.

Inputs: campaign_id, include_tiers, include_creator. Returns: id, url, name, tiers, +18 more

get_identityA
Read-onlyIdempotent

Get the authenticated Patreon user (the creator behind the token).

Inputs: include_email, include_campaign. Returns: id, url, about, email, +9 more

get_liveA
Read-onlyIdempotent

Get a livestream's state and RTMP connection details.

The stream key is redacted unless include_stream_key is true.

Inputs: live_id (required), include_stream_key. Returns: id, state, title, rtmp_url, +3 more

get_managed_postB
Read-onlyIdempotent

Get a post/draft via the web API; content is capped at 100,000 characters.

Inputs: post_id (required). Returns: id, url, title, content, +16 more

get_memberB
Read-onlyIdempotent

Get one patron by member UUID.

Inputs: member_id (required), include_note, include_user, include_email, +2 more. Returns: id, note, user, email, +14 more

get_postB
Read-onlyIdempotent

Get one post, including its full HTML content.

Inputs: post_id (required). Returns: id, url, title, content, +16 more

list_campaignsB
Read-onlyIdempotent

List campaigns owned by the authenticated creator.

Inputs: include_tiers, include_creator. Returns: total, campaigns

list_draftsB
Read-onlyIdempotent

List unpublished drafts for a campaign through the web editor API.

Inputs: cursor, page_size, campaign_id. Returns: posts, total, next_cursor

list_membersB
Read-onlyIdempotent

List patrons for a campaign with cursor pagination.

Inputs: cursor, page_size, campaign_id, include_note, +4 more. Returns: total, members, next_cursor

list_postsB
Read-onlyIdempotent

List posts for a campaign with cursor pagination.

Inputs: cursor, page_size, campaign_id, include_content. Returns: posts, total, next_cursor

list_webhooksA
Read-onlyIdempotent

List this API client's webhooks. Signing secrets are redacted by default.

Inputs: include_secrets. Returns: webhooks

publish_postB
DestructiveIdempotent

Publish an existing draft through Patreon's web editor API.

Inputs: post_id (required). Returns: id, url, title, content, +16 more

update_liveB
DestructiveIdempotent

Start or end a livestream. The stream key is redacted by default.

Inputs: state (required), live_id (required), include_stream_key. Returns: id, state, title, rtmp_url, +3 more

update_postA
DestructiveIdempotent

Update or publish an existing post through Patreon's web editor API.

Requires a web session. Pass publish=true to publish now, or publish=true plus scheduled_for to schedule. Omitting publish saves without changing publication state.

Inputs: post_id (required), tags, title, content, +7 more. Returns: id, url, title, content, +16 more

update_webhookA
DestructiveIdempotent

Update a webhook's URI, triggers, or paused state.

Changing the URI requires PATREON_WEBHOOK_ALLOWED_HOSTS to permit the host. Unpausing can redeliver queued patron events.

Inputs: webhook_id (required), uri, paused, triggers. Returns: id, uri, paused, secret, +3 more

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    B3.4/5.0

    Scored across 20 tools

    Disambiguation3/5

    Most tools target distinct resources, but the server mixes two APIs (official OAuth vs. the web editor API), creating genuine overlap: get_post vs get_managed_post both fetch a post, and update_post (which can publish) overlaps with publish_post. The post/draft lifecycle (list_posts, list_drafts, create_post, get_managed_post) requires careful reading to select the right tool.

    Naming Consistency5/5

    Every tool follows a clean verb_noun snake_case pattern (get_identity, list_campaigns, create_post, update_webhook, publish_post). No deviation in style or casing across all 20 tools.

    Tool Count3/5

    20 tools is borderline heavy for the domain. A few are arguably redundant (get_post vs get_managed_post, update_post vs publish_post), and the dual-API split inflates the surface beyond a strictly minimal set.

    Completeness4/5

    Coverage is broad: posts have create/update/delete/list/get plus drafts, webhooks have full CRUD, and live has create/update/get. Minor gaps remain (no list/delete for live streams, no update/delete for campaigns or members), but core workflows are covered.

    Maintenance

    ActivityMaintained
    ResponsivenessNo recent community issues

    Related MCP Connectors

    Related MCP Servers

    • A
      license
      A
      quality
      D
      maintenance
      Enables interaction with Reddit through a comprehensive API interface supporting both read-only operations (browsing posts, comments, user profiles) and authenticated actions (posting, commenting, voting) via OAuth2 authentication.
      7
      MIT
    • F
      license
      Not graded
      quality
      D
      maintenance
      Enables interaction with X (Twitter) API v2 with multi-user OAuth 2.0 support, allowing users to manage bookmarks, create tweets, and access user information with encrypted token storage and automatic refresh.
      18 npm
      -
    • A
      license
      B
      quality
      D
      maintenance
      Enables interaction with the official Facebook Graph API, providing tools for managing Pages, Posts, Comments, Reactions, Media, Events, Insights, and credential storage/validation.
      38
      MIT