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 --helpUse tapstate help <command> or tapstate <command> --help to
inspect a command without connecting to a server.
Launch and help options
| Option | Purpose |
|---|---|
-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. |
--version | Print only the installed CLI version and exit. Use tapstate version to report both the CLI and server versions. |
--help | Print 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 connectedThe 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 workOffline 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.ymlIt 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 workFrequently used options:
| Option | Purpose |
|---|---|
--kind source|pipeline|transform|view|serve | Select 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=value | Set 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, -y | Refuse missing required answers instead of prompting. |
--dry-run | Print the generated resource without writing it. |
--force | Replace 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.modealias
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 uninstallInstalling 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 worktapstate> 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 workAfter 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:
| Command | Purpose |
|---|---|
help | Show REPL help. |
connect <host:port> | Select a server. |
disconnect | Leave the current server. |
login <username> | Authenticate to the selected server. |
logout | End the authenticated session. |
:ctx, context | Manage saved server contexts. |
auth login <username> | Sign in and save a session for the selected context. |
auth status | Report 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. |
version | Report the CLI version and the connected server version. |
cd <dir> | Change the REPL workspace directory. |
pwd | Print the current workspace directory. |
exit, quit | End 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_stateThe 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
| Syntax | Use |
|---|---|
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.
| Operator | Meaning |
|---|---|
Bare value or $eq | Equal to a value. For example, {status: 'paid'}. |
$ne, $gt, $gte, $lt, $lte | Compare a field with a value. |
$in | Match one of a non-empty list of values. |
$exists | Test whether a field exists; the value must be true or false. |
$contains | Find a literal substring in a text field. |
$and, $or | Combine 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:
| Command | Behavior |
|---|---|
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
| Command | Purpose |
|---|---|
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:
| Command | Purpose |
|---|---|
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
| Command | Purpose |
|---|---|
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
| Command | Purpose |
|---|---|
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> --watch | Stream 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> --follow | Stream 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 yamlIn 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
| Code | Meaning |
|---|---|
0 | The command completed successfully. |
1 | A coded domain diagnostic was returned or the operation was refused. |
2 | The command line or operand usage is invalid. |
3 | The 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.