Portainer MCP Docker
Dockerized Portainer MCP Server (stdio/streamable HTTP) for easy deployment alongside Portainer
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-mcpbinary - 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-token
Networking: 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-token
MCP 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:9443with your Portainer's actualhostname:portif 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:
-
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. -
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 32
Use the output as your MCP_API_TOKEN in the .env file and configure the same value in your MCP client's Authorization: Bearer <token> 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:http
Docker 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-token
MCP 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_TOKENyou 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 <host:port> | Portainer server address, without protocol prefix (required) |
-token <token> | Portainer API access token (required) |
-tools <path> | 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<upstream>-<build>:
v0.7.0-1- First build of upstream v0.7.0 (stdio)v0.7.0-1-http- Same version, HTTP variantv0.7.0-2- Rebuild (e.g., base image security update)latest- Most recent stdio buildhttp- 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.
関連サーバー
Alpaca
Interact with the Alpaca trading API for stock trading, account management, and market data using LLMs.
Netbird
List and analyze Netbird network peers, groups, policies, and more.
Alpaca
Interact with the Alpaca trading API for stock trading, market data, and account management.
Jimeng MCP Server
An MCP server that integrates with the Jimeng AI image generation service.
Snowflake Cortex AI
A server for Snowflake providing tools for its Cortex AI features, including Search, Analyst, and Complete.
SolarWinds Logs
Access and visualize logs from SolarWinds Observability.
Certus
Provides real-time medical and medication information using the openFDA API.
Alibaba Cloud OPS
A server for managing Alibaba Cloud services, requiring an Access Key ID and Secret for authentication.
ArgoCD
Expose the entire ArgoCD API to LLMs via MCP using just 2 auto-generated tools powered by the OpenAPI spec.
IBM Storage Insights MCP Server
An open-source MCP server providing real-time observability for IBM Storage Insights assets.