Skip to main content
Glama
nlqdb

nlqdb

Official

nlqdb — your autonomous DBA.

nlqdb attaches to the Postgres or Cloudflare D1 database you already run, proposes the changes it needs, applies the ones you approve, measures them, and reverts any that regress.

Why it exists: the mission — encapsulate the trial-and-error journey every company walks to a good database infrastructure.

Where it is going (docs/END_GOAL.md): paste a connection string — on nlqdb.com, with the CLI, through the SDK, or from your coding agent over MCP — and the first proposals arrive within minutes, each with its expected effect, cost and inverse. Apply is one click; nlqdb then measures p95 on the same queries and keeps the change or reverts it, never on your app's request path. That loop is being built (Roadmap); what is live today is the hosted product below.

No backend to build. You write HTML; each component asks for what it wants in plain English; nlqdb infers the schema, writes the SQL, runs it, and renders the result. There is no backend for you to build.

Two actions. That's the whole product:

  1. Create a database — one word: a name (or a goal).

  2. Talk to it in plain English.

<script src="https://elements.nlqdb.com/v1.js" type="module"></script>

<nlq-data
  goal="the 5 newest orders, with customer and item"
  api-key="pk_live_xxx"
  template="table"
  refresh="10s"
></nlq-data>

That's the entire backend for a live order list — no API to write, no schema to define, no JSON to parse. Engine choice (Postgres / Mongo / Redis / DuckDB / pgvector / …), schema inference, indexing, backups, and auto-migration between engines based on your real workload are background concerns you never have to see.

Status — early, open

nlqdb is early and built in the open, but fully public — no gate, no invite code. The marketing site, the /v1/ask pipeline, the <nlq-data> / <nlq-action> elements, the chat app, the TypeScript SDK, the hosted MCP server, and the nlq CLI are all live in some form (see the surface table below). Natural-language → SQL accuracy is still climbing toward our public bar (BIRD ≥ 0.65, Spider 2.0 ≥ 0.75 on the free model chain), so answers can be wrong — every response carries a confidence signal and the SQL it ran.

Related MCP server: ogham-mcp

Use it

Connecting an agent over MCP? On Claude Code, one marketplace add wires the hosted server and both memory skills in a single step:

/plugin marketplace add nlqdb/nlqdb
/plugin install nlqdb-memory@nlqdb

On any other MCP host, connect your agent with one browser-OAuth approval; headless hosts skip the browser with npx -y @nlqdb/mcp and an sk_mcp_* MCP key (MCP setup). @nlqdb/sdk and @nlqdb/mcp are both published and importable from npm.

The 60-second walkthrough — plain HTML, CLI, and ten framework wrappers — lives at docs.nlqdb.com. Start with the HTML tutorial or the CLI tutorial.

You don't generate an API key separately: describe your database at nlqdb.com, and the chat hands you a <nlq-data> snippet with the key already inlined.

Examples

examples/ — minimal scaffolds in plain HTML, Next.js, Nuxt, SvelteKit, Astro, plus a CLI-only walkthrough. Each is the smallest valid integration around one <nlq-data> element or one CLI session.

What makes it different

Four things every release has to move, none allowed to regress (GLOBAL-025):

  • Engine quality — natural-language → SQL accuracy (measured continuously on BIRD + Spider 2.0 + an internal eval), plus the multi-engine layer that moves your data to the right engine for your workload.

  • Onboarding — landing to first answer in under a minute, no card, no config.

  • UX — see the diff before any write, see the SQL behind every answer, and on low confidence get a one-click clarify — a guided turn, never a dead-end, and never a silent guess.

  • Performance — sub-400 ms cached, sub-1.5 s cold.

The bet: get this right on free, open models and it only gets better on frontier ones — the scaffolding compounds with whatever model is underneath.

Models & plans

  • Free forever on the built-in open-model chain — queries, embeds, and the elements, no card required.

  • Bring your own LLM key (Anthropic / OpenAI / Gemini / Grok / OpenRouter) on any tier, at no markup.

  • Hosted premium models on paid plans, when you'd rather not manage a key of your own.

  • Self-host the source — the engine, CLI, MCP server, and SDKs are source-available under FSL-1.1-ALv2: free to self-host for any non-competing use, bring your own LLM key, no per-call fees. The license auto-converts to Apache 2.0 two years after each release.

The hosted-premium model lane went live 2026-08-14. The full model strategy is in GLOBAL-026.

Surfaces at a glance

Surface

Status

Where

HTTP API (POST /v1/ask, POST /v1/run, POST /v1/insert)

✓ shipped

apps/api/src/ask/**

<nlq-data> + <nlq-action> elements

✓ shipped (v0.1)

packages/elements/**

@nlqdb/sdk (TypeScript)

✓ shipped (incl. runSql + cross-tenant grant + pack-import runner verbs) — installable from npm; insert() and runSql params publish in 0.5.0

packages/sdk/**

Framework wrappers (React / Next / Vue / Nuxt / Svelte / SvelteKit / Astro / Solid + Swift)

~ built + CI-tested; npm / SPM publish pending

packages/{react,next,…}/**

Chat app nlqdb.com/app

✓ shipped

apps/web/**

Hosted MCP server mcp.nlqdb.com/mcp

✓ shipped (host auto-detect pending)

apps/mcp/**, packages/mcp/**

Local stdio MCP server @nlqdb/mcp

✓ shipped — npx -y @nlqdb/mcp with an sk_mcp_* key

packages/mcp/**

Droppable agent artifacts (AGENTS.md · Claude Code skill + plugin · Cursor rules · Codex config)

✓ shipped — /plugin marketplace add nlqdb/nlqdb installs the server + skills in one step

apps/web/public/agent-artifacts/**

nlq CLI (Go)

✓ shipped (core verbs; device-login pending)

cli/**

Full integration matrix in docs/progress.md.

Packages on npm

Published to the public npm registry with build provenance (SK-CIPERM-003). Version badges are live from npm; the table itself is generated from the workspace by scripts/sync-readme-packages.mjs, so it lists exactly the packages that are un-gated ("private" removed) and nothing that isn't.

Package

Version

What it is

Source

@nlqdb/cli

@nlqdb/cli

Shim that installs the nlq CLI binary for the host platform.

packages/cli-shim

@nlqdb/mcp

@nlqdb/mcp

Analytical-memory MCP server for nlqdb — a real database your AI agent can GROUP BY / JOIN / aggregate over in natural language, not just recall.

packages/mcp

@nlqdb/sdk

@nlqdb/sdk

Typed HTTP client for the nlqdb /v1 API — works in browsers, Node, Bun, Workers.

packages/sdk

Roadmap

The section below is the live focus; the numbered phases after it are the hosted product's roadmap, kept until the GLOBAL-043 deletion series. Canonical plan + exit gates: docs/phase-plan.md. Legend: ✓ shipped · ~ in progress · ◯ planned.

This roadmap is yours to shape. Want something added, reprioritised, or dropped? Open a PR editing this section (and docs/phase-plan.md if it's engine-facing), or open an issue to float it first. Say why now — which of the four north-star pillars (engine quality, onboarding, UX, performance) it moves. New to the codebase? Point your coding agent at this repo and paste:

Read README.md and docs/phase-plan.md, then propose a roadmap change:
add/change "<your idea>" under the right section in one line, with a
"why now" naming which north-star pillar it moves. Open a PR with just
that edit — no code.

Setup, branch naming, and the CLA are in CONTRIBUTING.md.

Now — attach to the database you already run (GLOBAL-043)

One loop — observe → propose → apply → verify → revert — on your Postgres (Supabase, Neon, RDS) or Cloudflare D1. Plan, KPIs and exit gate: GLOBAL-043.

  • ~ /app/dba change ledger — every change with its inverse, newest first; Apply / Reject on each proposal

  • ~ Attach product on synthetic databases — observer, create_index proposal, apply → verify → auto-revert, the four doors (the web door, paste a Postgres string at /app/connect then Apply / Reject in /app/dba, the API door, POST /v1/attach / client.attach() with client.applyProposal() / rejectProposal(), the CLI door, nlq attach / nlq proposals / nlq apply / nlq reject, and the MCP door, nlqdb_connect_database / nlqdb_list_proposals / nlqdb_apply_proposal / nlqdb_reject_proposal; the web, API, CLI and stdio MCP (@nlqdb/mcp 0.4.0) doors are live; hosted mcp.nlqdb.com serves the MCP tools once its held deploy runs; verify runs on its own once an applied proposal's 72 h window has passed; on D1 the API door attaches, applies and rejects so far), tested in CI

  • ~ Postgres spike — one index proposed, applied and measured (before/after p95) on a real-traffic database (the spike DB attaches read-only in CI, first proposal in 2.7 s; no index applied yet)

  • ◯ D1 attach on the real rateme12 — the dogfood

  • ◯ The playbook — unused-index drops, bloat, retypes, partitioning, retention, placement

Phase 0 — Foundations ✓

Worker skeleton · KV + D1 + R2 bindings · Neon adapter + OTel · LLM router (free chain) · Better Auth (GitHub + Google + magic link) · /v1/ask end-to-end · events queue + drain · Stripe webhook · CI/CD + PR preview environments.

Phase 1 — On-ramp

A stranger lands on nlqdb.com, creates a DB in plain English, embeds it, and shares the link — in under 60 seconds, no card, no config.

  • ✓ Marketing site (Astro, live at nlqdb.com)

  • ✓ <nlq-data> + <nlq-action> elements (v0.1)

  • ✓ Sign-in — magic link + GitHub + Google

  • ✓ Chat surface — streaming three-part response (answer / data / trace), anonymous mode

  • ✓ Anonymous mode — 72h token, adopted onto your account on sign-in

  • ✓ Hosted db.create pipeline (table-card embeddings stubbed pending the pgvector slice)

  • ✓ API keys dashboard (/app/keys)

  • ◯ Hello-world tutorial polish

Phase 1.5 — Trust + telemetry

  • ✓ Diff preview on writes + visible SQL trace on every response

  • ✓ Demand-signal telemetry on every "not yet" path

  • ◯ Confidence floor (clarify-on-low-confidence — a guided turn, not a dead-end) — lands with quality-eval

Phase 2 — Distribution (agent + developer surfaces)

  • ✓ Hosted MCP server (mcp.nlqdb.com/mcp) — host auto-detect pending; local stdio @nlqdb/mcp is on npm, so npx -y @nlqdb/mcp with an sk_mcp_* key is a headless route in with no browser consent step (/agents now carries it; the per-host install panel is still OAuth-only). On Claude Code, /plugin marketplace add nlqdb/nlqdb installs the server + both memory skills in one step

  • ✓ CLI nlq (Go) — core verbs + raw-SQL escape hatch; device-login + chat REPL pending

  • ✓ @nlqdb/sdk — basic methods + runSql + cross-tenant grant + pack-import runner verbs; published and importable from the registry; insert() and runSql params publish in 0.5.0

  • ~ Framework wrappers + native Swift package — built + CI-tested; npm / SPM publish pending

  • ✓ Quality-eval harness (BIRD + Spider 2.0) — a CI regression alarm for the NL→SQL interface, not a KPI

  • ~ Bring-your-own-LLM dispatch — HTTP lane live; remaining surfaces in progress

  • ◯ CSV upload in chat

  • ~ Docs-site reference completeness — SDK + framework-wrapper guides, an enumerable error-code reference, and a build-time /llms.txt for agents now live; tutorial polish remains

  • ◯ Custom domains for embeds

Phase 3 — Multi-engine engine (the moat)

  • ◯ Workload analyzer → migration orchestrator

  • ◯ ClickHouse / DuckDB / Redis as additional engines

  • ◯ Dual-read verification

  • ✓ Hosted-premium model lane (demand-gated) — live 2026-08-14 (PREMIUM_METER_LIVE flipped)

Phase 4 — Beyond v1

  • ~ Bring-your-own Postgres / ClickHouse — connect path live end-to-end (POST /v1/db/connect + web UI, CLI, SDK, query dispatch); prod-gated on the BYO_SECRET_KEK secret. Supabase adds one-click OAuth connect over the read-only Management-API (no DSN to paste); prod-gated on the SUPABASE_OAUTH_CLIENT_ID / _SECRET secrets, with a graceful fall-back to paste when unset

  • ◯ SSO (SAML / OIDC), audit-log export, per-org quotas

  • ◯ EU data residency, VPC peering, SOC 2

Develop locally

git clone git@github.com:nlqdb/nlqdb.git && cd nlqdb
scripts/bootstrap-dev.sh   # installs everything, pulls Ollama models, seeds .envrc
scripts/login-cloud.sh     # signs you into cloud providers that have a CLI flow

bootstrap-dev.sh stands up the whole toolchain in one shot — Bun, Node 20+, Go 1.25+, uv; Biome / gofumpt / golangci-lint / ruff; lefthook git hooks; the cloud CLIs (wrangler, flyctl, stripe, gh); a local Ollama so the LLM router works offline; and a .envrc with self-generated dev secrets. Details in docs/history/infrastructure-setup.md §8.

Day-to-day:

bun run fix          # biome format + lint --write (most issues)
bun run check:all    # biome + golangci-lint + ruff (what CI runs)
bun run hooks:run    # run pre-commit hooks against staged files

End-to-end tests (manual trigger)

E2E coverage is persona-driven and manually triggered so cost stays inside the free-tier envelope — one workflow_dispatch workflow per surface:

gh workflow run e2e-opencheck.yml             # web — live LLM, Neon branch, Workers preview
gh workflow run e2e-cli.yml                   # Go testscript, hermetic
gh workflow run e2e-sdk.yml                   # vitest + cassettes, hermetic
gh workflow run e2e-mcp.yml                   # InMemoryTransport protocol tests, hermetic
gh workflow run e2e-examples.yml              # Playwright across HTML/Next/Astro/Nuxt/SvelteKit
gh workflow run e2e-examples.yml -f live=true # + staging for the curl + CLI shell smokes

Run the hermetic surfaces locally without GitHub:

( cd tests/e2e/cli && go test ./... )
( cd tests/e2e/sdk && bun install && bun run test )
( cd tests/e2e/mcp && bun install && bun run test )
( cd tests/e2e/examples && bun install && bun run install:browsers && bun run test )

Only execution is manual: tests/e2e/{sdk,mcp,examples} live outside the root workspace, so CI's typecheck-e2e job tscs them on every PR — the free backstop against a suite that compiles today and rots before the next dispatch.

Conventions, persona mapping, and cassette governance are in docs/features/e2e-coverage/FEATURE.md.

Docs & reference

  • CONTRIBUTING.md — dev setup, branch naming, commits, CLA flow.

  • CODE_OF_CONDUCT.md — Contributor Covenant 2.1. Reports to conduct@nlqdb.com.

  • SECURITY.md — vulnerability disclosure (security@nlqdb.com). 90-day fix target.

  • SUPPORT.md — where to ask questions and what we don't (yet) offer.

  • CLA.md — Contributor License Agreement, signed once via the bot on your first PR.

  • TRADEMARKS.md — what you can and can't do with the nlqdb name and logo.

  • SUBPROCESSORS.md — third-party services that may process personal data on our behalf.

  • IMPRESSUM.md — Swiss UWG-mandated operator disclosures.

  • Privacy policy and terms of service: nlqdb.com/privacy · nlqdb.com/terms.

License

FSL-1.1-ALv2 — Functional Source License, Apache 2.0 future license. Source-available for any non-competing use; auto-converts to Apache 2.0 two years after each release. (Pattern used by Sentry, Convex, and others.)

nlqdb™ is an unregistered trademark of the project's licensor. See TRADEMARKS.md for usage guidelines.

Available Tools

10 tools
nlqdb_apply_proposalApply one of the DBA's proposalsA
Idempotent
Inspect

Apply a proposal on the attached database: its DDL runs (an index built CONCURRENTLY), the ledger records this key as who decided, and verify measures the query it targets after the window — a regression is reverted automatically by the stored inverse. Applying the same id again is a no-op (replayed: true).

NameRequiredDescriptionDefault
idYesThe proposal's `id` from nlqdb_list_proposals or nlqdb_connect_database.

TDQS

A4.4/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Adds substantial behavior beyond annotations: DDL runs, an index is built CONCURRENTLY, the ledger records the deciding key, verification measures the targeted query after the window, and a regression triggers automatic revert via the stored inverse. The idempotent no-op with replayed: true is also disclosed.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the core action and packed with relevant behavior in two tight sentences. The parenthetical and em-dash clauses each carry distinct operational meaning, so nothing is wasted.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the mutation complexity and no output schema, the description covers the important side effects and idempotency well. It only partially describes the return payload beyond replayed: true, leaving a minor gap for an agent that needs the full response shape.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the single id parameter is already documented well. The description adds the retry/no-op behavior for the same id, but does not add syntax or constraints beyond what the schema and annotations provide.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

State a specific verb and resource: 'Apply a proposal on the attached database.' It goes beyond a restatement by explaining the DDL execution, ledger recording, verification, and automatic rollback, and its contrast with the sibling reject_proposal is clear from the verb.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description establishes when to use it: a proposal exists on the attached database and its id comes from nlqdb_list_proposals or nlqdb_connect_database. It also explains replay behavior, though it does not explicitly state when not to use it or name reject_proposal as the alternative.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

nlqdb_connect_databaseConnect an existing database so the agent can query it in EnglishAInspect

Connect (attach) an existing Postgres or ClickHouse database: the agent can query it in natural language with nlqdb_query, and on Postgres nlqdb's DBA starts watching it — no migration, no schema upload. Pass the engine and a connection URL; the credential is stored sealed server-side and never echoed back. Returns the new dbId, a preview of the discovered schema and, on Postgres, the DBA's first proposals to apply or reject.

NameRequiredDescriptionDefault
nameNoOptional display name for the connection; defaults to the database/host name.
engineYesWhich engine the existing database runs — 'clickhouse' or 'postgres'.
connection_urlYesThe full connection URL for the database, including credentials (e.g. postgres://user:pass@host:5432/db or https://host:8443?user=…). Stored sealed server-side and never echoed back.

TDQS

A4.1/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations only declare destructiveHint=false, so the description carries the real burden and does so well: it discloses the side effect (the DBA starts watching the database on Postgres), the credential handling guarantee (stored sealed server-side, never echoed back), and the return shape (dbId, schema preview, first proposal set). It stops short of idempotency on re-connect (duplicate dbId?) or auth/permission prerequisites.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three dense sentences, front-loaded with the verb and resource, then side effects, then return value. "No migration, no schema upload" is a worthwhile disambiguation rather than filler, though the credential-storage clause is stated twice within the same paragraph.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description correctly compensates by enumerating what comes back (dbId, schema preview, Postgres proposals). Combined with the sealed-credential note and engine options, an agent has everything needed to call it correctly; only failure/duplicate-connection behavior is unspecified.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% and all three parameters are already documented with an enum on engine and format examples on connection_url. The description only restates "pass the engine and a connection URL" and repeats the sealed-credential note already present in the schema, so it adds little beyond the structured data.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ("connect (attach) an existing Postgres or ClickHouse database") and immediately ties it to its downstream consumer (nlqdb_query). The supported engine list is named inline, so an agent can rule the tool in or out without opening the schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Clear context for when to use: onboarding an existing database so it can be queried in natural language, with the explicit reassurance "no migration, no schema upload" that rules out a migration-style interpretation. It does not name a when-not condition or point at siblings such as nlqdb_list_databases for checking whether a connection already exists.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

nlqdb_describeDescribe one memory databaseA
Read-only
Inspect

Inspect the shape of one of your agent's memory databases. Return schema metadata (slug, engine, schema name) for one database. Requires a user-scoped key (sk_live_ or sk_mcp_).

NameRequiredDescriptionDefault
dbYesDatabase id or slug to describe.

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The readOnlyHint annotation already indicates a safe read operation, and the description adds context by specifying the exact metadata returned and the required key type. This goes beyond the annotation without contradicting it, but does not disclose potential error or edge cases.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is three concise sentences, each with clear value: the operation, the return structure, and the auth prerequisite. No redundant or filler content is present.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's simplicity (one parameter, no output schema, no nested objects), the description covers all necessary aspects: purpose, return value, and prerequisites. The description fully compensates for the lack of an output schema by explicitly listing the metadata fields returned.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the baseline is 3. The single 'db' parameter is described in the schema as 'Database id or slug to describe,' and the tool description does not add any additional parameter-specific detail beyond that.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states a specific action ('Inspect the shape of one of your agent's memory databases') and specifies the return value ('schema metadata (slug, engine, schema name)'). This distinguishes it from siblings like list_databases and query, which handle listing and querying respectively.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly notes it operates on a single database, contrasting with list_databases. It also mentions the auth requirement ('Requires a user-scoped key'), though it does not explicitly name alternative tools or provide a 'when not to use' exclusion.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

nlqdb_insertInsert rows; unseen tables and fields are createdA
Destructive
Inspect

Insert structured rows into a table with no data modelling: an unseen table or field is created in the same transaction, typed from the values, and the rows land exactly as sent — no model call. Pass key to upsert: a row whose key exists is updated instead of duplicated. Returns the stored rows (generated ids included) and, when the schema widened, the DDL it ran. Use it whenever you hold the exact values; use nlqdb_query to write something described in words.

NameRequiredDescriptionDefault
dbYesDatabase id to write to (from nlqdb_list_databases).
keyNoFields that identify a row, e.g. ["server_id", "user_id"]. When set, a row whose key already exists is updated (only the fields it names) instead of duplicated, so re-running an import is safe. Every row must carry every key field; the first keyed write adds a unique index on them.
rowsYesRows as JSON objects, up to 1 000 per call. Keys become lower_snake_case columns (serverId → server_id); a field the table hasn't seen is added, typed from the values (number → numeric, string → text, object/array → jsonb, boolean → boolean). A key a row omits takes the column default. No model call, so the values land exactly as sent — use this for structured writes, nlqdb_query for writes described in words.
tableYesTable to insert into. It need not exist: an unseen table is created, and its name is snake_cased like the columns.

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations only flag destructiveHint=true; the description supplies the substance behind it — schema widening happens in the same transaction, column types are inferred from values, naming is snake_cased, and the DDL that ran is returned. It doesn't say that the created table/columns persist and cannot be undone if the write was a mistake, which is the one behavioural consequence of the destructive hint left implicit.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the core action and its no-modelling trait, then the upsert rule, then the return shape, then the sibling routing. It is dense but every clause carries information; slightly heavy punctuation and a couple of restated points (no model call appears twice) keep it from a 5.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description steps in and explains the return values (stored rows with generated ids, plus the DDL when the schema widened). Combined with the disclosed write limits and upsert behaviour, an agent has everything needed to call it correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% and the schema already spells out `key` upsert semantics, value→type mapping, and the 1000-row cap in detail. The description restates the same facts ('Pass `key` to upsert', 'typed from the values') without adding syntax, format, or edge-case meaning beyond the schema, so baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States the specific verb and resource ('Insert structured rows into a table') and immediately names the distinctive trait — no data modelling, unseen tables/fields auto-created — that separates it from nlqdb_query. An agent can pick between this and its siblings without opening either schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives an explicit selection rule: 'Use it whenever you hold the exact values; use nlqdb_query to write something described in words.' It also states when to use the `key` parameter (upsert / safe re-import), so both tool choice and mode choice are covered.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

nlqdb_list_databasesList your agent's memory databasesA
Read-only
Inspect

List the memory databases your agent can query, scoped to the authenticated user. Requires a user-scoped key (sk_live_ or sk_mcp_). Returns engine per row.

NameRequiredDescriptionDefault

No parameters

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, so the read-only nature is known. The description adds the auth requirement (user-scoped key) and the return format ('engine per row'), which exceeds what annotations provide and helps set expectations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three short sentences each carry distinct value: purpose, auth requirement, and return format. The description is front-loaded with the primary action and contains no filler or redundancy.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a zero-parameter listing tool, the description covers all essential aspects: what is listed, scope, authentication prerequisite, and return shape. No output schema exists, so the description appropriately compensates by mentioning 'engine per row'.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool has zero parameters, so schema coverage is trivially 100%. Baseline 4 applies, and the description appropriately mentions the scope and auth context without needing to explain parameter syntax.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb ('List') and resource ('memory databases') with clear scoping ('scoped to the authenticated user'), making the operation unambiguous. It also distinguishes itself from siblings like query or remember, which perform different actions.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Provides useful context: the tool lists databases the agent can query and requires a user-scoped key. It does not explicitly name alternatives or when-not-to-use, but the naming and description sufficiently imply the intended use case.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

nlqdb_list_proposalsList the DBA's proposals on an attached databaseA
Read-only
Inspect

List what nlqdb's DBA proposes for an attached Postgres — each an index with the statement that undoes it and the reason — plus the ones already decided, with verify's measured p95 before/after once the window has passed. Pass the dbId nlqdb_connect_database returned.

NameRequiredDescriptionDefault
dbYesId of the attached database (the dbId nlqdb_connect_database returned).

TDQS

A4.1/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With readOnlyHint=true already covering safety, the description adds real substance: it enumerates what each proposal contains (undo statement, rationale) and notes that decided proposals carry verify's measured p95 before/after only once the observation window has passed. That timing caveat is the kind of context annotations cannot express.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single dense sentence that front-loads the core purpose before the payload details and the dbId instruction. It is information-rich with little waste, though the nested clauses make it slightly harder to parse than it needs to be.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a one-parameter read tool with no output schema, the description covers purpose, the parameter's provenance, and the shape of the returned items, including the conditional p95 data. Missing only explicit guidance on what to do with the results (apply/reject), which the sibling tools would cover.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Single parameter with 100% schema coverage, so the schema already documents `db` fully. The description's 'Pass the dbId nlqdb_connect_database returned' merely restates the schema's own text, adding no new syntax or format detail — baseline 3.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('List what nlqdb's DBA proposes for an attached Postgres') and spells out the payload — index, undo statement, reason, plus already-decided items with measured p95. This is clearly distinguishable from the sibling nlqdb_apply_proposal / nlqdb_reject_proposal, which act on those proposals.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Establishes the prerequisite explicitly ('Pass the dbId nlqdb_connect_database returned'), which sequences the agent after connecting. It stops short of naming alternatives or exclusions — e.g. that this is the review step before nlqdb_apply_proposal / nlqdb_reject_proposal — so routing to siblings is left implicit.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

nlqdb_queryQuery your agent's memory in natural languageA
Destructive
Inspect

Query your agent's structured memory in natural language — a real database it can GROUP BY / JOIN / aggregate over, not just recall. Returns rows + the compiled SQL (in trace). The database is materialised on first reference — no separate create tool. Destructive plans return requires_confirm: true + a diff; re-call with confirm: true to commit.

NameRequiredDescriptionDefault
qYesThe natural-language goal. Example: 'top 5 customers by revenue this year'. Name tables explicitly when you know them; avoid pronouns.
dbNoTarget database id or slug. Optional: omit to let nlqdb pick — it auto-targets your only DB (or creates one from the goal when you have none), and on multiple DBs returns ambiguous_db with candidate ids to choose from. Ignored for pk_live_ keys (already scoped to one DB).
modelNoModel preset: 'fast' pins the free built-in chain, 'best' requires a frontier model (errors model_unavailable unless the account stored a BYOLLM key or has a paid plan), omit/'auto' lets nlqdb pick.
confirmNoDestructive writes are two calls: the first (confirm absent) returns requires_confirm: true plus a diff preview; show the diff, then re-call with confirm: true to commit. Read-only queries ignore this.

TDQS

A4.4/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Beyond the destructiveHint annotation, the description discloses the two-step confirmation for destructive plans (requires_confirm + diff, then confirm: true), the auto-creation of the database on first reference, and the return of rows along with compiled SQL in trace. These details give the agent a clear understanding of side effects and expected output.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is three sentences, each delivering unique value: purpose and capabilities, return values and auto-creation, and destructive confirmation. It is front-loaded and free of redundant or filler content.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description adequately covers return behavior (rows + SQL trace) and critical side effects (auto-creation, destructive confirm flow). Parameter descriptions handle errors like ambiguous_db and model_unavailable. It could be slightly more explicit about result formatting, but given the tool's complexity, it is sufficiently complete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema already provides 100% parameter descriptions, including examples, edge cases, and enumeration. The tool description adds no further parameter semantics beyond what the schema states; even the confirm behavior is repeated verbatim from the schema. Baseline 3 is appropriate as the schema handles parameter documentation.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool queries the agent's structured memory in natural language, emphasizing its capability for GROUP BY/JOIN/aggregate operations. It distinguishes itself from simple recall and the sibling tools by positioning itself as a real database query interface.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies this tool is for structured queries involving joins or aggregations, contrasting with 'not just recall' which hints at nlqdb_remember. It also explains the confirmation flow for destructive plans, guiding when confirm is needed. However, it does not explicitly name alternatives for listing or connecting databases, so it lacks a fully explicit when/when-not structure.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

nlqdb_readRead your agent's memory in natural language (never writes)A
Read-only
Inspect

Read-only natural-language query over your agent's memory — SELECT / aggregate / JOIN over existing data. Guaranteed never to write, create, or modify: a request whose plan would change data is refused (use nlqdb_query for that), so this tool is safe to mark 'always allow' in your host. Auto-targets your only database; pass db to pick one when you have several. Returns rows + the compiled SQL in trace.

NameRequiredDescriptionDefault
qYesThe natural-language question. Read-only: SELECT / aggregate / JOIN over existing data. Example: 'top 5 customers by revenue this year'. Name tables explicitly when you know them; avoid pronouns.
dbNoTarget database id or slug. Optional: omit to auto-target your only database. Unlike nlqdb_query, this tool never creates a database — with several databases and no `db` it returns ambiguous_db with candidate ids; with none it asks you to create one via nlqdb_query first.
modelNoModel preset: 'fast' pins the free built-in chain, 'best' requires a frontier model (errors model_unavailable unless the account stored a BYOLLM key or has a paid plan), omit/'auto' lets nlqdb pick.

TDQS

A5/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations only mark readOnlyHint: true, but the description goes much further: it guarantees no write/create/modify, states that plan-to-change requests are refused, discloses auto-target behavior and the ambiguous_db edge case, and tells the agent it returns rows plus compiled SQL. This is rich, non-contradictory behavioral disclosure well beyond structured hints.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Four sentences, all value-dense and front-loaded with the core purpose and safety guarantee. Each sentence delivers a distinct piece of actionable information — behavior, exception, db targeting, return format — without repetition. It is concise but not under-specified.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description is fully self-contained for a read-only natural-language query tool. It covers the safety contract, failure cases (ambiguous_db, no db, now database), model selection, and the exact return output (rows + compiled SQL). Given the lack of an output schema, this description effectively compensates by disclosing the return shape.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Although schema coverage is 100%, the description adds meaningful semantic context: `db` can be omitted to auto-target the only database, but with several it returns candidate IDs; `model`'s 'best' presets require specific account conditions; 'unique' is the default for nlqdb to choose. This goes beyond the schema's basic parameter docs, clarifying real usage nuances.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb+resource pattern: 'Read-only natural-language query over your agent's memory — SELECT / aggregate / JOIN over existing data.' It clearly distinguishes this from sibling nlqdb_query and from a generic list/connect tool by emphasizing it never writes. The tool's intent is immediately transparent.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicit guidance is given: 'a request whose plan would change data is refused (use nlqdb_query for that), so this tool is safe to mark always allow.' It also explains when to pass `db` vs. auto-targeting and touches on ambiguous-database behavior. This leaves little ambiguity about when to use this tool versus alternatives.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

nlqdb_reject_proposalReject one of the DBA's proposalsA
Idempotent
Inspect

Decline a proposal; nothing runs on the database and it is never proposed again. Give a one-sentence reason (e.g. 'this table is append-only') — the DBA learns from it.

NameRequiredDescriptionDefault
idYesThe proposal's `id` from nlqdb_list_proposals or nlqdb_connect_database.
reasonNoWhy not, in a sentence — kept on the proposal for the DBA to learn from.

TDQS

A3.8/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Goes beyond the annotations by stating the side-effect profile: nothing runs on the database and the proposal is 'never proposed again', which tells the agent the rejection is durable. Idempotence and non-destructiveness are already in annotations, so no credit is needed there. What is missing is what happens with an invalid or already-decided id.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two tight sentences, front-loaded with the action and its consequence, then the parameter guidance. No filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a two-parameter mutation with no output schema, the description covers the essential behavioral fact (nothing executes) and the reason field. Only error/edge-case behavior on invalid ids is left unspecified.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so both parameters are fully documented in the schema; the description only echoes the reason guidance with an example. Baseline 3 applies because the schema does the heavy lifting.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb ('Decline') and resource ('a proposal') and the goal is unmistakable, distinguishing it from nlqdb_apply_proposal by implication. It does not name the sibling explicitly, but the action is unambiguous.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is implied — you reject a proposal you don't want executed — but there is no explicit statement of when to reject versus apply or edit, and no prerequisites or error conditions mentioned.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

nlqdb_rememberRemember something in your agent's memoryAInspect

Write a typed row into your agent's memory database — a fact to recall later, a conversation episode, or an entity (person/project/thing). Materialises directly into the agent_memory_v1 schema with no LLM in the loop, so it's deterministic. Omit db on first use and this tool will find (or provision) the agent_memory_v1 database for you and echo dbId (and db_created: true on a fresh provision) in the result — pin that id on subsequent calls. Query it back later with nlqdb_query (which can GROUP BY / aggregate over what you remembered). Set kind + tags on facts — they are the columns those aggregates group by.

NameRequiredDescriptionDefault
dbNoOptional. The agent_memory_v1 database id (db_agent_memory_v1_…). Omit on first use and this tool will find (or provision) your account's memory DB automatically and return the new dbId in the result — pass that on subsequent calls. A non-memory DB is rejected with wrong_preset and the recovery is the same: omit `db` to auto-provision.
kindYesWhich memory table to write into. Prefer 'entity' for anything with a current state (a project, a person, a config) — an entity is the CURRENT SNAPSHOT and upserts on (agent+kind+name), so re-remembering refreshes it in place instead of accumulating stale rows. Use 'fact' for a statement whose truth is time-bound (a status update, an observation, an idea) — give it a ttlSeconds when it's transient. Use 'episode' for one conversation/tool turn (append-only log).
payloadYesKind-specific fields. fact: { content, kind?, tags?, source? }. episode: { role, content, tool_calls?, tokens? }. entity: { kind, canonical_name, properties? }. Write for the queries you'll ask later: fact kind + tags become GROUP BY columns — reuse a small lower_snake kind vocabulary (leaving every row on the default 'fact' makes categories unqueryable) and tag every id/topic the row touches. Entities are current snapshots: keep the state in `properties` (JSONB) and re-remember the entity to update it — an upsert on (agent, kind, canonical_name) replaces properties when provided, so re-send the whole object. Prefer updating an entity over accumulating facts about it. Supersede rather than accumulate: when a fact becomes wrong or outdated, write the corrected fact (same tags) rather than piling on — old facts fade via ttlSeconds; entities are refreshed in place. Make content one self-describing sentence, so a row reads correctly on its own in a result set.
threadIdNoOptional thread/conversation scope (facts / episodes).
endUserIdNoOptional end-user scope (facts / episodes).
ttlSecondsNoOptional TTL in seconds — sets expires_at on a fact. Expired facts stop appearing in queries (RLS filters them out) and are physically evicted opportunistically on subsequent writes, so memory forgets what it no longer needs. Set this on any fact whose relevance is time-bound (a status, an observation, a hypothesis) — a day for daily standups, a week for weekly plans, a month for quarterly context. Facts without a TTL live forever; entities never expire (update them in place instead).

TDQS

A4.6/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations provide only destructiveHint=false, so the description must cover the write behavior. It explains that writing is deterministic, materializes directly into a schema, and describes auto-provisioning of the database on first use. It also hints that facts with a TTL expire and are filtered out, and entities are upserted in place. However, it does not explicitly state that writing is not read-only beyond the annotation's implication – a small gap but overall strong transparency.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is packed with valuable details but is somewhat lengthy. Each sentence adds meaning, though some repetition occurs (e.g., the TTL concept appears in both `payload` and `ttlSeconds` descriptions). It is front-loaded with the core purpose, making the rest readable. A bit more brevity could improve it.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given 6 parameters (2 required) and no output schema, the description covers all key aspects: how to start, parameter semantics, expected results (dbId, db_created), and how to query later. It lacks an explicit note on error handling beyond the wrong_preset for `db`, but overall it is sufficient for an agent to use the tool correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, yet the description adds significant value beyond the schema. For `kind`, it explains the semantics of each enum option (snapshot vs time-bound vs append-only). For `payload`, it provides detailed structure per kind and advice on query design. For `ttlSeconds`, it describes expiration behavior and usage patterns. The description transforms raw schema fields into actionable guidance.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool writes a typed row into the agent's memory database, listing three use cases (fact, episode, entity) and distinguishes it from siblings like nlqdb_query by specifying this is the write side. It also explains the deterministic behavior without an LLM in the loop.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Provides explicit guidance on when to omit `db` for first use, how to pin the returned `dbId`, references sibling tool nlqdb_query for reading back the data, and gives detailed instructions on choosing among kind values and whether to use entity vs fact. It also advises on superseding old facts rather than accumulating stale rows.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 3 tool updatesv0.1.27
    • Addednlqdb_apply_proposal
    • Addednlqdb_list_proposals
    • Addednlqdb_reject_proposal
  2. 1 tool updatev0.1.23
    • Changednlqdb_insert1 field changed
      • addedInput schema / properties / key
        Added value: +{
        +  "description": "Fields that identify a row, e.g. [\"server_id\", \"user_id\"]. When set, a row whose key already exists is updated (only the fields it names) instead of duplicated, so re-running an import is safe. Every row must carry every key field; the first keyed write adds a unique index on them.",
        +  "items": {
        +    "minLength": 1,
        +    "type": "string"
        +  },
        +  "minItems": 1,
        +  "type": "array"
        +}
  3. 3 tool updatesv0.1.22
    • Addednlqdb_insert
    • Addednlqdb_read
    • Changednlqdb_remember5 fields changed
      • changedInput schema / properties / db / description
        Previous value: -"The agent_memory_v1 database id (db_agent_memory_v1_…). Provision one with db.create { preset: 'agent_memory_v1' }; a non-memory DB is rejected with wrong_preset."New value: +"Optional. The agent_memory_v1 database id (db_agent_memory_v1_…). Omit on first use and this tool will find (or provision) your account's memory DB automatically and return the new dbId in the result — pass that on subsequent calls. A non-memory DB is rejected with wrong_preset and the recovery is the same: omit `db` to auto-provision."
      • changedInput schema / properties / kind / description
        Previous value: -"Which memory table to write into: 'fact' (a durable statement to recall later), 'episode' (one conversation/tool turn), or 'entity' (a person/project/thing — upserts on agent+kind+name)."New value: +"Which memory table to write into. Prefer 'entity' for anything with a current state (a project, a person, a config) — an entity is the CURRENT SNAPSHOT and upserts on (agent+kind+name), so re-remembering refreshes it in place instead of accumulating stale rows. Use 'fact' for a statement whose truth is time-bound (a status update, an observation, an idea) — give it a ttlSeconds when it's transient. Use 'episode' for one conversation/tool turn (append-only log)."
      • changedInput schema / properties / payload / description
        Previous value: -"Kind-specific fields. fact: { content, kind?, tags?, source? }. episode: { role, content, tool_calls?, tokens? }. entity: { kind, canonical_name, properties? }."New value: +"Kind-specific fields. fact: { content, kind?, tags?, source? }. episode: { role, content, tool_calls?, tokens? }. entity: { kind, canonical_name, properties? }. Write for the queries you'll ask later: fact kind + tags become GROUP BY columns — reuse a small lower_snake kind vocabulary (leaving every row on the default 'fact' makes categories unqueryable) and tag every id/topic the row touches. Entities are current snapshots: keep the state in `properties` (JSONB) and re-remember the entity to update it — an upsert on (agent, kind, canonical_name) replaces properties when provided, so re-send the whole object. Prefer updating an entity over accumulating facts about it. Supersede rather than accumulate: when a fact becomes wrong or outdated, write the corrected fact (same tags) rather than piling on — old facts fade via ttlSeconds; entities are refreshed in place. Make content one self-describing sentence, so a row reads correctly on its own in a result set."
      • changedInput schema / properties / ttlSeconds / description
        Previous value: -"Optional TTL in seconds — sets expires_at on a fact so it can be swept later."New value: +"Optional TTL in seconds — sets expires_at on a fact. Expired facts stop appearing in queries (RLS filters them out) and are physically evicted opportunistically on subsequent writes, so memory forgets what it no longer needs. Set this on any fact whose relevance is time-bound (a status, an observation, a hypothesis) — a day for daily standups, a week for weekly plans, a month for quarterly context. Facts without a TTL live forever; entities never expire (update them in place instead)."
      • changedInput schema / required
        Previous value: -[
        -  "db",
        -  "kind",
        -  "payload"
        -]New value: +[
        +  "kind",
        +  "payload"
        +]
  4. 5 tool updatesv0.1.0
    • First observednlqdb_connect_database
    • First observednlqdb_describe
    • First observednlqdb_list_databases
    • First observednlqdb_query
    • First observednlqdb_remember

TDQS

A4.2/5.0

Scored across 10 tools

Disambiguation4/5

The descriptions do a good job of separating overlapping write paths: nlqdb_insert takes exact values, nlqdb_remember writes typed memory rows deterministically, and nlqdb_query is for writes described in words. The read/write split between nlqdb_read and nlqdb_query is also clearly stated, though four tools with query-like or write-like semantics (insert, remember, query, read) still require careful reading to pick correctly.

Naming Consistency4/5

All tools use a uniform nlqdb_ snake_case prefix, which makes the set highly predictable. However, several names are bare verbs (describe, insert, query, read, remember) rather than verb_noun, so the pattern is mostly rather than fully consistent.

Tool Count5/5

Ten tools is squarely in the well-scoped range, and each earns its place: database introspection, connection, three memory/insert write paths, read/query, and a coherent proposal lifecycle.

Completeness4/5

The surface covers listing, describing, connecting, reading, querying, inserting, remembering, and the full proposal apply/reject lifecycle, with destructive writes handled via confirm. Minor gaps remain: no disconnect/drop-database operation and no first-class delete/update row tool (upsert only via key on insert, deletes only via nlqdb_query's confirm flow).

Maintenance

ActivityActive
ResponsivenessSyncing

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    A
    maintenance
    Persistent shared memory for AI agents. Hybrid search (pgvector + tsvector), knowledge graph, cognitive scoring, and 16-language temporal extraction. 97.2% Recall@10 on LongMemEval with one PostgreSQL query. Works across Claude Code, Cursor, Codex, OpenClaw, and any MCP client.
    116
    MIT
  • A
    license
    Not graded
    quality
    B
    maintenance
    Persistent semantic memory for AI agents using PostgreSQL and vector embeddings, enabling cross-session continuity and semantic search.
    AGPL 3.0
  • A
    license
    Not graded
    quality
    D
    maintenance
    Provides a standardized interface for interacting with Neon's tools and services through a unified API via the Model Context Protocol.
    1,485 PyPI
    MIT