A Model Context Protocol (MCP) server for Alpaca's Trading API
7.5K
Unofficial multi-arch Docker image of Alpaca's open-source MCP server (alpacahq/alpaca-mcp-server), kept in sync with upstream. Build source: mannbadal/alpaca-mcp-server.
Get your free API keys at app.alpaca.markets (paper trading available).
Docker Compose:
services:
alpaca-mcp:
image: mannbadal/alpaca-mcp:latest
container_name: alpaca-mcp
command:
[
"alpaca-mcp-server",
"--transport",
"streamable-http",
"--host",
"0.0.0.0",
"--port",
"8000",
]
environment:
- ALPACA_API_KEY=${ALPACA_API_KEY}
- ALPACA_SECRET_KEY=${ALPACA_SECRET_KEY}
- ALPACA_PAPER_TRADE=True # Set to False for live trading
ports:
- "8000:8000"
restart: unless-stopped
Then connect your MCP client to http://localhost:8000/mcp.
Notes for v2.3+
- The image now starts in stdio mode by default. Keep the
commandblock above to run it as an HTTP server.- The V1
servesubcommand is no longer needed. It is still accepted, but you can remove it.- HTTP requests are only accepted for
localhost/127.0.0.1unless you allow other hostnames (see Remote access below).
| Variable | Required | Default | Description |
|---|---|---|---|
ALPACA_API_KEY | Yes | — | Alpaca API key |
ALPACA_SECRET_KEY | Yes | — | Alpaca secret key |
ALPACA_PAPER_TRADE | No | True | True for paper trading, False for live |
ALPACA_TOOLSETS | No | all | Comma-separated toolsets to enable, e.g. account,trading,stock-data |
FASTMCP_HTTP_ALLOWED_HOSTS | No | localhost only | Extra hostnames allowed in the HTTP Host header. Must be a JSON list |
Available toolsets: account, trading, watchlists, assets, stock-data, crypto-data, options-data, corporate-actions, news, fixed-income-data, locates.
The server rejects requests (HTTP 421 Misdirected Request) whose Host header isn't localhost or 127.0.0.1. This protects against DNS-rebinding attacks. If clients reach the container any other way, list those hostnames:
| Client connects via | Needs FASTMCP_HTTP_ALLOWED_HOSTS? |
|---|---|
http://localhost:8000/mcp on the Docker host | No |
LAN IP, Tailscale, or DNS name (e.g. 192.168.1.50:8000) | Yes |
Another container by service name (e.g. alpaca-mcp:8000) | Yes |
| Reverse proxy forwarding a public hostname | Yes |
environment:
- ALPACA_API_KEY=${ALPACA_API_KEY}
- ALPACA_SECRET_KEY=${ALPACA_SECRET_KEY}
- ALPACA_PAPER_TRADE=True
- 'FASTMCP_HTTP_ALLOWED_HOSTS=["192.168.1.50","myserver.local","alpaca-mcp"]'
a,b) or a bare * makes the server exit on startup."alpaca-mcp-*" are supported.⚠️ Security: the server has no authentication, and anyone who can reach the port can trade with your API keys. Don't expose it to the public internet. Keep it on localhost or a private network/VPN, or put an authenticating proxy in front.
| Tag | Platforms | Description |
|---|---|---|
latest | linux/amd64, linux/arm64 | Synced daily with upstream main and rebuilt daily |
For any MCP client that supports remote/HTTP connections, the URL is:
http://localhost:8000/mcp
Claude Code:
claude mcp add --transport http alpaca http://localhost:8000/mcp
Claude Desktop (~/Library/Application Support/Claude/claude_desktop_config.json on macOS, %APPDATA%\Claude\claude_desktop_config.json on Windows). The config file only launches local commands, so bridge to HTTP with mcp-remote (requires Node.js):
{
"mcpServers": {
"alpaca": {
"command": "npx",
"args": ["-y", "mcp-remote", "http://localhost:8000/mcp"]
}
}
}
Cursor (~/.cursor/mcp.json):
{
"mcpServers": {
"alpaca": {
"url": "http://localhost:8000/mcp"
}
}
}
VS Code (.vscode/mcp.json):
{
"servers": {
"alpaca": {
"type": "http",
"url": "http://localhost:8000/mcp"
}
}
}
Credentials go in the Docker Compose environment block, not in the client config. The server holds the Alpaca keys, and clients connect without authentication.
Content type
Image
Digest
sha256:81aa5070f…
Size
78.1 MB
Last updated
about 23 hours ago
docker pull mannbadal/alpaca-mcp