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

VariableDefaultDescriptionExample
LOG_LEVELinfoLogging verbosity leveldebug, info, warning, error, fatal
USER_AGENTActivityPub-MCP-Client/<version>Custom User-Agent for HTTP requestsMyApp-ActivityPub/2.0
REQUEST_TIMEOUT10000HTTP request timeout in milliseconds (10 seconds)45000 (45 seconds)
MAX_RETRIES3Maximum retry attempts5

Cache Settings

VariableDefaultDescriptionExample
CACHE_TTL300000Cache time-to-live in milliseconds (5 minutes)600000 (10 minutes)
CACHE_MAX_SIZE1000Max items in the LRU caches2000

Rate Limiting

VariableDefaultDescriptionExample
RATE_LIMIT_ENABLEDtrueEnable/disable rate limitingfalse to disable
RATE_LIMIT_MAX100Maximum requests per window200
RATE_LIMIT_WINDOW900000Rate limit window in milliseconds1800000 (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 — /health is liveness, not readiness. v3 deliberately reduced /health to a trivial in-process liveness check; it no longer performs an outbound connectivity probe (the HEALTH_CHECK_* knobs were removed), so a 200 OK confirms 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.

VariableDefaultDescription
MCP_TRANSPORT_MODEstdioTransport mode: stdio (default) or http
MCP_HTTP_PORT3000Port for the HTTP transport
MCP_HTTP_HOST127.0.0.1Bind host for the HTTP transport
MCP_HTTP_SECRETnone — requiredBearer-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_HOSTSemptyComma-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_ORIGINSemptyComma-separated Origin allowlist for DNS-rebinding protection. Empty → derived from the CORS origins. Not the same as the CORS settings below.
MCP_HTTP_CORS_ENABLEDfalseEnable CORS for the HTTP transport.
MCP_HTTP_CORS_ORIGINSemptyComma-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.

VariableDefaultDescription
MCP_THREAD_MAX_DEPTH5Maximum recursion depth when walking inReplyTo chains.
MCP_THREAD_MAX_REPLIES50Maximum total replies fetched per thread.
MCP_THREAD_CROSS_ORIGIN_FETCHfalseIf 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.

VariableDefaultDescription
ACTIVITYPUB_ENABLE_WRITESfalseSet 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.

VariableDefaultDescription
INSTANCE_BLOCKING_ENABLEDtrueEnforce the operator instance blocklist on every fetch (and redirect hop).
BLOCKED_INSTANCESemptyComma-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_SIZE10485760Max bytes read from any remote response, to prevent memory exhaustion (10 MB).
MAX_UPLOAD_SIZE104857600Max 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_ENABLEDtrueRecord tool invocations (writes/uploads, SSRF blocks, rate-limit denials) in the in-memory audit trail.
AUDIT_LOG_MAX_ENTRIES10000Max audit entries kept in memory (oldest evicted). Floored at 1.

Logging Configuration

Log Levels

LevelDescription
debugDetailed debugging information, HTTP requests/responses, internal state changes
infoGeneral operational messages, tool executions, resource access (default)
warningWarning conditions, rate limiting, recoverable errors (recommended for production)
errorError conditions, failed requests, unrecoverable issues
fatalCritical 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