Skip to content

Give your agent memory — one command

nlqdb is an autonomous DBA: a real Postgres your agent connects to over MCP and queries in plain English, with the schema inferred from what the agent writes. Used as memory, that means GROUP BY, JOIN, aggregate over what it remembered — not just the top-k a vector store recalls. One command connects it.

The hosted server lives at https://mcp.nlqdb.com/mcp (the protocol is at /mcp, not the bare domain). Follow the one step for your host — each host’s key names differ, so copy its own block, not a neighbour’s.

  1. Claude Code — run in your terminal:

    Terminal window
    claude mcp add --transport http nlqdb https://mcp.nlqdb.com/mcp
  2. Codex — add to ~/.codex/config.toml (remote HTTP servers are not addable via codex mcp add, which is stdio-only):

    [mcp_servers.nlqdb]
    url = "https://mcp.nlqdb.com/mcp"
  3. Claude Desktop — Settings → Connectors → Add custom connector, then paste the URL above. This is the one host whose documented remote path is a dialog, so it is the one step here a coding agent can’t run for you — take the headless route instead, which is a file it can write for you (you still quit and reopen the app).

  4. Windsurf — merge the nlqdb entry into mcpServers in ~/.codeium/windsurf/mcp_config.json, keeping any servers already there (a remote entry uses serverUrl, not url):

    { "mcpServers": { "nlqdb": { "serverUrl": "https://mcp.nlqdb.com/mcp" } } }
  5. Zed — merge the context_servers key into ~/.config/zed/settings.json (same path on macOS and Linux; zed: open settings file opens it). That file holds every Zed setting — theme, keymap, language servers — so add the key, don’t overwrite the file:

    { "context_servers": { "nlqdb": { "url": "https://mcp.nlqdb.com/mcp" } } }
  6. Cursor — merge the nlqdb entry into mcpServers in the project’s .cursor/mcp.json (or ~/.cursor/mcp.json to apply it everywhere), keeping any servers already there:

    { "mcpServers": { "nlqdb": { "url": "https://mcp.nlqdb.com/mcp" } } }
  7. VS Code — merge the nlqdb entry into .vscode/mcp.json, keeping any servers already there (the root key is servers, and a remote entry needs "type": "http"):

    { "servers": { "nlqdb": { "type": "http", "url": "https://mcp.nlqdb.com/mcp" } } }

Every file-based host above is machine-followable: a coding agent edits the config itself, no GUI click. Each block shows only the nlqdb entry — merge it in; overwriting the file drops the developer’s other servers and settings. On Cursor and VS Code the one-click deep-link buttons on nlqdb.com/integrations are a faster route for a human, not a requirement — the file works either way. Claude Desktop is the exception on this route: its connector dialog needs a human. The headless route below reaches it through a file instead, which an agent can write.

Every block above points at the hosted server, whose first tool call opens a browser page someone has to approve. If nobody is at a browser — an unattended agent, CI, a container — run the same five tools locally over stdio instead. npx fetches @nlqdb/mcp and it talks to the same production API; the credential is an sk_mcp_ MCP key in the host config, so no browser opens at any point.

Mint the key once at app.nlqdb.com/app/keys (that page needs a signed-in account — pick MCP key, and name the host and device it is for), then swap the nlqdb entry from your host’s Step 1 block for this one — same root key, only the server value changes. An MCP key is scoped to MCP: it can ask, list and describe your databases and read/write memory, but it cannot connect external databases or manage keys, and you can revoke that one host+device without touching anything else. It is still a live credential, so put it in the user-level config — ~/.cursor/mcp.json, ~/.codex/config.toml, or VS Code’s MCP: Open User Configuration rather than its workspace .vscode/mcp.json — never a file your repo commits. Revoke it at /app/keys if it leaks.

{ "command": "npx", "args": ["-y", "@nlqdb/mcp"], "env": { "NLQDB_API_KEY": "sk_mcp_REPLACE_ME" } }

That object is also the route into Claude Desktop, whose hosted path is the one dialog on this page: merge it into mcpServers in claude_desktop_config.json~/Library/Application Support/Claude/ on macOS, %APPDATA%\Claude\ on Windows, or Settings → Developer → Edit Config to open it — then fully quit and reopen the app.

VS Code additionally needs "type": "stdio" on that entry, in place of the "type": "http" its hosted block carries. Claude Code reads that same object too, but its JSON file is the repo-committed .mcp.json — so use the CLI, which writes the key to ~/.claude.json and nothing into your project:

Terminal window
claude mcp add --env NLQDB_API_KEY=sk_mcp_REPLACE_ME --transport stdio nlqdb -- npx -y @nlqdb/mcp

(the --transport stdio between --env and nlqdb is deliberate — the CLI reads a bare name straight after --env as another KEY=value pair and rejects it). Codex takes TOML, not JSON — its ~/.codex/config.toml table becomes:

[mcp_servers.nlqdb]
command = "npx"
args = ["-y", "@nlqdb/mcp"]
env = { NLQDB_API_KEY = "sk_mcp_REPLACE_ME" }

Steps 3–5 below apply to both routes.

Hosted route: on the first tool call, nlqdb opens an OAuth page in your browser. Approve it once; the host stores the token. There is no key to generate or paste, but it does need a human at a browser (as does Claude Desktop’s connector dialog in Step 1).

Headless route: already done — the sk_mcp_ key in the config above authenticates every call, and nothing opens a browser.

After connecting, the host lists these nlqdb tools:

  • nlqdb_query — ask your memory a question in English; returns rows plus the exact SQL it ran (in trace). The database materialises on first reference — there is no separate create step.
  • nlqdb_read — the read-only counterpart: same natural-language query, but guaranteed never to write, create, or modify (a write plan is refused), so you can mark it always allow in your host without a prompt per call.
  • nlqdb_list_databases — list the memory databases scoped to your account.
  • nlqdb_describe — inspect one database’s shape (slug, engine, schema).
  • nlqdb_connect_database — attach an existing ClickHouse/Postgres so the agent can query it in English (no migration, no schema upload).
  • nlqdb_remember — write a typed memory row directly into an agent_memory_v1 preset database. See What’s live today — live for signed-in keys; set kind and tags on every fact (they become your GROUP BY columns), and fall back to nlqdb_query if it answers wrong_preset.

Store one fact, then read it back, both through nlqdb_query. The natural-language goal is the q argument; omit db and nlqdb targets your memory database — no database name to invent (a db slug that doesn’t exist yet returns db_not_found). The very first query has nothing to target yet, so nlqdb provisions the database from your goal on that call and returns db_created (the compiled schema rides in trace) — that is the “first reference”, and there is no separate create step to run. Every write after that goes through a render-before-commit gate: the write call returns requires_confirm: true plus a diff of what it will write, and you re-call with confirm: true to commit. Reads run straight through.

# First query provisions your memory DB from the goal (one-time) → db_created
Agent → nlqdb_query(q: "remember that the user prefers metric units")
→ db_created: true, dbId: "db_…" (+ the compiled schema in trace)
# Write — previews first, then commit
Agent → nlqdb_query(q: "remember that the user prefers metric units")
→ requires_confirm: true (+ a diff of the row it will insert)
Agent → nlqdb_query(q: "remember that the user prefers metric units", confirm: true)
→ committed (+ the SQL in trace)
# Read — no confirm needed
Agent → nlqdb_query(q: "what do you remember about the user?")
→ rows (+ the SQL in trace)

The read returning your fact — with the SQL visible in trace — confirms setup end to end: connected, authenticated, a database provisioned, and writing (through the confirm gate) and reading memory.

  • 404 / connection refused on first call (hosted route) — the config points at the bare domain. It must be the full https://mcp.nlqdb.com/mcp (the protocol is served at /mcp). The headless route carries no URL at all, so it cannot fail this way.
  • Auth loop / unauthorized (hosted route) — the browser OAuth was dismissed. Trigger any tool again and complete the approval.
  • Headless route: NLQDB_API_KEY is not set — the host didn’t pass env through. The binary exits before connecting, so the host reports the server as failed rather than showing a tool error; check the env block sits inside the nlqdb entry, and restart the host so it re-reads the file.
  • Headless route: unexpected prefix — the key was copied with a stray quote or whitespace, or it isn’t an account key.
  • nlqdb_connect_database answers connect_requires_account — expected on an sk_mcp_ key: attaching an external database is deliberately outside what an MCP key can do. Do it once from the dashboard (or with an sk_live_ account key); everything else on this page works on the MCP key.
  • Headless route: a tool call answers “This tool requires a user-scoped key” — the config reached the server and the server reached nlqdb, but the key isn’t valid. Mint a fresh one at app.nlqdb.com/app/keys and restart the host.
  • Host doesn’t show the tools — restart the host after editing its config, then re-list MCP servers. If they still don’t appear, check the root key: Cursor reads mcpServers from .cursor/mcp.json, VS Code reads servers from its mcp.json, each entry needing a "type""http" on the hosted route, "stdio" on the headless one. The wrong key parses as zero servers, with no error.
  • nlqdb_remember returns wrong_preset — the target database isn’t an agent_memory_v1 preset. Create one (db.create { preset: 'agent_memory_v1' } or the dashboard), or write through nlqdb_query instead (see below).

Want the coding agent you build with to wire this up once and use it forever? Drop a ready-made artifact into your project — the connect command in each is pinned by a test to the same source as this page, so the two can’t drift apart.

Claude Code: install the plugin — it bundles the MCP server and both skills, so this replaces Step 1 rather than following it. Run both lines inside Claude Code:

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

The plugin is nlqdb’s published artifacts directory itself, so its skills are the same files listed below — never a copy that can drift. Authentication is the hosted route above: the first tool call opens the browser OAuth page once.

Any host (Claude Code, Cursor, Codex) — installs the skill alone with the skills CLI (public repo, no account):

Terminal window
npx skills add https://github.com/nlqdb/nlqdb/tree/main/apps/web/public/agent-artifacts/nlqdb-memory

It writes .agents/skills/nlqdb-memory/SKILL.md — the cross-agent skill directory Cursor and Codex read directly — plus a .claude/skills/ symlink to it (Claude Code documents only .claude/skills/) and a skills-lock.json. Verified against the live CLI 2026-07-25. It does not write a .cursor/rules/ file and does not edit AGENTS.md; if your host reads only AGENTS.md, append the snippet below by hand.

Or drop a file in by hand:

  • AGENTS.md (host-neutral — Claude Code, Codex, and any agent that reads it): append AGENTS.snippet.md.
  • Claude Code (skill): save SKILL.md as .claude/skills/nlqdb-memory/SKILL.md.
  • Cursor: save nlqdb-memory.mdc as .cursor/rules/nlqdb-memory.mdc.
  • Codex: merge codex-config.toml into ~/.codex/config.toml.

Index + drop locations: nlqdb.com/agent-artifacts/README.md.

A second skill points the same memory at the repo it lives in. It extracts the structure your docs already carry — decision ids and statuses, open questions with the dates they appeared, queues, trackers, and the references between them — so “which features have open questions older than 30 days” and “which decisions reference GLOBAL-013” become one query instead of an afternoon of grep. It ingests structure only, never prose paragraphs, and the sync is one-way: markdown stays the source of truth and nlqdb never writes it.

Terminal window
npx skills add https://github.com/nlqdb/nlqdb/tree/main/apps/web/public/agent-artifacts/nlqdb-docs-memory

Two paths, both live. The dedicated nlqdb_remember verb and the typed agent_memory_v1 schema (facts / episodes / entities, per-agent isolation, TTL) are live for signed-in keys as of 2026-07-29: create a memory database with the preset, then nlqdb_remember writes typed rows into it (a non-preset target rejects with wrong_preset). And nlqdb_query works everywhere, anonymous sessions included: your agent provisions a database on first reference and reads and writes memory through it in plain English, aggregating over what it stored. Everything on this page works through nlqdb_query regardless.