keithn/sql

Go

1

25 commits

updated Mar 23, 2026

See the code

README

sql

A terminal SQL client for developers who live in the terminal. First-class MS SQL Server support, plus PostgreSQL and SQLite. Keyboard-driven, fast, works over SSH and inside tmux.

Go

The Experiment

This is a agentic AI coded piece of software. It is an experiment in doing everything with an AI agent and working out the best ways to develop software this way. While the version is less that 1.0.0 the software is likely to have a bunch of rough edges but my plans is to dogfood it (use it myself for real work) and have replaced using DataGrip. It is actually going really well and I find it a lot more useful than DataGrip (it is tailored to my workflows after all!). Once I think it is reasonably well polished and feature complete I will do a v1.

Features

  • Multi-database — SQL Server, PostgreSQL, SQLite (pure Go, no CGo)
  • Named/saved connections — raw DSNs, saved connections, keychain-backed passwords, last-used connection restore, and auto-reconnect on dropped connections
  • Connection management in-app — Ctrl+K switcher (with Ctrl+D to delete); Ctrl+N add-connection modal with connection-string or form-builder mode
  • Command + history palettes — Ctrl+P for app actions (including snippets), Ctrl+H for recent SQL
  • Named snippets — save/browse/paste reusable SQL blocks from the command palette
  • Smart block execution — Ctrl+E runs the logical statement under the cursor; F5 runs the full buffer
  • Transaction workflow — begin/commit/rollback from the command palette; run current block or full buffer inside a transaction; explain plans
  • Editor refactors — Ctrl+R popup: alias tables, expand SELECT *, convert SELECT↔UPDATE, IDENTITY_INSERT wrapping, tab rename
  • SQL formatting — format the active block with Ctrl+Shift+F
  • Goto line — Ctrl+G (editor and vim :42 syntax)
  • Schema-aware assistance — autocomplete, JOIN predicate inference, missing-table highlighting
  • Schema browser — Ctrl+B/F2; fuzzy filter, column selection for JOIN-aware SELECT, action menu (a), row counts (r)
  • Vim mode — toggleable; persistent across sessions; supports motions, operators, visual, undo/redo; shown in status bar
  • Results grid — virtual scrolling, column sort (s), row numbers (#), stacked column filters (f), configurable row limit (L), poll/auto-refresh (P), zoom modes (z/Z)
  • Row detail view — Enter opens a vertical column/value overlay; navigate rows with h/l
  • Row tagging — Space tags rows; V range-tag; Ctrl+A tag all/clear; tagged rows highlighted; export respects selection
  • Column selection — | toggles a column (purple header); \ opens a fuzzy column picker with multi-select; t toggles SELECTED ONLY view showing only tagged rows and/or selected columns
  • Result diff/pin — p pins the current result; re-running the same query shows added/removed/changed rows
  • Cell edit → UPDATE — e in the results grid or row detail view opens an inline cell editor (with vim mode); on confirm an UPDATE preview panel appears showing the generated SQL — execute it with Ctrl+E, copy with y, close with Esc; results refresh automatically on success; Ctrl+D sets the value to NULL
  • Export — X in results: CSV, Markdown, JSON, SQL INSERT, or WHERE IN list — honours row tags and column selection; to clipboard or file
  • Screenshot — F10 captures the current view to clipboard or file
  • MCP server mode — --mcp starts a background JSON-RPC server so Claude Code can drive the TUI as an agent
  • Multi-tab editor — Ctrl+N new tab, Ctrl+W close, Ctrl+PgDn/Ctrl+PgUp switch
  • Session restore — open tabs and cursor positions saved on quit and restored on reconnect
  • Help/settings overlay — F1 shows keybindings, state, and loaded config values
  • Lua config — %APPDATA%\sql\config.lua (Windows) / ~/.config/sql/config.lua

Installation

Download a release

Grab a pre-built binary from the Releases page and put it on your PATH.

Build from source

Requires Go 1.21+.

go install github.com/sqltui/sql/cmd/sql@latest

Or clone and build:

git clone https://github.com/sqltui/sql
cd sql
go build -o sql ./cmd/sql/

Usage

# Connect with a connection string
sql "server=1.2.3.4;user id=sa;password=...;database=mydb"

# List saved connections
sql --list

# Save a named connection
sql --add "server=1.2.3.4;user id=sa;password=...;database=mydb" --name prod

# Connect using a saved connection
sql prod

# SQLite
sql ./mydb.sqlite

# PostgreSQL
sql "postgres://user:pass@localhost/mydb"

# Start TUI with MCP socket server on port 45678
sql --mcp
sql --mcp prod

# Relay an MCP client (e.g. Claude Code) to a running TUI
sql --mcp-relay
sql --mcp-relay --mcp-port 9999

Once connected, the last-used connection is saved and restored on next launch.

Connection strings

DatabaseFormat
SQL Serverserver=host;user id=user;password=pass;database=db
SQL Serversqlserver://user:pass@host?database=db
PostgreSQLpostgres://user:pass@host/db
PostgreSQLhost=localhost user=postgres dbname=mydb sslmode=disable
SQLite./path/to/file.db or file:path/to/file.db

Passwords are never displayed in the UI.

Keybindings

Global

KeyAction
F1Help / settings overlay
Ctrl+PCommand palette
Ctrl+HQuery history palette
Ctrl+KConnection switcher
Ctrl+EExecute block under cursor
Ctrl+Shift+F / Ctrl+FFormat active block
F5Execute full buffer
F3 / Alt+1Focus editor
F4 / Alt+2Focus results
Ctrl+B / F2Toggle schema browser
Ctrl+QQuit (saves session)

Editor

KeyAction
Ctrl+NNew tab
Ctrl+WClose tab
Ctrl+PgDn / Alt+LNext tab
Ctrl+PgUp / Alt+HPrevious tab
Alt+Up / Alt+DownPrevious / next query block
Ctrl+GGoto line
Ctrl+RRefactor popup
Ctrl+\Toggle comment
TabInsert 4 spaces
Ctrl+Alt+VToggle vim mode

Refactor popup (Ctrl+R):

KeyAction
NName/alias current table
EExpand SELECT *
u / UConvert SELECT → UPDATE (or append UPDATE)
s / SConvert UPDATE → SELECT (or append SELECT)
iWrap INSERT with IDENTITY_INSERT ON/OFF
TRename current tab

Command palette (Ctrl+P) also exposes:

  • begin / commit / rollback transaction
  • run current block / full buffer in transaction
  • explain current block / full buffer
  • save current block as snippet
  • browse snippets

Results

KeyAction
↑ / ↓ or j / kScroll rows
PgUp / PgDnScroll a page
Home / EndJump to top / bottom row
← / → or h / lScroll columns
0 / $Jump to first / last column
Alt+PgUp / Alt+PgDnPrevious / next result set
EnterRow detail view (vertical)
sSort by cursor column (cycles: none → ▲ → ▼)
fFilter by cursor column (regex, stacks — add multiple)
FClear all filters
#Toggle row numbers
LChange row limit
pPin result as diff baseline (re-run to see diff)
PToggle poll / auto-refresh
SpaceTag / untag current row (advances cursor)
VRange-tag rows
Ctrl+ATag all rows / clear all tags
|Toggle current column selection (purple header)
\Column picker — fuzzy search columns; ↓/Tab enters list, Space tags, Enter applies
Ctrl+\Clear all column selections
tToggle SELECTED ONLY view — show only tagged rows and/or selected columns
eEdit cell → UPDATE preview panel
ERow edit form (multi-column UPDATE)
XExport (CSV / Markdown / JSON / SQL INSERT / WHERE IN → clipboard or file)
vOpen cell value viewer
yCopy current cell to clipboard
zZoom: shrink editor to active query block
ZZoom: results fullscreen (hides editor)
F10Screenshot to clipboard / file

Row detail view

KeyAction
j / k or ↑ / ↓Scroll fields
h / ←Previous row
l / →Next row
yCopy focused field to clipboard
eEdit focused cell → UPDATE preview panel
EscClose

Cell edit overlay

KeyAction
TypeEdit value (vim mode supported)
Ctrl+SConfirm and open UPDATE preview
Ctrl+DSet value to NULL and open UPDATE preview
EscCancel

UPDATE preview panel

KeyAction
Ctrl+E / EnterExecute UPDATE
y / Ctrl+CCopy SQL to clipboard
↑ / ↓ / j / kScroll
EscClose

Schema browser

KeyAction
TypeFilter tables
↓ / EnterMove to table list
j / kNavigate tables
EnterPaste SELECT into editor
TabSelect / deselect column
rFetch row count for selected table
aAction menu (copy name, DDL, indexes, row count)
/Return to search input
EscClose browser
Alt+← / Alt+→Resize panel

Configuration

Config file location:

  • Windows: %APPDATA%\sql\config.lua
  • macOS / Linux: ~/.config/sql/config.lua
-- config.lua
editor = {
  result_limit = 500,   -- default rows fetched per query
  vim_mode     = false, -- start in vim mode
}

theme = {
  line_number        = "#555555",
  cursor_line_number = "#aaaaaa",
}

MCP server mode

--mcp enables MCP (Model Context Protocol) support. There are two modes depending on how the process is launched:

Headless / stdio mode (for Claude Code and other MCP clients)

When stdin is a pipe (i.e. launched by an MCP client), sql --mcp runs as a headless JSON-RPC 2.0 server over stdio with no TUI. This is the mode used by .claude/mcp.json:

{
  "mcpServers": {
    "sqltui": {
      "command": "sql",
      "args": ["--mcp", "myconnection"]
    }
  }
}

Replace myconnection with a saved connection name or a raw DSN. The agent can then query the database directly.

TUI + socket mode (query building assistant)

When launched in a terminal, --mcp starts the TUI normally and also opens a TCP socket server on port 45678 (default) so an agent can drive the live TUI — reading/writing the editor, executing queries, and seeing results.

sql --mcp                        # TUI + socket on default port 45678
sql --mcp myconn                 # connect and open socket
sql --mcp --mcp-port 9999 myconn # custom port

Press F1 to see the socket address. The agent writes queries into a new editor tab and executes them so you can watch the results appear live.

Relay mode (Claude Code + live TUI)

--mcp-relay connects to a running TUI's socket and bridges it over stdio, allowing Claude Code to drive the live TUI via .claude/mcp.json:

{
  "mcpServers": {
    "sqltui": {
      "command": "sql",
      "args": ["--mcp", "myconnection"],
      "description": "Headless SQL client. Use for running queries and exploring the database."
    },
    "sqltui-live": {
      "command": "sql",
      "args": ["--mcp-relay"],
      "description": "Live SQL TUI. Use when the user wants queries written into their editor. Requires sql --mcp to be running in a terminal."
    }
  }
}
  • Use sqltui when you want Claude to query the database independently.
  • Use sqltui-live (or ask Claude to "write it in the editor") when you want to see the query built live in your terminal.

Available MCP tools

ToolDescription
read_editorReturn current editor content
write_editor(sql, mode)Write SQL — new_tab (default), replace, append
list_tabsList open tab names
switch_tab(name)Switch to a named tab
execute_query(sql)Execute SQL and return results as JSON
get_resultsReturn the current results grid
get_schemaReturn the introspected schema as JSON

Building

go build ./...          # build all packages
go test ./...           # run all tests
go test -cover ./...    # with coverage

keithn/sql

Go

1

25 commits

updated Mar 23, 2026

See the code

README

sql

A terminal SQL client for developers who live in the terminal. First-class MS SQL Server support, plus PostgreSQL and SQLite. Keyboard-driven, fast, works over SSH and inside tmux.

Go

The Experiment

This is a agentic AI coded piece of software. It is an experiment in doing everything with an AI agent and working out the best ways to develop software this way. While the version is less that 1.0.0 the software is likely to have a bunch of rough edges but my plans is to dogfood it (use it myself for real work) and have replaced using DataGrip. It is actually going really well and I find it a lot more useful than DataGrip (it is tailored to my workflows after all!). Once I think it is reasonably well polished and feature complete I will do a v1.

Features

  • Multi-database — SQL Server, PostgreSQL, SQLite (pure Go, no CGo)
  • Named/saved connections — raw DSNs, saved connections, keychain-backed passwords, last-used connection restore, and auto-reconnect on dropped connections
  • Connection management in-app — Ctrl+K switcher (with Ctrl+D to delete); Ctrl+N add-connection modal with connection-string or form-builder mode
  • Command + history palettes — Ctrl+P for app actions (including snippets), Ctrl+H for recent SQL
  • Named snippets — save/browse/paste reusable SQL blocks from the command palette
  • Smart block execution — Ctrl+E runs the logical statement under the cursor; F5 runs the full buffer
  • Transaction workflow — begin/commit/rollback from the command palette; run current block or full buffer inside a transaction; explain plans
  • Editor refactors — Ctrl+R popup: alias tables, expand SELECT *, convert SELECT↔UPDATE, IDENTITY_INSERT wrapping, tab rename
  • SQL formatting — format the active block with Ctrl+Shift+F
  • Goto line — Ctrl+G (editor and vim :42 syntax)
  • Schema-aware assistance — autocomplete, JOIN predicate inference, missing-table highlighting
  • Schema browser — Ctrl+B/F2; fuzzy filter, column selection for JOIN-aware SELECT, action menu (a), row counts (r)
  • Vim mode — toggleable; persistent across sessions; supports motions, operators, visual, undo/redo; shown in status bar
  • Results grid — virtual scrolling, column sort (s), row numbers (#), stacked column filters (f), configurable row limit (L), poll/auto-refresh (P), zoom modes (z/Z)
  • Row detail view — Enter opens a vertical column/value overlay; navigate rows with h/l
  • Row tagging — Space tags rows; V range-tag; Ctrl+A tag all/clear; tagged rows highlighted; export respects selection
  • Column selection — | toggles a column (purple header); \ opens a fuzzy column picker with multi-select; t toggles SELECTED ONLY view showing only tagged rows and/or selected columns
  • Result diff/pin — p pins the current result; re-running the same query shows added/removed/changed rows
  • Cell edit → UPDATE — e in the results grid or row detail view opens an inline cell editor (with vim mode); on confirm an UPDATE preview panel appears showing the generated SQL — execute it with Ctrl+E, copy with y, close with Esc; results refresh automatically on success; Ctrl+D sets the value to NULL
  • Export — X in results: CSV, Markdown, JSON, SQL INSERT, or WHERE IN list — honours row tags and column selection; to clipboard or file
  • Screenshot — F10 captures the current view to clipboard or file
  • MCP server mode — --mcp starts a background JSON-RPC server so Claude Code can drive the TUI as an agent
  • Multi-tab editor — Ctrl+N new tab, Ctrl+W close, Ctrl+PgDn/Ctrl+PgUp switch
  • Session restore — open tabs and cursor positions saved on quit and restored on reconnect
  • Help/settings overlay — F1 shows keybindings, state, and loaded config values
  • Lua config — %APPDATA%\sql\config.lua (Windows) / ~/.config/sql/config.lua

Installation

Download a release

Grab a pre-built binary from the Releases page and put it on your PATH.

Build from source

Requires Go 1.21+.

go install github.com/sqltui/sql/cmd/sql@latest

Or clone and build:

git clone https://github.com/sqltui/sql
cd sql
go build -o sql ./cmd/sql/

Usage

# Connect with a connection string
sql "server=1.2.3.4;user id=sa;password=...;database=mydb"

# List saved connections
sql --list

# Save a named connection
sql --add "server=1.2.3.4;user id=sa;password=...;database=mydb" --name prod

# Connect using a saved connection
sql prod

# SQLite
sql ./mydb.sqlite

# PostgreSQL
sql "postgres://user:pass@localhost/mydb"

# Start TUI with MCP socket server on port 45678
sql --mcp
sql --mcp prod

# Relay an MCP client (e.g. Claude Code) to a running TUI
sql --mcp-relay
sql --mcp-relay --mcp-port 9999

Once connected, the last-used connection is saved and restored on next launch.

Connection strings

DatabaseFormat
SQL Serverserver=host;user id=user;password=pass;database=db
SQL Serversqlserver://user:pass@host?database=db
PostgreSQLpostgres://user:pass@host/db
PostgreSQLhost=localhost user=postgres dbname=mydb sslmode=disable
SQLite./path/to/file.db or file:path/to/file.db

Passwords are never displayed in the UI.

Keybindings

Global

KeyAction
F1Help / settings overlay
Ctrl+PCommand palette
Ctrl+HQuery history palette
Ctrl+KConnection switcher
Ctrl+EExecute block under cursor
Ctrl+Shift+F / Ctrl+FFormat active block
F5Execute full buffer
F3 / Alt+1Focus editor
F4 / Alt+2Focus results
Ctrl+B / F2Toggle schema browser
Ctrl+QQuit (saves session)

Editor

KeyAction
Ctrl+NNew tab
Ctrl+WClose tab
Ctrl+PgDn / Alt+LNext tab
Ctrl+PgUp / Alt+HPrevious tab
Alt+Up / Alt+DownPrevious / next query block
Ctrl+GGoto line
Ctrl+RRefactor popup
Ctrl+\Toggle comment
TabInsert 4 spaces
Ctrl+Alt+VToggle vim mode

Refactor popup (Ctrl+R):

KeyAction
NName/alias current table
EExpand SELECT *
u / UConvert SELECT → UPDATE (or append UPDATE)
s / SConvert UPDATE → SELECT (or append SELECT)
iWrap INSERT with IDENTITY_INSERT ON/OFF
TRename current tab

Command palette (Ctrl+P) also exposes:

  • begin / commit / rollback transaction
  • run current block / full buffer in transaction
  • explain current block / full buffer
  • save current block as snippet
  • browse snippets

Results

KeyAction
↑ / ↓ or j / kScroll rows
PgUp / PgDnScroll a page
Home / EndJump to top / bottom row
← / → or h / lScroll columns
0 / $Jump to first / last column
Alt+PgUp / Alt+PgDnPrevious / next result set
EnterRow detail view (vertical)
sSort by cursor column (cycles: none → ▲ → ▼)
fFilter by cursor column (regex, stacks — add multiple)
FClear all filters
#Toggle row numbers
LChange row limit
pPin result as diff baseline (re-run to see diff)
PToggle poll / auto-refresh
SpaceTag / untag current row (advances cursor)
VRange-tag rows
Ctrl+ATag all rows / clear all tags
|Toggle current column selection (purple header)
\Column picker — fuzzy search columns; ↓/Tab enters list, Space tags, Enter applies
Ctrl+\Clear all column selections
tToggle SELECTED ONLY view — show only tagged rows and/or selected columns
eEdit cell → UPDATE preview panel
ERow edit form (multi-column UPDATE)
XExport (CSV / Markdown / JSON / SQL INSERT / WHERE IN → clipboard or file)
vOpen cell value viewer
yCopy current cell to clipboard
zZoom: shrink editor to active query block
ZZoom: results fullscreen (hides editor)
F10Screenshot to clipboard / file

Row detail view

KeyAction
j / k or ↑ / ↓Scroll fields
h / ←Previous row
l / →Next row
yCopy focused field to clipboard
eEdit focused cell → UPDATE preview panel
EscClose

Cell edit overlay

KeyAction
TypeEdit value (vim mode supported)
Ctrl+SConfirm and open UPDATE preview
Ctrl+DSet value to NULL and open UPDATE preview
EscCancel

UPDATE preview panel

KeyAction
Ctrl+E / EnterExecute UPDATE
y / Ctrl+CCopy SQL to clipboard
↑ / ↓ / j / kScroll
EscClose

Schema browser

KeyAction
TypeFilter tables
↓ / EnterMove to table list
j / kNavigate tables
EnterPaste SELECT into editor
TabSelect / deselect column
rFetch row count for selected table
aAction menu (copy name, DDL, indexes, row count)
/Return to search input
EscClose browser
Alt+← / Alt+→Resize panel

Configuration

Config file location:

  • Windows: %APPDATA%\sql\config.lua
  • macOS / Linux: ~/.config/sql/config.lua
-- config.lua
editor = {
  result_limit = 500,   -- default rows fetched per query
  vim_mode     = false, -- start in vim mode
}

theme = {
  line_number        = "#555555",
  cursor_line_number = "#aaaaaa",
}

MCP server mode

--mcp enables MCP (Model Context Protocol) support. There are two modes depending on how the process is launched:

Headless / stdio mode (for Claude Code and other MCP clients)

When stdin is a pipe (i.e. launched by an MCP client), sql --mcp runs as a headless JSON-RPC 2.0 server over stdio with no TUI. This is the mode used by .claude/mcp.json:

{
  "mcpServers": {
    "sqltui": {
      "command": "sql",
      "args": ["--mcp", "myconnection"]
    }
  }
}

Replace myconnection with a saved connection name or a raw DSN. The agent can then query the database directly.

TUI + socket mode (query building assistant)

When launched in a terminal, --mcp starts the TUI normally and also opens a TCP socket server on port 45678 (default) so an agent can drive the live TUI — reading/writing the editor, executing queries, and seeing results.

sql --mcp                        # TUI + socket on default port 45678
sql --mcp myconn                 # connect and open socket
sql --mcp --mcp-port 9999 myconn # custom port

Press F1 to see the socket address. The agent writes queries into a new editor tab and executes them so you can watch the results appear live.

Relay mode (Claude Code + live TUI)

--mcp-relay connects to a running TUI's socket and bridges it over stdio, allowing Claude Code to drive the live TUI via .claude/mcp.json:

{
  "mcpServers": {
    "sqltui": {
      "command": "sql",
      "args": ["--mcp", "myconnection"],
      "description": "Headless SQL client. Use for running queries and exploring the database."
    },
    "sqltui-live": {
      "command": "sql",
      "args": ["--mcp-relay"],
      "description": "Live SQL TUI. Use when the user wants queries written into their editor. Requires sql --mcp to be running in a terminal."
    }
  }
}
  • Use sqltui when you want Claude to query the database independently.
  • Use sqltui-live (or ask Claude to "write it in the editor") when you want to see the query built live in your terminal.

Available MCP tools

ToolDescription
read_editorReturn current editor content
write_editor(sql, mode)Write SQL — new_tab (default), replace, append
list_tabsList open tab names
switch_tab(name)Switch to a named tab
execute_query(sql)Execute SQL and return results as JSON
get_resultsReturn the current results grid
get_schemaReturn the introspected schema as JSON

Building

go build ./...          # build all packages
go test ./...           # run all tests
go test -cover ./...    # with coverage

Languages

Go

100.0%