Skip to Content

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

FlagPurpose
--urlOverride the server URL.
--formatOutput format. json or table.

Commands

CommandPurpose
gestalt auth loginLog in through the browser flow.
gestalt auth logoutClear local credentials.
gestalt auth statusShow current authentication state and server connectivity.
gestalt initRun the interactive setup wizard.
gestalt config get|set|unset|listManage the local client config.
gestalt plugin listList plugins from the server.
gestalt plugin connect NAMEConnect a plugin through OAuth or interactive manual authentication.
gestalt plugin disconnect NAMEDisconnect a plugin, removing stored credentials.
gestalt plugin invoke NAME [OPERATION]Invoke an operation or list operations when omitted.
gestalt plugin describe NAME OPERATIONShow 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 agentStart 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|revokeManage Gestalt API tokens.

URL resolution

The CLI resolves the server URL in this order:

  1. --url
  2. GESTALT_URL
  3. project-local .gestalt/config.json
  4. 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 postMessage

This 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 automation

Workflow 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-1

The 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"] } } JSON

gestalt 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 fast

Notes:

  • uv sync --group dev matters for source-backed Python providers. gestaltd init prefers the provider-local .venv when 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_KEY or ANTHROPIC_API_KEY for agent/simple.