✨ Read this must-read post from Hacker News 📖
📂 **Category**:
📌 **What You’ll Learn**:
“What if I had an AI assistant in every row of my Postgres table?”
I asked myself this a few weeks back and pgclaw is what I came up with: an open-source Postgres extension that introduces a claw data type to instantiate an AI agent – either a simple LLM or an “OpenClaw” agent – as a Postgres column.
With pgclaw, store your AI agents with the rest of your data. Supports:
- Simple LLM agents and more stateful “OpenClaw” agents
- Any LLM provider via rig: Anthropic, OpenAI, Ollama, Gemini, Groq, Together, DeepSeek, Mistral, Perplexity, Cohere, xAI, OpenRouter, and more
- A “Claude Code” in each row via claude-agent-sdk: agents that can read/write files, run code, and use tools
- ACID compliance, point-in-time recovery, JOINs, and all of the other great features of Postgres
- any language with a Postgres client
Prerequisites: Rust toolchain and PostgreSQL 17 dev headers.
cargo install cargo-pgrx
cargo pgrx init --pg17 download
git clone https://github.com/calebwin/pgclaw.git
cd pgclaw
cargo pgrx install
Then in postgresql.conf:
shared_preload_libraries="pgclaw"
pgclaw.api_key = 'sk-ant-...'
pgclaw.database="mydb"
CREATE EXTENSION pgclaw;
CREATE TABLE tickets (
id serial PRIMARY KEY,
title text,
body text,
priority text,
agent claw DEFAULT claw('Set priority to low/medium/high/critical based on urgency.')
);
SELECT claw_watch('tickets');
INSERT INTO tickets (title, body) VALUES ('Login broken', '500 error on login page');
-- ~1-2s later: priority = 'critical'
A claw value binds an LLM agent to a row. Two modes:
Inline — just a prompt:
claw('Summarize this ticket in one sentence.')
claw('Classify sentiment.', model => 'claude-sonnet')
Agent reference — points to a reusable agent definition in claw.agents:
claw(agent => 'ticket-triage')
claw(agent => 'ticket-triage', model => 'claude-opus')
Define reusable agents with identity, instructions, and memory:
INSERT INTO claw.agents (id, soul, instructions, memory) VALUES (
'ticket-triage',
'You are a meticulous support ticket classifier.',
'Read the ticket. Set priority (low/medium/high/critical) and summary.
If unsure, set medium and explain in summary.',
'💬'
);
CREATE TABLE tickets (
id serial PRIMARY KEY,
title text,
body text,
priority text,
summary text,
agent claw DEFAULT claw(agent => 'ticket-triage')
);
SELECT claw_watch('tickets');
The agent can update its own memory by including 🔥 in its response.
Agents with Workspaces (Claude Code)
Agents with a workspace field get their own filesystem directory and run via Claude Code:
INSERT INTO claw.agents (id, soul, instructions, workspace) VALUES (
'engineer',
'You are a senior engineer. You write clean, tested code.',
'Implement the change. Run tests. Update status to pass/fail.',
'auto'
);
CREATE TABLE tasks (
id serial PRIMARY KEY, task text, status text DEFAULT 'pending', diff text,
agent claw DEFAULT claw(agent => 'engineer')
);
SELECT claw_watch('tasks');
Requires Claude Code CLI (npm install -g @anthropic-ai/claude-code). Workspace paths: 'auto' uses {pgclaw.workspace_dir}/{agent}/{table}/{pk}/, or use a custom template like '/data/{agent}/{table}/{pk}'.
Channels, Sessions, Heartbeats
INSERT INTO claw.agents (id, soul, instructions) VALUES (
'support-bot', 'You are the support bot for Acme Inc.', 'Help users with orders.'
);
INSERT INTO claw.bindings (channel, agent_id) VALUES ('telegram', 'support-bot');
INSERT INTO claw.heartbeats (agent_id, every) VALUES ('support-bot', '30 minutes');
SELECT claw.route('telegram', '*', 'user123', NULL, 'My order is late');
-- Pick up responses from claw.outbox
# Required
pgclaw.api_key = 'sk-ant-...' # API key for your provider
pgclaw.database="mydb" # Database for the background worker
# Optional
pgclaw.api_provider="anthropic" # see supported providers below
pgclaw.api_url="" # override API endpoint
pgclaw.default_model="claude-sonnet-4-5-20250929" # default model for inline claw values
pgclaw.enabled = true # enable/disable processing
pgclaw.workspace_dir="/tmp/pgclaw/workspaces" # base dir for Claude Code workspaces
Supported providers: anthropic (default), openai, ollama, gemini, groq, together, deepseek, perplexity, cohere, mistral, moonshot, openrouter, xai, hyperbolic, mira, galadriel
# OpenAI
pgclaw.api_provider="openai"
pgclaw.api_key = 'sk-...'
pgclaw.default_model="gpt-4o"
# Ollama (local, no API key needed)
pgclaw.api_provider="ollama"
pgclaw.default_model="llama3.1"
# OpenAI-compatible (vLLM, LM Studio, etc.)
pgclaw.api_provider="openai"
pgclaw.api_url="http://localhost:8000/v1"
- You add a
clawcolumn to a table and callclaw_watch() - On INSERT/UPDATE, a Postgres trigger enqueues the row to
claw.queue - A Postgres background worker polls the queue:
- LLM agents (no workspace): builds prompt from agent config + row data, calls LLM via rig
- Claude Code agents (with workspace): creates a workspace directory with
SOUL.md,AGENTS.md,context.json, spawns Claude Code via claude-agent-sdk
- The response is parsed for column updates (JSON
{"column": "value"}) and applied back to the row - Conversation history is preserved in
claw.historyfor multi-turn interactions
MIT of course!
{💬|⚡|🔥} **What’s your take?**
Share your thoughts in the comments below!
#️⃣ **#calebwinpgclaw #Clawdbot #row #lines #Postgres #SQL**
🕒 **Posted on**: 1770923718
🌟 **Want more?** Click here for more info! 🌟
