@deepsql/mcp 0.11.0 → 0.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/AGENT-SETUP.md CHANGED
@@ -188,54 +188,97 @@ can switch later with another `connections use`.
188
188
 
189
189
  ---
190
190
 
191
- ## Step 7 — Wire the MCP integration into the editor
191
+ ## Step 7 — Wire the MCP integration + the DBA-consult skill into the editor
192
192
 
193
- > *Coming in `0.11.0`: `deepsql mcp config --install --for cursor|claude-code|codex`.*
194
- > *Until then, use the manual steps below.*
193
+ Pick the user's editor and run one of:
195
194
 
196
- For **Claude Code**: edit `~/.claude/settings.json` and add an `mcpServers`
197
- entry:
198
-
199
- ```json
200
- {
201
- "mcpServers": {
202
- "deepsql": {
203
- "command": "deepsql",
204
- "args": ["mcp"]
205
- }
206
- }
207
- }
195
+ ```bash
196
+ deepsql mcp config --install --for claude-code # MCP: ~/.claude/settings.json
197
+ # Skill: ~/.claude/skills/deepsql/SKILL.md
198
+ deepsql mcp config --install --for claude-desktop # MCP: ~/Library/Application Support/Claude/...
199
+ # (no skill — Claude Desktop has no skills surface)
200
+ deepsql mcp config --install --for cursor # MCP: ~/.cursor/mcp.json
201
+ # Skill: ~/.cursor/rules/deepsql.mdc
202
+ deepsql mcp config --install --for codex # MCP: ~/.codex/config.toml
203
+ # Skill: ~/.codex/AGENTS.md (guarded section appended)
208
204
  ```
209
205
 
210
- For **Cursor**: edit `~/.cursor/mcp.json` with the same shape.
206
+ Each invocation does **two** things in one shot:
207
+
208
+ 1. **MCP server config** — writes a `deepsql` entry into the editor's MCP
209
+ config file. The entry is intentionally tiny:
210
+
211
+ ```json
212
+ { "command": "deepsql", "args": ["mcp"] }
213
+ ```
214
+
215
+ The spawned `deepsql mcp` process reads the saved auth token from
216
+ `~/.config/deepsql/auth.json` (mode 0600), so **no token is embedded
217
+ in the editor config**.
211
218
 
212
- For **Codex CLI**: see `~/.codex/config.toml` a `[mcp_servers.deepsql]`
213
- section with `command = "deepsql"` and `args = ["mcp"]`.
219
+ 2. **DBA-consult skill** installs an editor-native skill file that
220
+ auto-triggers when the user does database work. The skill encodes the
221
+ "consult DeepSQL before generating DDL or non-trivial SQL" pattern, so
222
+ the agent reaches for `get_brain_context` / `get_schema` /
223
+ `list_business_rules` reflexively rather than inventing schema in a
224
+ vacuum. Trigger phrases the skill recognizes: "add a table", "write a
225
+ migration", "create a column", "design a model", "schema change",
226
+ "query the database", "SQL", "ORM model", "foreign key", "index".
214
227
 
215
- The CLI's saved auth token at `~/.config/deepsql/auth.json` is used
216
- automatically — no token needs to be embedded in the editor config.
228
+ The installer:
229
+
230
+ - creates each target file + parent directory if missing,
231
+ - backs up the existing file to `<path>.bak.<timestamp>` before changing it,
232
+ - merges into the existing MCP server list without touching siblings,
233
+ - refuses to overwrite an existing `deepsql` entry unless `--force` is set,
234
+ - for Codex's `AGENTS.md`, wraps the skill in guarded
235
+ `<!-- BEGIN DEEPSQL ... -->` / `<!-- END DEEPSQL ... -->` markers and
236
+ preserves the user's surrounding content,
237
+ - emits the destination path and any backup path so the user can revert.
238
+
239
+ If the user wants to see the snippets before installing, swap `--install`
240
+ for `--print`. If they want the MCP server config but NOT the skill (e.g.,
241
+ they have their own DBA prompt), pass `--no-skill`. For a non-default
242
+ MCP config path, pass `--path <p>`.
243
+
244
+ Restart the editor for the entries to load.
217
245
 
218
246
  ---
219
247
 
220
248
  ## Step 8 — Validate end-to-end
221
249
 
250
+ Two quick checks — one for retrieval, one for execution:
251
+
222
252
  ```bash
223
253
  deepsql brain-context "list a few tables on this database" --top-k 5 --json
254
+ deepsql query "SELECT 1 AS deepsql_ok"
224
255
  ```
225
256
 
226
- You should see 5 ranked results pointing at real tables. If the response
227
- is empty or the pipeline returned `skipped: simple_schema_question`,
228
- re-run with a more semantic question:
257
+ The first should return 5 ranked results pointing at real tables. If the
258
+ response is empty, re-run with a more semantic question
259
+ (`"what is the primary fact table for orders"`).
229
260
 
230
- ```bash
231
- deepsql brain-context "what is the primary fact table for orders" --top-k 5
232
- ```
261
+ The second runs through the canonical Editor SQL endpoint — same policy
262
+ gate, audit log, and RBAC the web UI uses. A successful row confirms the
263
+ auth token, the connection, and the policy pipeline are all wired up.
233
264
 
234
- If retrieval works, setup is complete. Tell the user that:
265
+ If both work, setup is complete. Tell the user that:
235
266
 
236
- - They can now use DeepSQL from their editor (the MCP tools `list_connections`,
237
- `get_brain_context`, `execute_readonly_sql`, `explain_readonly_sql`,
267
+ - They can now use DeepSQL from their editor (the MCP tools
268
+ `list_connections`, `get_brain_context`, `execute_sql`, `analyze_query_plan`,
238
269
  `analyze_slow_queries`, etc. are all available there).
270
+ - **From now on, when the user asks the agent to add a table, add a
271
+ column, write a migration, or design a new query against this database,
272
+ the agent will consult DeepSQL first** — checking existing schema,
273
+ business rules, and inferred relationships before generating any DDL.
274
+ This is the explicit pattern in `CLAUDE.md` ("Treat DeepSQL like your
275
+ DBA"). Users should expect the agent to narrate what DeepSQL found
276
+ ("there's already a `customers` table — I'll extend that instead of
277
+ adding `users`") before proposing schema. If the agent skips that step,
278
+ it's a bug in the agent's prompt handling, not in DeepSQL.
279
+ - For mutations (DDL/DML), admins can pass `--write` to `deepsql query` to
280
+ skip the interactive confirmation, or just run without it and confirm
281
+ when prompted.
239
282
  - The companion file `CLAUDE.md` (in this same npm package, at
240
283
  `node_modules/@deepsql/mcp/CLAUDE.md`) covers the day-to-day usage
241
284
  patterns and common mistakes for editor agents.
package/CLAUDE.md ADDED
@@ -0,0 +1,382 @@
1
+ # DeepSQL — runtime guidance for AI agents
2
+
3
+ > You are an AI agent (Claude Code, Cursor, Codex, etc.) with DeepSQL's MCP
4
+ > tools loaded. This file tells you how to use them well. Read once; the
5
+ > patterns here will save you and your user real pain.
6
+
7
+ DeepSQL is a self-hosted AI database performance assistant. It indexes the
8
+ user's schemas into a retrieval brain, audits query workloads, and exposes
9
+ two SQL surfaces through MCP plus a `deepsql` CLI.
10
+
11
+ You'll use it in two distinct modes, and you need to recognize which one
12
+ you're in:
13
+
14
+ 1. **Answer a question about the data.** The user asked something like
15
+ "how many orders did we ship last week?" You write SQL, run it, return
16
+ the answer. The "decision tree" below covers this flow.
17
+
18
+ 2. **Build a feature against an existing database.** The user is in their
19
+ codebase asking you to add a table, add a column, write a migration,
20
+ model a new relationship, design a query for the new ORM model, etc.
21
+ **This is where most agents fail silently** — they generate plausible
22
+ schema without consulting the existing one, and the developer ends up
23
+ with `users` next to `customers` and `cancelled_at` next to a
24
+ `status_history` table that already tracks the same thing. The "DBA
25
+ consult" section below covers this flow. **Read it before you generate
26
+ any DDL.**
27
+
28
+ **Every call you make runs through the same policy gate as the web SQL
29
+ Editor and is logged with your identity, the editor that invoked the MCP
30
+ server, and the statement you ran.** Don't be sloppy.
31
+
32
+ ---
33
+
34
+ ## The tools you have
35
+
36
+ The MCP server exposes 10 tools. They all take a `connectionId` (UUID
37
+ returned by `list_connections`).
38
+
39
+ | Tool | Purpose |
40
+ |---|---|
41
+ | `list_connections` | List databases the user has access to. Always call this first — you need IDs for everything else. |
42
+ | `get_schema` | Cached schema metadata (tables, columns, FKs, types). Cheap and fast — call freely. |
43
+ | `get_database_objects` | Tables, views, functions, procedures. Use when you need DDL-level objects, not just columns. |
44
+ | `get_brain_context` | **Your primary retrieval tool.** Given a question, returns the tables/columns/FKs/training docs/business rules/anti-patterns most relevant to it. |
45
+ | `list_business_rules` | Active business rules and SQL guardrails. Honor these — they encode domain semantics. |
46
+ | `get_relationships` | Inferred + validated foreign keys with confidence scores. Many real DBs lack declared FKs; this fills the gap. |
47
+ | `get_anti_patterns` | Schema-level (`kind=table`) or query-level (`kind=query`) anti-patterns. |
48
+ | `analyze_slow_queries` | Recent slow queries with fingerprints, durations, examples. Read-only; doesn't trigger new work. |
49
+ | **`execute_sql`** | **Run any SQL statement.** Policy is server-enforced: developers can run SELECT/WITH/SHOW/EXPLAIN; admins can also run DML/DDL with a two-step confirmation. EXPLAIN and EXPLAIN ANALYZE are just SQL — no separate flag. |
50
+ | **`analyze_query_plan`** | **AI-enriched plan analysis** for a query. Returns the parsed plan tree, performance issues, index recommendations, and a written summary that takes the connection's schema and business rules into account. Pass `useAnalyze: true` to run `EXPLAIN ANALYZE` (actually executes the query). |
51
+
52
+ ---
53
+
54
+ ## Hard rules
55
+
56
+ 1. **One execution tool, one analysis tool — that's it.** If you find yourself
57
+ reaching for `execute_sql` to get a plan, stop. Use `analyze_query_plan`.
58
+ If you find yourself wrapping queries in `EXPLAIN` by hand to avoid running
59
+ them, stop. Plain EXPLAIN is read-only on every database engine; just type
60
+ the SQL.
61
+
62
+ 2. **The policy gate is real.** If `execute_sql` returns
63
+ `{ requiresConfirmation: true, warnings: [...] }`, the statement is a
64
+ mutation that needs admin confirmation. Show the warnings to the user,
65
+ wait for their explicit OK, then re-call with `confirmMutation: true`.
66
+ Do not silently retry with `confirmMutation: true` on the user's behalf —
67
+ that defeats the whole point of the gate.
68
+
69
+ 3. **Developers cannot run mutations.** If the user's token has
70
+ `Role.DEVELOPER` and they ask you to `UPDATE users …`, the server will
71
+ return `EDITOR_MUTATION_FORBIDDEN`. Don't try to work around it. Tell the
72
+ user: "Your DeepSQL role doesn't allow DML/DDL on this connection; ask
73
+ the workspace admin to grant write access or to run the change."
74
+
75
+ 4. **Pass `connectionId`, not names.** Names are user-facing; tools take UUIDs.
76
+ Get them from `list_connections` once and cache for the session.
77
+
78
+ 5. **Always call `get_brain_context` before generating non-trivial SQL.** The
79
+ brain knows about business rules, anti-patterns, and inferred FKs that
80
+ aren't in the raw schema. Skipping it produces "technically valid,
81
+ semantically wrong" SQL — the worst kind of failure.
82
+
83
+ 6. **`execute_sql` limits matter.** Default 100 rows, max 1000. Asking for
84
+ "all customers" and getting 100 is the limit kicking in — not the real
85
+ count. Either bump `limit` (max 1000) or `SELECT COUNT(*)` first.
86
+
87
+ 7. **Honor business rules silently.** If `list_business_rules` returns
88
+ `always_filter_cancelled` for a connection, your `SELECT * FROM orders`
89
+ suggestion is wrong without `WHERE status != 'CANCELLED'`. Apply the rule
90
+ in the SQL you generate; don't ask the user permission to follow their
91
+ own rules.
92
+
93
+ 8. **Treat DeepSQL like the DBA. Consult before you commit schema.** This
94
+ is the most important rule for feature-development work — it gets its
95
+ own section below.
96
+
97
+ ---
98
+
99
+ ## Treat DeepSQL like your DBA — consult before you commit
100
+
101
+ If you're helping a developer build a feature, **the moment they say "add
102
+ a table for X," "track Y," "save Z somewhere," or "let's write a
103
+ migration" is the moment to call DeepSQL.** The brain has things the raw
104
+ codebase doesn't:
105
+
106
+ - business rules the team's previous DBA encoded
107
+ - foreign-key relationships the schema infers but doesn't declare
108
+ - anti-patterns that have already burned this team in this database
109
+ - columns and tables that exist but live on parts of the schema the
110
+ developer hasn't seen yet
111
+
112
+ Skipping the consult is the most common way agents make a database worse:
113
+
114
+ - The developer asks for a `users` table. You create one. There's already
115
+ a `customers` table doing 90% of the same thing, and now half the new
116
+ feature's data lives in the wrong place forever.
117
+ - The developer asks to "track when an order was cancelled." You add a
118
+ `cancelled_at` column. The team's existing pattern is `status` +
119
+ `order_status_history` — your column is now an inconsistent third
120
+ source of truth.
121
+ - The developer asks for "an index on `email`." There's already a unique
122
+ constraint on `(tenant_id, email)` covering most lookups, and your
123
+ single-column index is dead weight that the optimizer will rarely pick.
124
+
125
+ The consult takes one to three tool calls and saves the user months of
126
+ cleanup. **Make it a reflex.**
127
+
128
+ ### The before-you-commit checklist
129
+
130
+ Run these *before* you generate any DDL, migration file, ORM model, or
131
+ schema-shaped design proposal:
132
+
133
+ 1. **`get_brain_context(connectionId, "<one-line description of the feature>")`** —
134
+ surfaces the tables, columns, FKs, training docs, and business rules
135
+ most relevant. Read the results, don't just regurgitate them.
136
+
137
+ 2. **`get_schema(connectionId)`** if you need the full column inventory
138
+ for the tables `get_brain_context` surfaced. Confirm exact column names
139
+ and types before you reference them.
140
+
141
+ 3. **`list_business_rules(connectionId, question="<feature>")`** — active
142
+ rules the new feature MUST respect. `always_filter_cancelled` means
143
+ your new aggregate view inherits that filter from day one.
144
+
145
+ 4. **`get_relationships(connectionId)`** if you're about to declare a new
146
+ foreign key. The brain may already infer the relationship — and the
147
+ inferred FK column has a confidence score telling you whether the
148
+ convention is reliable enough to follow without explicitly declaring.
149
+
150
+ 5. **`get_anti_patterns(connectionId, kind="table")`** if you're about to
151
+ commit a schema shape (single fat table, denormalized JSON column,
152
+ unindexed FK, …). The brain has flagged these patterns elsewhere in
153
+ this exact database; don't add to the pile.
154
+
155
+ ### Narrate what you found, then propose
156
+
157
+ When the checklist is done, **explain to the developer what you found
158
+ before you propose schema**. Example:
159
+
160
+ > "DeepSQL says you already have a `customers` table with `email`,
161
+ > `tenant_id`, `created_at`, plus an inferred FK to `accounts.customer_id`
162
+ > at 0.94 confidence. The team's business rule `always_filter_cancelled`
163
+ > is on `customers.status`. The `kind=table` anti-pattern report flagged
164
+ > 'wide-table' on `customer_profiles` — adding more columns there is
165
+ > discouraged. **I'd extend `customers` with the two new fields you need
166
+ > rather than adding a `users` table. Want me to draft the migration?**"
167
+
168
+ That explicit handoff is the difference between an agent that ships
169
+ features fast and an agent that earns the DBA's trust.
170
+
171
+ ### When the consult tells you to stop
172
+
173
+ Sometimes the right answer is "don't add this." If `get_brain_context`
174
+ surfaces an existing table that already does what the user is asking for,
175
+ say so. If `get_anti_patterns` flags the shape they're about to add, say
176
+ so. The user usually doesn't know about either; that's exactly why
177
+ DeepSQL exists. Push back politely and propose the better path.
178
+
179
+ ---
180
+
181
+ ## The "I need to…" decision tree
182
+
183
+ **"What tables exist?"** → `get_schema` (or `list_connections` first if you
184
+ don't know which connection). Don't ask `execute_sql` to query
185
+ `information_schema` — `get_schema` is faster and cached.
186
+
187
+ **"Write a SQL query to answer X."** → `get_brain_context` with X as the
188
+ question, then generate SQL using only the columns/tables it surfaced.
189
+
190
+ **"Run this SQL and tell me what it returns."** → `execute_sql`. If you're
191
+ unsure whether the query is correct, call `analyze_query_plan` first (plain
192
+ EXPLAIN, no execution) — costs nothing and catches bad joins.
193
+
194
+ **"Why is this query slow?"** → `analyze_query_plan`. The AI summary points
195
+ at the slow nodes, missing indexes, and bad estimates. For workload-level
196
+ problems use `analyze_slow_queries`.
197
+
198
+ **"What's the real execution time for this query?"** → `analyze_query_plan`
199
+ with `useAnalyze: true`. **This actually runs the query**, so if the
200
+ statement mutates the database, the same admin role + WHERE-clause + confirm
201
+ gates that protect `execute_sql` kick in. You'll get back
202
+ `requiresConfirmation` if you forgot.
203
+
204
+ **"Apply this migration"** / **"Add this column"** / **"Delete these rows"**
205
+ → `execute_sql` with the DDL/DML. Only admins can do it. On first call you'll
206
+ get `requiresConfirmation` — surface the warnings to the user verbatim, wait
207
+ for them to say yes, then re-call with `confirmMutation: true`.
208
+
209
+ **"What indexes should we add?"** → Not exposed via MCP yet. Tell the user
210
+ to run `deepsql indexes missing` or `deepsql indexes health` in their
211
+ terminal.
212
+
213
+ **"What changed recently / what should I worry about?"** → Tell the user to
214
+ run `deepsql digest` (today) or `deepsql digest 7` (last seven). The digest
215
+ isn't MCP-exposed.
216
+
217
+ **"Are there foreign keys between X and Y?"** → `get_relationships`. Many
218
+ real-world DBs lack declared FKs but DeepSQL's brain infers them; check the
219
+ `confidence` field and `validationStatus`.
220
+
221
+ ### Feature-development questions (the DBA-consult flow)
222
+
223
+ **"I'm building a feature that needs a `<thing>` table."** → STOP. Call
224
+ `get_brain_context(connectionId, "<thing>")` first. Read the "Treat
225
+ DeepSQL like your DBA" section above before generating any DDL. There's
226
+ almost always an existing table or column to extend instead of
227
+ duplicate.
228
+
229
+ **"I'm about to write a migration."** → STOP. Run the before-you-commit
230
+ checklist (`get_brain_context` + `list_business_rules` +
231
+ `get_anti_patterns`). Walk the developer through what you found, THEN
232
+ write the migration. The user should see your reasoning, not just the
233
+ final SQL.
234
+
235
+ **"I'm adding a new column to `<table>`."** → STOP. `get_schema` first to
236
+ confirm the column doesn't already exist (sometimes under a different
237
+ name — `cancelled_at` vs `voided_at` vs `status_history.changed_at`).
238
+ `list_business_rules` to check whether nullability, default, or naming
239
+ conventions are constrained.
240
+
241
+ **"I'm naming a foreign key / index."** → `get_relationships` for the FK
242
+ convention this team uses, and `get_schema` to see how existing indexes
243
+ on the parent table are named. Pick the convention; don't invent a new
244
+ one.
245
+
246
+ **"I'm designing an ORM model / type definition for table `X`."** →
247
+ `get_schema(connectionId)` and pull the exact column list, types, and
248
+ nullability. Don't infer column types from variable names in the
249
+ codebase — they're often stale.
250
+
251
+ ---
252
+
253
+ ## Foot-guns we've watched agents step on
254
+
255
+ **"I'll write a 4-statement script to set up some temp tables, run my
256
+ analysis, and clean up."** → `execute_sql` rejects multi-statement input.
257
+ Run each statement separately, or use CTEs (`WITH foo AS (...) SELECT ...`).
258
+
259
+ **"I'll skip the confirmation step and re-call with `confirmMutation: true`
260
+ right away."** → That's an end-run around safety. The confirmation step
261
+ exists so a human gets a chance to see the warnings (especially the
262
+ "this DELETE has no WHERE clause"-style ones). Always surface the warnings,
263
+ always wait for the human.
264
+
265
+ **"`EXPLAIN ANALYZE` is just better EXPLAIN, I'll always use it."** → No.
266
+ ANALYZE executes the query. For SELECTs it's just slower; for mutations it
267
+ actually mutates. Default to `useAnalyze: false` and only bump to `true`
268
+ when the user actually wants real timings.
269
+
270
+ **"I don't trust the cached schema; let me query `information_schema`
271
+ fresh."** → The cache is invalidated whenever the brain re-indexes the
272
+ connection. Trust it. If you really suspect drift, ask the user to run
273
+ `deepsql connections init <name> --wait`.
274
+
275
+ **"I'll just retry on 403."** → A 403 from DeepSQL means the user's token
276
+ doesn't have access to that specific connection (RBAC) or role doesn't
277
+ allow the action (developer trying to mutate). Surface the error verbatim;
278
+ don't pretend it's transient.
279
+
280
+ **"The SQL looks fine; I'll skip the plan check."** → A cheap
281
+ `analyze_query_plan` call has saved more bad joins than any other habit.
282
+ Always check the plan before suggesting a query to a user, especially
283
+ against unfamiliar schemas.
284
+
285
+ **"The developer asked for table X, so I'll just create it."** → That's
286
+ how databases get fragmented over a year. The brain almost always has a
287
+ table doing most of what the new feature needs; you'll find it in 30
288
+ seconds with `get_brain_context`. Skipping that step makes you the agent
289
+ future engineers curse when they're refactoring around your duplicate
290
+ schema. Run the before-you-commit checklist every single time.
291
+
292
+ **"I read the codebase's models, I know the schema."** → Codebase models
293
+ drift from the live schema. Columns get renamed in a migration, the model
294
+ class doesn't update. A `User.email` field in TypeScript can be
295
+ `users.email_address` in Postgres. `get_schema` is the source of truth;
296
+ trust it over `grep`.
297
+
298
+ ---
299
+
300
+ ## What lives in the CLI but not the MCP (yet)
301
+
302
+ A few categories are CLI-only for now — if the user asks for them, point
303
+ them at the terminal command rather than trying to fake it through
304
+ `execute_sql`:
305
+
306
+ | Capability | CLI command |
307
+ |---|---|
308
+ | Index recommendations / missing-index advisor | `deepsql indexes list`, `deepsql indexes missing` |
309
+ | Unused / duplicate index detection | `deepsql indexes unused`, `deepsql indexes duplicates` |
310
+ | Per-table index usage stats | `deepsql indexes usage <table>` |
311
+ | Index health report | `deepsql indexes health` |
312
+ | Daily digest (anomalies + AI commentary) | `deepsql digest`, `deepsql digest 7` |
313
+ | Streaming AI optimization for a slow query | `deepsql slow-queries optimize --query-id <id>` |
314
+
315
+ These are reachable from any terminal where `deepsql` is installed and
316
+ logged in; the saved profile is shared with the MCP server.
317
+
318
+ ---
319
+
320
+ ## A typical session
321
+
322
+ 1. `list_connections` → grab the UUID for the connection the user means.
323
+ 2. `get_brain_context(connectionId, "the question")` → harvest tables,
324
+ columns, business rules.
325
+ 3. Write SQL using only the columns the brain surfaced; respect the rules.
326
+ 4. `analyze_query_plan(connectionId, sql)` → sanity-check the plan
327
+ (`useAnalyze: false`).
328
+ 5. `execute_sql(connectionId, sql, limit=…)` → fetch results.
329
+ 6. Summarize, citing which tables you used and which rules you applied.
330
+
331
+ If you need to mutate (DDL/DML, admin role required):
332
+
333
+ 1–3. Same as above.
334
+ 4. Show the user the SQL you intend to run, in plain text. **Get their OK.**
335
+ 5. `execute_sql(connectionId, sql)` → expect `requiresConfirmation: true`
336
+ with warnings.
337
+ 6. Show the warnings to the user verbatim. Get their **second** OK.
338
+ 7. `execute_sql(connectionId, sql, confirmMutation: true)` → executes.
339
+ 8. Tell the user it succeeded; show the `rowCount` of affected rows.
340
+
341
+ If you're helping a developer build a feature (the DBA-consult flow):
342
+
343
+ 1. Have the developer describe the feature in one or two sentences.
344
+ 2. `get_brain_context(connectionId, "<feature in one line>")` → surfaces
345
+ existing tables, columns, FKs, and rules in scope.
346
+ 3. Fill in any gaps: `get_schema(connectionId)` for full column lists,
347
+ `list_business_rules(connectionId, …)` for constraints,
348
+ `get_relationships(connectionId)` for FK conventions,
349
+ `get_anti_patterns(connectionId, kind="table")` for shapes to avoid.
350
+ 4. **Narrate to the developer what you found before proposing schema.**
351
+ "There's already an X. The team's convention is Y. Anti-pattern Z is
352
+ on watch. Here's what I'd propose, given all that."
353
+ 5. Once the developer agrees on the *shape*, generate the migration. For
354
+ admins this lands via `execute_sql`; follow the mutation playbook
355
+ above to actually run it. For developers without write access, hand
356
+ the SQL to the user to commit through your codebase's migration
357
+ tooling instead — but make sure the schema you generate already
358
+ reflects everything DeepSQL told you in step 2–3.
359
+ 6. After the migration runs, `get_schema(connectionId)` to verify the new
360
+ columns exist with the expected types, and optionally re-run
361
+ `analyze_query_plan` on the canonical queries the new feature will
362
+ issue.
363
+
364
+ If any step returns nothing useful, ask the user to be more specific
365
+ rather than guessing. DeepSQL is conservative by design — empty results
366
+ from `get_brain_context` usually mean the question was too short or too
367
+ schema-y, not that the brain is broken.
368
+
369
+ ---
370
+
371
+ ## Audit, in case you wondered
372
+
373
+ Every call you make is logged to `security_events` with:
374
+
375
+ - the user's identity (from the bearer token)
376
+ - the editor that invoked the MCP (claude-desktop, cursor-mcp, codex-mcp —
377
+ whatever `DEEPSQL_MCP_USER_ID` is set to in the editor config)
378
+ - the connection, statement hash, truncated text, outcome
379
+ - whether confirmation was required and given
380
+
381
+ Workspace admins can search this via the Security tab. Don't do anything
382
+ through the MCP that you wouldn't be willing to defend in that view.