portainer-mcp-docker
Dockerized Portainer MCP Server for easy deployment alongside Portainer
Documentation
portainer-mcp-docker
Dockerized version of the Portainer MCP Server for easy deployment.
Instead of manually downloading and managing binaries, this project provides minimal Alpine-based Docker images that can be deployed alongside Portainer using Docker Compose.
Features
- Minimal Alpine Linux image with the official `portainer-mcp` binary
- Two variants: stdio (local) and HTTP (remote/web)
- Multi-architecture support (linux/amd64, linux/arm64)
- Automatic updates via GitHub Actions when new upstream releases are published
- Base image updates via Dependabot with auto-merge (security patches, Alpine updates)
- Versioned tags matching the upstream release (e.g., `v0.7.0-1`)
Image Variants
| Image Tag | Transport | Use Case |
|---|---|---|
| `latest` / `v0.7.0-1` | stdio | Local MCP clients (Claude Desktop, Claude Code CLI) |
| `http` / `v0.7.0-1-http` | Streamable HTTP | Remote access (Claude Web, shared servers) |
stdio (default)
The standard image. MCP clients launch the container and communicate over stdin/stdout. Best for local setups where the MCP client runs on the same machine.
HTTP
Wraps the MCP server with mcp-proxy to expose it over Streamable HTTP. Supports bearer token authentication so the endpoint is not publicly accessible. Best for remote access, e.g., connecting from Claude Web to a Portainer instance on your server.
Installation
Prerequisites
- A running Portainer instance
- A Portainer API access token (generated from the Portainer UI under *My Account > Access Tokens*)
- Docker and Docker Compose
stdio Variant (Local)
Quick Start
docker pull ghcr.io/serraniel/portainer-mcp-docker:latest
docker run -i --rm ghcr.io/serraniel/portainer-mcp-docker:latest \
-server your-portainer:9443 \
-token your-api-tokenNetworking: Portainer on the Same Host
When Portainer runs on the same machine as the MCP container, `localhost` inside the container refers to the container itself, not the host. Use `host.docker.internal` instead:
docker run -i --rm \
--add-host=host.docker.internal:host-gateway \
ghcr.io/serraniel/portainer-mcp-docker:latest \
-server host.docker.internal:9443 \
-token your-api-tokenMCP Client Configuration
Claude Desktop
Add to your `claude_desktop_config.json`:
{
"mcpServers": {
"portainer": {
"command": "docker",
"args": [
"run", "-i", "--rm",
"--add-host=host.docker.internal:host-gateway",
"ghcr.io/serraniel/portainer-mcp-docker:latest",
"-server", "host.docker.internal:9443",
"-token", "your-api-token"
]
}
}
}> Replace `host.docker.internal:9443` with your Portainer's actual `hostname:port` if it runs on a different machine.
Claude Code
Add to your Claude Code MCP settings:
{
"mcpServers": {
"portainer": {
"command": "docker",
"args": [
"run", "-i", "--rm",
"--add-host=host.docker.internal:host-gateway",
"ghcr.io/serraniel/portainer-mcp-docker:latest",
"-server", "host.docker.internal:9443",
"-token", "your-api-token"
]
}
}
}HTTP Variant (Remote)
Generating Tokens
The HTTP variant requires two tokens:
1. Portainer API token (`PORTAINER_TOKEN`) — authenticates the MCP server against your Portainer instance. Generate one in the Portainer UI under *My Account > Access Tokens > Add access token*.
2. MCP bearer token (`API_ACCESS_TOKEN`) — protects the HTTP endpoint so only authorized MCP clients can connect. This is a secret you create yourself. Generate a secure random token:
openssl rand -hex 32Use the output as your `MCP_API_TOKEN` in the `.env` file and configure the same value in your MCP client's `Authorization: Bearer ` header.
Quick Start
docker pull ghcr.io/serraniel/portainer-mcp-docker:http
docker run -d --rm \
-p 8080:8080 \
-e PORTAINER_SERVER=your-portainer:9443 \
-e PORTAINER_TOKEN=your-portainer-api-token \
-e API_ACCESS_TOKEN=your-mcp-bearer-token \
ghcr.io/serraniel/portainer-mcp-docker:httpDocker Compose
services:
portainer:
image: portainer/portainer-ce:latest
restart: always
ports:
- "9443:9443"
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- portainer_data:/data
portainer-mcp:
image: ghcr.io/serraniel/portainer-mcp-docker:http
restart: always
ports:
- "8080:8080"
environment:
- PORTAINER_SERVER=portainer:9443
- PORTAINER_TOKEN=${PORTAINER_TOKEN}
- API_ACCESS_TOKEN=${MCP_API_TOKEN}
# Optional:
# - PORTAINER_READ_ONLY=true
# - PORTAINER_DISABLE_VERSION_CHECK=true
# - MCP_PORT=8080
# - MCP_HOST=0.0.0.0
volumes:
portainer_data:Create a `.env` file:
PORTAINER_TOKEN=your-portainer-api-token
MCP_API_TOKEN=your-mcp-bearer-tokenMCP Client Configuration (Remote)
Claude Web / Claude Desktop (Remote URL)
Configure your MCP client to connect to the HTTP endpoint:
- URL: `http://your-server:8080/sse`
- Authorization: Bearer token (the `MCP_API_TOKEN` you configured)
Claude Code (Remote)
{
"mcpServers": {
"portainer": {
"type": "url",
"url": "http://your-server:8080/sse",
"headers": {
"Authorization": "Bearer your-mcp-bearer-token"
}
}
}
}Environment Variables (HTTP)
| Variable | Required | Description |
|---|---|---|
| `PORTAINER_SERVER` | Yes | Portainer server address as `host:port` (no protocol prefix, HTTPS is used automatically) |
| `PORTAINER_TOKEN` | Yes | Portainer API access token |
| `API_ACCESS_TOKEN` | Recommended | Bearer token for MCP endpoint authentication |
| `PORTAINER_READ_ONLY` | No | Set to `true` for read-only mode |
| `PORTAINER_DISABLE_VERSION_CHECK` | No | Set to `true` to skip version validation |
| `MCP_PORT` | No | HTTP listen port (default: `8080`) |
| `MCP_HOST` | No | HTTP listen address (default: `0.0.0.0`) |
Command Line Options (stdio)
All flags from the upstream binary are supported:
| Flag | Description |
|---|---|
| `-server ` | Portainer server address, without protocol prefix (required) |
| `-token ` | Portainer API access token (required) |
| `-tools ` | Path to custom tools YAML file |
| `-read-only` | Restrict to read-only operations (GET requests only) |
| `-disable-version-check` | Skip Portainer server version validation |
Versioning
Image tags follow the format `v-`:
- `v0.7.0-1` - First build of upstream v0.7.0 (stdio)
- `v0.7.0-1-http` - Same version, HTTP variant
- `v0.7.0-2` - Rebuild (e.g., base image security update)
- `latest` - Most recent stdio build
- `http` - Most recent HTTP build
How Automatic Updates Work
| Trigger | What happens |
|---|---|
| New upstream release | Daily check creates a new tag (e.g., `v0.8.0-1`) and builds both images |
| Dependabot PR merged | Auto-merged after build test, increments build number and rebuilds |
| Manual dispatch | Workflow can be triggered manually with a specific upstream version |
Upstream Documentation
For full documentation on the Portainer MCP server capabilities, tools, and Portainer version compatibility, see the upstream README.
License
This project is licensed under the European Union Public License v1.2 (EUPL-1.2).
The upstream portainer-mcp binary is licensed under the Zlib License.
Frequently asked questions
What is portainer-mcp-docker?
portainer-mcp-docker is Dockerized Portainer MCP Server for easy deployment alongside Portainer
How do I install portainer-mcp-docker?
Open the GitHub repository and follow its README. Most MCP servers are added to your client's MCP config, then called by your agent.
Is portainer-mcp-docker open source?
Yes — it is hosted on GitHub at https://github.com/Serraniel/portainer-mcp-docker.
Related MCP tools
Model Context Protocol Servers
Pre-indexed code knowledge graph, auto syncs on code changes, for Claude Code, Codex, Gemini, Cursor, OpenCode, AntiGravity, Kiro, CoPilot, and Hermes Agent — fewer tokens, fewer tool calls, 100% local
an open source, extensible AI agent that goes beyond code suggestions - install, execute, edit, and test with any LLM
The easy-to-use open source Business Intelligence and Embedded Analytics tool that lets everyone work with data :bar_chart:
The Open-Source Multimodal AI Agent Stack: Connecting Cutting-Edge AI Models and Agent Infra
Cognee is the open-source AI memory platform for agents. Give your AI agents persistent long-term memory across sessions with a self-hosted knowledge graph engine.
Run your own MCP server? See who uses it and what to fix.
Measure it with TrackMCP