MCP server for Portainer container management
Server has 10 tools with consistent naming (verb_noun pattern: status, endpoints, containers, logs, start, stop, restart, stacks, stack_info, redeploy). All tools have descriptions (10-200 chars, within baseline 34-392 range). Input schemas are present with type definitions for all parameters. However, descriptions lack LLM-optimized depth, most are 1-2 sentences without dependency hints, prerequisites, or recovery guidance. Parameter descriptions are minimal (e.g., 'Endpoint ID (default: 4)' lacks context on why endpoint 4 is special or how to discover valid endpoints). Output schemas are not documented, LLMs cannot predict response structure. Error handling is absent from tool definitions. No enum constraints on string parameters (e.g., 'container' accepts free-form strings, risking typos). Tool composition is sound (each does one thing), but chaining is not optimized, e.g., containers() returns container names but logs() requires exact match, forcing agents to handle name resolution.
List all containers on an endpoint. Args: endpoint: Endpoint ID (default: 4, the production remote endpoint). Returns list of containers with name, state, status, image, and id.
List all Docker environments (endpoints). Returns list of endpoints with id, name, type (local/remote), and status.
Get recent logs from a container. Args: container: Container name (exact match, e.g. "steinbergerraum-web-1"). endpoint: Endpoint ID (default: 4). tail: Number of log lines to return (default: 100). Returns log output as text.
Pull latest from git and redeploy a stack. Fetches current stack config (env vars, git credentials) and triggers a git-based redeploy with image pull. Args: stack_id: The numeric stack ID to redeploy. Returns confirmation message or error.
Restart a container. Args: container: Container name (exact match). endpoint: Endpoint ID (default: 4). Returns confirmation message.
Output schemas not documented. LLMs cannot predict response structure (e.g., what fields does containers() return? Is 'id' a string or int?). This forces agents to guess and risks parsing errors.
Parameter descriptions lack context and constraints. 'Endpoint ID (default: 4)' does not explain why 4 is the default, how to discover valid endpoints, or what happens if an invalid ID is passed. Agents cannot self-correct.
No error handling guidance in tool definitions. If a container name does not exist, what error is returned? Can the agent retry? Should it call containers() first to discover valid names? Undefined behavior.
Inferred effective spec: <=2025-11-25.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | C | 65 | <=2025-11-25 | v2 |
Get detailed info for a specific stack. Args: stack_id: The numeric stack ID. Returns stack details including git config and environment.
List all stacks. Returns list of stacks with id, name, status, endpoint, and type.
Start a stopped container. Args: container: Container name (exact match). endpoint: Endpoint ID (default: 4). Returns confirmation message.
Get Portainer server version and status. Returns server version and instance info.
Stop a running container. Args: container: Container name (exact match). endpoint: Endpoint ID (default: 4). Returns confirmation message.
String parameters accept free-form input without enum constraints. 'container' parameter in logs(), start(), stop(), restart() should validate against available containers or provide a discovery tool. Current design invites hallucinated container names.
Tool descriptions lack dependency hints. 'logs()' requires exact container name match but does not mention calling containers() first. 'redeploy()' requires stack_id but does not mention calling stacks() first. Agents must infer multi-step workflows.