Mastodon Blade MCP
A security-first, token-efficient MCP server for Mastodon. 45 tools across timelines, statuses, notifications, search, and social interactions.
Why another Mastodon MCP?
| The-Focus-AI/mastodon-mcp | cameronrye/activitypub-mcp | This | |
|---|---|---|---|
| Tools | ~4 (minimal) | 53 (ActivityPub-generic) | 45 (Mastodon-targeted) |
| Token cost | Full JSON dumps | Verbose output | Pipe-delimited, HTML-stripped |
| Write safety | None | None | Write gate + confirm gate |
| Rate limiting | None | None | X-RateLimit-* header parsing, adaptive backoff |
| Multi-instance | Single only | Single | Native multi-instance |
| Notifications | None | Basic | Full filtering by type |
| Credential safety | N/A | N/A | Scrubbed from all output |
This MCP is designed for agentic platforms that need:
- Precise reads -- query one status, one thread, one hashtag. No full-state dumps.
- Safe writes -- two-tier gating (env var + per-call confirm) for destructive operations.
- Multi-instance -- manage multiple Mastodon servers from a single MCP.
- Token efficiency -- pipe-delimited output, HTML stripping, null-field omission.
- Rate limit awareness -- parses Mastodon headers, warns at thresholds, backs off when exhausted.
Quick Start
Install
# With uv (recommended)
uv tool install mastodon-blade-mcp
# Or from source
git clone https://github.com/groupthink-dev/mastodon-blade-mcp.git
cd mastodon-blade-mcp
make install
Configure
# Single instance
export MASTODON_INSTANCE="https://mastodon.social"
export MASTODON_TOKEN="your-access-token"
# Multi-instance
export MASTODON_PROVIDERS="social,hachyderm"
export MASTODON_SOCIAL_INSTANCE="https://mastodon.social"
export MASTODON_SOCIAL_TOKEN="token-for-social"
export MASTODON_HACHYDERM_INSTANCE="https://hachyderm.io"
export MASTODON_HACHYDERM_TOKEN="token-for-hachyderm"
# Enable posting, favouriting, following (disabled by default)
export MASTODON_WRITE_ENABLED="true"
Create an access token at Preferences > Development > New Application on your Mastodon instance.
Run
# stdio (default -- for Claude Code, Claude Desktop)
mastodon-blade-mcp
# HTTP transport (for remote access)
MASTODON_MCP_TRANSPORT=http MASTODON_MCP_API_TOKEN=your-secret mastodon-blade-mcp
Claude Code Integration
{
"mcpServers": {
"mastodon": {
"command": "uvx",
"args": ["mastodon-blade-mcp"],
"env": {
"MASTODON_INSTANCE": "https://mastodon.social",
"MASTODON_TOKEN": "your-token",
"MASTODON_WRITE_ENABLED": "true"
}
}
}
}
Claude Desktop Integration
{
"mcpServers": {
"mastodon": {
"command": "uvx",
"args": ["mastodon-blade-mcp"],
"env": {
"MASTODON_INSTANCE": "https://mastodon.social",
"MASTODON_TOKEN": "your-token"
}
}
}
}
Tools (45)
Read (25 tools)
| Tool | Description | Token Cost |
|---|---|---|
mastodon_info |
Instance info, write gate, rate limit status | Low |
mastodon_verify |
Verify credentials (current user) | Low |
mastodon_timeline_home |
Home timeline (followed accounts) | Medium |
mastodon_timeline_public |
Public/federated timeline | Medium |
mastodon_timeline_local |
Local instance timeline | Medium |
mastodon_timeline_hashtag |
Hashtag timeline | Medium |
mastodon_timeline_list |
List timeline | Medium |
mastodon_status |
Get specific status by ID | Low |
mastodon_context |
Thread context (ancestors + descendants) | Medium |
mastodon_search |
Unified search (accounts/statuses/hashtags) | Medium |
mastodon_account |
Account info by ID | Low |
mastodon_account_statuses |
Account's statuses with filters | Medium |
mastodon_relationships |
Check relationships with accounts | Low |
mastodon_followers |
List followers | Medium |
mastodon_following |
List following | Medium |
mastodon_notifications |
Notifications (filterable by type) | Medium |
mastodon_trending_tags |
Trending hashtags | Low |
mastodon_trending_statuses |
Trending statuses | Medium |
mastodon_trending_links |
Trending links | Low |
mastodon_bookmarks |
Bookmarked statuses | Medium |
mastodon_favourites |
Favourited statuses | Medium |
mastodon_lists |
All lists | Low |
mastodon_list_accounts |
Accounts in a list | Medium |
mastodon_conversations |
DM conversations | Medium |
mastodon_filters |
Active content filters (v2) | Low |
Write (20 tools -- require MASTODON_WRITE_ENABLED=true)
| Tool | Description | Confirm Gate |
|---|---|---|
mastodon_post |
Create new status (text, CW, media, schedule) | |
mastodon_reply |
Reply to a status | |
mastodon_edit |
Edit existing status | |
mastodon_delete |
Delete status | Yes |
mastodon_favourite |
Favourite a status | |
mastodon_unfavourite |
Remove favourite | |
mastodon_boost |
Reblog a status | |
mastodon_unboost |
Remove reblog | |
mastodon_bookmark |
Bookmark a status | |
mastodon_unbookmark |
Remove bookmark | |
mastodon_pin |
Pin to profile | |
mastodon_unpin |
Unpin from profile | |
mastodon_follow |
Follow an account | |
mastodon_unfollow |
Unfollow an account | |
mastodon_block |
Block an account | Yes |
mastodon_unblock |
Unblock an account | |
mastodon_mute |
Mute an account (optional duration) | Yes |
mastodon_unmute |
Unmute an account | |
mastodon_dismiss_notification |
Dismiss single notification | |
mastodon_media_upload |
Upload media attachment |
Output Format
All output is pipe-delimited for token efficiency:
# Status
109876543210 | @user@mastodon.social | 2026-04-04 10:30 | public | Hello world! | fav=5 | boost=2 | reply=1
# Account
@user@mastodon.social | Test User | followers=100 | following=50 | statuses=200
# Notification
99999 | mention | @other@mastodon.social | 2026-04-04 11:00 | status=109876543210 | "@user Hey there!"
# Search results
## Accounts (1)
@user@mastodon.social | Test User | followers=100 | following=50 | statuses=200
## Hashtags (1)
#python | uses_7d=42
# Thread context
## Ancestors (1)
anc-1 | @parent@mastodon.social | 2026-04-04 09:00 | public | Original post
## Descendants (2)
desc-1 | @reply1@mastodon.social | 2026-04-04 11:00 | public | First reply
desc-2 | @reply2@mastodon.social | 2026-04-04 12:00 | public | Second reply
Security Model
| Layer | Mechanism |
|---|---|
| Write gate | MASTODON_WRITE_ENABLED=true env var for any mutation |
| Confirm gate | confirm=true parameter for delete, block, mute |
| Credential scrubbing | Tokens and instance URLs stripped from all error output |
| Bearer auth | Optional MASTODON_MCP_API_TOKEN for HTTP transport (timing-safe comparison) |
| Rate limiting | X-RateLimit-* header parsing with adaptive backoff |
| No caching | Credentials read from env at startup, never persisted |
Multi-Instance Support
Target a specific instance with the instance parameter on any tool:
mastodon_timeline_home instance="social"
mastodon_timeline_home instance="hachyderm"
Omit instance to use the default (first configured) instance.
Environment Variables
| Variable | Description | Required |
|---|---|---|
MASTODON_INSTANCE |
Instance URL (single-instance) | Yes* |
MASTODON_TOKEN |
OAuth access token | Yes* |
MASTODON_PROVIDERS |
Comma-separated provider names | No |
MASTODON_{NAME}_INSTANCE |
Per-provider instance URL | Per-provider |
MASTODON_{NAME}_TOKEN |
Per-provider token | Per-provider |
MASTODON_WRITE_ENABLED |
Enable write operations | No (default: false) |
MASTODON_MCP_TRANSPORT |
stdio or http |
No (default: stdio) |
MASTODON_MCP_HOST |
HTTP bind address | No (default: 127.0.0.1) |
MASTODON_MCP_PORT |
HTTP port | No (default: 8770) |
MASTODON_MCP_API_TOKEN |
Bearer token for HTTP transport | No |
* Required if MASTODON_PROVIDERS is not set.
Development
# Install with dev deps
make install-dev
# Run tests
make test
# Coverage report
make test-cov
# Lint + format + type check
make check
# Run the server
make run
Architecture
src/mastodon_blade_mcp/
├── server.py -- FastMCP 2.0 server, 45 tool definitions
├── client.py -- MastodonClient: httpx async, multi-instance
├── formatters.py -- Token-efficient pipe-delimited output, HTML stripping
├── models.py -- ProviderConfig, write gate, confirm gate, credential scrubbing
├── rate_limiter.py -- X-RateLimit-* header parsing, adaptive backoff
├── auth.py -- Bearer token middleware for HTTP transport
└── __main__.py -- Entry point
Dependencies: fastmcp, httpx, pydantic. No Mastodon.py dependency -- pure HTTP against the Mastodon REST API.
Sidereal Marketplace
This MCP conforms to the social-v1 service contract (20/20 operations):
- Required (4/4): timeline, status, search, notifications
- Recommended (6/6): context, account, trending, bookmarks, favourites, relationships
- Optional (4/4): lists, filters, conversations, instance
- Gated (6/6): post, delete, favourite, boost, follow, block
See sidereal-plugin.yaml for the full plugin manifest.
License
MIT
Metadata
Release files for mastodon-blade-mcp 0.2.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| mastodon_blade_mcp-0.2.0.tar.gz | 108.0 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| mastodon_blade_mcp-0.2.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 131.0 kB
Release files / mastodon_blade_mcp-0.2.0.tar.gz
| Download URL | mastodon_blade_mcp-0.2.0.tar.gz |
|---|---|
| Size | 108.0 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
0f9d877e6ae9791db993aa9e92108886e733e7da4369066c3f506879aa3a5be0
|
|
BLAKE2b-256 checksum How to use checksums |
73153330e4a5fd764c923dfad9f4f1db0888547b7d367c83af57185329732bce
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Apr 28, 2026.
Transparency logRelease files / mastodon_blade_mcp-0.2.0-py3-none-any.whl
| Download URL | mastodon_blade_mcp-0.2.0-py3-none-any.whl |
|---|---|
| Size | 23.1 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
f48d7b43ec815f62f1c872041c282f674fa3facaa5bf9a9da5c35fda9f8ed580
|
|
BLAKE2b-256 checksum How to use checksums |
a93b1eb5986eb058589836dd7e4da5737eb63196bd214496d36f21a145ee46aa
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Apr 28, 2026.
Transparency log