Agent-ergonomic CLI for Microsoft SQL Server and Azure SQL — schema discovery, row previews, read-only queries, showplans, and gated mutations, in token-efficient TOON output.
mssql-axi is a SQL Server AXI (Agent eXperience
Interface): a CLI designed for autonomous agents rather than humans. It talks to the
server through the native Microsoft ODBC driver via the npm odbc binding, or tedious
for optional, explicitly selected Azure CLI token authentication.
It accepts ODBC-style connection strings, is read-by-default, and answers with minimal
schemas plus contextual next-step hints.
Across extensive AXI benchmark studies (over 900 runs), agent-first CLIs achieve 100% task success at ~50% fewer turns and 50–66% lower cost than MCP:
| Interface | Context (Turn 0) | Output | Measured Payload | Write Safety | Guidance |
|---|---|---|---|---|---|
mssql-axi |
~55 tokens (on-demand) | TOON | -34.8% vs ASCII, -53.3% vs JSON (weighted avg) | ✅ Read-only by default; double-gated dry-run | Structured hints (help[]) |
Raw CLI (sqlcmd) |
~0 tokens | Wide ASCII | Baseline (whitespace padding & uncapped dumps) | ❌ Direct execution, no read-only guarantee | Human error text / generic codes |
| Database MCP | ~5k–10k tokens (15–30 schemas) | JSON-RPC | Highest cost (~185k input tokens/task across turns) | Varies | Schema validation errors |
Install globally (recommended for repeated use):
npm install -g @jeffreyhaen/mssql-axi
mssql-axi --helpFor a one-off invocation without installing:
npx -y @jeffreyhaen/mssql-axi --helpPrerequisites: Node.js 22 or newer. Native ODBC connections require the Microsoft
ODBC Driver 17 or 18 (Windows: the MSI from Microsoft; Linux/macOS: unixodbc + the
Microsoft driver). Azure CLI is optional: only Authentication=AzureCli requires
Azure CLI and an existing login. Other authentication modes do not use it.
Install the skill so an agent loads the usage guide on demand:
npx skills add jeffreyhaen/mssql-axi --skill mssql-axi -gOmit -g to install the skill for the current project only. To have the agent start
each session with the active connection's home view:
mssql-axi setup hooksA connection is resolved in this order (first non-empty wins):
--connection-string "<ODBC-style string>"— explicit authentication modeMSSQL_CONNECTION_STRING— same shapemssql-axi.config.jsonin the working directory (or--config <path>), with--connection <name>to pick a non-default entry
mssql-axi setup config > mssql-axi.config.json # writes an example to edit
mssql-axi doctor --connection dev{
"default": "dev",
"connections": {
"dev": "Driver={ODBC Driver 17 for SQL Server};Server=localhost\\SQLEXPRESS;Database=app;Trusted_Connection=Yes;TrustServerCertificate=Yes;",
"azure": "Driver={ODBC Driver 18 for SQL Server};Server=tcp:myapp.database.windows.net,1433;Database=app;Authentication=ActiveDirectoryInteractive;Encrypt=Yes;",
"azureCli": "Driver={ODBC Driver 18 for SQL Server};Server=tcp:myapp.database.windows.net,1433;Database=app;Authentication=AzureCli;Encrypt=Yes;"
}
}- Local SQL Server works over Share
8000
d Memory with Windows Auth
(
Trusted_Connection=Yes), including named instances (Server=HOST\INSTANCE). - Azure SQL without Azure CLI: use a suitable native ODBC mode for your identity
and environment, such as
ActiveDirectoryInteractive,ActiveDirectoryIntegrated,ActiveDirectoryServicePrincipalorActiveDirectoryMsi. SQL username/password auth (SqlPasswordorUID+PWD) also works when enabled on the server. Entra username/password auth (ActiveDirectoryPassword) remains supported but is deprecated and incompatible with MFA. Interactive authentication may prompt for every call; see the agent authentication rules. - Optional Azure SQL login reuse with Azure CLI: explicitly select
Authentication=AzureCli. mssql-axi obtains a SQL token throughAzureCliCredential, using Azure CLI's cache and refresh, and connects with tedious. It never opens a login dialog or falls back to another credential. Missing/expired login returnsAUTH_REQUIRED; runaz loginyourself when requested. RemoveUID,PWD,PasswordandTrusted_Connectionwhen selecting this mode. An optional GUID-valuedTenantIdorSubscriptionIdselects the CLI account; they cannot be combined. Omit both to use the current CLI account. - Secrets live in the connection string, in a shell-interpolated env var
(
"...Password=${MSSQL_AGENT_PWD};..."), or in a secret manager that exportsMSSQL_CONNECTION_STRING.Password=,Pwd=, andUID=are redacted from every error message. - See
docs/connection-strings.mdfor the ODBC 17 vs 18 keyword differences and one line per supported auth flow.
The npm odbc binding calls the native Microsoft
ODBC driver. This remains the default for local Windows identity, Shared Memory,
named instances and configured ODBC authentication.
Authentication=AzureCli is a mssql-axi extension, not an ODBC driver keyword;
its TCP connection uses tedious with strict TLS
(TDS 8.0) and certificate validation, with no downgrade fallback.
See connection-string limits.
mssql-axi # home: server, database, largest tables
mssql-axi doctor # connectivity + read-only role check
mssql-axi list tables # tables | views | indexes | schemas
mssql-axi list views --schema sales --limit 50
mssql-axi inspect dbo.Users # columns, primary key, foreign keys
mssql-axi inspect view dbo.vActiveUsers
mssql-axi sample dbo.Users --limit 5
mssql-axi sample dbo.Users --where "createdAt > '2026-01-01'" --full
mssql-axi query "SELECT TOP 10 id, email FROM dbo.Users"
mssql-axi explain "SELECT * FROM dbo.Users WHERE email = 'a@b.c'"
mssql-axi plan "ALTER TABLE dbo.Users ADD nickname NVARCHAR(50) NULL"
mssql-axi execute "UPDATE dbo.Users SET active = 0 WHERE id = 42" \
--confirm "UPDATE dbo.Users SET active = 0 WHERE id = 42" --execute
mssql-axi setup role # T-SQL to create the agent_reader role
mssql-axi update --check # check for a newer versionEvery command supports --help. SQL and object names may be passed positionally
(query "SELECT 1", inspect dbo.Users) or through flags (--sql, --schema/--name);
[bracketed].[names] are accepted and the schema defaults to dbo. Lists support
--limit; row output truncates long cells at 200 characters unless --full is given.
- Database-side — a dedicated
agent_readerrole withdb_datareaderanddb_denydatawriter. Set up once withmssql-axi setup role;mssql-axi doctorreports whether the current login is a member. - Application-side — a validator on every read command. Only
SELECT(optionally with a leadingWITH cte AS (...)),EXPLAIN, andSET SHOWPLAN_XML ONare accepted.INSERT,UPDATE,DELETE,MERGE,DROP,TRUNCATE,EXEC, stacked statements, and;GOare refused with a structured error before any connection is opened.
execute is dry-run by default and prints the normalised T-SQL. Committing requires
--confirm "<the same statement>" (compared after comments are stripped and whitespace
is normalised) and --execute. Destructive shapes — DROP, TRUNCATE, and
DELETE/UPDATE without a WHERE — additionally require --allow-destructive.
--max-rows-affected (default 10,000) refuses to report success for a runaway
statement, and --timeout (default 30s) bounds the run.
Built against the ten AXI principles: TOON output, minimal default schemas, truncation
with --full, pre-computed aggregates (row counts, totals), definitive empty states,
structured errors on stdout with exit code 2 for usage errors, a content-first
no-argument home view, contextual next-step hints, and concise per-command help.
pnpm install
pnpm run typecheck
pnpm run build
pnpm test
pnpm run dev -- list tables --connection-string '...'Tests run the command layer against an injected fake ODBC driver (test/fakeDb.ts), so
no live SQL Server is needed. CI runs build, typecheck, tests, and a CLI smoke test on
Node 22 and 24 (Linux) and Node 24 (Windows).
- Move the
Unreleasedsection inCHANGELOG.mdunder## [x.y.z] - <date>. - Bump
versioninpackage.json. - Commit as
chore: release vX.Y.Z, then tag and push:
git tag -a vX.Y.Z -m "Release vX.Y.Z"
git push --follow-tagsPushing the tag runs .github/workflows/release.yml: it typechecks, builds, tests,
publishes to npm, and creates the GitHub release with the matching CHANGELOG.md section
as its body (scripts/release-notes.mjs). An existing release is left as is, so the
workflow can be re-run safely.
MIT © Jeffrey Haen
See CHANGELOG.md for release notes.
- docs/connection-strings.md — the ODBC 17 vs 18 keyword differences, one line per supported auth flow
- AXI — agent eXperience interface · kunchenguid/axi
- TOON — token-optimized object notation · toonformat/toon