The workloads API provides a unified interface for managing MCP server deployments across different runtimes. This document explains how workloads are created, managed, and destroyed.
The workloads manager abstracts lifecycle operations across:
- Local Docker/Podman deployments
- Remote MCP servers
- Kubernetes deployments (via operator)
Implementation: pkg/workloads/manager.go
stateDiagram-v2
[*] --> Starting: Deploy
Starting --> Running: Success
Starting --> Error: Failed
Running --> Stopping: Stop
Running --> Unhealthy: Health Failed
Running --> Unauthenticated: Auth Failed
Running --> Stopped: Container Exit
Stopping --> Stopped: Success
Stopped --> Starting: Restart
Stopped --> Removing: Delete
Unauthenticated --> Starting: Re-authenticate
Unauthenticated --> Removing: Delete
Removing --> [*]: Success
Error --> Starting: Restart
Error --> Removing: Delete
States: pkg/container/runtime/types.go
starting,running,stopping,stoppedremoving,error,unhealthy,unauthenticated
Foreground:
thv run my-server --foregroundCreates transport → deploys container → starts proxy → blocks until shutdown
Detached:
thv run my-serverSaves state → forks process → returns immediately → child runs in background
Implementation: pkg/workloads/manager.go
thv stop my-serverContainer workload: Stops proxy process → stops container → preserves state
Remote workload: Stops proxy → preserves state
Implementation: pkg/workloads/manager.go
thv start my-serverNote:
thv restartremains available as an alias for backward compatibility.
Loads state → verifies not running → starts workload with saved config
Implementation: pkg/workloads/manager.go
thv rm my-serverContainer workload: Stops proxy → removes container → deletes state
Remote workload: Stops proxy → deletes state
Implementation: pkg/workloads/manager.go
Listing combines container workloads from the runtime with remote workloads from persisted state. The manager can filter workloads by label or group, and can optionally include stopped workloads.
Implementation: pkg/workloads/manager.go
Some operations (stop, delete) support processing multiple workloads in a single invocation, handling each workload sequentially or in parallel as appropriate.
Pattern: Operations return errgroup.Group
Timeout: 5 minutes per operation
Implementation: Uses golang.org/x/sync/errgroup
Components:
- Container (via runtime)
- Proxy process (detached mode)
- Permission profile
- Network isolation
Available operations: All
Components:
- Proxy process only
- No container
- No permission profile
Available operations: Deploy, stop, restart, delete, list
Detection: RunConfig.RemoteURL != ""
Implementation: pkg/workloads/manager.go
RunConfig state:
- Path:
$XDG_STATE_HOME/toolhive/runconfigs/<name>.json - Default:
~/.local/state/toolhive/runconfigs/<name>.json - Contains: Full RunConfig
- Used for: Restart, export
Status file:
- Path:
$XDG_DATA_HOME/toolhive/statuses/<name>.json - Default:
~/.local/share/toolhive/statuses/<name>.json - Contains: Status, PID, timestamps
- Used for: List, monitoring
PID file (container workloads only):
- Path:
$XDG_DATA_HOME/toolhive/pids/toolhive-<name>.pid - Default:
~/.local/share/toolhive/pids/toolhive-<name>.pid - Contains: Proxy process PID
- Used for: Stop operation
Implementation: pkg/state/, pkg/workloads/statuses/
Provides atomic status updates:
SetWorkloadStatus- Update statusGetWorkload- Read statusSetWorkloadPID- Set PIDDeleteWorkloadStatus- Remove status
Implementation: pkg/workloads/statuses/file_status.go
The system automatically applies standard labels to workloads:
toolhive-name- Full workload nametoolhive-basename- Base name without timestamptoolhive-transport- Transport protocol typetoolhive-port- Proxy port number
Implementation: pkg/labels/, pkg/runner/config.go
Users can apply custom labels for organizational purposes. Labels support filtering during list operations.
Implementation: pkg/workloads/types/labels.go
- Core Concepts - Workload concept
- Deployment Modes - Lifecycle per mode
- Transport Architecture - Transport lifecycle
- Groups - Group operations