npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@agent-runner/store-postgres

v0.1.1

Published

PostgreSQL store adapter for agent-runner — multi-server production storage

Readme

@agent-runner/store-postgres

npm version License: MIT Node.js

PostgreSQL storage adapter for agent-runner. Production-ready persistent storage for multi-server deployments with automatic migrations, JSONB storage, connection pooling, and configurable table prefixes.

Install

npm install @agent-runner/store-postgres @agent-runner/core
# or
pnpm add @agent-runner/store-postgres @agent-runner/core
# or
yarn add @agent-runner/store-postgres @agent-runner/core

Quick Start

import { createRunner, defineAgent } from "@agent-runner/core";
import { PostgresStore } from "@agent-runner/store-postgres";

const runner = createRunner({
  store: new PostgresStore("postgresql://user:pass@localhost:5432/mydb"),
});

runner.registerAgent(defineAgent({
  id: "greeter",
  name: "Greeter",
  systemPrompt: "You are a friendly greeter.",
  model: { provider: "openai", name: "gpt-4o-mini" },
}));

const result = await runner.invoke("greeter", "Hello!");
console.log(result.output);

Usage

Connection String

The simplest way — pass a PostgreSQL connection string:

const store = new PostgresStore("postgresql://user:pass@localhost:5432/mydb");

Existing Connection Pool

Share a pg.Pool across your application to manage connections centrally:

import pg from "pg";
import { PostgresStore } from "@agent-runner/store-postgres";

const pool = new pg.Pool({
  connectionString: process.env.DATABASE_URL,
  max: 20,
  idleTimeoutMillis: 30000,
});

const store = new PostgresStore({ connection: pool });

// The store won't close this pool on shutdown (you own it)

Pool Configuration

Pass a pg.PoolConfig object for fine-grained control:

const store = new PostgresStore({
  connection: {
    host: "localhost",
    port: 5432,
    database: "mydb",
    user: "myuser",
    password: "mypassword",
    max: 10,
    ssl: { rejectUnauthorized: false },
  },
});

Table Prefix

Avoid naming conflicts by customizing the table prefix (default: ar_):

const store = new PostgresStore({
  connection: "postgresql://localhost:5432/mydb",
  tablePrefix: "myapp_",
});
// Tables: myapp_agents, myapp_sessions, myapp_messages, etc.

Skip Auto-Migration

If you manage migrations separately:

const store = new PostgresStore({
  connection: "postgresql://localhost:5432/mydb",
  skipMigration: true,
});

API Reference

PostgresStore

Implements UnifiedStore from @agent-runner/core — provides AgentStore, SessionStore, ContextStore, and LogStore in a single class.

Constructor

new PostgresStore(connectionString: string)
new PostgresStore(options: PostgresStoreOptions)

PostgresStoreOptions

| Option | Type | Default | Description | |---|---|---|---| | connection | string \| pg.Pool \| pg.PoolConfig | — | Required. Connection string, pool instance, or pool config | | tablePrefix | string | "ar_" | Prefix for all table names | | skipMigration | boolean | false | Skip automatic schema migration |

Store Methods

AgentStore:

| Method | Description | |---|---| | getAgent(id) | Get an agent definition by ID | | listAgents() | List all agents (id, name, description) | | putAgent(agent) | Create or update an agent | | deleteAgent(id) | Delete an agent |

SessionStore:

| Method | Description | |---|---| | getMessages(sessionId) | Get all messages in a session | | append(sessionId, messages) | Append messages (creates session if needed) | | deleteSession(sessionId) | Delete a session and its messages | | listSessions(agentId?) | List sessions, optionally filtered by agent |

ContextStore:

| Method | Description | |---|---| | getContext(contextId) | Get all entries for a context bucket | | addContext(contextId, entry) | Add an entry to a context bucket | | clearContext(contextId) | Clear all entries in a context bucket |

LogStore:

| Method | Description | |---|---| | log(entry) | Write an invocation log | | getLogs(filter?) | Query logs with optional filters | | getLog(id) | Get a single log by ID |

Lifecycle:

| Method | Description | |---|---| | close() | Close the connection pool (only if the store created it) | | pgPool | Access the underlying pg.Pool for advanced queries |

Schema

The store creates the following tables automatically (prefixed with ar_ by default):

| Table | Description | |---|---| | ar_agents | Agent definitions stored as JSONB | | ar_sessions | Session metadata with timestamps | | ar_messages | Conversation messages with JSONB tool calls | | ar_context_entries | Shared context entries between agents | | ar_invocation_logs | Full invocation logs with token usage | | ar_schema_version | Migration version tracking |

Indexes are created on session_id, agent_id, and timestamp columns for efficient querying.

Performance Notes

  • JSONB storage for agent definitions and tool calls — supports efficient querying and indexing
  • Connection pooling via pg.Pool — configure max connections based on your workload
  • Transaction safety — session message appends and deletes use transactions with rollback
  • Async migrations — schema migrations run automatically on first use, not on construction
  • Shared pools — pass an existing pg.Pool to avoid creating duplicate connections

Recommended Production Settings

import pg from "pg";

const pool = new pg.Pool({
  connectionString: process.env.DATABASE_URL,
  max: 20,                    // Max connections
  idleTimeoutMillis: 30000,   // Close idle connections after 30s
  connectionTimeoutMillis: 5000, // Fail fast on connection issues
  ssl: process.env.NODE_ENV === "production"
    ? { rejectUnauthorized: true }
    : false,
});

const store = new PostgresStore({ connection: pool });

PostgreSQL Setup

If you need to create a database:

CREATE DATABASE mydb;
CREATE USER myuser WITH PASSWORD 'mypassword';
GRANT ALL PRIVILEGES ON DATABASE mydb TO myuser;

Or with Docker:

docker run -d \
  --name agent-runner-pg \
  -e POSTGRES_DB=mydb \
  -e POSTGRES_USER=myuser \
  -e POSTGRES_PASSWORD=mypassword \
  -p 5432:5432 \
  postgres:16

Graceful Shutdown

process.on("SIGTERM", async () => {
  await runner.shutdown();  // Cleans up MCP connections
  await store.close();      // Closes the pg pool (if store-owned)
  process.exit(0);
});

Examples

Split Stores

Use PostgreSQL for agents and logs, but a different store for sessions:

import { createRunner, MemoryStore } from "@agent-runner/core";
import { PostgresStore } from "@agent-runner/store-postgres";

const pgStore = new PostgresStore(process.env.DATABASE_URL!);

const runner = createRunner({
  agentStore: pgStore,
  logStore: pgStore,
  sessionStore: new MemoryStore(), // ephemeral sessions
  contextStore: pgStore,
});

With Studio

import { createRunner } from "@agent-runner/core";
import { PostgresStore } from "@agent-runner/store-postgres";
import { createStudio } from "@agent-runner/studio";

const runner = createRunner({
  store: new PostgresStore(process.env.DATABASE_URL!),
});

// Studio reads/writes through the same Postgres store
const studio = await createStudio(runner, { port: 4000 });

Related Packages

| Package | Description | |---|---| | @agent-runner/core | Core SDK — createRunner, agents, tools, stores | | @agent-runner/store-sqlite | SQLite adapter for single-server deployments | | @agent-runner/studio | Development UI |

Contributing

See the main CONTRIBUTING.md for guidelines.

License

MIT © Aaron Bidworthy