Configuration
This guide covers the configuration options for the AT Protocol MCP Server.
Configuration Methods
The server can be configured through:
- Environment Variables - Recommended, especially for MCP client setups
- Command Line Arguments - Quick overrides
.envFile - Convenient for local development- MCP Client Configuration - Client-specific settings (e.g. Claude Desktop)
Transport
By default the server communicates over stdio (the standard setup for MCP clients such as Claude Desktop) and binds no TCP port. With --transport http it instead serves the MCP Streamable HTTP transport at http://<host>:<port>/mcp — see Command Line Arguments below and the Deployment guide.
Environment Variables
The ConfigManager reads the variables defined in ENV_MAPPINGS in src/utils/config.ts (listed below), plus LOG_LEVEL (read by the logger) and NODE_ENV (used to relax validation under test). One additional variable is read directly by a specific subsystem: ATPROTO_MEDIA_DIR (base directory that tool-supplied media file paths must stay within; defaults to the working directory). Other variables — including the legacy OAUTH_CLIENT_ID / OAUTH_CLIENT_SECRET / OAUTH_REDIRECT_URI names and the former ATPROTO_RELAY — are ignored.
Authentication
| Variable | Description | Required | Default |
|---|---|---|---|
ATPROTO_IDENTIFIER | Your AT Protocol handle or DID | No* | - |
ATPROTO_PASSWORD | App password for authentication | No* | - |
ATPROTO_SERVICE | AT Protocol service URL | No | https://bsky.social |
ATPROTO_AUTH_METHOD | Authentication method (app-password or oauth) | No | app-password |
ATPROTO_CLIENT_ID | OAuth client ID (experimental — see Authentication) | No | - |
ATPROTO_CLIENT_SECRET | OAuth client secret (experimental) | No | - |
* Required only for authenticated operations. App passwords are the supported auth path; see Authentication. Without credentials the server runs in unauthenticated mode (only public/enhanced tools such as get_user_profile work; tools like search_posts require authentication, since the AT Protocol search API changed in 2025 to require auth).
Server
| Variable | Description | Default |
|---|---|---|
MCP_SERVER_NAME | Server name advertised over the MCP protocol | atproto-mcp |
MCP_SERVER_PORT | HTTP port for --transport http (the stdio transport ignores it) | 3000 |
MCP_SERVER_HOST | HTTP bind host for --transport http (the stdio transport ignores it) | localhost |
LOG_LEVEL | Logging level (debug, info, warn, error) | info |
Port and host only apply to the HTTP transport
MCP_SERVER_PORT and MCP_SERVER_HOST (and the --port/--host flags, which override them) only take effect with --transport http. Under the default stdio transport the server binds no port and no host — there is no HTTP server and no /health or /metrics endpoint. In HTTP mode the only route served is /mcp, and localhost is pinned to the IPv4 loopback 127.0.0.1.
Command Line Arguments
Override environment variables with command line flags:
atproto-mcp [options]Available Options
These are the only flags the CLI accepts (defined in src/cli.ts):
-t, --transport <mode> Transport: stdio|http (default: stdio)
-p, --port <number> HTTP port for --transport http (default: 3000; stdio ignores it)
-H, --host <string> HTTP bind host for --transport http (default: 127.0.0.1, loopback; stdio ignores it)
-s, --service <url> AT Protocol service URL (default: https://bsky.social)
-a, --auth <method> Authentication method: app-password|oauth (optional)
-l, --log-level <level> Log level: debug|info|warn|error (default: info)
-h, --help Show this help message
-v, --version Show version informationNote that -h is the short flag for --help; the short flag for --host is the capital -H.
Examples
# Start with debug logging
atproto-mcp --log-level debug
# Use a custom AT Protocol service (e.g. a self-hosted PDS)
atproto-mcp --service https://custom-pds.example.com
# Select the authentication method explicitly
atproto-mcp --auth app-password
# Serve the Streamable HTTP transport on loopback port 8080
atproto-mcp --transport http --port 8080HTTP transport binding
--transport http binds the loopback interface (127.0.0.1) by default, so only local clients can connect. Binding any other host (e.g. --host 0.0.0.0) exposes the server to the network — securing that exposure (firewalling, reverse proxy, authentication) is the operator's responsibility.
MCP Client Configuration
Claude Desktop
Add to ~/Library/Application Support/Claude/claude_desktop_config.json:
{
"mcpServers": {
"atproto": {
"command": "atproto-mcp",
"args": ["--log-level", "info"],
"env": {
"ATPROTO_IDENTIFIER": "your-handle.bsky.social",
"ATPROTO_PASSWORD": "your-app-password",
"LOG_LEVEL": "info"
}
}
}
}Other MCP Clients
Generic MCP client configuration (the server uses the stdio transport by default):
{
"servers": [
{
"name": "atproto",
"command": "atproto-mcp",
"transport": "stdio",
"environment": {
"ATPROTO_IDENTIFIER": "your-handle.bsky.social",
"ATPROTO_PASSWORD": "your-app-password"
}
}
]
}Environment File (.env)
For local development, create a .env file:
# Copy example file
cp .env.example .envExample .env file (only the variables the server actually reads):
# Authentication (optional — required for authenticated operations)
ATPROTO_IDENTIFIER=your-handle.bsky.social
ATPROTO_PASSWORD=your-app-password
ATPROTO_SERVICE=https://bsky.social
ATPROTO_AUTH_METHOD=app-password
# Server
MCP_SERVER_NAME=atproto-mcp
LOG_LEVEL=debug
# MCP_SERVER_PORT / MCP_SERVER_HOST set the default binding for
# `--transport http`; the default stdio transport ignores them.
# MCP_SERVER_PORT=3000
# MCP_SERVER_HOST=localhostDocker Configuration
Docker Compose
The repository does not ship a Compose file, but you can define a service of your own — for example:
services:
atproto-mcp:
image: atproto-mcp:latest
environment:
- ATPROTO_IDENTIFIER=${ATPROTO_IDENTIFIER}
- ATPROTO_PASSWORD=${ATPROTO_PASSWORD}
- ATPROTO_SERVICE=https://bsky.social
- LOG_LEVEL=info
restart: unless-stoppedTIP
By default the server speaks stdio, so there is nothing to publish with ports:. The image's Dockerfile deliberately has no EXPOSE line — the container binds no port unless you opt into the HTTP transport. To run the Streamable HTTP transport in a container instead, override the command with node dist/cli.js --transport http --host 0.0.0.0 and publish the port (ports: ['3000:3000']) — and secure that exposure yourself.
Docker Environment File
Create .env for Docker Compose:
ATPROTO_IDENTIFIER=your-handle.bsky.social
ATPROTO_PASSWORD=your-app-password
ATPROTO_SERVICE=https://bsky.social
LOG_LEVEL=infoRate Limiting
The server applies a built-in per-tool rate limit of 100 requests per minute per tool (a 60-second window enforced by the SecurityManager). This is not configurable via environment variables or CLI flags. Bluesky may apply its own platform-level limits independently.
Validation
Validate your setup:
# Show available flags
atproto-mcp --help
# Start with debug logging to confirm configuration is loaded
atproto-mcp --log-level debug
# Verify the environment variables you've set
env | grep ATPROTOThe ConfigManager class (src/utils/config.ts) builds and validates the configuration from defaults, environment variables, and overrides at startup.
Troubleshooting
Configuration Not Loading
# Check environment variables
echo $ATPROTO_IDENTIFIER
# Verify .env file contents
cat .env
# Check file permissions
ls -la .envAuthentication Issues
See Authentication for app-password setup and common auth errors.
Next Steps
- Authentication - Set up authentication
- Deployment - Deploy to production
- Troubleshooting - Common issues
Previous: Installation ← | Next: Authentication →