tapstateDocs
Reference

CLI reference

Use tapstate offline workspace commands, connected sessions, and one-shot commands

The tapstate CLI has three operating forms:

  • Offline commands read or create local workspace files. They do not require a running server.
  • Connected sessions retain the selected workspace, server, and login in an interactive REPL.
  • Connected one-shot commands use launch options to connect, authenticate, run one command, and exit.

Run this command to see the command set included with your installed version:

tapstate --help

Use tapstate help <command> or tapstate <command> --help to inspect a command without connecting to a server.

Launch and help options

OptionPurpose
-w, --workdir <dir>Select the workspace for an interactive session. For an offline one-shot command, place this option after the command. The default is tap-work, or $TAPSTATE_WORKDIR when set.
-c, --connect <url>Connect to a server before opening a session or running a one-shot command.
--context <name>Select a saved server context for connected commands. Use tapstate context or :ctx to create and manage contexts.
-u, --user <name>Log in as this user during launch when -c is also supplied. Without -c, the CLI stays in an offline session.
-p, --password <password>Supply the password inline. Prefer TAPSTATE_PASSWORD or the prompt because command-line values are visible in shell history and process listings.
--versionPrint only the installed CLI version and exit. Use tapstate version to report both the CLI and server versions.
--helpPrint top-level help and exit.

Report CLI and server versions

The CLI and server are installed separately and can run different builds. Use tapstate version when you need the complete version pair for troubleshooting or compatibility checks:

$ tapstate version
cli    <cli-version>
server not connected

The command works without a server. After you connect, run version in the same session to read the server's current value:

tapstate(127.0.0.1:8080)> version
cli    <cli-version>
server <server-version> (127.0.0.1:8080)

tapstate --version is different: it reports only the local executable and does not contact a server.

When connect finds different CLI and server versions, it reports cli.version-mismatch but keeps the connection open. Install the CLI version that matches the server, or connect to a server on the CLI version. If their contracts differ, the server decides which operations it accepts. A server that does not expose its version is reported as not reported; the CLI does not assume that the versions match.

Running tapstate without a subcommand starts the REPL. A global work directory can be supplied before the session starts:

tapstate -w work

Offline workspace commands

demo

Create a complete three-file order-state workspace:

tapstate demo [-w DIR] [--print-steps] [--force] [-o text|json|yaml]

The command writes:

source/orders_db.tap.yml
source/fulfillment_db.tap.yml
pipeline/order_pipeline.tap.yml

It generates local files only. It does not start Docker, connect to a server, test either database, or run the pipeline. Use --print-steps to print the commands that apply and run the workspace after you configure its connection values.

By default, demo refuses to overwrite an existing demo workspace and returns cli.demo-workspace-exists. Use a new directory, or review the files before running with --force. If the directory cannot be written, the command returns cli.workspace-not-writable with path and reason, restores files it replaced, and removes files it created. Empty directories created during the attempt can remain.

validate

Validate resource structure, field values, modes, and references:

tapstate validate [-w DIR] [-o text|json|yaml] [path]

When path is omitted, the command validates the selected workspace.

new

Create a source, pipeline, transform, view, or serve resource:

tapstate new --kind source \
  --connector mysql \
  --id orders_source \
  --mode snapshot \
  --set host=localhost \
  --set port=3306 \
  --workdir work

Frequently used options:

OptionPurpose
--kind source|pipeline|transform|view|serveSelect the resource kind.
--type <type>Set a transform type: filter, map, js, union, nest, or join. Use with --kind transform.
--id <id>Set the resource ID.
--connector <id>Set the connector for a source resource.
--mode <mode>Set a source read mode.
--set key=valueSet a connector field; repeat for multiple fields.
--source <id>Set a pipeline's source reference.
--sync-to <id>Add a pipeline target; repeat for multiple targets.
--non-interactive, -yRefuse missing required answers instead of prompting.
--dry-runPrint the generated resource without writing it.
--forceReplace an existing generated target.
--out <dir>Write the generated artifact flat into this directory instead of the workspace's kind directory.

The command also accepts -c for --connector, -m for --mode, and -w for --workdir.

ls

List resources in the selected workspace:

tapstate ls [-w DIR] [-o text|json|yaml] [source|pipeline|transform|view|serve]

desc

Render one resource by ID:

tapstate desc [-w DIR] [-o text|json|yaml] <id>

explain

Describe the resource grammar or a field path:

tapstate explain [-o text|json|yaml] [field.path]

For example:

tapstate explain source.mode

alias

The installed command is tapstate. A release bundle can also provide the shorter tap alias when that name is available:

tapstate alias install
tapstate alias uninstall

Installing or removing the alias does not replace the canonical tapstate command. The CLI refuses to overwrite an unrelated file named tap. For a non-default installation, set TAPSTATE_INSTALL_DIR to the directory that contains tapstate before running the alias command.

Start a connected session

Start the REPL, connect to a server, and log in:

tapstate -w work
tapstate> connect http://127.0.0.1:8080
tapstate> login admin
Password:

The password prompt masks its input. connect selects the server; login creates the authenticated session used by later commands.

Save a server context and session

For repeat work against the same server, run tapstate context in an interactive terminal. The context manager can create, choose, edit, bind, unbind, or delete a named context. A context holds its server URL and TLS-verification choice; you can bind it to the current workspace when you create it.

Inside a REPL, run :ctx (or context) to open the same manager. Select a saved context at launch with --context:

tapstate --context local-dev -w work

After auth login <username> succeeds for a saved context, the CLI can resume its cached session when it next uses that context. Run auth status to confirm the signed-in user. Run auth logout to revoke the remote session and remove the local cache, or auth logout --local-only to remove only the local cache. The latter leaves the remote session valid until it expires.

Use a saved context for an interactive user session. A context does not turn a machine token into a saved credential, and a one-shot command that supplies --token remains scoped to that process.

REPL session commands:

CommandPurpose
helpShow REPL help.
connect <host:port>Select a server.
disconnectLeave the current server.
login <username>Authenticate to the selected server.
logoutEnd the authenticated session.
:ctx, contextManage saved server contexts.
auth login <username>Sign in and save a session for the selected context.
auth statusReport whether the selected context has a usable saved session.
auth logout [--local-only]Revoke and remove the saved session, or remove only its local cache.
versionReport the CLI version and the connected server version.
cd <dir>Change the REPL workspace directory.
pwdPrint the current workspace directory.
exit, quitEnd the session.

For a connected one-shot command, seed the connection and user before the verb:

TAPSTATE_PASSWORD="<server-password>" \
  tapstate -c http://127.0.0.1:8080 -u admin status orders_to_operational_state

The process connects, signs in, runs status, and exits. Without -c, a connected verb exits with code 3. connect, login, logout, and cd remain session commands; they are not one-shot verbs.

Read data from a declared source

Use a connected, authenticated session to inspect the data behind a declared source. Each read uses that source's configured connection. You do not provide a database URI or a database query language in the command.

In the current preview, row previews and live reads require a source that uses the mongodb connector. Collection listing and statistics can still be available for other connectors.

Read a collection

SyntaxUse
show collections [<source>]List the collections held by one declared source, or by every declared source when the argument is omitted. This lists the database's collections, not only resources declared in the workspace.
<source>.<collection>.stats()Report the collection metadata the connector provides. A row count is an estimate, and any size value can be unavailable.
<source>.<collection>.find([<filter>])Preview rows from one collection.

For example:

tapstate(admin@127.0.0.1:8080)> show collections warehouse
tapstate(admin@127.0.0.1:8080)> warehouse.orders.stats()
tapstate(admin@127.0.0.1:8080)> warehouse.orders.find({status: 'paid'}).sort({field: 'total', dir: 'desc'}).limit(25)

You can chain sort and limit onto find in either order:

<source>.<collection>.find([<filter>]) [.sort({field: '<field>', dir: 'asc'|'desc'})] [.limit(<rows>)]

find is a one-shot preview, not a paginated query. It returns 10 rows by default and accepts from 1 through 200 rows. It has no cursor or next-page token. When more rows remain, the CLI says so in the result footer. Without an explicit sort, the connector's natural order is not stable and is not a newest- first order.

For a connected one-shot command, quote the read expression and pass it to data-browser. Set TAPSTATE_PASSWORD in the environment when you do not want the CLI to prompt for it:

tapstate -c http://127.0.0.1:8080 -u admin data-browser \
  'warehouse.orders.find({status: "paid"}).limit(25)'

Filter rows

The CLI accepts a small, Mongo-shell-shaped filter syntax, then translates it to tapstate's own filter vocabulary. It does not forward a database query to the source.

OperatorMeaning
Bare value or $eqEqual to a value. For example, {status: 'paid'}.
$ne, $gt, $gte, $lt, $lteCompare a field with a value.
$inMatch one of a non-empty list of values.
$existsTest whether a field exists; the value must be true or false.
$containsFind a literal substring in a text field.
$and, $orCombine a non-empty list of conditions. Each $or item must be one condition.

Strings must be quoted. To apply more than one operator to the same field, use separate conditions inside $and.

Do not use {} to read every row; omit the filter instead. $regex, $where, $expr, $function, and $accumulator are not supported. Use $contains for a literal text search. Arbitrary nested Boolean groups are also not supported.

REST and MCP reads use structured field, op, and value objects rather than this CLI syntax. See the REST API preview or MCP integration when you are automating a read.

Address fields that contain dots

A dot normally selects a nested field. Quote and escape a dot that is part of a literal field name:

warehouse.orders.find({"price\.usd": {$gt: 10}})

For REST or MCP JSON, escape the backslash for JSON as well:

{
  "filter": {
    "field": "price\\.usd",
    "op": "gt",
    "value": 10
  }
}

You can filter a literal dotted field, but the read evaluates every row. You cannot sort by one; the server returns data-browser.unorderable-field.

Watch one row or tail collection changes

Use watch for an in-place view of the first matching row, or tail for an append-only stream of collection changes:

CommandBehavior
watch <source>.<collection> [<filter>]Refreshes one row in place about once per second. It requires an interactive terminal.
tail <source>.<collection> [<filter>]Writes inserts, updates, and deletes as they reach the source store. It works in a pipe or redirected output.

For example:

tapstate(admin@127.0.0.1:8080)> watch warehouse.orders {status: 'paid'}
tapstate(admin@127.0.0.1:8080)> tail warehouse.orders {status: 'paid'}

Press Ctrl+C to stop either command. watch returns cli.watch-needs-a-terminal with exit code 3 when its output is not a terminal; use tail for a pipeable stream or find for a one-shot read.

tail shows changes written to the store, so rapid intermediate updates might not appear separately. A follow that has no displayed change for 10 minutes is closed; run tail again to resume watching. A filter limits the events shown by the command. It does not modify the source or pipeline.

MCP integration

Use tapstate mcp when an MCP-compatible host needs to call a running tapstate server. The command starts a local stdio gateway; it does not start the server or open an interactive CLI prompt. See the MCP integration reference for host configuration, authentication, tools, and troubleshooting.

Apply and inspect resources

CommandPurpose
apply [path] [--if-match <hash>]Interpolate local environment variables and create or update one resource or the whole workspace. For a single existing resource, --if-match declares the content hash of the version being edited; it is not a batch-workspace precondition.
delete <id> [--if-match <hash>] [-o text|json|yaml]Permanently remove one stored artifact. When supplied, --if-match must match the artifact's current content hash.
get <id>Read one stored resource.
ls [kind]List stored resources, optionally by kind: source, pipeline, transform, view, or serve.
connectors [-o text|json|yaml]List registered connectors.
register <path> [-o text|json|yaml]Upload one connector JAR, or all direct *.jar children of a directory.

apply reports each resource as created, updated, or unchanged. Connector registration is idempotent for the same artifact.

Apply can run checks that need discovered source metadata. For example, dsl.upsert-needs-key means a selected source table written with upsert has no primary key in its discovered schema. Discover the source again and select a keyed table, or choose append only for insert-only delivery. See Choose a write mode.

For delete, omitting --if-match makes the CLI read the current artifact and use that version for the removal. Supplying a hash pins a version already held by the caller; a stale hash is refused instead of overwriting a newer version. Deletion is irreversible. The CLI get command prints the artifact content, not its hash; use the REST or MCP representation when you need to supply an explicit hash.

Manage machine tokens

An authenticated administrator can create, list, and revoke machine tokens from the REPL:

CommandPurpose
token create --scope <read|write|admin> [-o text|json|yaml]Create a machine token. The bearer value is returned once.
token list [-o text|json|yaml]List token IDs, scopes, creation times, and revocation state without bearer values.
token revoke <token-id> [-o text|json|yaml]Revoke a machine token.

Use the narrowest scope required by the integration. Store a newly created bearer value in a secret manager or process environment; it cannot be retrieved later.

Test and discover connections

CommandPurpose
test <connection-id> [-o text|json|yaml]Run a connection test and render its result.
test-result <connection-id> [-o text|json|yaml]Read the latest stored test result without rerunning the test.
discover-schema <connection-id> [-o text|json|yaml]Discover source objects using a stored connection.
schema <connection-id> [table] [-o text|json|yaml]Read the stored discovered schema, optionally for one table.

A successful resource validation does not establish network reachability, authentication, or data movement. Test the connection from the server environment before starting a pipeline.

Control and observe a pipeline

CommandPurpose
start <pipeline-id>Start a pipeline.
stop <pipeline-id>Stop a pipeline.
pause <pipeline-id>Pause a running pipeline.
resume <pipeline-id>Resume a paused pipeline.
status <pipeline-id>Read current pipeline and node state.
status <pipeline-id> --watchStream lifecycle changes until interrupted.
metrics <pipeline-id>Read current pipeline and per-table metrics or offsets.
logs <pipeline-id>Read recent node-local logs.
logs <pipeline-id> --followStream node-local logs until interrupted.
snapshot <pipeline-id>Read the current snapshot view when one is available.

Use Ctrl+C to end status --watch or logs --follow. This ends the local stream, not the pipeline.

Status and metrics report observed state and can lag a lifecycle command briefly. In this preview, snapshot may report that no snapshot is available; do not use that response alone as proof that a data path succeeded or failed.

Structured output

The offline commands validate, new, ls, desc, and explain support:

-o text
-o json
-o yaml

In a connected session, structured output is available for delete, token, test, test-result, discover-schema, schema, register, and connectors. Lifecycle, status, metrics, logs, and apply commands use their command-specific text output.

Successful command output is written to standard output. Text-mode usage and diagnostic messages are written to standard error. When -o json or -o yaml is selected, the structured result, including validation diagnostics, is written to standard output so automation can parse one stream and use the exit code for success or failure.

Exit codes

CodeMeaning
0The command completed successfully.
1A coded domain diagnostic was returned or the operation was refused.
2The command line or operand usage is invalid.
3The operation is unavailable in the current context, not connected, or not implemented.

Automation should check the exit code instead of matching human-readable output.

Commands not implemented in the current preview

The top-level help lists run, export, diff, and edit as reserved verbs. They return exit code 3. Do not build a workflow that depends on them.

On this page