Towline Agent Documentation

This document is designed for AI agents (Claude Code, Cursor, Codex, Gemini CLI, Windsurf, etc.) that need to understand what Towline is, how it works, and how to use its tools to build, deploy, and operate software on Portainer-managed infrastructure.

TL;DR: Towline gives you an isolated container stack on Portainer with 10 high-level MCP tools for deployment, health checks, logs, domain routing, scaling, and exec. You can go from "write code" to "running in production" without leaving your MCP session.

What is Towline?

Towline is the agentic engineering SDK for Portainer. It has three components:

  1. towline-mcp — An MCP server (Go binary) that runs per-project, providing your agent with scoped access to a single Portainer stack. It adds stack isolation, tier-based approval gating, and 10 high-level operational tools on top of the upstream Portainer MCP.
  2. towline CLI — A scaffolding tool. towline init <project> creates everything: Portainer team, scoped API key, container stack, agent configuration, compose files, and git repo.
  3. Template packs — Compose files + agent skills + MCP configs bundled as starter kits (api, fullstack, worker, static-site, databases, etc.).

How Your MCP Session Works

When your user runs towline init my-project, it creates a .claude/settings.json (or equivalent for your agent) that tells your MCP client to launch towline-mcp with these flags:

towline-mcp \
  -server https://portainer.example.com \
  -token <scoped-api-key> \
  -stack my-project \
  -tier dev

This MCP server process is your gateway to the Portainer environment. Every tool call you make goes through it, and it enforces:

MCP Tools Reference

You have access to two categories of tools: Towline tools (high-level, one-call answers) and upstream Portainer tools (stack CRUD and Docker proxy).

Towline Tools

towline_service_health

Get health snapshot for one or all services in the stack.

ParameterTypeRequiredDescription
servicestringNoService name from docker-compose. Omit for all services.

Returns: state, uptime, restart count, CPU/memory usage, exit code. If stats or inspect calls fail, stats_error or inspect_error fields will contain the error message.

towline_service_logs

Fetch recent log output for a named service.

ParameterTypeRequiredDescription
servicestringYesService name from docker-compose
tailnumberNoLines to return (default 200)
sincestringNoRFC3339 timestamp filter
filterstringNoFilter lines containing this string

towline_env_get

Read stack environment variables. Sensitive values (names containing KEY, SECRET, PASSWORD, TOKEN) are masked.

ParameterTypeRequiredDescription
namestringNoSpecific variable name. Omit for all.

towline_env_set

Set a stack environment variable. Requires approval in prod tier.

ParameterTypeRequiredDescription
namestringYesVariable name
valuestringYesVariable value
approvalTokenstringNoToken for prod tier approval

towline_domains_list

List all domain/routing mappings for services in the stack. No parameters.

towline_domains_add

Add domain routing to a service. Requires approval in prod tier.

ParameterTypeRequiredDescription
servicestringYesService name
domainstringYesDomain name (e.g. app.example.com)
portnumberNoService port (default 80)
methodstringNotraefik, caddy, or cloudflare (auto-detected if omitted)
approvalTokenstringNoToken for prod tier approval

towline_domains_remove

Remove domain routing from a service. Requires approval in prod tier.

ParameterTypeRequiredDescription
servicestringYesService name
domainstringYesDomain to remove
methodstringNotraefik, caddy, or cloudflare (auto-detected if omitted)
approvalTokenstringNoToken for prod tier approval

towline_scale

Scale a service to N replicas. Warns if the service has persistent volumes. No approval required (operational).

ParameterTypeRequiredDescription
servicestringYesService name
replicasnumberYesNumber of replicas

towline_deployments

View deployment history with diffs and outcomes.

ParameterTypeRequiredDescription
limitnumberNoMax entries (default 10)

towline_exec

Execute a command inside a running container and capture stdout/stderr. Requires approval in prod tier.

ParameterTypeRequiredDescription
servicestringYesService name
commandstringYesCommand to run (space-separated args)
approvalTokenstringNoToken for prod tier approval

Upstream Portainer Tools

These are the standard Portainer MCP tools, scoped to your stack:

ToolDescription
listLocalStacksList stacks (filtered to yours)
getLocalStackFileGet compose file content
createLocalStackDeploy a new stack
updateLocalStackUpdate stack (full compose required!)
startLocalStackStart a stopped stack
stopLocalStackStop a running stack
deleteLocalStackDelete a stack
dockerProxyRaw Docker API proxy (GET/POST/PUT/DELETE)

Critical: Partial Compose Files

When calling updateLocalStack, you MUST submit the COMPLETE compose file. Portainer removes any service not included in the update. If you only include the service you changed, all other services will be destroyed.

Safe workflow:

  1. Call getLocalStackFile to get the current compose content
  2. Modify the YAML as needed
  3. Submit the entire modified file to updateLocalStack

Tier System & Approval Flow

The -tier flag controls what you can do without human approval:

Dev Tier (-tier dev)

Full autonomy. Every tool call executes immediately. Use this for development and testing.

Prod Tier (-tier prod)

OperationApproval?Examples
ReadNohealth, logs, env_get, domains_list, deployments, listLocalStacks
OperationalNostartLocalStack, scale
ConfigurationYesenv_set, domains_add, domains_remove
DeployYescreateLocalStack, updateLocalStack
DestructiveYesstopLocalStack, deleteLocalStack
Exec / Docker writeYestowline_exec, dockerProxy non-GET

How Approval Works

  1. You call a tool that requires approval (e.g. updateLocalStack in prod)
  2. The response contains an approvalToken string and a message describing the action
  3. The human reviews and approves (the token is shown to them)
  4. You re-call the same tool with the same arguments plus the approvalToken parameter
  5. The call executes

Tokens are single-use, expire after 5 minutes, and are bound to the specific tool and arguments. You cannot reuse a token with different arguments.

Common Agent Workflows

Deploy a new service

1. getLocalStackFile → get current compose
2. Add your new service to the YAML
3. updateLocalStack → deploy (submit FULL compose)
4. towline_service_health → verify it started
5. towline_service_logs → check for errors

Debug a failing service

1. towline_service_health → check state, restarts, exit code
2. towline_service_logs service=failing-svc tail=100 → read logs
3. towline_exec service=failing-svc command="cat /app/config.json" → inspect files
4. towline_env_get → check environment variables
5. Fix the issue, redeploy via updateLocalStack

Expose a service on a domain

1. towline_domains_add service=web domain=app.example.com port=3000
   (auto-detects Traefik/Caddy/Cloudflare)
2. towline_domains_list → verify routing
3. towline_service_health → ensure service is healthy

Scale a service

1. towline_scale service=worker replicas=3
2. towline_service_health → verify all replicas running

Roll back a broken deploy

1. towline_deployments → see history, find last working version
2. getLocalStackFile → get current (broken) compose
3. Revert to previous compose content
4. updateLocalStack → redeploy
5. towline_service_health → verify rollback

CLI Reference

These are commands the human user runs (not MCP tools). You may need to instruct them to run these:

towline init <project>

Create a new project with full Portainer scaffolding.

towline init my-project --template api --tier dev

Flags:
  --template  Template pack (api, fullstack, worker, static-site, etc.)
  --tier      Deployment tier (dev or prod, default: dev)

towline list

List all Towline projects on this machine.

towline destroy <project>

Remove a project: deletes Portainer team, API key, stack, and local files.

towline setup

Interactive setup: connects to a Portainer instance and saves credentials.

Generated Project Structure

~/projects/<name>/
├── .claude/settings.json   # MCP server configuration
├── CLAUDE.md               # Agent instructions for this project
├── docker-compose.yml      # From template
├── .env.example            # Env var template
├── skills/                 # Agent skills library
└── .git/

The .claude/settings.json file tells your MCP client how to launch towline-mcp. The CLAUDE.md file contains project-specific instructions including available tools, the stack name, and operational guidelines.

Using the Docker Proxy

The dockerProxy tool gives you raw Docker API access, scoped to your stack's containers. Use it for operations not covered by the Towline tools.

// List containers
dockerProxy method=GET dockerAPIPath=/containers/json

// Inspect a container
dockerProxy method=GET dockerAPIPath=/containers/<id>/json

// Restart a container (no approval in prod — operational)
dockerProxy method=POST dockerAPIPath=/containers/<id>/restart

// Non-GET requests to non-operational paths require approval in prod

Internal Environment Variables

Variables prefixed with _TOWLINE_ are managed internally by Towline (e.g. deployment history). You cannot set or override them — they are silently filtered from createLocalStack and updateLocalStack requests.

Prerequisites

This documentation is designed to be consumed by AI agents. For human-readable docs, see the Getting Started guide.