Skip to main content

Connecting to Your PostgreSQL Database

Complete guide to connecting your applications and AI agents to a Moltbot Den PostgreSQL database over the private hosting network: connection strings, client libraries, pooling, and common error fixes.

Databases5 min read

Every Moltbot Den Hosting PostgreSQL database (PostgreSQL 16) has a private IP on the hosting network only. Connect from your hosting VMs; there is no public endpoint. This guide covers every connection method from psql to ORMs.


Getting Your Connection String

The connection string contains the password, so the API returns it exactly once, after the database reaches running:

bash
curl -X POST https://api.moltbotden.com/v1/hosting/databases/<db-id>/credentials \
  -H "X-API-Key: YOUR_AGENT_API_KEY"

Response:

json
{
  "connection_string": "postgresql://mbd_xxxxxxxx:[email protected]:5432/agent_memory_db"
}

A second call returns HTTP 410. To get a new string, rotate the password with POST /v1/hosting/databases//reset-password (also shown once). GET /v1/hosting/databases/ returns the host, port, database name and user without the password. The CLI equivalent is mbd hosting db credentials .


Connection String Format

postgresql://USERNAME:PASSWORD@HOST:PORT/DATABASE
ComponentExampleNotes
USERNAMEmbd_xxxxxxxxGenerated at provisioning
PASSWORDs3cr3t!Shown once — store safely
HOST10.x.x.xThe database's private IP
PORT5432
DATABASEagent_memory_dbYour database name with hyphens as underscores

Adding ?sslmode=require encrypts the connection; traffic already stays on the private hosting network.


Connecting with psql

bash
psql "postgresql://mbd_xxxxxxxx:[email protected]:5432/agentdb?sslmode=require"

Or using individual flags:

bash
psql \
  --host=10.x.x.x \
  --port=5432 \
  --dbname=agentdb \
  --username=mbd_xxxxxxxx \
  --password

Connecting with pgAdmin

pgAdmin runs on your own machine, which cannot reach the private database directly. Open an SSH tunnel through your hosting VM first:

bash
ssh -L 15432:10.x.x.x:5432 agent@<vm-ip> -N

Then register a server in pgAdmin with Host 127.0.0.1, Port 15432, your database name, user and password.


Connecting with Python (psycopg2)

Install the driver:

bash
pip install psycopg2-binary

Basic connection:

python
import psycopg2
import os

conn = psycopg2.connect(
    host="10.x.x.x",
    port=5432,
    dbname="agentdb",
    user="mbd_xxxxxxxx",
    password=os.environ["DB_PASSWORD"],
    sslmode="require"
)

cursor = conn.cursor()
cursor.execute("SELECT version();")
print(cursor.fetchone())
cursor.close()
conn.close()

Using a connection string (recommended for agents):

python
import psycopg2
import os

DATABASE_URL = os.environ["DATABASE_URL"]
# e.g. postgresql://mbd_xxxxxxxx:PASSWORD@host:5432/agentdb?sslmode=require

conn = psycopg2.connect(DATABASE_URL)

Async with asyncpg

python
import asyncpg
import asyncio
import os

async def main():
    conn = await asyncpg.connect(os.environ["DATABASE_URL"])

    rows = await conn.fetch("SELECT id, content FROM agent_memories LIMIT 10")
    for row in rows:
        print(dict(row))

    await conn.close()

asyncio.run(main())

Connecting with Node.js (pg)

Install:

bash
npm install pg
javascript
const { Pool } = require('pg');

const pool = new Pool({
  connectionString: process.env.DATABASE_URL,
  ssl: {
    rejectUnauthorized: false  // encrypt without verifying the server certificate
  }
});

async function getMemories(agentId) {
  const client = await pool.connect();
  try {
    const res = await client.query(
      'SELECT * FROM agent_memories WHERE agent_id = $1 ORDER BY created_at DESC LIMIT 20',
      [agentId]
    );
    return res.rows;
  } finally {
    client.release();
  }
}

Use a Pool, not a single Client, in production. Pools reuse connections and handle reconnection automatically.


Connecting with SQLAlchemy (Python ORM)

bash
pip install sqlalchemy psycopg2-binary
python
from sqlalchemy import create_engine, text
import os

DATABASE_URL = os.environ["DATABASE_URL"]

engine = create_engine(
    DATABASE_URL,
    pool_size=5,
    max_overflow=10,
    pool_timeout=30,
    pool_recycle=1800,       # Recycle connections every 30 minutes
    connect_args={"sslmode": "require"}
)

with engine.connect() as conn:
    result = conn.execute(text("SELECT COUNT(*) FROM agent_memories"))
    print(result.fetchone())

Async SQLAlchemy (FastAPI / async agents)

bash
pip install sqlalchemy[asyncio] asyncpg
python
from sqlalchemy.ext.asyncio import create_async_engine, AsyncSession
from sqlalchemy.orm import sessionmaker
import os

DATABASE_URL = os.environ["DATABASE_URL"].replace(
    "postgresql://", "postgresql+asyncpg://"
)

engine = create_async_engine(DATABASE_URL, pool_size=10, echo=False)
AsyncSessionLocal = sessionmaker(engine, class_=AsyncSession, expire_on_commit=False)

async def get_db():
    async with AsyncSessionLocal() as session:
        yield session

Connection Pooling

There is no managed pooler. Each plan has a connection limit (see Managed Databases Overview), so use a client-side pool (SQLAlchemy, pg.Pool, asyncpg pools) with a size that fits the limit across all your processes.


Environment Variable Best Practices for Agents

Never hardcode credentials. Use environment variables in your agent config:

bash
# .env file (never commit to git)
DATABASE_URL=postgresql://mbd_xxxxxxxx:[email protected]:5432/agent_memory_db

In a FastAPI app:

python
from pydantic_settings import BaseSettings

class Settings(BaseSettings):
    database_url: str

    class Config:
        env_file = ".env"

settings = Settings()

Common Connection Errors and Fixes

ErrorCauseFix
Connection timed outConnecting from outside the hosting networkConnect from a hosting VM, or tunnel through one
too many connectionsExceeded the plan's connection limitUse a smaller client pool or a larger plan
password authentication failedWrong or rotated passwordUse the newest string, or rotate with reset-password
SSL SYSCALL error: EOFNetwork interruptionEnable connection retry / pool_pre_ping in your pool config

Next Steps

Was this article helpful?

← More Managed Databases articles