Give your agent memory — one command
nlqdb is analytical memory for AI agents: a real Postgres your agent
connects to over MCP and queries in plain English — GROUP BY, JOIN,
aggregate over what it remembered, not just the top-k a vector store
recalls. One command connects it.
Step 1 — Connect the server
Section titled “Step 1 — Connect the server”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.
-
Claude Code — run in your terminal:
Terminal window claude mcp add --transport http nlqdb https://mcp.nlqdb.com/mcp -
Codex — add to
~/.codex/config.toml(remote HTTP servers are not addable viacodex mcp add, which is stdio-only):[mcp_servers.nlqdb]url = "https://mcp.nlqdb.com/mcp" -
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).
-
Windsurf — merge the
nlqdbentry intomcpServersin~/.codeium/windsurf/mcp_config.json, keeping any servers already there (a remote entry usesserverUrl, noturl):{ "mcpServers": { "nlqdb": { "serverUrl": "https://mcp.nlqdb.com/mcp" } } } -
Zed — merge the
context_serverskey into~/.config/zed/settings.json(same path on macOS and Linux;zed: open settings fileopens 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" } } } -
Cursor — merge the
nlqdbentry intomcpServersin the project’s.cursor/mcp.json(or~/.cursor/mcp.jsonto apply it everywhere), keeping any servers already there:{ "mcpServers": { "nlqdb": { "url": "https://mcp.nlqdb.com/mcp" } } } -
VS Code — merge the
nlqdbentry into.vscode/mcp.json, keeping any servers already there (the root key isservers, 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.
No browser? The headless route
Section titled “No browser? The headless route”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:
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.
Step 2 — Authenticate
Section titled “Step 2 — Authenticate”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.
Step 3 — Confirm the tools
Section titled “Step 3 — Confirm the tools”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 (intrace). The database materialises on first reference — there is no separate create step.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 anagent_memory_v1preset database. See What’s live today — live for signed-in keys; setkindandtagson every fact (they become yourGROUP BYcolumns), and fall back tonlqdb_queryif it answerswrong_preset.
Step 4 — Verify
Section titled “Step 4 — Verify”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_createdAgent → nlqdb_query(q: "remember that the user prefers metric units") → db_created: true, dbId: "db_…" (+ the compiled schema in trace)
# Write — previews first, then commitAgent → 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 neededAgent → 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.
Step 5 — On failure
Section titled “Step 5 — On failure”- 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 passenvthrough. The binary exits before connecting, so the host reports the server as failed rather than showing a tool error; check theenvblock sits inside thenlqdbentry, 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_databaseanswersconnect_requires_account— expected on ansk_mcp_key: attaching an external database is deliberately outside what an MCP key can do. Do it once from the dashboard (or with ansk_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
mcpServersfrom.cursor/mcp.json, VS Code readsserversfrom itsmcp.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_rememberreturnswrong_preset— the target database isn’t anagent_memory_v1preset. Create one (db.create { preset: 'agent_memory_v1' }or the dashboard), or write throughnlqdb_queryinstead (see below).
Drop it into your repo
Section titled “Drop it into your repo”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:
/plugin marketplace add nlqdb/nlqdb/plugin install nlqdb-memory@nlqdbThe 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):
npx skills add https://github.com/nlqdb/nlqdb/tree/main/apps/web/public/agent-artifacts/nlqdb-memoryIt 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): appendAGENTS.snippet.md.- Claude Code (skill): save
SKILL.mdas.claude/skills/nlqdb-memory/SKILL.md. - Cursor: save
nlqdb-memory.mdcas.cursor/rules/nlqdb-memory.mdc. - Codex: merge
codex-config.tomlinto~/.codex/config.toml.
Index + drop locations: nlqdb.com/agent-artifacts/README.md.
Make the repo’s own docs queryable
Section titled “Make the repo’s own docs queryable”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.
npx skills add https://github.com/nlqdb/nlqdb/tree/main/apps/web/public/agent-artifacts/nlqdb-docs-memoryWhat’s live today
Section titled “What’s live today”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.