Postgres Actions
VoltOps ships a managed Execute Postgres Query action so agents can run parameterized SQL against your databases with observability, retries, and credential management handled for you.
Prerequisitesβ
- A reachable Postgres database (host, port, database, user, password) with network access from Volt.
- A Volt project with API keys (
pk_β¦,sk_β¦). - A Postgres credential inside Volt:
- Go to Settings β Integrations β Add Credential β Postgres (Actions).
- Enter host, port, user, password, database, and optionally toggle SSL / reject self-signed certs.
- Save to generate a
cred_xxxidentifier.
- (Recommended) Save the credential ID as an environment variable:
POSTGRES_CREDENTIAL_ID=cred_xxx
Run Postgres actions from codeβ
import { VoltOpsClient } from "@voltagent/core";
const voltops = new VoltOpsClient({
publicKey: process.env.VOLTAGENT_PUBLIC_KEY!,
secretKey: process.env.VOLTAGENT_SECRET_KEY!,
});
// Parameterized query (recommended)
const result = await voltops.actions.postgres.executeQuery({
credential: { credentialId: process.env.POSTGRES_CREDENTIAL_ID! },
query:
"SELECT id, email, status FROM public.users WHERE status = $1 ORDER BY created_at DESC LIMIT 10;",
parameters: ["active"],
applicationName: "VoltAgent",
statementTimeoutMs: 30_000,
connectionTimeoutMs: 30_000,
ssl: { rejectUnauthorized: false },
});
console.log(result.responsePayload.rows);
No stored credential? You can pass inline connection details instead:
await voltops.actions.postgres.executeQuery({
credential: {
host: "db.example.com",
port: 5432,
user: "app_user",
password: process.env.POSTGRES_PASSWORD!,
database: "app_db",
ssl: true,
},
query: "SELECT table_name FROM information_schema.tables WHERE table_schema = 'public';",
});
Expose Postgres as an agent toolβ
import { createTool, VoltOpsClient } from "@voltagent/core";
import { z } from "zod";
const voltops = new VoltOpsClient({
publicKey: process.env.VOLTAGENT_PUBLIC_KEY!,
secretKey: process.env.VOLTAGENT_SECRET_KEY!,
});
export const runPostgresQueryTool = createTool({
name: "runPostgresQuery",
description: "Run a parameterized SQL query against Postgres",
parameters: z.object({
query: z.string(),
parameters: z.array(z.any()).default([]),
}),
execute: async ({ query, parameters }) => {
const exec = await voltops.actions.postgres.executeQuery({
credential: { credentialId: process.env.POSTGRES_CREDENTIAL_ID! },
query,
parameters,
statementTimeoutMs: 20_000,
});
return {
actionId: exec.actionId,
rows: exec.responsePayload.rows,
metadata: exec.metadata,
};
},
});
Attach runPostgresQuery to any agent; the planner will call it when SQL is needed. VoltOps records the request/response so you can replay or debug failures in Volt β Actions β Runs.
Testing payloads in the consoleβ
Open Volt Console β Actions β Add Action β Postgres. Pick your credential and use the Payload & Test editor. A sample payload is prefilled to list public tables:
{
"query": "SELECT table_name FROM information_schema.tables WHERE table_schema = 'public' ORDER BY table_name LIMIT 20;",
"parameters": []
}
Click Run Test to execute against your database; successful runs return rows plus a copy-ready SDK snippet.
Troubleshootingβ
- βunsupported startup parameter: statement_timeoutβ β Volt sets
statement_timeoutafter connecting (not as a startup param). If your server blocksSET statement_timeout, remove that field or lower the value. - SSL / self-signed certs β set
ssl: trueandssl.rejectUnauthorized: falseif your instance uses self-signed certificates. - Long-running queries β use
statementTimeoutMsto avoid hanging agents;connectionTimeoutMscontrols how long we wait to establish the socket. - Always parameterize β pass values via
parameters: []($1,$2, β¦) instead of string concatenation to avoid SQL injection and to match the Postgres action schema.