AutoGen Tutorial (TypeScript): connecting to PostgreSQL for beginners

By Cyprian AaronsUpdated 2026-04-21
autogenconnecting-to-postgresql-for-beginnerstypescript

This tutorial shows you how to connect an AutoGen TypeScript agent to PostgreSQL, run real SQL queries, and return results inside an agent conversation. You need this when your agent has to read from or write to business data instead of answering from memory.

What You'll Need

  • Node.js 18+ installed
  • A PostgreSQL database running locally or in Docker
  • A database user with SELECT permission on the target tables
  • An OpenAI API key
  • These packages:
    • autogen-core
    • pg
    • dotenv
    • typescript
    • tsx for running TypeScript directly during development

Install them with:

npm install autogen-core pg dotenv
npm install -D typescript tsx @types/node @types/pg

Create a .env file:

OPENAI_API_KEY=your_openai_key_here
PGHOST=localhost
PGPORT=5432
PGDATABASE=postgres
PGUSER=postgres
PGPASSWORD=postgres

Step-by-Step

  1. Start by creating a small PostgreSQL client wrapper. Keep the connection logic outside the agent so you can test it independently and reuse it in other services.
import "dotenv/config";
import { Pool } from "pg";

export const pool = new Pool({
  host: process.env.PGHOST,
  port: Number(process.env.PGPORT ?? 5432),
  database: process.env.PGDATABASE,
  user: process.env.PGUSER,
  password: process.env.PGPASSWORD,
});

export async function queryDb(text: string, params: unknown[] = []) {
  const result = await pool.query(text, params);
  return result.rows;
}
  1. Next, define a tool that AutoGen can call. In AutoGen TypeScript, the clean pattern is to expose a normal async function that your agent can invoke when it needs database data.
import { queryDb } from "./db";

export async function getCustomerByEmail(email: string) {
  const rows = await queryDb(
    "SELECT id, name, email, created_at FROM customers WHERE email = $1 LIMIT 1",
    [email]
  );

  if (rows.length === 0) {
    return { found: false };
  }

  return { found: true, customer: rows[0] };
}
  1. Now wire that tool into an AutoGen assistant agent. This example uses the TypeScript AutoGen runtime with OpenAI chat completions and a simple system prompt that tells the model when to use the database helper.
import "dotenv/config";
import { OpenAIChatCompletionClient } from "@autogen-ext/openai";
import { AssistantAgent } from "autogen-agentchat";
import { getCustomerByEmail } from "./tools";

const modelClient = new OpenAIChatCompletionClient({
  model: "gpt-4o-mini",
  apiKey: process.env.OPENAI_API_KEY,
});

const assistant = new AssistantAgent({
  name: "postgres_assistant",
  modelClient,
  systemMessage:
    "You are a helpful assistant. When asked about customer records, call getCustomerByEmail and use the returned data.",
});
  1. Register the tool and run a message through the agent. This is where the agent gets useful: it can decide whether to answer directly or hit PostgreSQL for fresh data.
import { UserMessage } from "autogen-agentchat";

await assistant.registerTool(
  {
    name: "getCustomerByEmail",
    description: "Fetch a customer record by email from PostgreSQL.",
    parametersSchema: {
      type: "object",
      properties: {
        email: { type: "string" },
      },
      required: ["email"],
      additionalProperties: false,
    },
    execute: async ({ email }: { email: string }) => getCustomerByEmail(email),
  },
);

const response = await assistant.run([
  new UserMessage("Find the customer record for jane@example.com", "user"),
]);

console.log(JSON.stringify(response.messages, null, 2));
  1. Finish with a small runner so you can execute everything locally. This keeps setup simple and makes debugging easier when you are still validating credentials and SQL access.
async function main() {
  const response = await assistant.run([
    new UserMessage("Look up jane@example.com in PostgreSQL", "user"),
  ]);

  for (const message of response.messages) {
    console.log(message.content);
  }

}

main().catch((error) => {
  console.error(error);
  process.exit(1);
});

Testing It

Run your script with npx tsx src/index.ts. If everything is wired correctly, you should see the assistant call the PostgreSQL tool and print back either a customer record or a “not found” result.

If you get a connection error, check your .env values first, then confirm PostgreSQL is listening on the expected host and port. If the model responds without calling the tool, tighten the system prompt so it explicitly says to use PostgreSQL for customer lookups.

A good smoke test is to insert one known row into customers, then ask for that exact email address. That verifies three things at once: database connectivity, SQL correctness, and agent-tool wiring.

Next Steps

  • Add write operations with transaction handling for safe updates and inserts
  • Move from one-off helpers to a proper tool registry with typed schemas per table
  • Add row-level authorization so the agent only sees data it is allowed to access

Keep learning

By Cyprian Aarons, AI Consultant at Topiax.

Want the complete 8-step roadmap?

Grab the free AI Agent Starter Kit — architecture templates, compliance checklists, and a 7-email deep-dive course.

Get the Starter Kit

Related Guides