-
Notifications
You must be signed in to change notification settings - Fork 0
Releases: ginkida/portainer-mcp
v0.5.1
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) andportainer_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_listand an invalid-id error-envelope check. - Suite: 138 -> 144 tests; ruff + mypy --strict clean.
Full Changelog: v0.5.0...v0.5.1
Assets 2
v0.5.0 — Reliability, redaction and tool-surface hardening
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
200bodies (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_errorscap data before serialization and report a structured"truncated"flag laravel_tinkernow finds backend containers across Swarm, plain-Compose and Compose-v1 naming — without misfiring on sibling services likebackend_workercontainer_statsno longer reports 0% CPU when the daemon sendsonline_cpus: 0- Secret redaction covers suffixed keys (
AWS_SECRET_ACCESS_KEY=...), quoted values with spaces,--passwordflags, 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_TTLenv var — proactive JWT refresh interval- Server-side filters on list tools:
name_filter(containers/volumes/networks),reference_filter(images) stack_updatederives the endpoint from the stack itself whenendpoint_idis 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_logsreturns 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.
Assets 2
v0.4.0 — Security & stability hardening
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_errorsreturns partial results instead of aborting the whole scan when one container fails (addscontainers_failed).portainer_container_logs_grepruns 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/authand the CSRFGET /api/statussucceed — 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_URLvalidated at startup (root URL only; warns on remote cleartext http); config values validated; integer path ids validated.ensure_ascii=Falseon 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). Shipspy.typed. ruff + mypy strict clean.
Minor behavior notes
portainer_stack_logs_errors:containers_scannednow counts successful containers; newcontainers_failedfield.portainer_status: on failure returns a sanitized error (still{"connected": false}).
Assets 2
v0.3.0
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_pullnow 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 anderrorDetailevents are surfaced as a tool error.registry_authparameter onportainer_image_pull— optional base64-encoded JSON{"username":..,"password":..,"serveraddress":..}forwarded asX-Registry-Auth. Required for private registries. Newencode_registry_auth(user, pass, server)helper exported fromtools.images.
Behavior changes (worth noting on upgrade)
portainer_image_pullmay 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_inspectwhitelists 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_authis nowasyncio.Lock-guarded with double-check;_refresh_authskips when another task already refreshed (auth-version counter). Eliminates the duplicate-auth and CSRF-token race underasyncio.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 portablegrep -E "production\.(ERROR|CRITICAL|EMERGENCY)"(escaped dot, no longer matchesproductionXERROR)._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: narrowsexcept Exceptiontohttpx.HTTPStatusErrorand logs the status; unexpected errors propagate to the caller.- Stack-name regex in
containers.pysynced withstacks.py(no dots — Docker Swarm doesn't allow them anyway). _validate_image_refaccepts@sha256:.../@sha512:...digest suffixes.errors.pytolerates non-dict JSON bodies (lists, scalars) and always returns a stringdetailsfield.
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.
Assets 2
v0.2.1 — Security hardening
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_errorswith explicitint()cast - PyPI environment restricted to
mainbranch only (OIDC trusted publishing)
Assets 2
v0.2.0 — Log Analysis & Laravel Debugging Tools
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)
Assets 2
v0.1.0
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