PostgreSQL Read-Only Query Skill
When to Use
- Use when querying PostgreSQL databases and access must stay strictly read-only
- Use when exploring schemas, tables, and data across multiple configured connections
- Use when you want defense-in-depth protection against accidental INSERT/UPDATE/DELETE or DDL
Execute safe, read-only queries against configured PostgreSQL databases.
Requirements
- Python 3.8+
- psycopg2-binary:
pip install -r requirements.txt
Setup
Create connections.json in the skill directory or ~/.config/claude/postgres-connections.json.
Security: Set file permissions to 600 since it contains credentials:
chmod 600 connections.json
{
"databases": [
{
"name": "production",
"description": "Main app database - users, orders, transactions",
"host": "db.example.com",
"port": 5432,
"database": "app_prod",
"user": "readonly_user",
"password": "your-password",
"sslmode": "require"
}
]
}
Config Fields
| Field |
Required |
Description |
| name |
Yes |
Identifier for the database (case-insensitive) |
| description |
Yes |
What data this database contains (used for auto-selection) |
| host |
Yes |
Database hostname |
| port |
No |
Port number (default: 5432) |
| database |
Yes |
Database name |
| user |
Yes |
Username |
| password |
Yes |
Password |
| sslmode |
No |
SSL mode: disable, allow, prefer (default), require, verify-ca, verify-full |
Usage
List configured databases
python3 scripts/query.py --list
Query a database
python3 scripts/query.py --db production --query "SELECT * FROM users LIMIT 10"
List tables
python3 scripts/query.py --db production --tables
Show schema
python3 scripts/query.py --db production --schema
Limit results
python3 scripts/query.py --db production --query "SELECT * FROM orders" --limit 100
Database Selection
Match user intent to database description:
| User asks about |
Look for description containing |
| users, accounts |
users, accounts, customers |
| orders, sales |
orders, transactions, sales |
| analytics, metrics |
analytics, metrics, reports |
| logs, events |
logs, events, audit |
If unclear, run --list and ask user which database.
Safety Features
- Read-only session: Connection uses PostgreSQL
readonly=True mode (primary protection)
- Query validation: Only SELECT, SHOW, EXPLAIN, WITH queries allowed
- Single statement: Multiple statements per query rejected
- SSL support: Configurable SSL mode for encrypted connections
- Query timeout: 30-second statement timeout enforced
- Memory protection: Max 10,000 rows per query to prevent OOM
- Column width cap: 100 char max per column for readable output
- Credential sanitization: Error messages don't leak passwords
Troubleshooting
| Error |
Solution |
| Config not found |
Create connections.json in skill directory |
| Authentication failed |
Check username/password in config |
| Connection timeout |
Verify host/port, check firewall/VPN |
| SSL error |
Try "sslmode": "disable" for local databases |
| Permission warning |
Run chmod 600 connections.json |
Exit Codes
- 0: Success
- 1: Error (config missing, auth failed, invalid query, database error)
Workflow
- Run
--list to show available databases
- Match user intent to database description
- Run
--tables or --schema to explore structure
- Execute query with appropriate LIMIT
Limitations
- Read-only protections reduce accidental writes but cannot override database-server policy,
triggers, extensions, or an over-privileged account. Use a database role with read-only
permissions as the primary control.
- Query results can contain personal, confidential, or regulated data. Confirm the intended
database and avoid exporting or sharing results without explicit authorization.
- The script is not a replacement for backups, auditing, access reviews, or production change
controls.
Source: sickn33/agentic-awesome-skills → skills/postgres-readonly-queries/SKILL.md
1---2name: postgres-readonly-queries3description: Execute safe read-only SQL queries against PostgreSQL databases with multi-connection support and defense-in-depth write protection.4---567# PostgreSQL Read-Only Query Skill89## When to Use1011- Use when querying PostgreSQL databases and access must stay strictly read-only12- Use when exploring schemas, tables, and data across multiple configured connections13- Use when you want defense-in-depth protection against accidental INSERT/UPDATE/DELETE or DDL1415Execute safe, read-only queries against configured PostgreSQL databases.1617## Requirements1819- Python 3.8+20- psycopg2-binary: `pip install -r requirements.txt`2122## Setup2324Create `connections.json` in the skill directory or `~/.config/claude/postgres-connections.json`.2526**Security**: Set file permissions to `600` since it contains credentials:27```bash28chmod 600 connections.json29```3031```json32{33 "databases": [34 {35 "name": "production",36 "description": "Main app database - users, orders, transactions",37 "host": "db.example.com",38 "port": 5432,39 "database": "app_prod",40 "user": "readonly_user",41 "password": "your-password",42 "sslmode": "require"43 }44 ]45}46```4748### Config Fields4950| Field | Required | Description |51|-------|----------|-------------|52| name | Yes | Identifier for the database (case-insensitive) |53| description | Yes | What data this database contains (used for auto-selection) |54| host | Yes | Database hostname |55| port | No | Port number (default: 5432) |56| database | Yes | Database name |57| user | Yes | Username |58| password | Yes | Password |59| sslmode | No | SSL mode: disable, allow, prefer (default), require, verify-ca, verify-full |6061## Usage6263### List configured databases64```bash65python3 scripts/query.py --list66```6768### Query a database69```bash70python3 scripts/query.py --db production --query "SELECT * FROM users LIMIT 10"71```7273### List tables74```bash75python3 scripts/query.py --db production --tables76```7778### Show schema79```bash80python3 scripts/query.py --db production --schema81```8283### Limit results84```bash85python3 scripts/query.py --db production --query "SELECT * FROM orders" --limit 10086```8788## Database Selection8990Match user intent to database `description`:9192| User asks about | Look for description containing |93|-----------------|--------------------------------|94| users, accounts | users, accounts, customers |95| orders, sales | orders, transactions, sales |96| analytics, metrics | analytics, metrics, reports |97| logs, events | logs, events, audit |9899If unclear, run `--list` and ask user which database.100101## Safety Features102103- **Read-only session**: Connection uses PostgreSQL `readonly=True` mode (primary protection)104- **Query validation**: Only SELECT, SHOW, EXPLAIN, WITH queries allowed105- **Single statement**: Multiple statements per query rejected106- **SSL support**: Configurable SSL mode for encrypted connections107- **Query timeout**: 30-second statement timeout enforced108- **Memory protection**: Max 10,000 rows per query to prevent OOM109- **Column width cap**: 100 char max per column for readable output110- **Credential sanitization**: Error messages don't leak passwords111112## Troubleshooting113114| Error | Solution |115|-------|----------|116| Config not found | Create `connections.json` in skill directory |117| Authentication failed | Check username/password in config |118| Connection timeout | Verify host/port, check firewall/VPN |119| SSL error | Try `"sslmode": "disable"` for local databases |120| Permission warning | Run `chmod 600 connections.json` |121122## Exit Codes123124- **0**: Success125- **1**: Error (config missing, auth failed, invalid query, database error)126127## Workflow1281291. Run `--list` to show available databases1302. Match user intent to database description1313. Run `--tables` or `--schema` to explore structure1324. Execute query with appropriate LIMIT133134## Limitations135136- Read-only protections reduce accidental writes but cannot override database-server policy,137 triggers, extensions, or an over-privileged account. Use a database role with read-only138 permissions as the primary control.139- Query results can contain personal, confidential, or regulated data. Confirm the intended140 database and avoid exporting or sharing results without explicit authorization.141- The script is not a replacement for backups, auditing, access reviews, or production change142 controls.143144---145146**Source:** [`sickn33/agentic-awesome-skills`](https://github.com/sickn33/agentic-awesome-skills) → `skills/postgres-readonly-queries/SKILL.md`