loading…
Search for a command to run...
loading…
A comprehensive MCP server that enables LLMs like Claude to explore and interact with the existing Fediverse through standardized MCP tools, resources, and prom
A comprehensive MCP server that enables LLMs like Claude to explore and interact with the existing Fediverse through standardized MCP tools, resources, and prompts.
Fediverse Client for LLMs
A comprehensive Model Context Protocol (MCP) server that enables LLMs like Claude to explore and interact with the existing Fediverse through standardized MCP tools, resources, and prompts.
Upgrading from v1? See MIGRATION-v2.md for the full v2.0.0 upgrade guide. v2 includes breaking changes (Node 20+, required HTTP secret, env var format change) — read the migration notes before upgrading.
Full write capabilities, multi-account support, and HTTP transport — all of it shipping in v2.0.0 with hardened security and a topic-organized source tree. See MIGRATION-v2.md if you are upgrading from v1.x.
| Post & Interact Create posts, reply, boost, favourite, and bookmark directly from your LLM |
Multi-Account Manage multiple fediverse accounts with secure credential storage |
Media & Polls Upload images with alt text, vote on polls, schedule posts |
| Export Anywhere Export timelines, threads, and accounts to JSON, Markdown, or CSV |
HTTP Transport Production-ready HTTP/SSE mode for enterprise deployments |
53 Tools 21 read-only + 28 authenticated + 4 export tools |
See Authenticated Tools | See Export Tools | Full Changelog
This project works on Windows, macOS, and Linux with automatic platform detection and appropriate script selection.
For the fastest setup, use our automated installation script:
# Install directly with npx (recommended)
npx activitypub-mcp install
# Or clone and run setup
git clone https://github.com/cameronrye/activitypub-mcp.git
cd activitypub-mcp
npm run setup
Windows (PowerShell):
# Clone and setup
git clone https://github.com/cameronrye/activitypub-mcp.git
cd activitypub-mcp
npm run setup:windows
# Or run PowerShell script directly
.\scripts\setup.ps1
macOS/Linux (Bash):
# Clone and setup
git clone https://github.com/cameronrye/activitypub-mcp.git
cd activitypub-mcp
npm run setup:unix
# Or run bash script directly
bash scripts/setup.sh
git clone https://github.com/cameronrye/activitypub-mcp.git
cd activitypub-mcp
npm install
Windows:
# Copy environment template
copy .env.example .env
# Edit configuration (optional)
notepad .env
macOS/Linux:
# Copy environment template
cp .env.example .env
# Edit configuration (optional)
nano .env
# Start the MCP server (no local ActivityPub server needed)
npm run mcp
Test MCP server with MCP Inspector:
# Install MCP Inspector
npm install -g @modelcontextprotocol/inspector
# Connect to the MCP server
mcp-inspector
To use this MCP server with Claude Desktop:
Locate your Claude Desktop config file:
~/Library/Application Support/Claude/claude_desktop_config.json%APPDATA%\Claude\claude_desktop_config.jsonAdd the server configuration:
{
"mcpServers": {
"activitypub": {
"command": "npx",
"args": ["-y", "activitypub-mcp"]
}
}
}
To use this MCP server with Cursor:
Locate Cursor's MCP config file (same on every platform):
~/.cursor/mcp.jsonAdd the server configuration (identical shape to Claude Desktop):
{
"mcpServers": {
"activitypub": {
"command": "npx",
"args": ["-y", "activitypub-mcp"]
}
}
}
After restarting your MCP client, ask it something like:
"Look up @[email protected] on the fediverse and summarize their latest posts."
The model will pick discover-actor to fetch the profile, then fetch-timeline to read recent posts.
For detailed usage instructions, examples, and troubleshooting, see the documentation site:
Resources provide read-only access to fediverse data from any ActivityPub server. All resources return JSON data unless otherwise specified.
Get information about the ActivityPub MCP server:
activitypub://server-info
Parameters:
Example Response:
Note: The
capabilitiesblock is dynamically generated from the live registry; the example below is illustrative.
{
"name": "activitypub-mcp",
"version": "2.0.0",
"description": "A Model Context Protocol server for exploring and interacting with the existing Fediverse",
"capabilities": {
"tools": [
"batch-fetch-actors",
"batch-fetch-posts",
"block-account",
"bookmark-post",
"boost-post",
"cancel-scheduled-post",
"convert-url",
"delete-post",
"discover-actor",
"discover-instances",
"discover-instances-live",
"favourite-post",
"fetch-timeline",
"follow-account",
"get-bookmarks",
"get-favourites",
"get-federated-timeline",
"get-home-timeline",
"get-instance-info",
"get-local-timeline",
"get-notifications",
"get-post-thread",
"get-relationship",
"get-scheduled-posts",
"get-trending-hashtags",
"get-trending-posts",
"health-check",
"list-accounts",
"mute-account",
"performance-metrics",
"post-status",
"recommend-instances",
"reply-to-post",
"search",
"search-accounts",
"search-hashtags",
"search-instance",
"search-posts",
"switch-account",
"unblock-account",
"unbookmark-post",
"unboost-post",
"unfavourite-post",
"unfollow-account",
"unmute-account",
"update-scheduled-post",
"upload-media",
"verify-account",
"vote-on-poll"
],
"resources": [
"federated-timeline",
"instance-info",
"local-timeline",
"post-thread",
"remote-actor",
"remote-followers",
"remote-following",
"remote-timeline",
"server-info",
"trending"
],
"prompts": [
"analyze-user-activity",
"community-health",
"compare-accounts",
"compare-instances",
"content-strategy",
"discover-content",
"explore-fediverse",
"find-experts",
"migration-helper",
"summarize-trending",
"thread-composer"
]
},
"features": {
"auditLogging": true,
"instanceBlocklist": true,
"contentWarnings": true,
"batchOperations": true
}
}
Get information about any actor in the fediverse:
activitypub://remote-actor/{identifier}
Parameters:
identifier (string): The actor's fediverse handle (e.g., [email protected])Example Response:
{
"@context": ["https://www.w3.org/ns/activitystreams"],
"id": "https://mastodon.social/users/alice",
"type": "Person",
"preferredUsername": "alice",
"name": "Alice Smith",
"summary": "Software developer passionate about decentralized social networks",
"inbox": "https://mastodon.social/users/alice/inbox",
"outbox": "https://mastodon.social/users/alice/outbox"
}
Access any actor's timeline/outbox from across the fediverse:
activitypub://remote-timeline/{identifier}
Parameters:
identifier (string): The actor's fediverse handle (e.g., [email protected])Example Response:
{
"@context": "https://www.w3.org/ns/activitystreams",
"type": "OrderedCollection",
"id": "https://mastodon.social/users/alice/outbox",
"totalItems": 42,
"orderedItems": [...]
}
Get information about any fediverse instance:
activitypub://instance-info/{domain}
Parameters:
domain (string): The instance domain (e.g., mastodon.social)Example Response:
{
"domain": "mastodon.social",
"software": "mastodon",
"version": "4.2.1",
"description": "The original server operated by the Mastodon gGmbH non-profit",
"registrations": true,
"stats": {
"user_count": 900000,
"status_count": 50000000
}
}
Access follower and following lists from any actor:
activitypub://remote-followers/{identifier}
activitypub://remote-following/{identifier}
Get trending hashtags and posts from an instance:
activitypub://trending/{domain}
Get the local public timeline from an instance:
activitypub://local-timeline/{domain}
Get the federated public timeline from an instance:
activitypub://federated-timeline/{domain}
Get a post and its full conversation thread:
activitypub://post-thread/{domain}/{statusId}
Note: The legacy form
activitypub://post-thread/{postUrl}is still accepted with a deprecation warning and will be removed in 2.1.0.
Tools enable LLMs to discover and interact with the fediverse. All tools return structured responses with success/error information.
Discover and get information about any actor in the fediverse:
{
"name": "discover-actor",
"arguments": {
"identifier": "[email protected]"
}
}
Parameters:
identifier (string, required): Fediverse handle (e.g., [email protected])Fetch posts from any actor's timeline with pagination support:
{
"name": "fetch-timeline",
"arguments": {
"identifier": "[email protected]",
"limit": 20,
"cursor": null,
"maxId": null
}
}
Parameters:
identifier (string, required): Fediverse handlelimit (number, optional): Number of posts to fetch (1-50, default: 20)cursor (string, optional): Pagination cursor from previous responseminId (string, optional): Return results newer than this IDmaxId (string, optional): Return results older than this IDsinceId (string, optional): Return results since this IDGet detailed information about any fediverse instance:
{
"name": "get-instance-info",
"arguments": {
"domain": "mastodon.social"
}
}
Parameters:
domain (string, required): Instance domainSearch for content on a specific fediverse instance:
{
"name": "search-instance",
"arguments": {
"domain": "mastodon.social",
"query": "typescript",
"type": "accounts"
}
}
Parameters:
domain (string, required): Instance domain to searchquery (string, required): Search querytype (string, optional): Type of content ("accounts", "statuses", "hashtags")Find popular fediverse instances by category or topic:
{
"name": "discover-instances",
"arguments": {
"category": "mastodon",
"topic": "technology",
"size": "medium"
}
}
Parameters:
category (string, optional): Software type ("mastodon", "pleroma", "misskey", etc.)topic (string, optional): Topic or interest to search forsize (string, optional): Instance size ("small", "medium", "large")region (string, optional): Geographic region or languagebeginnerFriendly (boolean, optional): Show only beginner-friendly instancesGet personalized instance recommendations based on interests:
{
"name": "recommend-instances",
"arguments": {
"interests": ["technology", "programming", "open source"]
}
}
Parameters:
interests (array, required): List of your interests or topicsReal-time instance discovery via instances.social API:
{
"name": "discover-instances-live",
"arguments": {
"software": "mastodon",
"language": "en",
"minUsers": 1000,
"openRegistrations": true,
"limit": 20
}
}
Parameters:
software (enum, optional): Filter by software type (mastodon, pleroma, misskey, pixelfed, lemmy, peertube, any)language (string, optional): Filter by language code (e.g., "en", "de", "ja")minUsers (number, optional): Minimum number of usersmaxUsers (number, optional): Maximum number of usersopenRegistrations (boolean, optional): Only show instances with open registrationssortBy (enum, optional): Sort by "users", "statuses", "connections", or "name"limit (number, optional): Number of results (default: 20)Get currently trending hashtags on an instance:
{
"name": "get-trending-hashtags",
"arguments": {
"domain": "mastodon.social",
"limit": 20
}
}
Get currently trending posts on an instance:
{
"name": "get-trending-posts",
"arguments": {
"domain": "mastodon.social",
"limit": 20
}
}
Get the local public timeline from an instance:
{
"name": "get-local-timeline",
"arguments": {
"domain": "mastodon.social",
"limit": 20
}
}
Get the federated public timeline from an instance:
{
"name": "get-federated-timeline",
"arguments": {
"domain": "mastodon.social",
"limit": 20
}
}
Fetch a post and its full conversation thread:
{
"name": "get-post-thread",
"arguments": {
"postUrl": "https://mastodon.social/@user/123456789",
"depth": 2,
"maxReplies": 50
}
}
Search for accounts on an instance:
{
"name": "search-accounts",
"arguments": {
"domain": "mastodon.social",
"query": "developer",
"limit": 20
}
}
Search for hashtags on an instance:
{
"name": "search-hashtags",
"arguments": {
"domain": "mastodon.social",
"query": "programming",
"limit": 20
}
}
Search for posts on an instance:
{
"name": "search-posts",
"arguments": {
"domain": "mastodon.social",
"query": "typescript",
"limit": 20
}
}
Fetch multiple actors in a single request:
{
"name": "batch-fetch-actors",
"arguments": {
"identifiers": ["[email protected]", "[email protected]"]
}
}
Fetch multiple posts in a single request:
{
"name": "batch-fetch-posts",
"arguments": {
"urls": ["https://mastodon.social/@user/123", "https://fosstodon.org/@user/456"]
}
}
Check the health status of the MCP server:
{
"name": "health-check",
"arguments": {}
}
Parameters:
Get performance metrics for the MCP server:
{
"name": "performance-metrics",
"arguments": {
"operation": "discover-actor"
}
}
Parameters:
operation (string, optional): Specific operation to get metrics for{
"name": "explore-fediverse",
"arguments": {
"interests": "technology and programming",
"instanceType": "mastodon"
}
}
{
"name": "compare-instances",
"arguments": {
"instances": "mastodon.social, fosstodon.org, hachyderm.io",
"criteria": "community size and focus"
}
}
{
"name": "discover-content",
"arguments": {
"topics": "artificial intelligence",
"contentType": "people"
}
}
{
"name": "compare-accounts",
"arguments": {
"accounts": "[email protected], [email protected]",
"aspects": "posting frequency, topics, engagement"
}
}
{
"name": "analyze-user-activity",
"arguments": {
"identifier": "[email protected]",
"depth": "standard"
}
}
{
"name": "find-experts",
"arguments": {
"topic": "machine learning",
"instances": "mastodon.social, fosstodon.org"
}
}
{
"name": "summarize-trending",
"arguments": {
"instances": "mastodon.social",
"focus": "tech"
}
}
Plan your fediverse content strategy based on trending topics:
{
"name": "content-strategy",
"arguments": {
"topics": "programming, open source",
"targetAudience": "developers",
"postingFrequency": "several-per-week"
}
}
Analyze instance moderation and community health:
{
"name": "community-health",
"arguments": {
"instance": "fosstodon.org",
"concerns": "moderation, spam"
}
}
Get help planning a migration to a new fediverse instance:
{
"name": "migration-helper",
"arguments": {
"currentInstance": "mastodon.social",
"targetInstance": "fosstodon.org",
"priorities": "moderation, privacy, community focus"
}
}
Help compose well-structured threaded posts:
{
"name": "thread-composer",
"arguments": {
"topic": "Introduction to the Fediverse",
"keyPoints": "What is ActivityPub, Popular instances, Getting started",
"tone": "informative",
"targetLength": "medium"
}
}
These tools require authentication via environment variables. See Configuration for setup.
list-accounts - List configured accountsswitch-account - Switch active accountverify-account - Verify account credentials{
"name": "post-status",
"arguments": {
"content": "Hello Fediverse!",
"visibility": "public",
"contentWarning": "optional CW"
}
}
post-status - Create a new postreply-to-post - Reply to an existing postdelete-post - Delete your own postboost-post / unboost-post - Boost (reblog) postsfavourite-post / unfavourite-post - Favourite postsbookmark-post / unbookmark-post - Bookmark postsfollow-account / unfollow-account - Follow/unfollow accountsmute-account / unmute-account - Mute accountsblock-account / unblock-account - Block accountsget-home-timeline - Your home timelineget-notifications - Your notificationsget-bookmarks - Your bookmarked postsget-favourites - Your favourited postsSearch across accounts, posts, and hashtags in a single query:
{
"name": "search",
"arguments": {
"domain": "mastodon.social",
"query": "typescript programming",
"type": "all",
"limit": 20
}
}
Parameters:
domain (string, optional): Instance domain to search on. Defaults to mastodon.social.query (string, required): Search querytype (string, optional): "all", "accounts", "posts", or "hashtags" (default: "all")limit (number, optional): Results per type (1-40, default: 20)resolve (boolean, optional): Attempt WebFinger lookup for remote accountsCheck your relationship status with another account:
{
"name": "get-relationship",
"arguments": {
"acct": "[email protected]"
}
}
Parameters:
acct (string, required): Account to check relationship with, in username@instance format.accountId (string, optional): Your account ID (defaults to active account).Note: This tool checks one account at a time. To check multiple accounts, call it once per account.
Returns: Following, followed_by, blocking, muting, and other relationship statuses.
Vote on polls in posts:
{
"name": "vote-on-poll",
"arguments": {
"pollId": "123456",
"choices": [0, 2]
}
}
Parameters:
pollId (string, required): The poll ID to vote onchoices (array, required): Array of choice indices (0-based)Returns: Updated poll with current results and visual bar chart.
Upload media files with alt text descriptions:
{
"name": "upload-media",
"arguments": {
"filePath": "/path/to/image.jpg",
"description": "A beautiful sunset over the ocean",
"focusX": 0.0,
"focusY": 0.5
}
}
Parameters:
filePath (string, required): Local file path or URL to uploaddescription (string, optional): Alt text for accessibility (recommended)focusX (number, optional): Horizontal focal point for crop, range -1.0 to 1.0 (default 0).focusY (number, optional): Vertical focal point for crop, range -1.0 to 1.0 (default 0).Supported types: Images (jpg, png, gif, webp), Videos (mp4, webm), Audio (mp3, ogg)
Manage scheduled posts:
{
"name": "get-scheduled-posts",
"arguments": {
"limit": 20
}
}
{
"name": "update-scheduled-post",
"arguments": {
"scheduledPostId": "123",
"scheduledAt": "<ISO 8601 timestamp at least one hour in the future>"
}
}
{
"name": "cancel-scheduled-post",
"arguments": {
"scheduledPostId": "123"
}
}
get-scheduled-posts - List all pending scheduled postsupdate-scheduled-post - Change the scheduled timecancel-scheduled-post - Cancel a scheduled postExport fediverse content in multiple formats (JSON, Markdown, CSV):
{
"name": "export-timeline",
"arguments": {
"identifier": "[email protected]",
"format": "markdown",
"limit": 50
}
}
export-timeline - Export actor timelineexport-thread - Export post thread with repliesexport-account-info - Comprehensive account data exportexport-hashtag - Export posts with a specific hashtagactivitypub-mcp/
├── src/ # Source code
│ ├── mcp-main.ts # MCP server entry point
│ ├── mcp-server.ts # MCP server wiring
│ ├── config.ts # Environment-driven configuration
│ ├── activitypub/ # Remote ActivityPub client
│ │ └── remote-client.ts
│ ├── audit/ # Audit logging
│ │ └── logger.ts
│ ├── auth/ # Authentication (multi-account)
│ │ ├── account-manager.ts
│ │ ├── authenticated-client.ts
│ │ └── index.ts
│ ├── discovery/ # WebFinger + instance discovery
│ │ ├── webfinger.ts
│ │ ├── instance-discovery.ts
│ │ └── dynamic-instance-discovery.ts
│ ├── mcp/ # MCP handlers
│ │ ├── tools.ts # Read-only tools
│ │ ├── tools-write.ts # Write tools
│ │ ├── tools-export.ts # Export tools
│ │ ├── resources.ts # Resource implementations
│ │ ├── prompts.ts # Prompt implementations
│ │ └── capabilities.ts # Capability registry
│ ├── policy/ # Instance blocklist
│ │ └── instance-blocklist.ts
│ ├── resilience/ # Rate limiting
│ │ └── rate-limiter.ts
│ ├── telemetry/ # Health, metrics, logging
│ │ ├── health-check.ts
│ │ ├── performance-monitor.ts
│ │ └── logging.ts
│ ├── transport/ # HTTP transport + auth middleware
│ │ ├── http.ts
│ │ └── auth-middleware.ts
│ ├── utils/ # Utility helpers
│ │ ├── errors.ts
│ │ ├── html.ts
│ │ ├── fetch-helpers.ts
│ │ └── lru-cache.ts
│ └── validation/ # Zod schemas + URL validation
│ ├── schemas.ts
│ ├── validators.ts
│ └── url.ts
├── docs/ # Documentation
├── scripts/ # Installation & setup scripts
├── tests/ # Test files
│ ├── unit/ # Unit tests
│ └── integration/ # Integration tests (gated)
├── dist/ # Built JavaScript files
├── package.json
└── README.md
LLM Client ←→ MCP Protocol ←→ Fediverse Client ←→ Remote ActivityPub Servers
↓
WebFinger Discovery
↓
Remote Data Fetching
For deeper guides, see the full documentation site at cameronrye.github.io/activitypub-mcp:
The docs/specifications/ directory in this repo contains LLM-readable
spec mirrors (ActivityPub, ActivityStreams, WebFinger, Fedify CLI) as
standalone Markdown. All other documentation moved to the Astro-built
site under src/pages/docs/ in v2.0.0.
npm run mcp - Start MCP servernpm run mcp:dev - Start MCP server in watch modenpm run test - Run testsnpm run build - Build TypeScriptCreate a .env file:
# MCP Server configuration
MCP_SERVER_NAME=activitypub-mcp
MCP_SERVER_VERSION=2.0.0
# Transport configuration (stdio or http; stdio is default)
MCP_TRANSPORT_MODE=stdio
MCP_HTTP_PORT=3000
MCP_HTTP_HOST=127.0.0.1
# REQUIRED if MCP_TRANSPORT_MODE=http. v2 refuses to start without it.
# Generate with: node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"
# MCP_HTTP_SECRET=
# CORS for HTTP transport. v2 default is empty (no origins allowed).
# Set explicitly for browser clients; "*" is allowed but discouraged.
# MCP_HTTP_CORS_ORIGINS=https://app.example.com
# Rate limiting
RATE_LIMIT_ENABLED=true
RATE_LIMIT_MAX=100
RATE_LIMIT_WINDOW=900000
# Logging
LOG_LEVEL=info
# Audit logging
AUDIT_LOG_ENABLED=true
AUDIT_LOG_MAX_ENTRIES=10000
# Instance blocklist (comma-separated domains)
BLOCKED_INSTANCES=
INSTANCE_BLOCKING_ENABLED=true
# Dynamic instance discovery
INSTANCES_SOCIAL_TOKEN=
DYNAMIC_INSTANCE_CACHE_TTL=3600000
# Content warnings
RESPECT_CONTENT_WARNINGS=true
SHOW_CONTENT_WARNINGS=true
# Thread traversal caps (v2 — applies to get-post-thread)
# MCP_THREAD_MAX_DEPTH=5
# MCP_THREAD_MAX_REPLIES=50
# MCP_THREAD_CROSS_ORIGIN_FETCH=false # true restores v1 fetch-everything behavior
# Health check
# Set to false to skip only the outbound connectivity probe (e.g., air-gapped envs).
# HEALTH_CHECK_EXTERNAL_PROBE=true
# Authentication — single account (optional)
ACTIVITYPUB_DEFAULT_INSTANCE=mastodon.social
ACTIVITYPUB_DEFAULT_TOKEN=your-oauth-access-token
ACTIVITYPUB_DEFAULT_USERNAME=your-username
# Authentication — multi-account (v2 pipe-delimited; v1 colon form is rejected)
# Format: id|instance|token|username|label,id2|...
# ACTIVITYPUB_ACCOUNTS=work|fosstodon.org|token1|work_account|Work,personal|mastodon.social|token2|personal_account|Personal
For production deployments, you can run the server in HTTP mode:
# Start with HTTP transport
MCP_TRANSPORT_MODE=http MCP_HTTP_PORT=8080 npm run mcp
# The server exposes:
# - /mcp - MCP protocol endpoint
# - /health - Health check endpoint
# - /metrics - Performance metrics
# - / - Server info
# Test MCP server with inspector
mcp-inspector
# Test fediverse interactions
npm run test
# Manual testing with specific actors
# Use the discover-actor tool to test WebFinger discovery
This project is designed to work seamlessly across different operating systems:
| Platform | Recommended Method | Alternative Methods |
|---|---|---|
| Windows | npm run setup |
.\scripts\setup.ps1 or npm run setup:windows |
| macOS | npm run setup |
bash scripts/setup.sh or npm run setup:unix |
| Linux | npm run setup |
bash scripts/setup.sh or npm run setup:unix |
Windows PowerShell Execution Policy:
# If you get execution policy errors, run:
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser
Windows Git Bash:
# Git Bash users can use Unix-style commands:
npm run setup:unix
Linux/macOS Permissions:
# If you get permission errors, make scripts executable:
chmod +x scripts/*.sh
git checkout -b feature/amazing-featuregit commit -m 'Add amazing feature'git push origin feature/amazing-featureThis project is licensed under the MIT License - see the LICENSE file for details.
Made with ❤️ by Cameron Rye
Run in your terminal:
claude mcp add activitypub-mcp-server -- npx Security
Low riskAutomated heuristic from public metadata — not a security guarantee.