DeepSQL documentation
Everything you need to run the database agent for Postgres and MySQL inside your own infrastructure — in about fifteen minutes.
Introduction
DeepSQL is an open-source database agent. Point it at PostgreSQL or MySQL and ask questions in plain English: schema exploration, query generation, slow query analysis, index recommendations, generated dashboards.
You bring the model. DeepSQL ships with no model provider of its own and no vendor account to sign up for. Point it at OpenAI, Azure OpenAI, Anthropic, a LiteLLM proxy, or a model running on your own hardware. Everything else runs in your environment: database credentials are encrypted in a local vault, and nothing leaves the machines you control except the prompts you send to the endpoint you chose.
Source: github.com/DeepSQLAI/deepsql. Architecture and design rationale live in the white paper.
Set up with an AI agent
These docs are published in a machine-readable form so Claude, Codex, Cursor or any other coding agent can install DeepSQL end to end for you. Give the agent your model endpoint and API key, paste the prompt below, and let it run.
Read https://deepsql.ai/llms-full.txt and set up DeepSQL on this machine
end to end, following it exactly. Use my model provider:
endpoint: <your endpoint>
model: <your model>
API key: <your key>
Run every verification step and stop and ask me if any of them fails.| URL | What it is |
|---|---|
| /llms.txt | Short index of every page an agent should know about. |
| /llms-full.txt | The full runbook: preflight, .env, install, verification commands, troubleshooting. |
The runbook is written as ordered steps with copy-runnable commands, explicit verification after each stage, and a troubleshooting table keyed to the actual failure messages — so an agent can self-correct instead of guessing. The only things it will ask you for are the model key/endpoint, the embedding key/endpoint, and the first admin account.
Requirements
- Docker Engine with Compose v2 and buildx — verify with
docker compose versionanddocker buildx version. Compose delegates builds to buildx and refuses anything older than 0.17.0. git,curlandopenssl- ~4 GB of memory available to Docker. The backend JVM is configured with a 3 GB max heap; a smaller allocation fails in ways that look unrelated.
- An API key for a model provider — you need this before you start, not after.
On a fresh server, one command does all of that:
sudo ./scripts/self-host/bootstrap-server.shIt handles Debian/Ubuntu and Amazon Linux 2023 / RHEL, installs whatever is missing, and verifies the result before exiting. Worth running even where Docker is already present: a stock dnf install docker on Amazon Linux 2023 ships neither the Compose plugin nor a buildx new enough to build.
Install
There are no prebuilt images and no container registry. Compose builds the backend and frontend from your checkout.
git clone https://github.com/DeepSQLAI/deepsql.git
cd deepsql
cp .env.example .envSet your model in .env (see Models), then run the installer:
./scripts/self-host/install.shThe installer generates your JWT secret, the credential-vault encryption key, the vault DB password and the DeepSQL Agent provision secret; prompts for the first admin account; builds the backend, frontend and Agent images; starts the stack; and verifies pgvector is live. The Agent tab and AI dashboard generation are served by the deepsql-agent Compose service — no host-side agent install is required.
Driving Compose yourself
.env.example ships two values empty on purpose — they are validated secrets, and the backend refuses to start without them.
printf 'SECURITY_JWT_SECRET=%s\n' "$(openssl rand -base64 64 | tr -d '\n')" >> .env
printf 'ENCRYPTION_KEY=%s\n' "$(openssl rand -base64 32)" >> .env
docker compose up -d --buildThat builds and starts everything but leaves you unable to log in: there is no seeded account, self-service signup is disabled, and the wizard's POST /setup/initialize is disabled. The first user is created through a localhost-only bootstrap endpoint — set SECURITY_ADMIN_BOOTSTRAP_ENABLED=true and ADMIN_BOOTSTRAP_SECRET in .env and call it yourself. install.sh does exactly this, then turns the flag back off.
First login
Open http://localhost:3000 and log in with the admin email and password you entered during install. From there: add a database connection, teach the brain your business context, and point the agent at your slow query logs.
ENCRYPTION_KEY from .env now. It encrypts every database credential you store. Lose it and you re-enter all of them — there is no recovery path.Models
Open .env and set the chat group. Whatever you pick, the provider id stays openai — there is one provider implementation and it speaks OpenAI, Azure OpenAI, and every OpenAI-compatible server. It dispatches on the shape of your endpoint, not on a name you configure.
| Variable | What to put in it |
|---|---|
DEEPSQL_CHAT_PROVIDER | always openai, for every provider below |
DEEPSQL_CHAT_API_KEY | Your key. For a local model, any non-empty string. |
DEEPSQL_CHAT_ENDPOINT | The base URL. No working default — set it explicitly. |
DEEPSQL_CHAT_MODEL | Model name, or your Azure deployment name |
OpenAI
DEEPSQL_CHAT_PROVIDER=openai
DEEPSQL_CHAT_API_KEY=sk-your-key
DEEPSQL_CHAT_ENDPOINT=https://api.openai.com/v1
DEEPSQL_CHAT_MODEL=gpt-4oAzure OpenAI
An .azure.com or .azure-api.net endpoint switches authentication to the api-key header automatically. _MODEL is your deployment name.
DEEPSQL_CHAT_PROVIDER=openai
DEEPSQL_CHAT_API_KEY=your-azure-openai-key
DEEPSQL_CHAT_ENDPOINT=https://your-resource.cognitiveservices.azure.com/
DEEPSQL_CHAT_MODEL=your-deployment-nameAnthropic
Anthropic serves an OpenAI-compatible /v1/chat/completions, so it needs no gateway. It publishes no embeddings API, so pair it with another provider for embeddings.
DEEPSQL_CHAT_PROVIDER=openai
DEEPSQL_CHAT_API_KEY=sk-ant-your-key
DEEPSQL_CHAT_ENDPOINT=https://api.anthropic.com/v1
DEEPSQL_CHAT_MODEL=claude-haiku-4-5-20251001Ollama, vLLM, LM Studio, TGI — your own hardware
Anything speaking the OpenAI wire format. No key is required, but the variable must be non-empty.
DEEPSQL_CHAT_PROVIDER=openai
DEEPSQL_CHAT_API_KEY=ollama
DEEPSQL_CHAT_ENDPOINT=http://host.docker.internal:11434/v1
DEEPSQL_CHAT_MODEL=llama3.1LiteLLM proxy
DEEPSQL_CHAT_PROVIDER=openai
DEEPSQL_CHAT_API_KEY=sk-your-litellm-virtual-key
DEEPSQL_CHAT_ENDPOINT=http://litellm:4000/v1
DEEPSQL_CHAT_MODEL=your-aliasName your alias carefully. _USE_RESPONSES_API defaults to auto, which decides from the model name rather than from what your endpoint implements. An alias beginning gpt-5, o1, o3, o4 or codex selects the Responses API. If your gateway does not serve /v1/responses, avoid those prefixes or set DEEPSQL_CHAT_USE_RESPONSES_API=false.
DEEPSQL_CHAT_PROVIDER gates the whole group: with it unset, no other DEEPSQL_CHAT_* variable is read. That is the most common reason a carefully filled-in .env appears to be ignored.Embeddings
Configured independently of chat, so they can point at a different provider, key or endpoint — exactly what you need when your chat model has no embeddings API.
DEEPSQL_EMBEDDING_PROVIDER=openai
DEEPSQL_EMBEDDING_API_KEY=sk-your-key
DEEPSQL_EMBEDDING_ENDPOINT=https://api.openai.com/v1
DEEPSQL_EMBEDDING_MODEL=text-embedding-3-largeSkipping this is survivable — the app starts and retrieval falls back to keyword-only — but answer quality drops noticeably, so treat it as part of setup rather than an extra.
rag_documents.embedding is a single vector(3072) column shared by every connection, so text-embedding-3-small (1536) is rejected. Changing width means migrating the column.Environment reference
Everything lives in .env, documented inline. The variables that matter most:
| Variable | Purpose |
|---|---|
DEEPSQL_CHAT_PROVIDER, _API_KEY, _ENDPOINT, _MODEL | The chat model. Required. |
DEEPSQL_EMBEDDING_PROVIDER, _API_KEY, _ENDPOINT, _MODEL | Embeddings for retrieval. Optional; without them retrieval is keyword-only. |
DEEPSQL_CHAT_TEMPERATURE, _API_VERSION, _USE_RESPONSES_API | Optional chat tuning. _USE_RESPONSES_API is true / false / auto. |
SECURITY_JWT_SECRET | Signs session tokens. Generate with openssl rand -base64 64. |
ENCRYPTION_KEY | Or ENCRYPTION_KEYS + ENCRYPTION_KEY_ID. AES-GCM key(s) for the credential vault. The backend refuses to start without one. |
DB_URL, DB_USERNAME, DB_PASSWORD | The vault database. Compose points these at its own postgres service. |
SPRING_PROFILES_ACTIVE | prod for self-hosting — hardened defaults. |
SECURITY_AUTH_ENABLED | Set false only for local development. |
SECURITY_ADMIN_BOOTSTRAP_ENABLED, ADMIN_BOOTSTRAP_SECRET | Gate the localhost-only first-admin endpoint. |
CORS_ALLOWED_ORIGINS | Browser origins allowed to call the API. |
VECTOR_STORE_TYPE | pgvector (the self-hosting default) or azure. |
EMBEDDING_FAIL_OPEN | Whether a failed embedding call degrades silently or raises. |
SLACK_*, EMAIL_* | Optional Slack bot and SMTP. |
Ports
| Service | Port | Override |
|---|---|---|
| Frontend | 3000 | DEEPSQL_FRONTEND_PORT |
| Backend | 8080 | DEEPSQL_BACKEND_PORT |
| Postgres | 5432 | DEEPSQL_POSTGRES_PORT |
| Valkey | 6379 | DEEPSQL_VALKEY_PORT |
What it does
- Answers BI questions. The agent loads your business context, resolves the schema, drafts and validates SQL, then executes it read-only — with every step you can inspect. The hand-written SQL editor is the only path that can mutate, and only for a confirming admin.
- Fixes slow queries. Reads
pg_stat_statementsor the MySQL slow log, groups queries by fingerprint, ranks them by cost, and flags regressions against their baseline. - Index recommendations. Advises, and can apply them for you —
CREATE INDEX CONCURRENTLYon PostgreSQL, so no table lock. - Watches your schema. Tracks what changed and what needs attention, so drift surfaces before it breaks a query or a dashboard.
- A brain that knows your business. Teach it your metrics, rules and conventions once — MRR, active accounts, currency handling — and every query, dashboard and recommendation uses the same governed definitions.
- Dashboards without the analyst backlog. An agent writes a single self-contained HTML document, rendered in a sandboxed iframe with no network access. It reads data only through a read-only query bridge back to the backend.
- Postgres and MySQL, in your infra. One dialect registry, read-only execution, and SSH tunnelling to reach databases behind a bastion.
Demo database
To explore DeepSQL without connecting your own database:
./scripts/self-host/seed-demo-data.shThis creates a demo_shop e-commerce database with 100 products, 500 customers and 5,000+ orders, intentionally suboptimal query patterns to trigger recommendations, pre-configured slow query analysis and index recommendations, sample saved queries in the SQL editor, and sample agent conversation history.
Alternatively set DEEPSQL_SEED_DEMO_DATA=1 in .env before running install.sh to seed automatically.
MCP server
mcp/ exposes 44 tools wrapping the backend API, so coding agents reuse the same orchestration, retrieval and guardrails instead of getting raw database credentials. SQL execution is read-only-enforced before it reaches the backend.
DEEPSQL_API_BASE_URL=http://localhost:8080/api/ \
DEEPSQL_AUTH_TOKEN=<your-deepsql-token> \
npm run mcp:phase1It has no npm dependencies of its own — npm run mcp:phase1 is just node mcp/deepsql-phase1-server.js, so it runs straight from a fresh clone. See mcp/README.md for editor configuration and the full tool table.
CLI & Slack
Ask DeepSQL from anywhere: the web UI, your terminal, or a Slack channel. Over MCP (stdio), Claude Code, Cursor, Codex and Claude Desktop get the same capabilities as the built-in agent — governed definitions, read-only execution, schema guardrails.
The Slack bot is optional and configured with the SLACK_* variables in .env; once connected, anyone in the channel can ask business questions without the data leaving your infrastructure.
Operating the stack
./scripts/self-host/status.sh # compose ps + health probes
./scripts/self-host/smoke-test.sh # end-to-end check against the vault DB
./scripts/self-host/seed-demo-data.sh # seed demo e-commerce database
./scripts/self-host/uninstall.sh # stop and remove containers, keep data
./scripts/self-host/uninstall.sh --purge-data # also drop the volumesUpgrading:
git pull && docker compose up -d --buildRemote access (SSH tunnel)
If DeepSQL runs on a server you only reach through a bastion, forward the frontend port locally instead of exposing it to the internet.
ssh -N -L 3100:localhost:3000 -o ExitOnForwardFailure=yes <user>@<bastion-host>If the target host is itself only reachable from inside the bastion's network, add a Host entry per leg in ~/.ssh/config and let ProxyJump chain them:
Host my-bastion
HostName <bastion-ip-or-dns>
User <bastion-user>
IdentityFile ~/.ssh/<bastion-key>
Host deepsql
HostName <target-host-ip-or-dns>
Port <target-ssh-port>
User <target-user>
IdentityFile ~/.ssh/<target-key>
ProxyJump my-bastion
LocalForward 3100 localhost:3000
ServerAliveInterval 30
ExitOnForwardFailure yesssh -N deepsqlThen open http://localhost:3100. Use a non-3000 local port if something on your machine already binds 3000 — ExitOnForwardFailure=yes makes a port collision fail loudly instead of handing you a dead tunnel that looks connected.
Telemetry
The backend can report anonymous install and usage counters to PostHog. No project key ships with the repository, so the sink is a no-op unless you configure deepsql.telemetry.posthog-project-key yourself. DO_NOT_TRACK=1 or DEEPSQL_TELEMETRY_DISABLED=1 disables it outright, as does the admin toggle.
Development
Run the stateful dependencies in Docker — PostgreSQL needs the pgvector extension — and everything else natively for hot reload.
docker compose up -d postgres valkey # requires .env to exist
cd backend && ./mvnw spring-boot:run # http://localhost:8080/api
npm install && npm run dev # http://localhost:3000You need JDK 25 and Node 22. Maven comes from the wrapper (./mvnw). The backend needs the same environment as the container: at minimum DB_URL, DB_USERNAME, DB_PASSWORD, SECURITY_JWT_SECRET, ENCRYPTION_KEY and the DEEPSQL_CHAT_* group.
npm run lint # eslint
npm run build # production frontend bundle
cd backend && ./mvnw test # backend test suiteStack: Spring Boot 4 on Java 25 · React 19 + Vite · PostgreSQL with pgvector · Valkey for caching · nginx. Licensed under Apache 2.0.
Support
Stuck on an install, or want a second pair of eyes on a workload? Reach us: