CLI
gestalt is the client CLI for interacting with a running gestaltd server. It handles authentication, plugin connections, operation invocation, workflow management, agent sessions and turns, and API token management. A Docker image is also available for CI and containerized environments.
Global flags
| Flag | Purpose |
|---|---|
--url | Override the server URL. |
--format | Output format. json or table. |
Commands
| Command | Purpose |
|---|---|
gestalt auth login | Log in through the browser flow. |
gestalt auth logout | Clear local credentials. |
gestalt auth status | Show current authentication state and server connectivity. |
gestalt init | Run the interactive setup wizard. |
gestalt config get|set|unset|list | Manage the local client config. |
gestalt plugin list | List plugins from the server. |
gestalt plugin connect NAME | Connect a plugin through OAuth or interactive manual authentication. |
gestalt plugin disconnect NAME | Disconnect a plugin, removing stored credentials. |
gestalt plugin invoke NAME [OPERATION] | Invoke an operation or list operations when omitted. |
gestalt plugin describe NAME OPERATION | Show one operation’s parameter contract. |
gestalt workflow schedules ... | Create, list, inspect, update, pause, resume, or delete workflow schedules. |
gestalt workflow triggers ... | Create, list, inspect, update, pause, resume, or delete workflow triggers. |
gestalt workflow events publish ... | Publish an event into the workflow system. |
gestalt workflow runs ... | List, inspect, and cancel workflow runs. |
gestalt agent | Start or resume an interactive agent session. |
gestalt agent sessions ... | Create, list, inspect, and update agent sessions. |
gestalt agent turns ... | Create, list, inspect, cancel, and stream agent turns. |
gestalt tokens create|list|revoke | Manage Gestalt API tokens. |
URL resolution
The CLI resolves the server URL in this order:
--urlGESTALT_URL- project-local
.gestalt/config.json - user-local config at
~/.config/gestalt/config.json
For authentication, the CLI checks GESTALT_API_KEY first, then stored credentials from gestalt auth login. When the target server reports loginSupported: false from /api/v1/auth/info, the CLI can operate without stored credentials or an API key.
Authentication Status
gestalt auth status reports structured connectivity information: the target server URL, where the URL came from, whether the server is reachable, whether login is supported, and what credentials are available. This is the first thing to run when debugging connection issues.
Project config file
gestalt init can create a .gestalt/config.json file in the current directory. This is a project-local override for the server URL, intended for cases where one checkout or deployment directory should always point to a specific Gestalt server.
{
"url": "https://gestalt.example.com"
}The CLI searches the current directory and then parent directories until it finds the nearest .gestalt/config.json.
Plugin connect flags
gestalt plugin connect NAME accepts --connection and --instance. When the selected connection uses manual authentication instead of OAuth, the CLI prompts for the required credential fields and connection parameters.
Plugin disconnect flags
gestalt plugin disconnect NAME accepts --connection and --instance to target a specific named connection or stored instance. When both are omitted, the default connection is disconnected.
Invoke flags
gestalt plugin invoke accepts -p/--param key=value, --input-file file.json (use - for stdin), --connection, --instance, and --select. Use := instead of = to pass JSON values: -p items:='["a","b"]'.
Operation name matching
Operation names with dots (like chat.postMessage) can be typed as space-separated segments:
gestalt plugin invoke slack chat postMessageThis resolves to chat.postMessage. If the segments match a prefix shared by multiple operations, the CLI displays the matching subset instead of an error. For example, gestalt plugin invoke slack chat lists all operations starting with chat..
Examples
gestalt plugin list
gestalt plugin connect notion --connection MCP
gestalt plugin describe slack chat.postMessage
gestalt plugin invoke slack chat postMessage \
--connection plugin \
-p channel=C123 \
-p text='hello'
gestalt workflow schedules create \
--cron "0 */6 * * *" \
--plugin github \
--operation issues.list \
-p owner=valon-technologies \
-p repo=gestalt
gestalt workflow triggers create \
--type roadmap.item.updated \
--source roadmap \
--subject item \
--plugin slack \
--operation chat.postMessage \
-p channel=C123 \
-p text='Roadmap item updated'
gestalt workflow events publish \
--type roadmap.item.updated \
--source roadmap \
--subject item \
-p id=item-1 \
-e traceId=trace-1
gestalt workflow runs list --plugin github --status failed
gestalt tokens create --name automationWorkflow commands
The workflow CLI currently covers global schedules, global triggers, and workflow runs.
Schedules
gestalt workflow schedules list
gestalt workflow schedules list --plugin github
gestalt workflow schedules get <schedule-id>
gestalt workflow schedules create \
--cron "0 */6 * * *" \
--timezone America/New_York \
--plugin github \
--operation issues.list \
--connection default \
--instance acme-org \
-p owner=valon-technologies \
-p repo=gestalt \
-p state=open
gestalt workflow schedules update <schedule-id> --cron "0 9 * * 1-5"
gestalt workflow schedules pause <schedule-id>
gestalt workflow schedules resume <schedule-id>
gestalt workflow schedules delete <schedule-id>Use -p key=value for strings and -p key:=json for structured values. Use
--input-file file.json to load the target input from JSON instead of flags.
Triggers
gestalt workflow triggers list
gestalt workflow triggers list --plugin slack --type roadmap.item.updated
gestalt workflow triggers get <trigger-id>
gestalt workflow triggers create \
--type roadmap.item.updated \
--source roadmap \
--subject item \
--plugin slack \
--operation chat.postMessage \
--connection default \
-p channel=C123 \
-p text='Roadmap item updated'
gestalt workflow triggers update <trigger-id> --type roadmap.item.synced
gestalt workflow triggers pause <trigger-id>
gestalt workflow triggers resume <trigger-id>
gestalt workflow triggers delete <trigger-id>The create and update commands use the same target input conventions as
schedules. --type is required. --source and --subject are optional exact
match fields.
Event publishing
gestalt workflow events publish \
--type roadmap.item.updated \
--source roadmap \
--subject item \
--data-content-type application/json \
-p id=item-1 \
-e traceId=trace-1The publish command sends one event to POST /api/v1/workflow/events. Gestalt
fills in the event ID, spec version, and timestamp when you omit them, then
fans the event out across the configured workflow providers so matching
triggers can create runs. In practice, this is how multi-step workflows are
composed today: one operation publishes a domain event, and later triggers
start the next operations.
Runs
gestalt workflow runs list
gestalt workflow runs list --plugin github --status failed
gestalt workflow runs get <run-id>
gestalt workflow runs cancel <run-id> --reason "operator requested"Agent
gestalt agent --provider simple --model fast
gestalt agent resume <session-id>
gestalt agent resume --provider simple
gestalt agent sessions create --provider simple --model fast
gestalt agent sessions list --provider simple --state active
gestalt agent sessions get <session-id>
gestalt agent sessions update <session-id> --state archived
gestalt agent turns create <session-id> \
--message "Summarize the roadmap risk." \
--tool roadmap:sync
gestalt agent turns list <session-id> --status succeeded
gestalt agent turns get <turn-id>
gestalt agent turns transcript <turn-id>
gestalt agent turns cancel <turn-id> --reason "operator requested"
gestalt agent turns events list <turn-id> --after 0 --limit 100
gestalt agent turns events stream <turn-id> --after 100
# advanced fields such as responseSchema, metadata, or providerOptions
# go through --input, which also accepts "-" for stdin:
cat <<'JSON' | gestalt --format json agent turns create session-1 --input -
{
"model": "gpt-5.4",
"messages": [
{"role": "user", "text": "Summarize the roadmap risk."}
],
"toolRefs": [
{"pluginName": "roadmap", "operation": "sync"}
],
"responseSchema": {
"type": "object",
"properties": {
"summary": {"type": "string"}
},
"required": ["summary"]
}
}
JSONgestalt agent is the interactive path. It creates a session when you pass
--provider; gestalt agent resume [session-id] resumes either a specific
session or the most recently updated active session. The first turn in a CLI
session can include repeated --system messages, repeated --message prompts,
and repeated --tool plugin:operation additions. During execution, the CLI
parses the event stream, renders assistant/tool/interaction events, cancels the
active turn on Ctrl-C, and resolves pending interactions inline. TTY sessions
use a full-screen terminal UI with a persistent transcript, streaming assistant
output, a multiline composer, queued prompts while a turn is running, Ctrl-C
cancellation, and inline interaction panels. Press Enter to send, Alt-Enter to
insert a newline, PageUp/PageDown to scroll, /session to show the active
session and resume command, and /model to show or set the model for future
turns. Non-TTY sessions keep the
prompt-and-print fallback used by scripts and tests; there, end an input line
with \ to continue the same user message on the next prompt.
gestalt agent turns create is the non-interactive equivalent. It supports
repeated --system, repeated --message, repeated --tool plugin:operation,
--idempotency-key, and --input. gestalt agent turns transcript renders a
stored turn by combining the turn’s messages from
GET /api/v1/agent/turns/{turnID} with stored display-projected events from
GET /api/v1/agent/turns/{turnID}/events. gestalt agent turns events list
reads stored events from GET /api/v1/agent/turns/{turnID}/events. --after
is an event sequence cursor and --limit controls the page size. gestalt agent turns events stream reads
GET /api/v1/agent/turns/{turnID}/events/stream and writes the raw
server-sent event stream to stdout.
Interactive sessions use GET /api/v1/agent/turns/{turnID}/events/stream
with until=blocked_or_terminal, which lets the CLI switch immediately from
streaming output to interaction prompts when a provider requests input.
Local Quickstart
For a no-auth local setup with the first-party agent/simple provider:
cd /path/to/gestalt-providers/agent/simple
uv sync --group dev
cd /path/to/gestalt
go run ./cmd/gestaltd init --config ./config.yaml
go run ./cmd/gestaltd serve --locked --config ./config.yaml
gestalt --url http://localhost:18080 agent --provider simple --model fastNotes:
uv sync --group devmatters for source-backed Python providers.gestaltd initprefers the provider-local.venvwhen it builds locked artifacts.- If your local server has no platform auth configured, the CLI can connect without
GESTALT_API_KEY. - Successful turns still need the upstream model credentials expected by your configured provider, such as
OPENAI_API_KEYorANTHROPIC_API_KEYforagent/simple.