Skip to main content
Glama
Cuti27

mcp-portainer-lite

by Cuti27

mcp-portainer-lite

npm version GHCR CI License

Lightweight MCP server for Portainer CE, focused on Docker Swarm environments. Unofficial project.

Why this project?

The official Portainer MCP server is comprehensive but heavy. mcp-portainer-lite is:

  • Lightweight: no unnecessary dependencies, built with Node.js HTTP, Zod, and Pino.

  • Swarm-focused: tools designed for Swarm environments.

  • Write-protected: mutation operations are disabled by default.

  • Dual transport: works over stdio (npx) and HTTP (Docker).

Comparison with portainer/portainer-mcp

Aspect

portainer/portainer-mcp

mcp-portainer-lite

Size

~25 MB installed

~8 MB installed

Focus

Docker + Swarm

Swarm only

Mutations

Always enabled

ALLOW_MUTATIONS=true required

Transports

stdio

stdio + HTTP

Auth

API key or credentials

API key + optional bearer token

Related MCP server: dynamic-mcp

Requirements

  • Node.js >= 20 (for npx usage) or Docker (for container)

  • Portainer CE 2.39.x or higher

  • Portainer API key with read permissions (and write if using mutations)

Installation

version: '3.8'
services:
  portainer-mcp:
    image: ghcr.io/cuti27/mcp-portainer-lite:latest
    container_name: portainer-mcp
    ports:
      - "3000:3000"
    environment:
      - PORTAINER_URL=http://portainer:9000
      - PORTAINER_API_KEY=ptr_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
      - PORTAINER_ENDPOINT_ID=1
      - ALLOW_MUTATIONS=false
      - MCP_AUTH_TOKEN=your-secure-token-here
      - PORT=3000
      - HOST=0.0.0.0
      # Only for plain HTTP Portainer. Use HTTPS in production.
      - PORTAINER_ALLOW_HTTP=true
    networks:
      - portainer-net

networks:
  portainer-net:
    external: true

⚠️ Security warning: HOST=0.0.0.0 exposes the MCP server to the network. Only use it inside Docker with MCP_AUTH_TOKEN set, and put the container behind a TLS-terminating reverse proxy. Never expose the HTTP transport to the internet without authentication and TLS.

npx

PORTAINER_URL=http://localhost:9000 \
PORTAINER_API_KEY=ptr_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx \
PORTAINER_ENDPOINT_ID=1 \
PORTAINER_ALLOW_HTTP=true \
npx -y @cuti27/mcp-portainer-lite

Claude Desktop

Add to your claude_desktop_config.json:

{
  "mcpServers": {
    "portainer": {
      "command": "npx",
      "args": ["-y", "@cuti27/mcp-portainer-lite"],
      "env": {
        "PORTAINER_URL": "http://localhost:9000",
        "PORTAINER_API_KEY": "ptr_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
        "PORTAINER_ENDPOINT_ID": "1",
        "PORTAINER_ALLOW_HTTP": "true"
      }
    }
  }
}

Environment variables

Variable

Required

Default

Description

PORTAINER_URL

Yes

Portainer base URL (e.g. http://portainer:9000)

PORTAINER_API_KEY

Yes

Portainer API key

PORTAINER_ENDPOINT_ID

No

first endpoint

Default endpoint ID

ALLOW_MUTATIONS

No

false

Enable write tools

MCP_TRANSPORT

No

stdio

Transport: stdio or http

MCP_AUTH_TOKEN

Only for HTTP

Bearer token to authenticate MCP HTTP requests

PORT

No

3000

HTTP port (http transport only)

HOST

No

127.0.0.1

HTTP bind address (http transport only)

PORTAINER_ALLOW_HTTP

No

false

Allow plain HTTP for PORTAINER_URL (not recommended for production)

TLS_CERT_PATH

No

Path to TLS certificate (HTTPS transport directly)

TLS_KEY_PATH

No

Path to TLS private key (HTTPS transport directly)

TRUSTED_PROXIES

No

Comma-separated trusted proxy IPs/CIDRs for X-Forwarded-For parsing

LOG_LEVEL

No

info

Log level: trace/debug/info/warn/error/fatal

Available tools

Phase 1 — Read (always available)

Tool

Description

list_endpoints

List Portainer-managed environments

list_stacks

List stacks for an endpoint

get_stack

Get stack details

get_service

Get service details

list_services

List Swarm services for an endpoint

get_service_logs

Get last N log lines from a service (best-effort sensitive data redaction)

get_endpoint_summary

Get endpoint summary

Phase 2 — Mutation (only with ALLOW_MUTATIONS=true)

Tool

Description

restart_service

Restart a service

start_service

Scale a service to 1 replica

stop_service

Scale a service to 0 replicas

restart_stack

Restart all services in a stack

Security

  • Authentication: When using HTTP transport, MCP_AUTH_TOKEN is required. All requests must include Authorization: Bearer <token>. Requests without a valid token receive 401 Unauthorized.

  • API key redaction: The Portainer API key and Authorization header are automatically redacted from logs by Pino.

  • Write protection: Mutation operations are disabled by default. Enable them only with ALLOW_MUTATIONS=true.

  • Input validation: All service IDs, endpoint IDs, and stack IDs are validated against alphanumeric patterns before being used in API calls, preventing path traversal.

  • Rate limiting: The HTTP server enforces 60 requests per minute per IP. Excess requests receive 429 Too Many Requests.

  • Body size limit: HTTP POST bodies are limited to 1 MB. Larger payloads receive 413 Payload Too Large.

  • Safe error messages: Internal error details are logged server-side but never returned to the client.

  • Host binding: Defaults to 127.0.0.1 (localhost only). If set to 0.0.0.0, a warning is emitted.

  • HTTPS recommended: Use https:// for PORTAINER_URL in production. A startup warning is shown if using plain HTTP.

  • Principle of least privilege: Use a Portainer API key with minimum required permissions (read-only if mutations are not needed).

Compatibility

Tested with Portainer CE 2.39.x. Compatible with newer versions barring breaking API changes.

Local test environment

The repository includes helper scripts to spin up a disposable Docker Swarm sandbox with Portainer CE and dummy services for safe end-to-end testing.

# Start the test environment (Portainer CE on http://localhost:9000)
./scripts/test-swarm-up.sh

# The script prints credentials and writes a ready-to-use .env.test file.
source .env.test
npm run start:stdio

# Destroy everything when done
./scripts/test-swarm-down.sh

These scripts only touch resources named portainer-test or test-apps; your existing Docker containers, networks, and volumes are left untouched.

Development

# Clone
git clone https://github.com/cuti27/mcp-portainer-lite.git
cd mcp-portainer-lite

# Install
npm install

# Watch mode
npm run dev

# Build
npm run build

# Run
npm start

Tests

# Unit + integration tests
npm test

# With coverage
npm run test:coverage

License

MIT. See LICENSE.

A
license - permissive license
-
quality - not tested
C
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/Cuti27/mcp-portainer-lite'

If you have feedback or need assistance with the MCP directory API, please join our Discord server