sscli
SQL Server CLI for AI coding agents.
One install. Your agents automatically know how to inspect SQL Server databases, run safe queries, and export results.
Quick Start (Agent Users)
1. Install sscli
# macOS/Linux
# or with cargo
2. Teach your agents
Done. Your agents now know how to browse schemas, run safe queries, and export results.
What changes?
| Before | After |
|---|---|
| You paste schema context into prompts | Agent discovers schema on demand |
| Agent guesses at SQL Server commands | Agent knows sscli tables, sscli describe, etc. |
| Risk of accidental writes | Read-only by default, explicit --allow-write override |
| Verbose output bloats context | Token-efficient markdown output |
Manual Usage
For humans who want to use sscli directly.
1-minute setup (first run)
# Create a starter config in ./.sql-server/config.yaml (safe defaults)
# Set the password env var referenced by passwordEnv in your config
# Sanity-check connectivity + server metadata
# See the effective settings + which config file was used
Common commands
Why sscli?
| Token-efficient | Markdown output by default keeps agent context lean |
| Read-only safe | Blocks INSERT, UPDATE, DELETE — no accidents |
| Single binary | Fast startup, no runtime dependencies |
| CLI over MCP | No "tool bloat" from long-running servers |
| Progressive disclosure | Core commands visible, advanced hidden until needed |
For interactive SQL, keep using sqlcmd. For agent workflows, scripts, and CI — sscli is built for that.
Installation
Homebrew (macOS/Linux)
Quick install script
|
Cargo binstall (fast, no compilation)
From source
Prebuilt binaries
Download from GitHub Releases.
Development build
Updating
# Homebrew
# Cargo
Agent Integration
Supported agents
| Agent | Command | What it installs |
|---|---|---|
| Claude Code | sscli integrations skills add --global |
~/.claude/skills/sscli/SKILL.md |
| Codex | (same command) | ~/.codex/skills/sscli/SKILL.md |
| Gemini CLI | sscli integrations gemini add --global |
~/.gemini/extensions/sscli/ |
| Other agents | Via OpenSkills | Bridge to installed skills |
Per-project vs global
| Flag | Installs to | Use case |
|---|---|---|
--global |
~/.claude/skills/ |
Available in all projects |
| (none) | ./.claude/skills/ |
Project-specific override |
What the skill teaches agents
The installed skill file tells agents:
- When to use sscli (database inspection, schema discovery, safe queries)
- Available commands and their purpose
- Output preferences (markdown for context efficiency,
--jsonfor structured data) - Safety model (read-only default,
--allow-writefor mutations)
Configuration
sscli supports three ways to configure a connection (highest priority wins):
# 1) CLI flags (one-off / scripts)
# 2) Environment variables (CI-friendly)
# 3) Config file (recommended for repeated use)
&& &&
Creating a config file
Generate a commented template (writes ./.sql-server/config.yaml by default):
Or copy the example file in this repo:
Config discovery (where sscli looks)
--config <PATH>SQL_SERVER_CONFIG/SQLSERVER_CONFIG- Walk up from CWD looking for
.sql-server/config.{yaml,yml,json}or.sqlserver/config.{yaml,yml,json} - Global config:
$XDG_CONFIG_HOME/sql-server/config.{yaml,yml,json}(platform-dependent) - Environment variables
- Hardcoded defaults
Run sscli config to confirm which config file is being used and what values are in effect.
Example config.yaml
defaultProfile: default
profiles:
default:
server: localhost
port: 1433
database: master
user: sa
passwordEnv: SQL_PASSWORD
encrypt: true
trustCert: true
For a fully commented example (including settings.output.*, timeout, and defaultSchemas), see config.example.yaml.
Environment variables
Environment variables override values from the config file.
.env file support: sscli automatically loads a .env file from the current directory if present. This is useful for local development without polluting your shell environment.
| Purpose | Environment variables (first match wins) |
|---|---|
| Config path | SQL_SERVER_CONFIG, SQLSERVER_CONFIG |
| Profile | SQL_SERVER_PROFILE, SQLSERVER_PROFILE |
| Connection URL | DATABASE_URL, DB_URL, SQLSERVER_URL |
| Server | SQL_SERVER, SQLSERVER_HOST, DB_HOST |
| Port | SQL_PORT, SQLSERVER_PORT, DB_PORT |
| Database | SQL_DATABASE, SQLSERVER_DB, DATABASE, DB_NAME |
| User | SQL_USER, SQLSERVER_USER, DB_USER |
| Password | SQL_PASSWORD, SQLSERVER_PASSWORD, DB_PASSWORD |
| Encrypt | SQL_ENCRYPT |
| Trust server certificate | SQL_TRUST_SERVER_CERTIFICATE |
| Connect timeout (ms) | SQL_CONNECT_TIMEOUT, DB_CONNECT_TIMEOUT |
Commands
Core (shown in --help):
| Command | Purpose |
|---|---|
status |
Connectivity check |
databases |
List databases |
tables |
Browse tables and views (--describe for batch DDL) |
describe |
Any object: table, view, trigger, proc, function |
sql |
Execute read-only SQL |
table-data |
Sample rows from a table |
columns |
Find columns across tables |
Advanced (shown in help --all):
| Command | Purpose |
|---|---|
indexes |
Index details with usage stats |
foreign-keys |
Table relationships |
stored-procs |
List and execute read-only procedures |
sessions |
Active database sessions |
query-stats |
Top cached queries by resource usage |
backups |
Recent backup history |
integrations |
Install agent skills/extensions |
Output Formats
| Context | Default |
|---|---|
| Terminal (TTY) | Pretty tables |
| Piped / non-TTY | Markdown tables |
--json flag |
Stable JSON (v1 contract) |
--csv <file> |
CSV export |
JSON output emits exactly one object to stdout. Errors go to stderr.
Safety
sscli sql enforces read-only mode by default:
- Allowed: SELECT, WITH (CTEs), whitelisted stored procedures
- Blocked: INSERT, UPDATE, DELETE, DROP, ALTER, TRUNCATE, MERGE, etc.
Override with --allow-write when you intentionally need mutations.
JSON Contract (v1)
Each command returns a stable top-level object:
| Command | Shape |
|---|---|
status |
{ status, latencyMs, serverName, serverVersion, currentDatabase, timestamp, warnings } |
databases |
{ total, count, offset, limit, hasMore, nextOffset, databases: [...] } |
tables |
{ total, count, offset, limit, hasMore, nextOffset, tables: [...] } |
describe |
{ object: {schema, name, type}, columns, ddl?, indexes?, triggers?, foreignKeys?, constraints? } |
table-data |
{ table, columns, rows, total, offset, limit, hasMore, nextOffset } |
sql |
{ success, batches, resultSets, csvPaths? } |
Errors (stderr):
Testing
DB-backed integration tests (opt-in):
SSCLI_INTEGRATION_TESTS=1 SQL_SERVER_CONFIG=/path/to/config.yaml \
SQL_PASSWORD=...