neon-drizzle-expert

neon-drizzle-expert is an agent for Claude Code from Matt-Dionis/claude-code-configs. It costs 77 tokens per session (5,430 once invoked), scanned A, original, MIT.

A coding guide for building memory systems with Neon PostgreSQL, a hosted PostgreSQL database, Drizzle ORM, a tool for type-safe database access, and Zod, a data-validation library.

In plain words
What is it for?
Use it when designing or implementing a production memory database, including PostgreSQL schemas, pgvector tables, Drizzle configuration, validation, and migration workflows.
Why use it?
It provides version-specific patterns for database connections, schemas, validation, and migrations in a serverless application.

Agent for Claude Code

Written for Claude Code: installed under .claude/. Also seen: names the TodoWrite tool.

Needs its repository: it reads a path above its own folder, which exists only inside the repository. The line is import { db } from "../db/client";.

Good fit Use it when designing or implementing a production memory database, including PostgreSQL schemas, pgvector tables, Drizzle configuration, validation, and migration workflows.

Compare 6 agents from other repositories ↓
Install

Getting it into your agent

It runs from inside its repository, so the clone comes first — what it calls does not travel with the file alone.

Clone the repo
git clone --depth 1 https://github.com/Matt-Dionis/claude-code-configs
agentmods
npx agentmods add agents/matt-dionis/claude-code-configs/neon-drizzle-expert

Made for: Claude Code.

Wrote this? Show the measurements

A badge with what this costs and how it scanned, read live from this page, so it follows the numbers instead of freezing them. Markdown for a README, HTML for a documentation site or a project page.

agentmods badge for neon-drizzle-expert

README.md
[![agentmods](https://agentmods.dev/badge/agents/matt-dionis/claude-code-configs/neon-drizzle-expert/github.svg)](https://agentmods.dev/agents/matt-dionis/claude-code-configs/neon-drizzle-expert)
Your own site
<a href="https://agentmods.dev/agents/matt-dionis/claude-code-configs/neon-drizzle-expert"><img src="https://agentmods.dev/badge/agents/matt-dionis/claude-code-configs/neon-drizzle-expert/github.svg" alt="Measured on agentmods" height="20"></a>

Or the 80×15 button, for a site that already has a row of RSS and ATOM ones. Only the verdict fits; the numbers stay here.

agentmods 80×15 button for neon-drizzle-expert

Your own site · 80×15
<a href="https://agentmods.dev/agents/matt-dionis/claude-code-configs/neon-drizzle-expert"><img src="https://agentmods.dev/badge/agents/matt-dionis/claude-code-configs/neon-drizzle-expert.svg" alt="Reviewed on agentmods" width="80" height="20"></a>
Per session 77 Only the description is in the session, so the agent can decide to use it. The body loads when it is invoked.
When invoked 5,430 The whole file, excluding the scripts and references it only reads on demand.
Security scan A 1 finding. A grade says what 26 rules found in the file — not that it is safe.
Origin original No closer match found in the catalogue.
Token cost

What it costs to keep this loaded

Counted locally with the o200k_base tokenizer, which is exact for GPT models; Claude uses its own tokenizer and its counts differ. Treat this as one consistent yardstick across the catalogue rather than a bill. Prices are per million input tokens.

ModelPer sessionOnce invoked
Fable 5.1 $0.00077 $0.05430
Opus 5 $0.00039 $0.02715
Sonnet 5 $0.00015 $0.01086
Haiku 4.5 $0.00008 $0.00543

Measured 9d ago against content hash fca15682b92a, method: parsed. Prices are Anthropic first-party input rates as of 2026-09-09, from the pricing page.

Security

Grade A, and why

neon-drizzle-expert scanned grade A with 1 finding against 26 rules in 11 categories — prompt injection, anti-refusal, data exfiltration, privilege escalation, supply chain, agent snooping, system-prompt leakage, SSRF and excessive agency — measured 9d ago.

A static scan of the body, not an audit. Every finding is printed with the line that produced it so you can judge whether it matters here. A mod is markdown that instructs an agent; that is exactly why what it instructs is worth reading.

Makes network callslowCapability

Not a fault in itself. Listed so you know the mod talks to something, and to what.

const response = await axios.post(
configurations/mcp-servers/memory-mcp-server/.claude/agents/neon-drizzle-expert.md · 694 lines

How it starts

The opening of the file, as written. The whole thing — 694 lines — stays where its author put it; the contents beside it link to each section on GitHub.

You are an expert in Neon PostgreSQL (v17), Drizzle ORM (v0.44.4), and building type-safe database layers for production MCP memory servers.

Package Versions

  • @neondatabase/serverless: 1.0.1
  • drizzle-orm: 0.44.4
  • drizzle-kit: 0.31.4
  • drizzle-zod: 0.8.3
  • zod: 4.0.17
  • PostgreSQL: 17

Neon PostgreSQL Setup

Connection Configuration

// .env.local
DATABASE_URL="postgresql://[user]:[password]@[neon-hostname]/[database]?sslmode=require"
DATABASE_URL_POOLED="postgresql://[user]:[password]@[neon-pooler-hostname]/[database]?sslmode=require"

// For migrations (direct connection)
DIRECT_DATABASE_URL="postgresql://[user]:[password]@[neon-hostname]/[database]?sslmode=require"

Drizzle Configuration

// drizzle.config.ts
import { Config } from "drizzle-kit";
import * as dotenv from "dotenv";

dotenv.config({ path: ".env.local" });

export default {
  schema: "./src/db/schema.ts",
  out: "./drizzle",
  driver: "pg",
  dbCredentials: {
    connectionString: process.env.DIRECT_DATABASE_URL!,
  },
  verbose: true,
  strict: true,
} satisfies Config;

Schema Design with Drizzle

Core Tables with pgvector

// src/db/schema.ts
import { 
  pgTable, 
  text, 
  timestamp, 
  uuid, 
  jsonb, 
  integer,
  index,
  vector,
  real,
  boolean,
  primaryKey
} from "drizzle-orm/pg-core";
import { sql } from "drizzle-orm";
import { createId } from "@paralleldrive/cuid2";

// Enable pgvector extension
export const vectorExtension = sql`CREATE EXTENSION IF NOT EXISTS vector`;

// Companions table (AI entities)
export const companions = pgTable("companions", {
  id: text("id").primaryKey().$defaultFn(() => createId()),
  name: text("name").notNull(),
  description: text("description"),
  config: jsonb("config").$type<{
    model?: string;
    temperature?: number;
    systemPrompt?: string;
    capabilities?: string[];
  }>().default({}),
  ownerId: text("owner_id").notNull(), // Organization or user that owns this companion
  isActive: boolean("is_active").default(true),
  createdAt: timestamp("created_at").defaultNow().notNull(),
  updatedAt: timestamp("updated_at").defaultNow().notNull(),
}, (table) => ({
  ownerIdx: index("companions_owner_idx").on(table.ownerId),
  activeIdx: index("companions_active_idx").on(table.isActive),
}));

// Users interacting with companions
export const users = pgTable("users", {
  id: text("id").primaryKey().$defaultFn(() => createId()),
  externalId: text("external_id").notNull().unique(), // ID from your auth system
  metadata: jsonb("metadata").$type<{
    name?: string;
    email?: string;
    preferences?: Record<string, any>;
  }>().default({}),
  createdAt: timestamp("created_at").defaultNow().notNull(),
  updatedAt: timestamp("updated_at").defaultNow().notNull(),
}, (table) => ({
  externalIdIdx: index("users_external_id_idx").on(table.externalId),
}));

// Memories with vector embeddings
export const memories = pgTable("memories", {
  id: text("id").primaryKey().$defaultFn(() => createId()),
  companionId: text("companion_id").notNull().references(() => companions.id, { onDelete: "cascade" }),
  userId: text("user_id").notNull().references(() => users.id, { onDelete: "cascade" }),
  
  // Content
  content: text("content").notNull(),
  summary: text("summary"), // AI-generated summary for quick scanning
  embedding: vector("embedding", { dimensions: 1536 }), // OpenAI ada-002 dimensions
  
  // Metadata
  type: text("type", { enum: ["fact", "experience", "preference", "instruction", "reflection"] }).notNull(),
  importance: real("importance").default(5).notNull(), // 0-10 scale
  confidence: real("confidence").default(1).notNull(), // 0-1 scale
  
  // Context
  context: jsonb("context").$type<{
    conversationId?: string;
    turnNumber?: number;
    emotionalTone?: string;
    topics?: string[];
    entities?: Array<{ name: string; type: string }>;
    source?: string;
    timestamp?: string;
  }>().default({}),
  
  // Lifecycle
  accessCount: integer("access_count").default(0).notNull(),
  lastAccessedAt: timestamp("last_accessed_at"),
  expiresAt: timestamp("expires_at"),
  isArchived: boolean("is_archived").default(false),
  
  createdAt: timestamp("created_at").defaultNow().notNull(),
  updatedAt: timestamp("updated_at").defaultNow().notNull(),
}, (table) => ({
  // Composite index for companion-user queries
  companionUserIdx: index("memories_companion_user_idx").on(table.companionId, table.userId),
  // Type filtering
  typeIdx: index("memories_type_idx").on(table.type),
  // Importance-based retrieval
  importanceIdx: index("memories_importance_idx").on(table.companionId, table.userId, table.importance),
  // Vector similarity search (using ivfflat for performance)
  embeddingIdx: index("memories_embedding_idx").using("ivfflat", table.embedding.op("vector_cosine_ops")),
  // Archive status
  archivedIdx: index("memories_archived_idx").on(table.isArchived),
  // Expiration handling
  expiresAtIdx: index("memories_expires_at_idx").on(table.expiresAt),
}));

// Memory relationships (for knowledge graphs)
export const memoryRelations = pgTable("memory_relations", {
  id: text("id").primaryKey().$defaultFn(() => createId()),
  fromMemoryId: text("from_memory_id").notNull().references(() => memories.id, { onDelete: "cascade" }),
  toMemoryId: text("to_memory_id").notNull().references(() => memories.id, { onDelete: "cascade" }),
  relationType: text("relation_type", { 
    enum: ["follows", "contradicts", "elaborates", "corrects", "references", "causes"] 
  }).notNull(),
  strength: real("strength").default(1.0).notNull(), // 0-1 relationship strength
  metadata: jsonb("metadata").$type<Record<string, any>>().default({}),
  createdAt: timestamp("created_at").defaultNow().notNull(),
}, (table) => ({
  fromIdx: index("relations_from_idx").on(table.fromMemoryId),
  toIdx: index("relations_to_idx").on(table.toMemoryId),
  typeIdx: index("relations_type_idx").on(table.relationType),
}));

// Companion sessions (for StreamableHTTP)
export const companionSessions = pgTable("companion_sessions", {
  id: text("id").primaryKey().$defaultFn(() => createId()),
  sessionId: text("session_id").notNull().unique(), // MCP session ID
  companionId: text("companion_id").notNull().references(() => companions.id, { onDelete: "cascade" }),
  userId: text("user_id").references(() => users.id, { onDelete: "cascade" }),
  
  metadata: jsonb("metadata").$type<{
    ipAddress?: string;
    userAgent?: string;
    protocol?: string;
  }>().default({}),
  
  lastActivityAt: timestamp("last_activity_at").defaultNow().notNull(),
  expiresAt: timestamp("expires_at").notNull(),
  createdAt: timestamp("created_at").defaultNow().notNull(),
}, (table) => ({
  sessionIdx: index("sessions_session_id_idx").on(table.sessionId),
  companionIdx: index("sessions_companion_idx").on(table.companionId),
  expiresIdx: index("sessions_expires_idx").on(table.expiresAt),
}));

Read the full file on GitHub · 694 lines

Changes

What this file has done since we first saw it

Hashed on every crawl. A supply-chain change to an agent config is a question of when, not whether, so the history is kept rather than the latest state alone.

  1. 9d ago First seen · 694 lines · 77 tokens per session scan A fca15682b92a

Subscribe to this mod's changes

neon-drizzle-expert is an agent published in the GitHub repository Matt-Dionis/claude-code-configs (624 stars, last pushed 1y ago), licensed MIT. It adds 77 tokens to every session and 5,430 once invoked, about $0.0004 per session on Opus 5. A static security scan graded it A with 1 finding (makes network calls). No closer match exists in the catalogue, so it is treated as the original; first seen 2026-08-30.

Related

Other agents, from other repositories

PostgreSQL Database Administrator

Work with PostgreSQL databases using the PostgreSQL extension.

github/awesome-copilot · 17 tokens

supabase-substrate-explorer

Specialist research agent for discovering creative, non-obvious applications of the Supabase SUBSTRATE dimension (Postgres Database, Storage object store, pgvector) to Thoughtbox's reasoning-persistence surfaces. Use proactively when exploring how substrate-layer primitives could become new "organs" for Thoughtbox…

Kastalien-Research/thoughtbox · 117 tokens

supabase-rag-implementer

Materializa RAG em Supabase em 3 layers - migration vector(N)+HNSW, RPC matchdocuments security invoker com RLS por tenant, Edge Function embedding server-side. Use ao implementar RAG.

luanpdd/kit-mcp · 52 tokens

database-reviewer

PostgreSQL specialist for query performance, schema design, security/RLS, and migration safety. Use PROACTIVELY when writing SQL, creating migrations, designing schemas, or troubleshooting database performance.

sjarmak/coding-agent-workflows · 43 tokens

supabase-roles-implementer

Gera SQL de Postgres Roles em Supabase (CREATE ROLE + GRANT matrix + BYPASSRLS) para system access — service accounts, BI, cron jobs. Recebe spec via Task(). Nao substitui RLS + Custom Claims.

luanpdd/kit-mcp · 59 tokens

evolution-go-integrator

Gera tabelas orgwhatsappconfigs + whatsappmessages, webhook Edge Function e send queue pgmq para WhatsApp (Evolution Go ou Meta Cloud API) em Supabase B2B multi-tenant. (pesado — despacha.

luanpdd/kit-mcp · 53 tokens