Docs/Guides/Neon Postgres Integration

Neon Postgres Integration

Connect AI agents to Neon serverless Postgres through Keystore. Access databases without exposing connection strings.


Neon Postgres Integration

This guide walks through connecting an AI agent to a Neon serverless Postgres database via Keystore. Your agent uses a ks_ token instead of a real database connection string. The Keystore proxy injects the real credentials at request time.

Prerequisites

  • A Keystore account with a Neon provider configured
  • An agent token (starts with ks_)
  • A Neon database with a connection string
  • Node.js 18+

Set things up with the CLI:

bash
1
2
3
keystore login
keystore providers add        # choose neon, byok, paste your connection string
keystore agents create        # save the ks_ token

Install Dependencies

bash
1
npm install @neondatabase/serverless @keystore/sdk

Option A: Wrap the Neon Driver

The wrapNeon function creates a tagged template wrapper that routes SQL queries through the Keystore proxy. The proxy injects the real Neon connection string.

typescript
1
2
3
4
5
6
7
8
9
import { neon } from "@neondatabase/serverless";
import { Keystore, wrapNeon } from "@keystore/sdk";

const ks = new Keystore({ agentToken: "ks_abc123..." });
const sql = wrapNeon(neon, ks);

// Use the sql tagged template as usual.
const users = await sql`SELECT * FROM users LIMIT 10`;
console.log(users);

The wrapped sql function has the same tagged template interface as the standard Neon driver. Write queries exactly as you normally would.

Option B: Intercept All Fetch Requests

interceptAll patches globalThis.fetch to reroute requests to Neon's serverless driver endpoint through the Keystore proxy.

typescript
1
2
3
4
5
6
7
8
9
10
11
12
13
import { neon } from "@neondatabase/serverless";
import { Keystore } from "@keystore/sdk";

const ks = new Keystore({ agentToken: "ks_abc123..." });
ks.interceptAll(["neon"]);

// The connection string is unused -- the proxy resolves it.
const sql = neon("postgresql://unused:unused@unused/unused");

const posts = await sql`SELECT * FROM posts WHERE published = true`;
console.log(posts);

ks.restore();

Option C: Set Environment Variables

Use setupEnv to write DATABASE_URL into process.env. Useful when your ORM or framework reads the connection string from the environment.

typescript
1
2
3
4
5
6
7
import { Keystore } from "@keystore/sdk";

const ks = new Keystore({ agentToken: "ks_abc123..." });
ks.setupEnv(["neon"]);

// process.env.DATABASE_URL is now set to the proxy URL.
// Any framework that reads DATABASE_URL will route through Keystore.

Using with Drizzle ORM

Keystore works with Drizzle ORM's Neon adapter. Wrap the underlying Neon driver, then pass it to Drizzle.

typescript
1
2
3
4
5
6
7
8
9
10
import { neon } from "@neondatabase/serverless";
import { drizzle } from "drizzle-orm/neon-http";
import { Keystore, wrapNeon } from "@keystore/sdk";
import * as schema from "./schema";

const ks = new Keystore({ agentToken: "ks_abc123..." });
const sql = wrapNeon(neon, ks);
const db = drizzle(sql, { schema });

const users = await db.select().from(schema.users).limit(10);

Alternatively, use setupEnv and let Drizzle read DATABASE_URL from the environment:

typescript
1
2
3
4
5
6
7
8
9
10
11
import { Keystore } from "@keystore/sdk";

const ks = new Keystore({ agentToken: "ks_abc123..." });
ks.setupEnv(["neon"]);

// In your Drizzle config or db initialization:
import { neon } from "@neondatabase/serverless";
import { drizzle } from "drizzle-orm/neon-http";

const sql = neon(process.env.DATABASE_URL!);
const db = drizzle(sql);

Parameterized Queries

The wrapped driver supports parameterized queries through tagged templates, which protects against SQL injection.

typescript
1
2
3
4
5
6
const userId = 42;
const user = await sql`SELECT * FROM users WHERE id = ${userId}`;

const name = "Alice";
const email = "alice@example.com";
await sql`INSERT INTO users (name, email) VALUES (${name}, ${email})`;

Monitoring

Track database queries through the Keystore CLI:

bash
1
2
keystore usage ag_abc123
keystore logs ag_abc123 --provider neon

Each proxied query is logged with status, latency, and provider information.