Skip to Content

CLI

gestalt is the client CLI for interacting with a running gestaltd server. It handles authentication, app 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 app listList apps from the server.
gestalt app connect NAMEConnect a app through OAuth or interactive manual authentication.
gestalt app disconnect NAMEDisconnect a app, removing stored credentials.
gestalt app invoke NAME [OPERATION]Invoke an operation or list operations when omitted.
gestalt app 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.
gestalt authorization ...Manage service account subjects, subject grants and tokens, dynamic authorization members, and authorization provider debug views.

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.

App connect flags

gestalt app 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.

App disconnect flags

gestalt app 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 app 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 app 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 app invoke slack chat lists all operations starting with chat..

Examples

gestalt app list gestalt app connect notion --connection MCP gestalt app describe slack chat.postMessage gestalt app invoke slack chat postMessage \ --connection app \ -p channel=C123 \ -p text='hello' gestalt workflow schedules create \ --cron "0 */6 * * *" \ --app github \ --operation issues.list \ -p owner=valon-technologies \ -p repo=gestalt gestalt workflow triggers create \ --type roadmap.item.updated \ --source roadmap \ --subject item \ --app 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 --app 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 --app github gestalt workflow schedules get <schedule-id> gestalt workflow schedules create \ --cron "0 */6 * * *" \ --timezone America/New_York \ --app 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 --app slack --type roadmap.item.updated gestalt workflow triggers get <trigger-id> gestalt workflow triggers create \ --type roadmap.item.updated \ --source roadmap \ --subject item \ --app 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>

Trigger creation uses the same single app-step input conventions as schedules. --type is required. --source and --subject are optional exact match fields. Use --target-file file.json when you want to pass the full workflow target object directly, for example a multi-step target or an agent step.

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 --app 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 modelOptions # 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": [ {"appName": "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 app: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 or supported Shift-Enter to insert a newline, Ctrl-J to insert a portable newline, PageUp/PageDown to scroll half a screen, Ctrl-Home/Ctrl-End to jump to the transcript start or end, Ctrl-L to redraw, Ctrl-D to exit an idle empty prompt, Up/Down to recall input history, /session to show the active session and resume command, and /model to show or set the model for future turns. Wheel and trackpad scrolling moves the transcript; set GESTALT_CLI_DISABLE_MOUSE=1 before launching the CLI to keep terminal-native mouse selection instead. 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 app: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.

Authorization

gestalt authorization covers service account subjects and the dynamic authorization admin surface. Built-in Gestalt admins can manage all dynamic grants. App admins can manage members for the specific apps they administer, so they can grant users or service accounts access without being global Gestalt admins. Admin subcommands may require --url pointing at the management base URL when public and management listeners are split.

gestalt authorization subjects list gestalt authorization subjects create release-bot \ --display-name "Release Bot" gestalt authorization subjects get service_account:release-bot gestalt authorization subjects update service_account:release-bot \ --description "Release automation" gestalt authorization subjects delete service_account:release-bot gestalt authorization subjects members list service_account:release-bot gestalt authorization subjects members set service_account:release-bot \ --email operator@example.com \ --role editor gestalt authorization subjects members remove service_account:release-bot \ user:user_123 gestalt authorization subjects grants list service_account:release-bot gestalt authorization subjects grants set service_account:release-bot github \ --role viewer gestalt authorization subjects grants remove service_account:release-bot github gestalt authorization subjects external-identities list service_account:release-bot gestalt authorization subjects external-identities add service_account:release-bot \ --type google \ --id google-123 gestalt authorization subjects external-identities remove service_account:release-bot \ --type google \ --id google-123 gestalt authorization subjects integrations list service_account:release-bot gestalt authorization subjects integrations connect service_account:release-bot github gestalt authorization subjects integrations disconnect service_account:release-bot github gestalt authorization subjects tokens list service_account:release-bot gestalt authorization subjects tokens create service_account:release-bot \ --name release-bot \ --permission github:issues.list gestalt authorization subjects tokens revoke service_account:release-bot <token-id> gestalt authorization subjects tokens revoke-all service_account:release-bot gestalt authorization apps list gestalt authorization apps members list github gestalt authorization apps members set github \ --subject-id service_account:release-bot \ --role viewer gestalt authorization apps members set github \ --email operator@example.com \ --role admin gestalt authorization apps members remove github service_account:release-bot gestalt authorization admins members list gestalt authorization admins members set \ --email admin@example.com \ --role admin gestalt authorization admins members remove user:user_123 gestalt authorization provider get gestalt authorization models list gestalt authorization relationships list \ --resource-type app_dynamic \ --resource-id github

Subject token creation accepts --permission app:operation, --action app:action, --scopes, or --permissions-file with a raw JSON permissions array. These inputs are mutually exclusive except --permission and --action, which can be combined. Provider-dev attach uses --action app:provider_dev.attach.

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 lock --config ./config.yaml go run ./cmd/gestaltd sync --locked --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 sync --locked 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.