sqlrooms CLI
Launch a local SQLRooms DuckDB project for adding data, authoring documents, and building Mosaic charts and dashboards.
Quick start
uvx sqlrooms ./sqlrooms.db
The sqlrooms distribution includes the CLI, UI, and reusable Python runtime.
See migration instructions before upgrading an environment that
contains the former sqlrooms-server distribution.
What happens:
- Runs one ASGI server: HTTP, DuckDB WebSockets at
/ws/duckdb, the browser bridge at/ws/mcp-bridge, and optional HTTP MCP at/mcpshare one port. - Serves the SQLRooms document UI on
http://localhost:3000, or the next free port, and opens your browser (disable with--no-open-browser). - Drag-and-drop CSV, TSV, JSON, Parquet, and DuckDB files to load them into DuckDB; files are uploaded to a local
sqlrooms_uploadsfolder and referenced by path. - UI state is stored in the SQLRooms meta namespace (default
__sqlrooms) of the selected DuckDB file.
Map basemaps
Maps use OpenFreeMap vector tiles with Positron for light mode and Dark for dark mode. No API key or registration is required.
New maps keep the light/dark style matching the app theme at creation, including after theme changes and workspace reloads. Change the saved style through Map settings → Basemap. Existing custom map styles are preserved.
CLI flags
DB_PATH(positional): DuckDB project file to load/create (e.g.sqlrooms ./my.db). Required unless--db-pathis provided.--version: Print the installedsqlroomsCLI version and exit.--db-path: DuckDB database to use as a flag alternative. Pass a filepath to persist, or:memory:for an explicit temporary in-memory session.--host/--port: HTTP host/port for the UI. The default bind address is127.0.0.1. If--portis omitted,3000or the next free port is chosen automatically.--ws-portand--mcp-port: Removed. Use--portfor all transports; old flags fail with migration guidance.--profile: Select a complete production capability profile:default,experimental, ordocument-charts-maps.--experimental: Compatibility alias for--profile experimental.--experimental-sync: Enable experimental sync (CRDT) over WebSocket (Loro). Requires theexperimentalprofile.--ai-devtools: Enable the AI session devtools button in the UI, including production-built UI bundles. Can also be set withSQLROOMS_AI_DEVTOOLS=1.--debug: Enable verbose debug logging, including HTTP access logs and DuckDB query timing.--meta-db: Optional path to a dedicated DuckDB file for SQLRooms meta tables (UI state + CRDT snapshots). If omitted, meta tables are stored in the main DB.--meta-namespace(default__sqlrooms): Namespace for SQLRooms meta tables. If--meta-dbis provided, used as ATTACH alias; otherwise used as a schema in the main DB.--no-open-browser: Skip automatically opening the browser tab.--ui: Optional path to a custom UI bundle directory (a Vitedist/). If omitted, uses the bundled default UI.--no-ui: Serve the same runtime/API without UI assets, equivalent tosqlrooms server --db-path ....--mcp: Enable/mcpon the shared listener, backed by the live browser room.--config: Path to a SQLRooms TOML config file. Defaults to~/.config/sqlrooms/config.toml(%APPDATA%\sqlrooms\config.tomlon Windows).--no-config: Disable config file loading.
Read-only artifact, document-block, and dashboard-panel image tools are always available in the CLI UI. Using their image results requires a vision-capable model and a provider that supports image tool results.
The server requires a loopback bind host. An explicitly configured development or external proxy must preserve the authenticated Host/Origin boundary.
The MCP listener uses the official stateless Streamable HTTP transport. The
browser must remain open and initialized because the live room owns the tool
catalog and execution state. Every MCP SQL query requires an allow-once dialog
in that browser. This approval and the one-statement SELECT check are not a
SQL sandbox; only approve SQL from a client and request you trust.
There is intentionally no sqlrooms add, sqlrooms import, or
sqlrooms doctor command in the first public CLI. Drag-and-drop import is the
supported first-launch path, and the release smoke checklist below covers the
doctor-style checks for now.
Data persistence
Tables created in the selected DuckDB file (or attached meta DB if --meta-db is provided):
__sqlrooms.ui_state(one row:key='default')__sqlrooms.sync_rooms(only used when--experimental --experimental-syncis enabled)
Uploads go to /api/upload. Runtime config for the UI is exposed at /api/config / /config.json.
Manual smoke test
Use this to prove the first-launch path:
uvx sqlrooms \
--no-open-browser \
./smoke.duckdb
Then open the printed UI URL and verify:
- The app starts without a database connection error.
- Dragging a small CSV file into the data panel creates a table.
- The uploaded CSV lands next to
smoke.duckdbundersqlrooms_uploads/. - The data sidebar shows
main.carsand does not show SQLRooms internal metadata. - A document is created or selected automatically and contains a
carsdata-table explorer block. - Users can create document and dashboard artifacts from the
Newmenu without enabling--experimental. - Map, notebook, canvas, app, HTML app, pivot, and SQL query surfaces stay hidden unless
--experimentalis provided. - Restarting the same command with
./smoke.duckdbrestores the imported table and persisted workspace state.
Config file
sqlrooms reads the app capability profile, AI provider settings, and connector
settings from a TOML config file.
AI settings changed in the CLI UI are saved back to this file automatically
when config loading is enabled and the config file is writable:
- macOS / Linux:
~/.config/sqlrooms/config.toml - Windows:
%APPDATA%\sqlrooms\config.toml
Override with --config <path>, or disable with --no-config.
Example config file:
[app]
profile = "default"
[ai]
default_provider = "openai"
default_model = "gpt-5"
[[ai.providers]]
id = "openai"
base_url = "https://api.openai.com/v1"
api_key_env = "OPENAI_API_KEY"
models = ["gpt-5", "gpt-4.1"]
[[ai.providers]]
id = "anthropic"
base_url = "https://api.anthropic.com"
api_key_env = "ANTHROPIC_API_KEY"
models = ["claude-4-sonnet"]
[[ai.custom_models]]
model_name = "local-qwen"
base_url = "http://localhost:11434/v1"
api_key = "local-key"
[ai.model_parameters]
max_steps = 12
additional_instruction = "Prefer short answers."
[[db.connectors]]
id = "postgres-local"
engine = "postgres"
title = "Postgres Local"
host = "localhost"
port = "5432"
database = "postgres"
user = "postgres"
password = "postgres"
[[db.connectors]]
id = "snowflake-prod"
engine = "snowflake"
title = "Snowflake Prod"
account = "your-account"
user = "your-user"
password = "your-password"
warehouse = "your-warehouse"
database = "your-database"
schema = "your-schema"
role = "your-role"
authenticator = "externalbrowser"
[[db.connectors]]
id = "snowflake-dev"
engine = "snowflake"
title = "Snowflake Dev"
account = "your-dev-account"
user = "your-dev-user"
warehouse = "your-dev-warehouse"
Server-only mode (no UI)
Use the consolidated distribution and the same authenticated app:
uvx sqlrooms server --db-path ./sqlrooms.db --port 4000
Connect to ws://127.0.0.1:4000/ws/duckdb using the private native
credential handoff described in AUTHENTICATION.md.
No UI assets are required in this mode. MCP tools still require an owning browser;
server-only mode does not make them headless. Use ./server to open a database
literally named server, as with ./agent.
Backend connectors (DbSlice bridge)
Use these modes to run remote queries through backend connectors and materialize results into core DuckDB for downstream notebook cells.
Install optional connector dependencies first:
uv tool install "sqlrooms[connectors]"
# or install just one connector:
uv tool install "sqlrooms[postgres]"
uv tool install "sqlrooms[snowflake]"
Postgres
uvx sqlrooms \
./sqlrooms.db \
--port 3000
Snowflake
uvx sqlrooms \
./sqlrooms.db \
--port 3000
What this enables:
sqlroomsexposes connector bridge endpoints under/api/db/*.- Runtime connector metadata is exposed via
/api/config, so frontendDbSliceauto-registers available backend connections. - Notebook SQL cells can select Postgres/Snowflake connectors from the connector dropdown.
- Arrow payloads are materialized into DuckDB and can be queried downstream in the same session.
Notes:
- Configure connectors in
sqlrooms.tomlusing[[db.connectors]]entries. - Connector libraries are optional extras (
postgres,snowflake, orconnectors).
Interactive Claude Code workspace
# Claude must already be installed and authenticated (claude auth login).
# Options precede the positional database path, following the CLI's parser.
sqlrooms --claude --profile document-charts-maps ./my-project.duckdb
--claude enables MCP and external execution mode, opens the browser, waits up
to 90 seconds for its authenticated workspace bridge, then runs a normal
interactive Claude terminal session with inherited stdin/stdout. DuckDB opens an
existing database or creates a missing file, just as in normal CLI startup;
:memory: is also supported for a temporary workspace. A terminal is required.
--no-open-browser is supported if you
open the temporary single-use link printed on the interactive terminal; --no-ui is incompatible. No SQLRooms AI
configuration is needed (--no-config is optional).
Claude retains its own authentication and model preferences. The launcher loads
the bundled native plugin and session-only MCP configuration; it does not edit
Claude's global configuration or select an evaluation model. Use
/sqlrooms:sqlrooms to load the document/chart/map workflow. Only this session's
SQLRooms MCP server is attached. The child receives a private credential-file path;
a scoped header helper reads it to authenticate MCP. Tokens never appear in command
arguments or shared agent configuration. See local authentication
for browser launch tickets, native clients, expiry, and platform support.
The browser owns the workspace. Keep it open; manually edited content is visible
through MCP. Verified reads of workspace tables run without a prompt. External or unverified
SELECTs and database-writing commands require per-request browser approval.
Use db.import-file to materialize local CSV/Parquet/JSON files and
db.create-table-from-query for derived tables; both preserve existing tables
unless replacement is explicit. The CLI does not expose room.add-url-data-source.
See data import and approvals.
Commands retain their existing validation. Disconnects fail pending operations;
the launcher reports disconnect/reconnect without replaying edits. On Claude
exit or cancellation, the launcher stops the HTTP/MCP listeners and reaps its
Claude child. It does not close browser windows or terminate unrelated sessions.
The DuckDB backend thread shares the launcher process lifetime, as in ordinary
CLI launches. Forced termination of arbitrary Claude-spawned descendants is not
claimed; Claude owns its native tool/subagent lifecycle.
For a browser managed by another client, use
sqlrooms --execution-mode external --mcp ./existing.duckdb. Execution mode is
independent of --profile. External mode composes no SQLRooms AI, AI-settings,
or artifact/chat slice. Existing saved conversations and settings pass through
workspace persistence unchanged until embedded mode is used again. This retains
the existing persistence mechanism; it is not a new durability guarantee.
pnpm --filter sqlrooms-python build:ui prepares both the UI bundle and the plugin
from the canonical CLI skill. Plugin generation runs after the cached UI build,
so this step also supports CI and deployment paths that invoke uv build directly.
pnpm --filter sqlrooms-python build prepares these assets, then packages and
verifies them in the wheel. No marketplace installation or publication is needed.
See the verification record
for tested behavior and outstanding real-Claude authentication requirements.
All CLI listeners require authentication, including localhost callers. Public base URLs show a bootstrap recovery screen. See local authentication for the private native credential file and development proxy configuration.
Agent-managed workspaces
Run sqlrooms agent setup --client claude-desktop or --client claude-code to
preview one-time integration. The stable sqlrooms agent connect MCP adapter can
list saved projects, create named persistent workspaces, reuse live browsers, and
reopen by saved workspace ID. sqlrooms agent status reports redacted diagnostics.
Claude Code setup offers a recommended trust option for the known SQLRooms MCP
tools, avoiding duplicate Claude prompts while retaining SQLRooms browser approvals.
Use --no-trust-tools to opt out; existing user permissions and restrictions are
preserved. See tool permissions.
See agent-managed workspaces for setup, profiles, explicit instance routing, recovery, lifecycle, and current verification limitations.
Reusable ASGI runtime
The core imports no CLI, UI assets, profiles or sync implementation unless enabled:
from pathlib import Path
from sqlrooms.server.access import LocalAccess
from sqlrooms.server.app import create_app, UVICORN_OPTIONS
from sqlrooms.server.runtime import DuckDBRuntime
from sqlrooms.server.security import TransportSecurity
access = LocalAccess()
runtime = DuckDBRuntime("analysis.duckdb", Path("./storage"), extensions=[])
security = TransportSecurity(access, {"http://127.0.0.1:3000"}, {"127.0.0.1:3000"})
app = create_app(runtime, security, title="My analysis app")
# uvicorn.run(app, host="127.0.0.1", port=3000, **UVICORN_OPTIONS)
create_app(..., configure=callable, lifespan=async_context_manager) lets the caller
register application routes/assets after protocol routes and attach resources to
the shared lifespan. sync_enabled=True opts into CRDT. The caller provides its
own credential delivery; never embed the native token in browser source or URLs.
DuckDBRuntime.start(), run_db_task(callable, query_id=...), cancel_query(id),
ready, and close() own the database, per-operation cursors and executor.
Cancellation is best effort and never promises to undo committed statements.
Run one Uvicorn worker per writable workspace. Limits: 128 MiB input frames, 128 MiB/64 outgoing messages per connection (including the in-flight frame), 32 pending operations/128 MiB retained input per connection, 64 database operations, and 64 connections including authentication handshakes. Overflow closes the affected slow client with 1013; sends time out after 15 seconds. WebSocket compression is explicitly disabled because large-frame compression blocks the shared event loop and delays control traffic. Ping interval and timeout are 20 seconds. Results are reauthorized before enqueue and send. Metadata and final checkpoint errors propagate instead of reporting a save. Loro stays installed to preserve the tested sync path; disabled sync initializes no Loro documents or background tasks. Pandas remains required for JSON encoding.
Alternate local applications
sqlrooms.agent.settings.ApplicationSettings is the explicit boundary for
application identity, storage roots, managed launch policy and the browser tool
contract. Pass one settings instance to Catalog, Manager (via its catalog),
Runtime, Connector, and registry/development-launch helpers. Defaults preserve
SQLRooms profiles, paths and commands. A fixed alternate application can provide
an empty profile tuple, its own product/environment prefix and generated tool
contract. No global environment rewriting is needed; identities and registry
verification include the product as well as contract compatibility.
sqlrooms.server.bootstrap.register_bootstrap_routes installs the shared ticket
exchange, renewal and native bootstrap routes. The composing application still
must enforce the operation-specific TransportSecurity checks in middleware.
create_app(..., distribution="sqlrooms") controls /version metadata; alternate
applications supply their own installed distribution name.
DuckDBRuntime(..., sync_storage=False) skips creation of CRDT storage tables;
combine it with create_app(..., sync_enabled=False) to omit sync initialization
and routes. Neither setting removes installed Python dependencies.
Roomie under python/roomie is a concrete alternate composition. It owns its
application UI/routes and __roomie metadata, while reusing the server, access,
MCP and managed-lifecycle implementations. The two applications are tested in one
process to prevent identity or storage leaks.
Release files for sqlrooms 0.1.6
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| sqlrooms-0.1.6.tar.gz | 7.8 MB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| sqlrooms-0.1.6-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 15.0 MB
Release files / sqlrooms-0.1.6.tar.gz
| Download URL | sqlrooms-0.1.6.tar.gz |
|---|---|
| Size | 7.8 MB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
3b3d99e0aa4a3874c640a9e2772090ef5bcda9f98bd832ce84718c6bac9bba90
|
|
BLAKE2b-256 checksum How to use checksums |
44305ce436b761c48e40f51a0ee075110c5b885d71e8ce8e70d88d4376e575e1
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.11
|
Release files / sqlrooms-0.1.6-py3-none-any.whl
| Download URL | sqlrooms-0.1.6-py3-none-any.whl |
|---|---|
| Size | 7.3 MB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
518a66df52eb1bee622003025df6bb596071ec7d2290e6cc790dc7a5174ce183
|
|
BLAKE2b-256 checksum How to use checksums |
0dfd086be87c806296f193fa398134b9f871c0e4dcab991cd10376e184bb292e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.11
|