Skip to Content
ReferenceServer CLI

Server CLI

For production deployments, strongly prefer gestaltd lock, then gestaltd sync --locked during image build or release preparation, then gestaltd serve --locked at runtime. The lockfile pins resolved provider artifacts and verified hashes, and locked serve refuses to mutate deployment state.

gestaltd manages server lifecycle and provider releases.

Server commands

CommandPurpose
gestaltdLocal-friendly startup. Generates a config if needed and serves.
gestaltd serve --config PATHStart the server. Repeat --config to layer overrides.
gestaltd serve --config PATH --watchStart from layered config and restart after debounced local config, source provider, or local release metadata changes.
gestaltd serve --locked --config PATHStart read-only from an existing lockfile and prepared artifacts. Repeat --config to layer overrides.
gestaltd serve --artifacts-dir DIRDirectory for prepared provider artifacts.
gestaltd serve --lockfile PATHOverride the lockfile location. PATH resolves like a normal CLI path.
gestaltd lock --config PATHResolve published provider sources and write canonical lock metadata. Repeat --config to layer overrides.
gestaltd lock --check --config PATHVerify that the checked-in lockfile matches the current config without rewriting it.
gestaltd sync --locked --config PATHMaterialize prepared provider artifacts from an existing lockfile. Local source UI preparation uses bounded parallelism by default.
gestaltd sync --locked --check --config PATHVerify that prepared artifacts exist and match the lockfile without rewriting them.
gestaltd validate --config PATHValidate config without serving. Repeat --config to layer overrides.
gestaltd validate --lockfile PATHAccept the same explicit lockfile path used by lock, sync, and serve without mutating it.
gestaltd --versionPrint the server version.

Provider commands

CommandPurpose
gestaltd provider search [QUERY]Search configured provider repositories. Pass --repo NAME to search one repository.
gestaltd provider info PACKAGEShow available versions and release metadata for one package. Pass --repo NAME to disambiguate.
gestaltd provider add PACKAGE --config PATHAdd an indexed provider package to config and update the lockfile. Package sources are written by default.
gestaltd provider add PACKAGE --kind KIND --name NAMEChoose the provider kind and config entry name explicitly. UI providers also require --set path=/mount.
gestaltd provider add PACKAGE --version CONSTRAINTWrite a semver version constraint such as ^1.4.0, ~1.4.0, or an exact version.
gestaltd provider add PACKAGE --exact-sourceWrite the resolved provider-release.yaml URL instead of a package source.
gestaltd provider add PACKAGE --syncMaterialize prepared artifacts after locking.
gestaltd provider list --config PATHList configured providers and lock status. Pass --kind KIND to filter.
gestaltd provider remove NAME --config PATHRemove one provider entry and update the lockfile. Pass --kind KIND when the name is ambiguous.
gestaltd provider upgrade --config PATHRefresh lock state for all package sources without editing config version constraints.
gestaltd provider upgrade NAME --version CONSTRAINTChange one package source’s version constraint and update the lockfile.
gestaltd provider repo add NAME URLAdd a provider repository to the user-level store. Pass --config PATH to write providerRepositories into project config instead.
gestaltd provider repo listList the default, user-level, and project provider repositories.
gestaltd provider repo updateFetch and cache provider repository indexes.
gestaltd provider repo remove NAMERemove a provider repository from the user-level store. Pass --config PATH to remove it from project config instead.
gestaltd serve --path PATHRun a local source app or UI bundle inside a synthesized Gestalt config. Serves /admin and any configured or inferred public UIs.
gestaltd serve --path PATH --config PATHLayer supporting providers, apps, and UI mounts on top of the synthesized local baseline. Repeat --config to merge left-to-right.
gestaltd serve --remote URL --path PATHAttach one local source app to an authenticated remote gestaltd session. The remote server matches by manifest source and keeps its configured auth, authorization, connections, app config, and host services.
gestaltd serve --remote URL --config PATHAttach every source-backed app in the layered config. Use repeated --config files when you need explicit local config overrides or multiple local apps.
gestaltd provider attach list --remote URLList your active remote provider-dev attachments on that server.
gestaltd provider attach show --remote URL ATTACH_IDInspect one active remote provider-dev attachment.
gestaltd provider attach detach --remote URL ATTACH_IDDetach a stuck remote provider-dev attachment owned by your authenticated principal.
gestaltd provider validate --path PATHValidate a local source app or UI bundle inside the same synthesized Gestalt config used by gestaltd serve --path.
gestaltd provider validate --config PATHValidate the target provider together with selected supporting providers and null deletions from layered config overlays.
gestaltd provider package --version VERSIONBuild provider release archives from a source directory. Executable source providers use SDK-native source packages or build.command and default to the host platform; UI and declarative providers default to a generic archive. Pass --platform ... with os/arch targets or --platform all for multi-platform builds.
gestaltd provider package --output DIROutput directory for the release archives. Defaults to dist/.
gestaltd provider release --dist-dir DIRFinalize already-built release archives by validating them and writing checksums.txt and provider-release.yaml into the dist directory.

For config-free local development, inferred UI mount paths use the manifest source slug rather than the API-safe provider key. A source ending in vm-style-guide mounts at /vm-style-guide, while the local integration key may still be vm_style_guide. Explicit apps.<name>.ui.path values take precedence for app-owned or sibling UI, and explicit providers.ui.<name>.path values take precedence when developing a UI bundle directly.

Provider package commands use the provider repository model described in Provider packages. Mutating package commands accept one --config path so the CLI edits the intended file instead of a merged runtime view. provider add, provider remove, and provider upgrade NAME --version update the lockfile by default. provider add and provider remove accept --no-lock when you need to edit config only.

gestaltd sync --locked --parallelism N caps concurrent preparation for local source.path UI bundles. The default is up to four workers, capped by GOMAXPROCS; --parallelism 1 forces sequential preparation. Other provider types and sync --locked --check remain sequential.

Config Watch Mode

Use gestaltd serve --watch for config-based local development when your layered config points at local provider source paths or local provider-release.yaml metadata. Watch mode starts normally, then restarts the server after local file changes settle. If reload preparation fails, the current server keeps running and the failure is logged.

For faster iteration on one configured plugin, combine --watch with --app NAME so unrelated configured apps are not validated or prepared:

gestaltd serve \ --app support \ --config ./config.yaml \ --config ./local.yaml \ --watch

Watch mode applies only to config-based serve. It cannot be combined with --locked, --path, or --remote.

Examples

gestaltd gestaltd lock --config ./config.yaml gestaltd sync --locked --config ./config.yaml gestaltd sync --locked --config ./config.yaml --parallelism 2 gestaltd serve --locked --config ./config.yaml gestaltd validate --config ./config.yaml gestaltd lock --config ./config.yaml --lockfile ./local/gestalt.lock.json gestaltd sync --locked --config ./config.yaml --lockfile ./local/gestalt.lock.json gestaltd serve --config ./config.yaml --lockfile ./local/gestalt.lock.json gestaltd serve --config ./config.yaml --watch gestaltd serve --app support --config ./config.yaml --config ./local.yaml --watch gestaltd serve --locked --config ./config.yaml --lockfile ./local/gestalt.lock.json gestaltd lock --config ./base.yaml --config ./overrides/prod.yaml gestaltd sync --locked --config ./base.yaml --config ./overrides/prod.yaml gestaltd serve --locked --config ./base.yaml --config ./overrides/prod.yaml gestaltd provider search github gestaltd provider info github.com/valon-technologies/gestalt-providers/app/github gestaltd provider repo list gestaltd provider repo add valon https://registry.gestaltd.ai/provider-index.yaml --config ./config.yaml gestaltd provider repo update --config ./config.yaml gestaltd provider add github.com/valon-technologies/gestalt-providers/app/github --config ./config.yaml --name github gestaltd provider add github.com/valon-technologies/gestalt-providers/auth/oidc --config ./config.yaml --kind authentication --name oidc --version '^1.4.0' gestaltd provider add github.com/acme/gestalt-providers/ui/console --config ./config.yaml --repo acme --kind ui --name console --set path=/console gestaltd provider list --config ./config.yaml gestaltd provider list --config ./config.yaml --kind app gestaltd provider upgrade --config ./config.yaml gestaltd provider upgrade github --config ./config.yaml --kind app --version '^1.5.0' gestaltd provider remove github --config ./config.yaml --kind app gestaltd provider validate --path ./apps/support gestaltd provider validate --path ./ui/dashboard gestaltd provider validate --path ./apps/support --config ./dev/support.yaml --config ./dev/local.yaml gestaltd serve --path ./apps/support gestaltd serve --path ./ui/dashboard gestaltd serve --path ./apps/support --config ./dev/support.yaml --port 8080 gestaltd serve --remote https://gestalt.example.com --path ./apps/support gestaltd serve --remote https://gestalt.example.com --path ./apps/support --name support gestaltd serve --remote https://gestalt.example.com --remote-token <token-with-provider_dev.attach> --path ./apps/support gestaltd serve --remote https://gestalt.example.com --config ./remote.yaml --config ./local-overrides.yaml gestaltd provider attach list --remote https://gestalt.example.com gestaltd provider attach show --remote https://gestalt.example.com att_123 gestaltd provider attach detach --remote https://gestalt.example.com att_123 gestaltd provider package --version 0.0.1-alpha.1 gestaltd provider package --version 0.0.1-alpha.1 --platform all gestaltd provider package --version 0.0.1-alpha.1 --platform linux/amd64,linux/arm64 gestaltd provider release --dist-dir dist --version 0.0.1-alpha.1

When repeated, --config files merge left-to-right. Maps deep-merge, later scalar values win, lists replace inherited lists, and null deletes inherited keys. By default, lockfiles and artifact paths stay rooted at the leftmost config file. --lockfile overrides only the lockfile path. --artifacts-dir keeps the same config-relative resolution used by sync and serve.

gestaltd serve --remote is environment-agnostic: the URL is just the remote gestaltd instance to attach to. The local command only replaces source-backed plugin implementations for the authenticated principal that created the session. The remote server must opt in with server.dev.attachmentState; otherwise the command fails before local code is attached. Use attachmentState: indexeddb on shared or load-balanced servers so attachment metadata and queued provider calls are stored in the configured host IndexedDB. Process-local remote attachment state is not a supported server mode. For the interactive happy path, gestaltd serve --remote creates a short-lived attach approval request and opens the remote server in your browser. Approving that page with your normal browser session creates an owner-scoped attachment only when your resolved role is allowed by the app’s provider-dev attach configuration. The terminal prints a verification code, and the browser approval page requires that code before approval succeeds. --remote-token and GESTALT_API_KEY are the non-interactive direct-attach path; those API tokens must include permissions[].actions: ["provider_dev.attach"] for every attached app. Stored CLI credentials from gestaltd auth login are not used for direct attach; when no explicit token is provided, gestaltd serve --remote uses browser approval. With --remote URL --path PATH and no --config, the local command sends the manifest source and the local implementation only; the remote server chooses the configured app with the same manifest source and preserves that remote plugin’s config. If multiple remote apps share the same source, or the manifest has no source, pass --name to choose the configured remote app. All non-local apps and remote host services continue to resolve through the remote instance.

After browser approval or attach-token authentication, the remote creates an attachment and the CLI uses the returned attachId plus a one-time dispatcher secret for poll/complete traffic. The dispatcher secret is not shown by list/get diagnostics and is not needed for owner cleanup detach. Remote attach requests mark an attached provider with ui: true when the local dispatcher will serve that provider’s mounted UI assets; diagnostic responses report the mounted uiPath but never return local UI contents. Use gestaltd provider attach list --remote URL, gestaltd provider attach show --remote URL ATTACH_ID, and gestaltd provider attach detach --remote URL ATTACH_ID to inspect or clean up attachments owned by your authenticated principal. These diagnostic commands use --remote-token, GESTALT_API_KEY, or a matching stored Gestalt CLI credential, and they do not require provider_dev.attach because they cannot create a new attachment.

API-token attach creation requires an explicit token action permission:

{ "name": "slack local dev", "permissions": [ { "app": "slack", "actions": ["provider_dev.attach"] } ] }

Normal provider scopes and operation permissions do not grant remote attach, and provider_dev.attach does not grant normal invocation access. Subject-owned API tokens are not accepted for remote attach v1.

When --config is present, source-backed app entries in the layered local config are treated as explicit local overrides. Their app config is sent to the remote session instead of inheriting the remote server’s config. Remote mode allows missing local environment substitutions while loading config so unrelated deploy-only env vars do not block attach. Remote mode tunnels app RPC, catalog, post-connect, host-service calls, and app-owned UI assets for mounted UIs that already exist on the remote server. Raw GraphQL surfaces are not tunneled in v1.

For source-backed providers, gestaltd serve --path starts the manifest run argv when one is declared. If run is omitted, it serves or starts the declared entrypoint or SDK-native source package. Sequence-form build commands can prepare dependencies before local startup; output-producing build.command remains the packaging path for compiled artifacts.

See Configuration for the relationship between lock, sync --locked, serve --locked, and validate.