---
title: "Operate Your AI Catalog from the Terminal: Introducing the Pixeltable CLI"
date: "2026-06-12"
author: "Pierre Brunelle"
tags:
  - CLI
  - Developer Tools
  - Pixeltable
  - Deployment
  - HTTP Serving
  - Version Control
  - Agents
  - Multimodal AI
  - Production AI
description: "Define pipelines in Python once, then inspect tables, debug computed columns, roll back versions, script with JSON, and expose HTTP endpoints—all from the pxt command. No custom admin UI required."
url: "https://pixeltable.com/blog/pixeltable-cli-operate-catalog-from-terminal"
---

# Operate Your AI Catalog from the Terminal: Introducing the Pixeltable CLI

**Summary:** Pixeltable 0.6.5 shipped a first-class `pxt` CLI for catalog operations. Define your schema and computed columns in Python once; then use the terminal to list tables, peek at rows, inspect failed computed cells, roll back versions, and emit machine-readable JSON for agents. Serving is now one `app.py`: `TableModel` plus `FastAPIRouter`, applied with `pxt schema update` and served locally with `pxt service update`. A local daemon keeps commands fast (~40 ms after the first invocation), and `--json` output makes the CLI a stable interface for automation and AI assistants.

 
## You Defined the Pipeline in Python. Now What?

 
Most Pixeltable projects follow a familiar pattern: you create tables and views, attach computed columns for embeddings or LLM calls, add embedding indexes, and wire up `@pxt.query` functions for retrieval. That declarative Python layer is where the hard design work happens.

 
Then day-two operations begin. You need to answer questions like:

 

 - Did the new documents get chunked and embedded?

 - Which rows failed on the vision column—and why?

 - What changed between yesterday's schema and today's?

 - Can I expose this table as an HTTP endpoint without writing FastAPI boilerplate?

 

 
Jumping back into a REPL or building a one-off admin dashboard for every project does not scale—especially when [AI agents and coding assistants](/blog/designing-software-for-llms-as-customers) need stable, machine-readable ways to inspect your catalog.

 
The `pxt` CLI closes that gap. It ships with the `pixeltable` package and covers two surfaces:

 

 - **Catalog operations** — inspect, query, mutate, and version tables, views, and directories

 - **Service deployment** — declare `FastAPIRouter` routes in `app.py`, then `pxt service update` against a local dir or `pxt://`. `pxt service run` is local only

 

 
Full reference: [CLI documentation](https://docs.pixeltable.com/platform/cli). Step-by-step cookbook: [Working with the Pixeltable CLI](https://docs.pixeltable.com/howto/cookbooks/core/working-with-cli).

 
## Fast by Design: The Catalog Daemon

 
On the first catalog command, `pxt` auto-starts a long-lived local daemon bound to `127.0.0.1:22089` (override with `PXT_PORT`). The daemon survives across shell sessions, so subsequent commands avoid repeated Python startup—typically ~40 ms per call after the warm-up.

 
```bash
pip install -U pixeltable
pxt --help
pxt health
```

 
`pxt health` always returns JSON with version, PID, and configured paths. For runtime stats (table count, error count, media directories), use `pxt status`.

 
For HTTP serving, install the optional extra:

 
```bash
pip install 'pixeltable[serve]'
```

 
## Example 1: Inspect the Catalog

 
Suppose you have a video pipeline with a table and a frame view. In Python you might define:

 
```python
import pixeltable as pxt
from pixeltable.functions.video import frame_iterator

pxt.create_dir('cli_demo')
videos = pxt.create_table('cli_demo/videos', {'video': pxt.Video, 'title': pxt.String})
frames = pxt.create_view(
 'cli_demo/frames',
 videos,
 iterator=frame_iterator(videos.video, fps=1),
)
frames.add_computed_column(thumb=frames.frame.thumbnail((320, 180)))
videos.insert([{'video': 'sample.mp4', 'title': 'Demo'}])
```

 
From the terminal, explore without writing more Python:

 
```bash
# List entries with column counts, versions, and flags (c=computed, i=index)
pxt ls -l cli_demo

# Schema for the source table
pxt describe cli_demo/videos

# Computed columns on the frame view
pxt columns cli_demo/frames --computed

# Embedding and B-tree indexes
pxt idxs cli_demo/frames
```

 
Sample `pxt ls -l` output:

 
```text
path kind cols version flags
cli_demo/frames view 6 2 c
cli_demo/videos table 2 1 i
```

 
This is the fastest way to verify that your [computed column graph](/blog/dependency-graph-magic-computed-columns) materialized as expected after an insert or schema change.

 
## Example 2: Query Rows and Debug Failures

 
Catalog query commands read stored cells. Unstored computed columns are skipped by default—pass them explicitly with `--cols` when you want to force evaluation (which may invoke LLMs or expensive compute).

 
```bash
# Row count
pxt count cli_demo/frames

# First row, selected columns (thumbnails may compute on first access)
pxt rows cli_demo/frames -n 1 --cols pos,thumb

# Primary-key lookup when the table declares a PK
pxt get cli_demo/failures 42 --cols k,result
```

 
When a **stored** computed column fails, Pixeltable records the error on the row. Find every failure from the terminal:

 
```bash
pxt errors cli_demo/failures
pxt errors cli_demo/failures --col result
```

 
This is invaluable in production: partial API failures do not corrupt your table, and `pxt errors` gives you the primary keys to retry exactly where things broke—a pattern we covered in [rate limiting and graceful failure handling](/blog/rate-limiting).

 
## Example 3: Version History and Revert

 
Every insert and schema change creates a new table version. Pixeltable's [time travel and versioning](/blog/pixeltable-versioning-time-travel) are not just Python APIs—you can inspect and roll back from the CLI.

 
```bash
# Timeline of recent versions
pxt history cli_demo/videos -n 5

# Undo the last operation (irreversible—check history first)
pxt revert cli_demo/videos -f

# Roll back three consecutive versions
pxt revert cli_demo/videos --steps 3 -f
```

 
Destructive mutations (`drop`, `rm`, `revert`) prompt `[y/N]` in interactive terminals. In CI or agent scripts, pass `-f` to skip confirmation. Use `-n` / `--dry-run` to preview mutations without executing them.

 
## Example 4: Agent-Friendly Scripting with --json

 
Most inspection, query, and mutation commands accept `--json` for stable, machine-readable output. That makes the CLI a natural companion to the [Pixeltable MCP server](/blog/pixeltable-mcp-developer-edition-launch) and other agent harnesses: Python defines the pipeline; agents operate the catalog through predictable JSON.

 
```bash
pxt ls cli_demo --json | jq '.entries[] | select(.kind == "table")'
pxt count cli_demo/frames --json | jq '.count'
pxt rows cli_demo/frames -n 1 --cols pos --json
```

 
In Python scripts, shell out once and parse:

 
```python
import json
import subprocess

def pxt_json(*args: str) -> object:
 return json.loads(subprocess.check_output(['pxt', *args, '--json'], text=True))

tables = [
 e['path'] for e in pxt_json('ls', 'cli_demo')['entries']
 if e['kind'] == 'table'
]
frame_count = pxt_json('count', 'cli_demo/frames')['count']
print(tables, frame_count)
```

 
For many commands in one session, `pxt shell` keeps the daemon warm and errors from one command do not kill the REPL:

 
```bash
pxt shell
pxt> ls cli_demo
pxt> count cli_demo/frames
pxt> exit
```

 
Check configuration and credentials (values show as `<redacted>` when set):

 
```bash
pxt config --section openai
pxt status --sizes --json
```

 
## Example 5: HTTP Endpoints From the Same File

 
Declare `FastAPIRouter` routes in `app.py` next to the tables. `pxt schema update` creates the catalog; `pxt service update` starts local HTTP with OpenAPI docs at `/docs`. Preview the service plan without starting a process:

 
```bash
pxt service example --out app.py
pxt schema update app.py cli_demo
pxt service diff app.py cli_demo --json
```

 
Then serve and call an insert route:

 
```bash
pxt service update app.py cli_demo
pxt service list
# cli_demo/video-api http://127.0.0.1:49213

curl -X POST http://127.0.0.1:49213/videos \
 -H 'Content-Type: application/json' \
 -d '{"video": "https://example.com/sample.mp4", "title": "Demo"}'

pxt count cli_demo/frames
```

 
Same file on Cloud: `pxt db update pxt://org:db`, then `pxt schema update app.py pxt://org:db`, then `pxt service update app.py pxt://org:db`. `pxt service run` is local only. See the [HTTP Serving guide](https://docs.pixeltable.com/howto/deployment/serving) and our [application templates for agents](/blog/shipping-application-templates-for-ai-agents).

 
## Command Map at a Glance

 
| Category | Commands | Typical use |
| --- | --- | --- |
| Inspection | ls, describe, columns, computed, idxs, history, status, config | Schema discovery, index audit, config check |
| Query | rows, get, count, errors | Peek at data, PK lookup, failure triage |
| Mutation | drop, rm, rename, mv, revert | Catalog housekeeping, rollbacks |
| Interactive | shell | Multi-step exploration sessions |
| Serving | service, schema | Local HTTP from app.py; hosted tables via pxt schema update |
| Lifecycle | daemon, dashboard, health | Daemon control, browser UI, health probe |

 
Universal flags worth memorizing: `--json` (machine output), `-f` (skip confirmation on destructive ops), `-n` / `--dry-run` (preview mutations on `schema` and `service` update/prune).

 
## Where the CLI Fits in Your Stack

 
The CLI does not replace the Python SDK—it operationalizes it.

 

 - **Python SDK** — define tables, views, computed columns, and queries ([schema-driven infrastructure](/blog/schema-driven-infrastructure-ai))

 - **pxt CLI** — inspect, debug, script, and serve that catalog from the terminal

 - **MCP server** — expose the same operations to Claude, Cursor, and other agents conversationally

 - **Pixeltable Cloud** — managed org/database/dashboard layer for teams ([organization and collaboration](/blog/enterprise-directory-organization-team-collaboration))

 

 
If you are building agents whose session state must be durable and queryable, pair the CLI's inspection commands with the patterns in [agents as data: the session log as system of record](/blog/agents-as-data-session-log-system-of-record)—define the log in Python, operate and debug it from `pxt`.

 
## FAQ

 
### Do I need a separate install for the CLI?

 
No. `pxt` ships with `pip install pixeltable`. HTTP serving requires `pip install 'pixeltable[serve]'`.

 
### Why is there a daemon?

 
Catalog commands talk to a local daemon so each invocation stays fast (~40 ms after warm-up) instead of paying Python import and catalog connect costs on every call.

 
### Which commands support --json?

 
Inspection, query, and mutation catalog commands, plus the `schema` and `service` verbs, `db`, `org`, and `daemon status`. Exceptions: `shell` (interactive), `health` (always JSON), and `dashboard` (opens a URL).

 
### How is pxt service different from FastAPIRouter in Python?

 
They are the same contract. `FastAPIRouter` in `app.py` declares the routes; `pxt service update` runs that file against a local catalog or a `pxt://` database. `pxt service run` is local only. See the [serving guide](https://docs.pixeltable.com/howto/deployment/serving).

 
### Can AI agents use the CLI directly?

 
Yes. Stable `--json` output is designed for scripting and agent workflows. For conversational access, the [Pixeltable MCP server](/blog/pixeltable-mcp-developer-edition-launch) wraps catalog operations for Claude and Cursor; the CLI is the same surface in terminal form.

 
## Get Started

 

 - `pip install -U 'pixeltable[serve]'`

 - Define a table or view in Python (or use an existing catalog)

 - Run `pxt ls -l` and `pxt describe your_table`

 - Scaffold with `pxt service example --out app.py`, then `pxt schema update` and `pxt service update`

 - Read the [CLI reference](https://docs.pixeltable.com/platform/cli) and the [Working with the CLI cookbook](https://docs.pixeltable.com/howto/cookbooks/core/working-with-cli)

 

 
Define once in Python. Operate everywhere from the terminal.