Skip to content

Add the machine-readable pull/up/export surface, a drizzle-kit mcp adapter, and expand the skills catalog#5920

Open
dankochetov wants to merge 22 commits into
rc4from
ai
Open

Add the machine-readable pull/up/export surface, a drizzle-kit mcp adapter, and expand the skills catalog#5920
dankochetov wants to merge 22 commits into
rc4from
ai

Conversation

@dankochetov

@dankochetov dankochetov commented Jun 19, 2026

Copy link
Copy Markdown
Contributor

Builds on the machine-readable work from #5691.

What's in here

Machine-readable surface for pull / up / export / check

  • Extends the --output text|json envelope and typed SDK beyond generate/push to pull, up, export, and check.
  • New SDK entry points: src/sdk/pull.ts, src/sdk/up.ts, src/sdk/export.ts, src/sdk/check.ts, re-exported from src/sdk/index.ts.
  • JSON_CONTRACT.md / SDK.md document check() and the new commands as root SDK exports.

drizzle-kit mcp MCP adapter

  • New src/mcp/server.ts exposing three tools over stdio with a consent round-trip and a config param.
  • Registered as a brocli mcp verb, exempted from the after-hook process.exit(0).
  • Hardened for stdout purity (no stray writes that would corrupt the protocol) plus a credential-leak regression.
  • Documented in README.md and MCP.md.

Expanded installable skills catalog

  • Adds/updates skills: drizzle-migrations, drizzle-output-modes, drizzle-pull, drizzle-responses-and-errors, drizzle.

Hardening & tests

  • Fix tsc SIGABRT under moduleResolution: "node" in registerTool / hintSchema inference.
  • Widen toToolResult to accept the full SDK envelope unions.
  • New/extended suites: MCP (server.test.ts, stdio-smoke.test.ts, fixtures), public-surface post-build assertion, extended no-stdout / no-interactive regressions, check conformance scenarios, and type-level contract tests for CheckOptions/check.

…ck` brocli command, add `CheckOptions` derived type, and wire `check()` SDK export

- Export `checkOptions` const alongside `generateOptions`/`pushOptions` in `schema.ts`
- Add `prepareCheck` mirroring `prepareGenerate`: owns `setCliContext`, `assertCollisions`, `prepareCheckParams`
- Add `runCheck` mirroring `runGenerate`: `assertOrmCoreVersion`, `assertV3OutFolder`, calls `checkHandler`, returns `{status:'ok',dialect}`; no internal catch
- Shrink the `check` brocli command to reference `checkOptions`/`prepareCheck`/`runCheck`; preserve the text-mode success line exactly
- Add `CheckOptionsInput` and `CheckOptions` (derived via `BrocliInputOf`, omits `output`) in `contract.ts`
- Create `src/sdk/check.ts` as a 14-line wrapper matching the `generate`/`push` pattern
- Wire `src/sdk/index.ts`: add `export { check }` and `CheckOptions` to the type re-export
…build assertion, and extend type-level contract tests for `CheckOptions`/`check`
…K.md`

- Remove the "CLI-only — there is no `check()` SDK export" framing from `JSON_CONTRACT.md`
- Add note in the `## check` envelope section that `check()` SDK returns the same envelopes verbatim
- Extend "What the SDK gives you" bullet to include `CheckOptions`
- Change "Three root-level values" to "Four root-level values" in `SDK.md`
- Add `check` row to the values table and `CheckOptions` row to the types table
- Extend `--output` prose to mention `check` alongside `generate` and `push`
- Update import lines to include `check` and `CheckOptions`
- Add Minimal `check` example section with status-discriminator narrowing
… bump umbrella skill revision to 8; fix `drizzle-output-modes` YAML parse

- Rewrite the `check_error` section to state `check()` is a root SDK export returning the error envelope on integrity/conflict failures
- Bump `drizzle/SKILL.md` `metadata.revision` 7 → 8 (required when a skill body changes)
- Quote the `description` value in `drizzle-output-modes/SKILL.md` to fix the unquoted colon-space YAML parse failure that caused the skills CLI to silently drop the skill
…onses-and-errors` skill description and intro
…nbuilt outside CI and filter `default` from the CJS probe
…` fixture

- Create `src/mcp/` with `server.ts`: three SDK-wrapping tools (generate, push, check)
  with dual-channel results, correct MCP-03 annotations, loose outputSchema,
  and no credential or process.stdout.write calls
- Export `hintSchema` from `src/cli/hints.ts` (visibility-only) for reuse in the MCP layer
- Fix `writeDrizzleConfig` in `tests/mcp/fixtures.ts` to use a plain `export default`
  object instead of importing `defineConfig` from `drizzle-kit`, which requires a built
  dist and was causing `internal_error: Cannot find module index.js` in the test environment
…exit(0)

- Add `export const mcp` command to `src/cli/schema.ts` with a lazy
  `await import('../mcp/server')` handler so non-mcp invocations pay zero
  parse cost for the bundled MCP SDK
- Add `mcp` to the import and `run([...])` list in `src/cli/index.ts`
- Change the brocli after-hook condition to skip process.exit(0) for both
  `studio` and `mcp`, keeping the stdio transport alive for the session
- Add `writeSentinelPushConfig` to `tests/mcp/fixtures.ts`: creates a push config
  with a unique sentinel password in an unreachable postgres URL, alongside a
  minimal valid schema so push proceeds to the DB driver level
- Export `stageOut` from `tests/mcp/fixtures.ts` for use by the new test
- Add credential-leak regression in `tests/mcp/server.test.ts`: calls the push
  tool with the sentinel config and asserts the sentinel is absent from the text
  content block, structuredContent, and captured stderr
- Build `dist/bin.cjs` with the bundled MCP SDK and `mcp` verb; the spawned
  stdio smoke test now connects, lists check/generate/push, and sees the version
  banner on stderr — all 12 MCP tests green
…hintSchema` inference

Under moduleResolution:"node" the MCP SDK's registerTool generic resolves zod/v3 and
zod/v4/core as distinct module paths, then tries to unify them with the caller's zod
schema. This causes tsc to exhaust heap (TS2589 / SIGABRT) when the typetest suite
reaches server.ts via schema.ts's dynamic import.

Two sources of explosion, both fixed in server.ts only:

1. registerTool generic: cast McpServer to a local McpServerCompat interface whose
   registerTool takes z.ZodTypeAny (not the deep ShapeOutput<ZodObject<...>>
   instantiation). Runtime behavior is identical — the same Zod schemas are passed.

2. hintSchema 37-member union: the assignability check against the pinned type was
   still evaluated. Changed to a double-cast (as unknown as z.ZodTypeAny) so tsc
   skips the assignability proof entirely.

handler args change from inferred typed params to Record<string,unknown> with
inline casts — no effect on the MCP wire protocol or runtime validation.
MCP adapter:
- Return an `invalid_hints` envelope for malformed hints (loosened tool input schema) instead of an MCP `InvalidParams` protocol error
- Serialize tool calls so concurrent `generate`/`push` can't interleave snapshot reads/writes
- Guard dotenv from writing to the MCP stdout stream under `DOTENV_CONFIG_DEBUG`/`QUIET`
- Add a defensive handler catch and import `Hint` from `../sdk`

SDK:
- Resolve the migration `output` format from the active CLI context in `prepare{Generate,Push,Check}`, so the SDK wrappers no longer pass `output: 'json'` twice

Docs:
- Move the MCP tool list, consent round-trip, and config details from the README into a dedicated `MCP.md`
- Drop obsolete/redundant lines in `README.md` and `JSON_CONTRACT.md` and reword the tool descriptions
…the installable skills catalog

Complete drizzle-kit's machine surface for the three remaining lifecycle commands, each climbing the CLI-JSON → SDK → MCP pattern:

- CLI `--output text|json` for `export`, `up`, and `pull` — text byte-identical, JSON a typed envelope (`export` `{statements, warnings}` with no joined `sql`; `up` `{upgraded}`; `pull` a paths-only manifest that never emits `missing_hints`). All human chatter gated on `outputFormat()==='text'` and every `console.error`/`console.log`+`process.exit(1)` path converted to a typed throw.
- Root SDK exports `exportSql` (reserved-word alias for `export`), `up`, and `pull`, each returning the byte-identical CLI envelope side-effect-free at the host-process boundary — growing the public surface to `['check','defineConfig','exportSql','generate','pull','push','up']` (7 keys).
- MCP `export` (`readOnlyHint`+`idempotentHint`), `up` (`idempotentHint`, not `readOnlyHint`), and `pull` (config-path-only input; per-call `com.drizzle.team/pull.destructiveHint` `_meta` signal when `--init`) tools, registered as thin consumers of the SDK functions.
- Typed `database_driver_error` with redacted fields for `pull` connect/introspect and `--init` migrate failures; a credential-leak sentinel regression proving no auth substrings reach any channel.
- A `drizzle-pull` installable skill, snapshot-diff collapse guidance folded into the `drizzle-migrations` skill, declarative skill descriptions, and the umbrella `drizzle` skill revision bumped to `9`.
- Contract docs swept — `JSON_CONTRACT.md` / `SDK.md` / `MCP.md` / `OUTPUT_MODES.md` and the `drizzle-responses-and-errors` skill.
- CLI ≡ SDK conformance scenarios for `export` / `up` / `pull` and a 7-key public-surface regression. Zero new runtime dependencies.

Claude-Session: https://claude.ai/code/session_01FexAFYyJCxw4cvjTeyXgj2
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant