Configuration Guide
Configuration Overview
The ActivityPub MCP Server can be configured through:
- Environment Variables — Runtime configuration
- Client Configuration — MCP client settings (Claude Desktop, etc.)
- Command Line Arguments — Override settings at startup
Environment Variables
Configure the server using environment variables in your MCP client configuration.
Core Settings
| Variable | Default | Description | Example |
|---|---|---|---|
LOG_LEVEL | info | Logging verbosity level | debug, info, warning, error, fatal |
USER_AGENT | ActivityPub-MCP-Client/<version> | Custom User-Agent for HTTP requests | MyApp-ActivityPub/2.0 |
REQUEST_TIMEOUT | 10000 | HTTP request timeout in milliseconds (10 seconds) | 45000 (45 seconds) |
MAX_RETRIES | 3 | Maximum retry attempts | 5 |
Cache Settings
| Variable | Default | Description | Example |
|---|---|---|---|
CACHE_TTL | 300000 | Cache time-to-live in milliseconds (5 minutes) | 600000 (10 minutes) |
CACHE_MAX_SIZE | 1000 | Max items in the LRU caches | 2000 |
Rate Limiting
| Variable | Default | Description | Example |
|---|---|---|---|
RATE_LIMIT_ENABLED | true | Enable/disable rate limiting | false to disable |
RATE_LIMIT_MAX | 100 | Maximum requests per window | 200 |
RATE_LIMIT_WINDOW | 900000 | Rate limit window in milliseconds | 1800000 (30 minutes) |
HTTP Transport
Used only when MCP_TRANSPORT_MODE=http is set. The default stdio transport (used by Claude Desktop and Cursor) ignores all of these. The HTTP transport refuses to start without MCP_HTTP_SECRET.
In v3, the HTTP server exposes two endpoints: /mcp (Bearer-auth required) and /health (unauthenticated liveness probe returning \{"status":"ok"\}). The /metrics endpoint was removed in v3.
Operator note —
/healthis liveness, not readiness. v3 deliberately reduced/healthto a trivial in-process liveness check; it no longer performs an outbound connectivity probe (theHEALTH_CHECK_*knobs were removed), so a200 OKconfirms the process is up but not that the Fediverse is reachable from the host. If your orchestrator needs a readiness signal, drive a real read tool (e.g.discover-actor) against a known instance instead of relying on/health.
| Variable | Default | Description |
|---|---|---|
MCP_TRANSPORT_MODE | stdio | Transport mode: stdio (default) or http |
MCP_HTTP_PORT | 3000 | Port for the HTTP transport |
MCP_HTTP_HOST | 127.0.0.1 | Bind host for the HTTP transport |
MCP_HTTP_SECRET | none — required | Bearer-token secret for the /mcp endpoint. 32+ random chars recommended. Generate with node -e "console.log(require('crypto').randomBytes(32).toString('hex'))". Requests must include Authorization: Bearer <secret>. The /health endpoint stays unauthenticated. |
MCP_HTTP_ALLOWED_HOSTS | empty | Comma-separated allowed Host header values. Used to prevent DNS-rebinding attacks. Leave empty to allow all hosts (not recommended for public deployments). |
MCP_HTTP_ALLOWED_ORIGINS | empty | Comma-separated Origin allowlist for DNS-rebinding protection. Empty → derived from the CORS origins. Not the same as the CORS settings below. |
MCP_HTTP_CORS_ENABLED | false | Enable CORS for the HTTP transport. |
MCP_HTTP_CORS_ORIGINS | empty | Comma-separated CORS allowed origins. Setting * logs a startup warning. |
Self-host over HTTP with Docker
The repository ships a Dockerfile (stdio by default) and a docker-compose.yml
that flips the same image to HTTP mode. Generate a secret and bring it up:
export MCP_HTTP_SECRET=$(node -e "console.log(require('crypto').randomBytes(32).toString('hex'))")
docker compose up --build
Then probe it:
curl http://localhost:8080/health
# {"status":"ok"}
curl -H "Authorization: Bearer $MCP_HTTP_SECRET" http://localhost:8080/mcp
Or without compose, overriding the stdio default at docker run time:
docker build -t activitypub-mcp .
docker run --rm -p 8080:8080 \
-e MCP_TRANSPORT_MODE=http -e MCP_HTTP_HOST=0.0.0.0 -e MCP_HTTP_PORT=8080 \
-e MCP_HTTP_SECRET="$MCP_HTTP_SECRET" \
activitypub-mcp
For any non-localhost deployment, set MCP_HTTP_ALLOWED_HOSTS and
MCP_HTTP_ALLOWED_ORIGINS (DNS-rebinding defense), terminate TLS at a reverse
proxy, and keep writes disabled — a shared HTTP endpoint has no per-session
credential isolation. See SECURITY.md.
Thread Traversal Caps (v2)
Controls applied to the get-post-thread tool and activitypub://post-thread/… resource.
| Variable | Default | Description |
|---|---|---|
MCP_THREAD_MAX_DEPTH | 5 | Maximum recursion depth when walking inReplyTo chains. |
MCP_THREAD_MAX_REPLIES | 50 | Maximum total replies fetched per thread. |
MCP_THREAD_CROSS_ORIGIN_FETCH | false | If true, fetch replies whose origin differs from the root post (v1 behavior). Default returns cross-origin replies as stubs. |
Multi-Account Configuration (v2)
ACTIVITYPUB_ACCOUNTS uses the pipe (|) delimiter in v2 so tokens containing colons (e.g., JWTs) parse correctly. v2 refuses to start if it sees the legacy colon-delimited form.
# Format: id|instance|token|username|label, comma-separated
ACTIVITYPUB_ACCOUNTS=work|fosstodon.org|TOKEN1|me|Work,home|mastodon.social|TOKEN2|me|Personal
Write Tool Access
By default, the server registers only read-only tools. Write tools (posting, following, boosting, etc.) are gated behind ACTIVITYPUB_ENABLE_WRITES. This is the primary safety switch for deployments where the MCP client should not be able to mutate fediverse state.
| Variable | Default | Description |
|---|---|---|
ACTIVITYPUB_ENABLE_WRITES | false | Set to true to register write tools (post-status, reply-to-post, follow-account, boost-post, etc.). Also requires at least one authenticated account — from ACTIVITYPUB_ACCOUNTS, the ACTIVITYPUB_DEFAULT_INSTANCE/ACTIVITYPUB_DEFAULT_TOKEN pair, or activitypub-mcp login. |
Security & Limits
Hardening knobs for the SSRF/abuse and prompt-injection threat model (see the Security Model). Defaults are safe; tune only if you understand the tradeoff. Out-of-range numeric values are clamped to a safe floor at startup.
| Variable | Default | Description |
|---|---|---|
INSTANCE_BLOCKING_ENABLED | true | Enforce the operator instance blocklist on every fetch (and redirect hop). |
BLOCKED_INSTANCES | empty | Comma-separated domains to refuse. Exact match or *.example.com wildcard. An apex entry does not cover its subdomains — use the wildcard for a whole instance family. |
MAX_RESPONSE_SIZE | 10485760 | Max bytes read from any remote response, to prevent memory exhaustion (10 MB). |
MAX_UPLOAD_SIZE | 104857600 | Max bytes upload-media will read from a local file before sniffing/forwarding it (100 MB). Files over the cap are refused before being read. Raise it if your instance accepts larger media. |
AUDIT_LOG_ENABLED | true | Record tool invocations (writes/uploads, SSRF blocks, rate-limit denials) in the in-memory audit trail. |
AUDIT_LOG_MAX_ENTRIES | 10000 | Max audit entries kept in memory (oldest evicted). Floored at 1. |
Logging Configuration
Log Levels
| Level | Description |
|---|---|
debug | Detailed debugging information, HTTP requests/responses, internal state changes |
info | General operational messages, tool executions, resource access (default) |
warning | Warning conditions, rate limiting, recoverable errors (recommended for production) |
error | Error conditions, failed requests, unrecoverable issues |
fatal | Critical errors that cause server shutdown |
Log Output Examples
Debug Level
[DEBUG] HTTP Request: GET https://mastodon.social/.well-known/webfinger
[INFO] Discovering actor: @mastodon@mastodon.social
[DEBUG] WebFinger response received: 200 OK
[DEBUG] ActivityPub actor fetched successfully
Warning Level
[WARNING] Rate limit approaching for domain: example.social
[ERROR] Failed to fetch timeline: Network timeout
Performance Tuning
Request Timeout
Adjust REQUEST_TIMEOUT (in milliseconds) based on your network conditions:
- Fast networks: 5000–10000 ms (5–10 seconds)
- Standard networks: 10000 ms (10 seconds, default)
- Slow networks: 30000–60000 ms (30–60 seconds)
Cache Configuration
Optimize CACHE_TTL (in milliseconds) for your use case:
- Real-time data: 60000–300000 ms (1–5 minutes)
- General use: 300000–600000 ms (5–10 minutes, default 300000)
- Static data: 1800000+ ms (30+ minutes)
Rate Limiting
Configure rate limits to be respectful to fediverse servers:
- Conservative: 50 requests per 15 minutes
- Standard: 100 requests per 15 minutes (default)
- Aggressive: 200 requests per 10 minutes
Client Configuration
Claude Desktop
Add the server to your Claude Desktop configuration file.
Configuration file locations:
- macOS:
~/Library/Application Support/Claude/claude_desktop_config.json - Windows:
%APPDATA%\Claude\claude_desktop_config.json - Linux:
~/.config/Claude/claude_desktop_config.json
Basic Configuration
{
"mcpServers": {
"activitypub": {
"command": "npx",
"args": ["-y", "activitypub-mcp"],
"env": {
"LOG_LEVEL": "info"
}
}
}
}
Advanced Configuration
{
"mcpServers": {
"activitypub": {
"command": "npx",
"args": ["-y", "activitypub-mcp"],
"env": {
"LOG_LEVEL": "debug",
"USER_AGENT": "MyCustomBot/1.0",
"REQUEST_TIMEOUT": "60000",
"CACHE_TTL": "600000",
"RATE_LIMIT_MAX": "50"
}
}
}
}
Other MCP Clients
For other MCP-compatible clients, use similar configuration patterns:
{
"servers": {
"activitypub": {
"command": "npx",
"args": ["activitypub-mcp"],
"environment": {
"LOG_LEVEL": "info"
}
}
}
}
Configuration Examples
Development Configuration
Optimized for development with verbose logging and relaxed limits:
{
"mcpServers": {
"activitypub": {
"command": "npx",
"args": ["-y", "activitypub-mcp"],
"env": {
"LOG_LEVEL": "debug",
"REQUEST_TIMEOUT": "60000",
"CACHE_TTL": "60000",
"RATE_LIMIT_ENABLED": "false"
}
}
}
}
Production Configuration
Optimized for production with conservative settings:
{
"mcpServers": {
"activitypub": {
"command": "npx",
"args": ["-y", "activitypub-mcp"],
"env": {
"LOG_LEVEL": "warning",
"REQUEST_TIMEOUT": "30000",
"CACHE_TTL": "900000",
"RATE_LIMIT_ENABLED": "true",
"RATE_LIMIT_MAX": "50",
"USER_AGENT": "MyApp-ActivityPub/1.0"
}
}
}
}
High-Performance Configuration
Optimized for high-throughput scenarios:
{
"mcpServers": {
"activitypub": {
"command": "npx",
"args": ["-y", "activitypub-mcp"],
"env": {
"LOG_LEVEL": "error",
"REQUEST_TIMEOUT": "15000",
"CACHE_TTL": "1800000",
"RATE_LIMIT_ENABLED": "true",
"RATE_LIMIT_MAX": "200",
"RATE_LIMIT_WINDOW": "600000"
}
}
}
}
Advanced Configuration
Development Mode
For development and debugging:
export LOG_LEVEL=debug
export REQUEST_TIMEOUT=120000
npm run dev
Production Optimization
Recommended settings for production use:
export LOG_LEVEL=warning
export CACHE_TTL=900000
export RATE_LIMIT_MAX=200
Configuration Validation
Test Your Configuration
Use these commands to validate your configuration:
# Using MCP Inspector
npx @modelcontextprotocol/inspector
# Connect to: npx activitypub-mcp
Test Connectivity
Try discovering an actor to verify outbound connectivity:
# In Claude Desktop or MCP Inspector
discover-actor @mastodon@mastodon.social
Monitor Logs
Check logs for configuration issues:
# Enable debug logging temporarily
"LOG_LEVEL": "debug"
Common Configuration Issues
- Invalid JSON: Check for syntax errors in client config files
- Missing quotes: Environment variable values should be strings
- Wrong paths: Verify command paths and file locations
- Permission issues: Ensure the server has necessary permissions
Next Steps
- Claude Desktop Integration — Apply your configuration to Claude Desktop integration.
- Basic Usage Guide — Start using the server with your custom configuration.
- Troubleshooting — Resolve configuration and performance issues.