Vercel AI SDK — Node.js Scripts
Five small Node.js scripts. Each one adds a single idea, from a plain database query up to an agent that remembers you between runs.
| Script | What it shows |
|---|---|
|
Talk to Neo4j directly. No AI. A quick check that your database login works. |
|
An AI agent that queries Neo4j through an MCP server. |
|
The same agent plus your own hand-written Cypher tools. |
|
Memory done by hand: load memories before the answer, save the turn after. |
|
Memory done by the |
Shared helpers: mcp.mjs (MCP connection), prompts.mjs (system prompts), providers.mjs (which AI model to use).
Setup
cd vercel-agent/notebook
cp .env.example .env # fill in your keys
npm install
A plain npm install works. If it ever fails with ERESOLVE, delete node_modules/ and package-lock.json and install again.
Run
node 0-direct-query.mjs
node 1-mcp-agent.mjs
node 2-custom-tools-agent.mjs
node 3-memory-agent.mjs
node 4-nams-provider-agent.mjs # provider mode (default)
NAMS_MODE=middleware node 4-nams-provider-agent.mjs
NAMS_MODE=tools node 4-nams-provider-agent.mjs
NAMS_MODE=hooks node 4-nams-provider-agent.mjs
Script 4 asks two questions. The second one ("which company was I researching?") only works if memory recalled the first. Run it again and it still works, because the memory is stored in NAMS, not in the script.
The four memory modes (script 4)
NAMS_MODE |
Who takes care of memory |
|---|---|
|
A wrapper around the AI model adds memories before each answer and saves the turn after. |
|
The same wrapper, placed on a model you already have. |
|
The model itself, by calling |
|
The script: it loads the saved conversation before each answer and saves every turn after. |
Any other value stops the script with an error.
In every mode the script loads the saved conversation first, like the Next.js demo. It builds its agent once and reuses it, so it passes each question through prepareCall:
prepareCall: async ({ options, prompt: _p, messages: _m, ...settings }) => ({
...settings,
messages: [...(await session.loadSession()), { role: 'user', content: options.prompt }],
runtimeContext: options, // lets onFinish know what to save
}),
// hooks mode saves the whole turn; tools mode saves only the text; provider and middleware save it themselves
onFinish: async (event) => { await session.onFinish()(event); },
await agent.generate({ prompt: question, options: { prompt: question } });
Settings (.env)
| Variable | Needed for | What it does |
|---|---|---|
|
all AI scripts |
Your OpenAI key (or the key for |
|
optional |
|
|
optional |
Model to use. Default |
|
scripts 0 and 2 |
Direct database login. |
|
scripts 1–3, optional for 4 |
Where the Neo4j MCP server is. |
|
with MCP |
Login for the MCP server. A token wins if both are set. |
|
scripts 3 and 4 |
Your NAMS key, free at memory.neo4jlabs.com. |
|
optional |
Use a specific NAMS workspace. |
|
optional |
Whose memory to use. Same id = same memories across runs. |
|
script 4 |
|
MCP login: hosted Aura / NeoCompanion servers want a token (MCP_BEARER_TOKEN). Self-hosted servers usually want a username and password. On a login error, the scripts tell you which kind the server asked for.
Switching AI providers
Set AI_PROVIDER and the matching key. No code changes needed.
| Provider | AI_PROVIDER |
Key |
|---|---|---|
OpenAI (default) |
|
|
Google Gemini |
|
|
Anthropic Claude |
|
|
Mistral |
|
|
Good to know
-
All scripts use AI SDK v7. Agent loops stop with
stopWhen: stepCountIs(N), which replaced the oldmaxSteps. -
workspaceIdgoes on theMemoryClient, not oncreateConversation(). -
Script 4 also saves each reasoning step, the same trace the Next.js demo shows in its side panel.
-
mcp.mjsstops any database call after 30 seconds and cuts results over 50,000 characters. The model is told to write a smaller query instead of the script hanging.