tobira

package module
v1.7.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 5, 2026 License: MIT Imports: 0 Imported by: 0

README

扉  tobira

Every database, one terminal.

One CLI and terminal UI to browse, query and explain SQL, document, key-value, time-series and vector databases, with a read-only guard built in.

Go Reference CI


tobira (扉, Japanese for door) is one entry point to every database you work with: one binary, one set of keys and one connection config, whether the database is PostgreSQL, SQLite, a document store, a cache or a vector index.

tobira browsing, filtering, running a query and editing a row

Why

Every database ships its own client, with its own shell, flags and way of showing a table. You end up with five tools, five config files and five sets of habits.

With tobira you browse, query and edit all of them from one terminal app, with the same keys and commands everywhere. A read-only guard sits in front of every driver, so you can browse production without worrying about an accidental write.

AI ready. Ask questions in plain language with tobira ask or the AI panel, using Gemini, OpenAI, Anthropic or a local Ollama model. tobira mcp lets Claude Code, Cursor and other agents query the connections you choose, and an agent skill teaches your coding agent the whole CLI.

Built for scripts and CI. tobira query prints JSON, NDJSON or CSV and returns clear exit codes, and tobira doctor checks your setup in a pipeline, so the same tool works on your laptop and in CI.

Install

  • Homebrew (macOS): brew install xavidop/tap/tobira. This is a Homebrew cask, so it is macOS only.
  • Scoop (Windows): scoop bucket add xavidop https://github.com/xavidop/scoop-bucket, then scoop install tobira.
  • Linux packages: a .deb, .rpm or .apk for amd64 or arm64 from GitHub Releases, installed with dpkg -i, rpm -i or apk add --allow-untrusted. They include the shell completions.
  • Release binaries (Linux, macOS, Windows): download an archive for amd64 or arm64 from GitHub Releases, check it against checksums.txt, unpack it and put tobira on your PATH.

To build from source, see CONTRIBUTING.md. After you install, run tobira doctor to check your setup. More options are on the install page.

Quick start

tobira                                  # open the terminal UI on your configured connections
tobira connect sqlite:./app.db          # or on one connection or DSN (no config file needed)
tobira connections add                  # add a connection with a form
tobira connections add --name app --driver sqlite --dsn sqlite:./app.db   # or with flags
tobira query sqlite:./app.db "select * from users" --format table
tobira query sqlite:./app.db "delete from users" --read-only   # refused, exit code 4

Name a connection in ~/.config/tobira/config.yaml and use the name instead of the DSN:

connections:
  - name: local-pg
    dsn: postgres://app@localhost:5432/app?sslmode=disable
    password: env:LOCAL_PG_PASSWORD
    read_only: true
tobira query local-pg "select now()"

Features

  • Terminal UI. A sidebar of connections and collections, a data grid with paging, sort and filters, a row detail tree, mouse support, themes and a vim keymap.
  • Query editor. Highlighting for each dialect, completion, history, result tabs, :explain and cancellation.
  • Cross-source queries. Join rows from two or more connections, whatever their kind, in one statement: each @source runs its own native query read-only and SQLite joins them locally, from the editor or with tobira federate.
  • Inline editing. Edit, insert and delete rows, review the pending changes, then :apply them, in one transaction where the database has them.
  • Views for each kind of database. Document previews, key-value types and TTLs, time-series charts, wide-column key badges, search scores and vector similarity search.
  • Live tail. W in the TUI or tobira watch streams change events from PostgreSQL, Greenplum, MongoDB, Redis, DynamoDB, Firestore and Cosmos DB.
  • tobira query. Run one query and print a table, JSON, NDJSON or CSV, or stream a result of any size into a file with --output.
  • AI assistant. Ask questions in plain language, in the TUI or with tobira ask. See AI & MCP.
  • MCP server. tobira mcp gives an MCP client such as Claude Code access to the connections you choose.
  • Connections and secrets. Passwords are references (env:, file://, dotenv or the OS keyring), never stored in the config. Import connections from DBeaver, TablePlus or ~/.pgpass, and export them to another machine.
  • SSH tunnels. An ssh: block on a connection reaches a database behind a bastion host, with key, agent or password authentication and host keys checked against known_hosts.
  • tobira doctor. One command checks the config, connections, secrets, drivers, plugins, AI, MCP and file permissions.
  • Query history. Every query that tobira, the assistant or an MCP client runs is logged locally, with credentials masked.
  • Driver plugins. Add a database as an external tobira-driver-<name> program in any language. tobira driver install requires a --sha256 checksum.

Drivers

tobira ships thirty-two drivers in the binary, plus DuckDB as an external plugin. Elasticsearch and OpenSearch share one row but count as a driver each; pgvector is part of the PostgreSQL driver.

Driver Kind Browse Explain Vector search Time series Other capabilities Tested against
SQLite SQL yes yes (no ANALYZE) no no editing, transactions, completion, read-only guard real database
PostgreSQL SQL yes yes (ANALYZE rolled back) yes (pgvector extension) no editing, transactions, completion, export, watch, read-only guard real server
MySQL SQL yes yes (no ANALYZE) no no editing, transactions, completion, read-only guard real server
MariaDB SQL yes yes (no ANALYZE) no no editing, transactions, completion, read-only guard real server
SingleStore SQL yes yes (no ANALYZE) no no editing, completion MySQL and MariaDB (SingleStore mode)
CockroachDB SQL yes yes (ANALYZE rolled back) no no editing, transactions, completion, export, read-only guard real server
Amazon Redshift SQL yes yes (text plan, no ANALYZE) no no completion, read-only guard PostgreSQL 17 (Redshift mode)
Greenplum SQL yes yes (ANALYZE rolled back) yes (pgvector extension) no editing, transactions, completion, export, watch, read-only guard PostgreSQL 17 (Greenplum mode)
SQL Server SQL yes yes (estimated plan, never runs) no no editing, transactions, completion, read-only guard real server
Oracle SQL yes yes (estimated plan, never runs) no no editing, transactions, completion, read-only guard real server
libSQL / Turso SQL yes yes (no ANALYZE) no no editing, transactions, completion, read-only guard real server (sqld)
Cloudflare D1 SQL yes yes (no ANALYZE) no no editing, completion, read-only guard local fake of the D1 API
ClickHouse Columnar SQL yes yes (no ANALYZE) no no completion, export, read-only guard real server
BigQuery Columnar SQL yes yes (dry run: bytes and schema; no ANALYZE) no no completion, read-only guard BigQuery emulator
Snowflake Columnar SQL yes yes (EXPLAIN USING TEXT, never runs; no ANALYZE) no no editing, transactions, completion, read-only guard local fake (fakesnow)
Vertica Columnar SQL yes yes (plan only, no ANALYZE) no no editing, transactions, completion, read-only guard real server
MongoDB Document yes yes (executionStats, never applies a write) no no editing, completion, watch, read-only guard real server
Cloud Firestore Document yes no no no editing, completion, watch (snapshot listeners), read-only guard Firestore emulator
Azure Cosmos DB Document yes (continuation tokens) no yes (VectorDistance; L2, cosine, inner product; text with an embedder) no editing (ETag match), completion, watch (change feed), read-only guard Cosmos DB emulator
Redis Key-value yes no no no editing, watch, read-only guard real server
Amazon DynamoDB Key-value yes no no no editing, completion, watch (Streams), read-only guard DynamoDB Local
Cassandra Wide-column yes (paging state; tobira-side sort up to 10,000 rows) no no no editing (conditional writes), completion, read-only guard real server
Neo4j Graph yes (offset pages over a label) yes (EXPLAIN; PROFILE runs it) no no graph neighbourhood, read-only guard (server-enforced) real server
Elasticsearch / OpenSearch (2 drivers) Search yes (search_after on a point in time) yes (_validate/query, never runs; ANALYZE runs the search with profiling) Elasticsearch: yes (kNN on dense_vector, exact script_score for other metrics; text with an embedder); OpenSearch: no no editing, read-only guard real servers
InfluxDB Time series yes no no yes (windowed ranges, SQL or InfluxQL) read-only guard real server
Qdrant Vector yes no yes (per-vector metric, text with an embedder) no editing, read-only guard real server
pgvector (part of PostgreSQL) Vector yes yes yes (L2, cosine, inner product; text with an embedder) no read-only guard real server
GitHub API yes (page cursors; server-side filters where GitHub has them, the rest in tobira) yes (the requests a query would send, never sent) no no editing, completion, read-only guard local fake of the GitHub REST API
Pinecone Vector yes (list order; tobira-side filters, sort up to 10,000 records) no yes (index metric, text with an embedder) no editing, read-only guard Pinecone Local
Weaviate Vector yes (cursor API; offset pages when filtered or sorted) no yes (per-vector metric, text with an embedder) no editing, read-only guard real server
Chroma Vector yes (Chroma's order; tobira-side sort up to 10,000 records; server-side filters) no yes (collection's space, text with an embedder) no editing, read-only guard real server
Milvus Vector yes (primary-key order; sorted by tobira up to 10,000 entities) no yes (index metric; text via BM25/TEXTEMBEDDING functions or an embedder) no editing, read-only guard real server (2.6 standalone)
DuckDB (plugin) SQL yes yes (EXPLAIN; ANALYZE runs it, on read-only paths only for reads) no no editing, transactions, completion, read-only guard real database

Compatibility. "Real server" means the database itself. A driver tested against an emulator or a local fake has not yet been tested against the cloud service. Redshift and Greenplum are tested by running the PostgreSQL suite in Redshift or Greenplum mode, and SingleStore by running the MySQL and MariaDB suites in SingleStore mode; none has been tested against a real cluster yet. The read-only guard of the MySQL family needs MySQL 8.0 to 8.4 or MariaDB 11.1 to 11.x.

DuckDB is an external plugin, not part of the binary. The DuckDB page shows how to download it from its GitHub release or build it from source.

Read-only guard means a query run read-only cannot write, whatever its text says. SingleStore has no read-only transaction, so tobira refuses read-only connections to it. The drivers page has each driver's DSN and options, and the security page lists what each guard cannot stop.

AI & MCP

AI assistant

Add an ai: section to the config file and pick a provider:

ai:
  provider: googleai            # googleai, vertexai, anthropic, openai or ollama
  api_key: env:GEMINI_API_KEY   # a secret reference, never the key itself
  send_rows: ask                # ask, always or never
tobira ask local-pg "orders per day last week" --collection public.orders   # proposes a query
tobira ask local-pg "the ten newest orders" --run                            # proposes, then runs it read-only
tobira ask local-pg "how many users signed up today?" --answer               # runs read-only queries
  • Where. Press a in the terminal UI, or run tobira ask.
  • What it does. It proposes a query, answers a question by running read-only queries, explains a result and fixes a failed query.
  • What it sends. The schema (never DDL), your question and, if ai.send_rows allows it, row data. never keeps rows back, but it is not a hard security boundary against a hostile model.
  • Writes. Only in the terminal UI, after :ai execute on, and you confirm each statement.

See the AI page.

MCP server

tobira mcp lets an MCP client (Claude Code, Claude Desktop, Cursor, VS Code) use your connections. Nothing is exposed until you name it:

claude mcp add tobira -- tobira mcp --expose local-pg,cache
mcp:
  expose: [local-pg, cache]   # the only connections a client can see
  allow_writes: [cache]       # a subset of expose; the rest stay read-only
  max_rows: 200               # 1 to 1000
  send_rows: always           # always or never
  • Tools. list_connections, list_namespaces, list_collections, describe, sample, query and explain, all read-only; similar when an exposed connection supports vector search; federate (one read-only query over several exposed connections) when more than one is exposed; and execute only when allow_writes is not empty.
  • Rows. send_rows defaults to always here, because nobody is there to answer a prompt. Do not expose a connection whose data must not reach the model.
  • HTTP. --http 127.0.0.1:8765 serves over HTTP with a bearer token, on loopback only unless you pass --insecure-bind.
  • History. tobira history --mcp shows what each client ran.

Setup for each client is on the MCP page. A small Go client is in examples/mcp-client.

CLI

tobira                               open the terminal UI (on a terminal)
tobira connect <connection|dsn>      open the terminal UI on one connection
tobira connections list|add|edit|rm|test|set-password|export|import   manage, export and import connections
tobira query <connection|dsn> [q]    run a query and print the result (--output writes a file)
tobira federate [q]                  run one query over several connections (--explain, --output)
tobira watch <connection|dsn> <target>   stream change events as JSON lines (--max, --timeout)
tobira ask [connection] <question>   ask the AI assistant (--run runs the proposal read-only, --answer answers)
tobira mcp --expose <names>          serve connections to an MCP client (--http for HTTP)
tobira history [clear]               list the queries tobira ran, newest first (--source, --mcp), or remove them
tobira driver list|info|install      list drivers and plugins, inspect one, install a plugin (--sha256)
tobira doctor                        check the config, connections, secrets, plugins, AI and MCP (--no-ping)
tobira version                       print the version, commit and build date

Every flag, output format and exit code is in the CLI reference.

Agent skill

Teach your AI coding agent (Claude Code, Cursor, Copilot and others) to use tobira with the agent skill. It covers every command, the MCP setup, drivers and plugins.

npx skills add xavidop/tobira

Documentation

Contributing

Contributions are welcome, especially new drivers. Run make all before you send a change. See CONTRIBUTING.md for the repository layout, how to build and test, and the commit conventions.

License

MIT © Xavier Portilla Edo

Documentation

Overview

Package tobira is the root of tobira, a terminal client for every database ("Every database, one terminal.").

The root module never depends on a database SDK. Each database lives behind the driver model defined in the driver package, and concrete drivers ship as separate modules so that importing tobira does not pull in any client library. See package driver for the contract drivers implement and package drivertest for the conformance kit.

The tobira binary (module cmd/tobira) wires the drivers, the terminal UI, the AI assistant and the MCP server together; this root module holds the driver contract, the shared helpers and the internal packages they use.

Directories

Path Synopsis
Package api is tobira's stable surface for driver plugins and embedders.
Package api is tobira's stable surface for driver plugins and embedders.
cmd
tobira module
Package driver defines the model every tobira database driver implements, and the registry that finds drivers.
Package driver defines the model every tobira database driver implements, and the registry that finds drivers.
drivers
sqlite module
Package drivertest is the conformance kit every tobira driver must pass.
Package drivertest is the conformance kit every tobira driver must pass.
driverutil
netpolicy
Package netpolicy holds the transport rules every network driver applies before it sends a credential: what counts as this machine, which hosts are a TLS-only cloud service, when plain (unencrypted) transport is allowed, and how redirects are refused.
Package netpolicy holds the transport rules every network driver applies before it sends a credential: what counts as this machine, which hosts are a TLS-only cloud service, when plain (unencrypted) transport is allowed, and how redirects are refused.
sqlcomplete
Package sqlcomplete is a dependency-free SQL completion engine shared by the SQL drivers.
Package sqlcomplete is a dependency-free SQL completion engine shared by the SQL drivers.
sqlitecore
Package sqlitecore is the SQLite dialect logic shared by the SQLite-family drivers (sqlite, libsql, d1): the read-only and single-statement guards with the PRAGMA allow-list, declared-type mapping and value conversion, rowid-alias detection from the CREATE TABLE text, catalog row parsing, mutation and browse SQL building, and EXPLAIN QUERY PLAN trees.
Package sqlitecore is the SQLite dialect logic shared by the SQLite-family drivers (sqlite, libsql, d1): the read-only and single-statement guards with the PRAGMA allow-list, declared-type mapping and value conversion, rowid-alias detection from the CREATE TABLE text, catalog row parsing, mutation and browse SQL building, and EXPLAIN QUERY PLAN trees.
sqlscan
Package sqlscan is the SQL tokenizer shared by the SQL drivers' read-only guards and by driverutil/sqlcomplete.
Package sqlscan is the SQL tokenizer shared by the SQL drivers' read-only guards and by driverutil/sqlcomplete.
internal
assistant
Package assistant defines the AI assistant the TUI and the CLI program against.
Package assistant defines the AI assistant the TUI and the CLI program against.
assistant/assistanttest
Package assistanttest provides a scriptable assistant.Assistant for the CLI and TUI tests.
Package assistanttest provides a scriptable assistant.Assistant for the CLI and TUI tests.
cli
Package cli implements the tobira command-line interface.
Package cli implements the tobira command-line interface.
config
Package config loads the tobira connection list from the YAML config file (~/.config/tobira/config.yaml by default).
Package config loads the tobira connection list from the YAML config file (~/.config/tobira/config.yaml by default).
connio
Package connio moves connections in and out of tobira: it prepares the connections `tobira connections export` prints, with every password removed, and reads the connection lists of other tools (DBeaver, pgpass, TablePlus) and of export itself into an import plan.
Package connio moves connections in and out of tobira: it prepares the connections `tobira connections export` prints, with every password removed, and reads the connection lists of other tools (DBeaver, pgpass, TablePlus) and of export itself into an import plan.
export
Package export streams a query result or a whole collection into a csv, json or ndjson file, in constant memory, through internal/query's row writers.
Package export streams a query result or a whole collection into a csv, json or ndjson file, in constant memory, through internal/query's row writers.
federate
Package federate runs one query over several connections: each source is staged with its own native query, read-only, into a scratch SQLite database, and a final SQLite statement joins them there.
Package federate runs one query over several connections: each source is staged with its own native query, read-only, into a scratch SQLite database, and a final SQLite statement joins them there.
history
Package history keeps a local log of the queries tobira ran.
Package history keeps a local log of the queries tobira ran.
mcphttp
Package mcphttp is the network policy of `tobira mcp --http`: which addresses it may bind, and the guard every request passes before it reaches the MCP server (DNS-rebinding defence, bearer token, body limit).
Package mcphttp is the network policy of `tobira mcp --http`: which addresses it may bind, and the guard every request passes before it reaches the MCP server (DNS-rebinding defence, bearer token, body limit).
plugininstall
Package plugininstall puts a driver plugin binary into the plugins directory for `tobira driver install`: from an http(s) URL or a local path, only once its sha256 matches, through a temporary file renamed into place.
Package plugininstall puts a driver plugin binary into the plugins directory for `tobira driver install`: from an http(s) URL or a local path, only once its sha256 matches, through a temporary file renamed into place.
query
Package query runs one native query against a driver.Conn and renders the result as a table, JSON, NDJSON or CSV.
Package query runs one native query against a driver.Conn and renders the result as a table, JSON, NDJSON or CSV.
secrets
Package secrets turns a config.Connection into a driver.ConnConfig with its password resolved.
Package secrets turns a config.Connection into a driver.ConnConfig with its password resolved.
secrets/keyring
Package keyring resolves keyring:<name> password references from the OS keyring (macOS Keychain, Windows Credential Manager, the Secret Service on Linux).
Package keyring resolves keyring:<name> password references from the OS keyring (macOS Keychain, Windows Credential Manager, the Secret Service on Linux).
session
Package session manages the lazily opened database connections of one tobira run.
Package session manages the lazily opened database connections of one tobira run.
sshtunnel
Package sshtunnel reaches a database through an SSH server: it opens an SSH session, listens on a loopback port and forwards each connection to the host and port the DSN names, as seen from the SSH server.
Package sshtunnel reaches a database through an SSH server: it opens an SSH session, listens on a loopback port and forwards each connection to the host and port the DSN names, as seen from the SSH server.
sshtunnel/sshtest
Package sshtest is an in-process SSH server for tests: it accepts one public key and an optional password, and serves direct-tcpip channels, which is all a tunnel needs.
Package sshtest is an in-process SSH server for tests: it accepts one public key and an optional password, and serves direct-tcpip channels, which is all a tunnel needs.
textutil
Package textutil holds small string helpers shared by internal packages.
Package textutil holds small string helpers shared by internal packages.
tui
Package tui is the Bubble Tea terminal UI for tobira.
Package tui is the Bubble Tea terminal UI for tobira.
tui/async
Package async runs driver calls off the Bubble Tea update goroutine.
Package async runs driver calls off the Bubble Tea update goroutine.
tui/chart
Package chart draws a time series as text: a sparkline on a narrow pane, an ASCII line chart with min, max and last labels otherwise.
Package chart draws a time series as text: a sparkline on a narrow pane, an ASCII line chart with min, max and last labels otherwise.
tui/click
Package click recognises double-clicks for the grid and the sidebar: a second click on the same target within a short window.
Package click recognises double-clicks for the grid and the sidebar: a second click on the same target within a short window.
tui/connform
Package connform is the add/edit connection form: a charm.land/huh/v2 form wrapped as a component the TUI embeds as an overlay and the CLI runs standalone.
Package connform is the add/edit connection form: a charm.land/huh/v2 form wrapped as a component the TUI embeds as an overlay and the CLI runs standalone.
tui/detail
Package detail is the full-pane row view: the row's columns as key/value pairs, with Object, List and JSON values as an expandable tree.
Package detail is the full-pane row view: the row's columns as key/value pairs, with Object, List and JSON values as an expandable tree.
tui/editor
Package editor is the query editor: a multi-line text buffer with a grapheme-aware cursor, a selection and chroma highlighting.
Package editor is the query editor: a multi-line text buffer with a grapheme-aware cursor, a selection and chroma highlighting.
tui/filter
Package filter is the grid's filter bar: a one-line input parsed into a driver.Filter.
Package filter is the grid's filter bar: a one-line input parsed into a driver.Filter.
tui/grid
Package grid is the virtualised data grid: a table of rows held in pages of 200, drawn with cost proportional to the visible cells only.
Package grid is the virtualised data grid: a table of rows held in pages of 200, drawn with cost proportional to the visible cells only.
tui/help
Package help renders the help overlay: the key bindings of the active keymap, then the palette commands.
Package help renders the help overlay: the key bindings of the active keymap, then the palette commands.
tui/keymap
Package keymap maps named actions to key bindings.
Package keymap maps named actions to key bindings.
tui/palette
Package palette is the ":" command line.
Package palette is the ":" command line.
tui/sidebar
Package sidebar is the connection tree: connection, then namespace, then collection.
Package sidebar is the connection tree: connection, then namespace, then collection.
tui/statusbar
Package statusbar renders the one-line bar at the bottom of the screen: breadcrumb, row position and load time, read-only badge, connection status dot and key hints.
Package statusbar renders the one-line bar at the bottom of the screen: breadcrumb, row position and load time, read-only badge, connection status dot and key hints.
tui/theme
Package theme defines tobira's colour palettes and the lipgloss styles derived from them.
Package theme defines tobira's colour palettes and the lipgloss styles derived from them.
tui/tuitest
Package tuitest holds assertions shared by the view packages' tests.
Package tuitest holds assertions shared by the view packages' tests.
plugin
convert
Package convert translates between the driver types and the plugin protocol messages in plugin/proto/tobira/plugin/v1.
Package convert translates between the driver types and the plugin protocol messages in plugin/proto/tobira/plugin/v1.
host
Package host runs external driver plugins: tobira-driver-<name> binaries that speak the tobira.plugin.v1 protocol through hashicorp/go-plugin (see plugin/sdk for the plugin side).
Package host runs external driver plugins: tobira-driver-<name> binaries that speak the tobira.plugin.v1 protocol through hashicorp/go-plugin (see plugin/sdk for the plugin side).
shared
Package shared holds what both ends of a tobira driver plugin must agree on: the go-plugin handshake (protocol version and magic cookie) and the name under which the Driver service is dispensed.
Package shared holds what both ends of a tobira driver plugin must agree on: the go-plugin handshake (protocol version and magic cookie) and the name under which the Driver service is dispensed.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL