Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Releases: ginkida/portainer-mcp

v0.5.1

11 Jun 15:06
@ginkida ginkida

Choose a tag to compare

What's Changed

Test-only release — no functional changes to the 41-tool surface.

  • Added leak-canary tests for the sensitive-field whitelists: portainer_endpoint_inspect (TLS certs, Azure credentials) and portainer_user_inspect (password hashes, TFA secrets) are now regression-guarded against leaking credentials into tool output.
  • Added summary-shape tests for portainer_endpoints_list / portainer_users_list and an invalid-id error-envelope check.
  • Suite: 138 -> 144 tests; ruff + mypy --strict clean.

Full Changelog: v0.5.0...v0.5.1

Assets 2
Loading

v0.5.0 — Reliability, redaction and tool-surface hardening

04 Jun 08:59
@ginkida ginkida

Choose a tag to compare

Deep multi-agent review pass over the whole codebase with adversarial verification; all confirmed findings fixed.

Fixed

  • Client: a 401 followed by a 403-CSRF could re-auth twice and send a mutating request three times — now strictly one retry per request; empty 200 bodies (e.g. network connect/disconnect) no longer surface as JSON decode errors; response-size guard now also checks buffered chunked bodies
  • Docker stream parser: truncated first frame no longer leaks 8 binary header bytes into output; frame headers are validated for plausibility before being trusted
  • Truncated output is now always valid JSON: logs_grep / stack_logs_errors / laravel_errors cap data before serialization and report a structured "truncated" flag
  • laravel_tinker now finds backend containers across Swarm, plain-Compose and Compose-v1 naming — without misfiring on sibling services like backend_worker
  • container_stats no longer reports 0% CPU when the daemon sends online_cpus: 0
  • Secret redaction covers suffixed keys (AWS_SECRET_ACCESS_KEY=...), quoted values with spaces, --password flags, bare bearer tokens and connection-string credentials (including @ inside the password); guaranteed linear-time with a bounded input cap; validation and transport error messages are redacted too

Added

  • PORTAINER_JWT_TTL env var — proactive JWT refresh interval
  • Server-side filters on list tools: name_filter (containers/volumes/networks), reference_filter (images)
  • stack_update derives the endpoint from the stack itself when endpoint_id is omitted; compose content validation on deploy/update
  • AUDIT log lines for container start/stop/restart and laravel_errors; force= recorded for forced removals/disconnects; full-command redact-then-truncate previews
  • container_logs returns a structured JSON envelope (logs, truncated, total_chars)
  • Broader transport-error handling (httpx.TransportError) — read/protocol errors now report as connection errors instead of internal errors

Tests

59 → 138: full retry matrix, JWT TTL, CSRF capture, every error-handler branch, stream-parser edge cases, exec/tinker flows, force-flag propagation, filter forwarding, ReDoS timing guards, lifespan shutdown.

Tool count unchanged: 41.

Loading

v0.4.0 — Security & stability hardening

01 Jun 12:46
@ginkida ginkida

Choose a tag to compare

Backward-compatible release. No tool API changes (41 tools). Adds optional configuration and hardens the server against timeouts, ReDoS, fan-out overload, secret leakage, and auth-state wedging — surfaced by a multi-dimension security/stability audit.

Stability

  • Configurable timeouts PORTAINER_TIMEOUT (30s) / PORTAINER_LONG_TIMEOUT (300s); image pull, exec, and large log fetches no longer fail at the old fixed 30s.
  • Bounded multi-container scans (per-call semaphore + target cap) and explicit, configurable httpx pool limits.
  • portainer_stack_logs_errors returns partial results instead of aborting the whole scan when one container fails (adds containers_failed).
  • portainer_container_logs_grep runs the user regex in a worker thread under a deadline + length cap — a ReDoS pattern can no longer freeze the event loop.
  • Guaranteed httpx client cleanup; response-size guard; bounded image-pull / compose-inspect buffers.

Auth / CSRF

  • Auth state is committed only after both POST /api/auth and the CSRF GET /api/status succeed — a half-set JWT can no longer wedge the client.
  • 403-CSRF retry re-harvests the token; CSRF writes serialized by a dedicated lock; unsafe-method retries log a duplicate-risk warning.

Security

  • Secrets redacted from exec/tinker audit logs and surfaced error details.
  • PORTAINER_URL validated at startup (root URL only; warns on remote cleartext http); config values validated; integer path ids validated.
  • ensure_ascii=False on all JSON output (readable non-ASCII / Russian logs).

New environment variables (all optional)

PORTAINER_TIMEOUT, PORTAINER_LONG_TIMEOUT, PORTAINER_HTTP_MAX_CONNECTIONS, PORTAINER_HTTP_MAX_KEEPALIVE.

Tooling

  • New tests/ suite (59 tests; CSRF/auth state machine, config, helpers, stream parser, tool integration). Ships py.typed. ruff + mypy strict clean.

Minor behavior notes

  • portainer_stack_logs_errors: containers_scanned now counts successful containers; new containers_failed field.
  • portainer_status: on failure returns a sanitized error (still {"connected": false}).
Loading

v0.3.0

17 Apr 08:22
@ginkida ginkida

Choose a tag to compare

Bug-fix and hardening release. New optional registry_auth parameter on portainer_image_pull for private registries. README brought back in sync with the 41-tool surface.

Highlights

  • portainer_image_pull now reports failures. Docker streams pull progress as line-delimited JSON and returns HTTP 200 even when the pull fails — the previous version always reported success. The stream is now parsed and errorDetail events are surfaced as a tool error.
  • registry_auth parameter on portainer_image_pull — optional base64-encoded JSON {"username":..,"password":..,"serveraddress":..} forwarded as X-Registry-Auth. Required for private registries. New encode_registry_auth(user, pass, server) helper exported from tools.images.

Behavior changes (worth noting on upgrade)

  • portainer_image_pull may now return a {"error": "Image pull failed", ...} envelope where 0.2.x returned a success object regardless. Callers that assumed unconditional success should handle the error path.
  • portainer_user_inspect whitelists safe fields (Id, Username, Role, EndpointAuthorizations, PortainerAuthorizations, UserTheme, ThemeSettings, UseCache, TokenIssueAt). Password hash, TFA material and tokens are no longer forwarded.

Bug fixes

  • Concurrency: _ensure_auth is now asyncio.Lock-guarded with double-check; _refresh_auth skips when another task already refreshed (auth-version counter). Eliminates the duplicate-auth and CSRF-token race under asyncio.gather.
  • Header merge: caller-supplied request headers are preserved instead of silently dropped; auth/CSRF headers always win on conflict.
  • portainer_container_logs_grep: invalid regex now returns a clean validation error instead of a generic "internal error".
  • portainer_laravel_errors: uses portable grep -E "production\.(ERROR|CRITICAL|EMERGENCY)" (escaped dot, no longer matches productionXERROR).
  • _parse_docker_stream: truncated frames are decoded best-effort with a debug log; non-multiplexed responses fall back to plain decode (no longer drops the first 8 bytes).
  • portainer_stack_inspect: narrows except Exception to httpx.HTTPStatusError and logs the status; unexpected errors propagate to the caller.
  • Stack-name regex in containers.py synced with stacks.py (no dots — Docker Swarm doesn't allow them anyway).
  • _validate_image_ref accepts @sha256:... / @sha512:... digest suffixes.
  • errors.py tolerates non-dict JSON bodies (lists, scalars) and always returns a string details field.

Docs

  • README now lists all 41 tools across Authentication / Endpoints / Stacks / Containers (13) / Images / Volumes / Networks / System / Users.
  • Security section expanded with CSRF protocol, lock-guarded reauth and registry-auth handling.
Loading

v0.2.1 — Security hardening

10 Apr 10:08
@ginkida ginkida

Choose a tag to compare

Security

  • Pin all GitHub Actions to commit SHAs (prevents supply chain attacks via tag mutation)
  • Add upper bounds to dependencies (mcp<2.0.0, httpx<1.0.0)
  • Sanitize shell-interpolated parameter in laravel_errors with explicit int() cast
  • PyPI environment restricted to main branch only (OIDC trusted publishing)
Loading

v0.2.0 — Log Analysis & Laravel Debugging Tools

10 Apr 09:23
@ginkida ginkida

Choose a tag to compare

New Tools (4)

portainer_container_logs_grep

Search container logs by regex pattern with optional context lines. Useful for finding specific errors, status codes, or keywords without downloading full logs.

portainer_stack_logs_errors

Scan all running containers in a stack for errors in one call. Detects HTTP 4xx/5xx, exceptions, fatal errors, panics, OOM, PHP errors. Fetches logs concurrently via asyncio.

portainer_laravel_errors

Read Laravel application-level errors (storage/logs/laravel.log) from stack containers via exec. Returns production.ERROR / CRITICAL / EMERGENCY entries with exception details.

portainer_laravel_tinker

Execute PHP code via php artisan tinker inside a stack's backend container. Auto-discovers the container, handles shell escaping, and returns output with exit code. Audit-logged.

Total: 41 tools (was 37)

Loading

v0.1.0

02 Apr 08:04
@ginkida ginkida

Choose a tag to compare

Initial release of Portainer MCP Server.

Features:

  • 23 tools for managing Portainer via AI assistants
  • Stack management (deploy, update, start, stop, delete)
  • Container lifecycle (start, stop, restart, remove, logs, exec, stats)
  • Image management (list, inspect, pull, remove)
  • Volume and network management
  • User management
  • JWT auth with proactive refresh + CSRF token handling
  • Input validation, sensitive field filtering, audit logging

Install:

pip install portainer-mcp
Loading

AltStyle によって変換されたページ (->オリジナル) /