Back to skills
SkillHub ClubAnalyze Data & AIFull StackBackendData / AI

neon

Neon serverless Postgres — manage projects, branches, databases, roles, endpoints, and compute via the Neon API. Create database branches for development, manage connection endpoints, scale compute, and monitor usage. Built for AI agents — Python stdlib only, zero dependencies. Use for serverless Postgres, database branching, database management, development workflows, and cloud database automation.

Packaged view

This page reorganizes the original catalog entry around fit, installability, and workflow context first. The original raw source lives below.

Stars
3,083
Hot score
99
Updated
March 20, 2026
Overall rating
C4.0
Composite score
4.0
Best-practice grade
A92.0

Install command

npx @skill-hub/cli install openclaw-skills-neon

Repository

openclaw/skills

Skill path: skills/aiwithabidi/neon

Neon serverless Postgres — manage projects, branches, databases, roles, endpoints, and compute via the Neon API. Create database branches for development, manage connection endpoints, scale compute, and monitor usage. Built for AI agents — Python stdlib only, zero dependencies. Use for serverless Postgres, database branching, database management, development workflows, and cloud database automation.

Open repository

Best for

Primary workflow: Analyze Data & AI.

Technical facets: Full Stack, Backend, Data / AI.

Target audience: everyone.

License: MIT.

Original source

Catalog source: SkillHub Club.

Repository owner: openclaw.

This is still a mirrored public skill entry. Review the repository before installing into production workflows.

What it helps with

  • Install neon into Claude Code, Codex CLI, Gemini CLI, or OpenCode workflows
  • Review https://github.com/openclaw/skills before adding neon to shared team environments
  • Use neon for development workflows

Works across

Claude CodeCodex CLIGemini CLIOpenCode

Favorites: 0.

Sub-skills: 0.

Aggregator: No.

Original source / Raw SKILL.md

---
name: neon
description: "Neon serverless Postgres — manage projects, branches, databases, roles, endpoints, and compute via the Neon API. Create database branches for development, manage connection endpoints, scale compute, and monitor usage. Built for AI agents — Python stdlib only, zero dependencies. Use for serverless Postgres, database branching, database management, development workflows, and cloud database automation."
homepage: https://www.agxntsix.ai
license: MIT
compatibility: Python 3.10+ (stdlib only — no dependencies)
metadata: {"openclaw": {"emoji": "💚", "requires": {"env": ["NEON_API_KEY"]}, "primaryEnv": "NEON_API_KEY", "homepage": "https://www.agxntsix.ai"}}
---

# 💚 Neon

Neon serverless Postgres — manage projects, branches, databases, roles, endpoints, and compute via the Neon API.

## Features

- **Project management** — create, list, delete projects
- **Branch management** — create, restore, delete branches
- **Database operations** — create and manage databases
- **Role management** — database users and permissions
- **Endpoint management** — connection endpoints and pooling
- **Compute scaling** — auto-suspend, compute size control
- **Connection strings** — generate connection URIs
- **Operations history** — track async operations
- **Consumption metrics** — compute hours, storage, transfer
- **Branch restore** — point-in-time restore from history

## Requirements

| Variable | Required | Description |
|----------|----------|-------------|
| `NEON_API_KEY` | ✅ | API key/token for Neon |

## Quick Start

```bash
# List projects
python3 {baseDir}/scripts/neon.py projects --limit 20
```

```bash
# Get project details
python3 {baseDir}/scripts/neon.py project-get proj-abc123
```

```bash
# Create a project
python3 {baseDir}/scripts/neon.py project-create '{"project":{"name":"my-app","region_id":"aws-us-east-1"}}'
```

```bash
# Delete a project
python3 {baseDir}/scripts/neon.py project-delete proj-abc123
```



## Commands

### `projects`
List projects.
```bash
python3 {baseDir}/scripts/neon.py projects --limit 20
```

### `project-get`
Get project details.
```bash
python3 {baseDir}/scripts/neon.py project-get proj-abc123
```

### `project-create`
Create a project.
```bash
python3 {baseDir}/scripts/neon.py project-create '{"project":{"name":"my-app","region_id":"aws-us-east-1"}}'
```

### `project-delete`
Delete a project.
```bash
python3 {baseDir}/scripts/neon.py project-delete proj-abc123
```

### `branches`
List branches.
```bash
python3 {baseDir}/scripts/neon.py branches --project proj-abc123
```

### `branch-create`
Create a branch.
```bash
python3 {baseDir}/scripts/neon.py branch-create --project proj-abc123 '{"branch":{"name":"dev","parent_id":"br-main"}}'
```

### `branch-delete`
Delete a branch.
```bash
python3 {baseDir}/scripts/neon.py branch-delete --project proj-abc123 br-dev
```

### `branch-restore`
Restore branch to point in time.
```bash
python3 {baseDir}/scripts/neon.py branch-restore --project proj-abc123 br-main --timestamp '2026-02-01T00:00:00Z'
```

### `databases`
List databases.
```bash
python3 {baseDir}/scripts/neon.py databases --project proj-abc123 --branch br-main
```

### `database-create`
Create database.
```bash
python3 {baseDir}/scripts/neon.py database-create --project proj-abc123 --branch br-main '{"database":{"name":"mydb","owner_name":"neondb_owner"}}'
```

### `roles`
List roles.
```bash
python3 {baseDir}/scripts/neon.py roles --project proj-abc123 --branch br-main
```

### `endpoints`
List endpoints.
```bash
python3 {baseDir}/scripts/neon.py endpoints --project proj-abc123
```

### `connection-string`
Get connection string.
```bash
python3 {baseDir}/scripts/neon.py connection-string --project proj-abc123 --branch br-main --database mydb
```

### `consumption`
Get consumption metrics.
```bash
python3 {baseDir}/scripts/neon.py consumption --from 2026-01-01 --to 2026-02-01
```

### `operations`
List operations.
```bash
python3 {baseDir}/scripts/neon.py operations --project proj-abc123 --limit 10
```


## Output Format

All commands output JSON by default. Add `--human` for readable formatted output.

```bash
# JSON (default, for programmatic use)
python3 {baseDir}/scripts/neon.py projects --limit 5

# Human-readable
python3 {baseDir}/scripts/neon.py projects --limit 5 --human
```

## Script Reference

| Script | Description |
|--------|-------------|
| `{baseDir}/scripts/neon.py` | Main CLI — all Neon operations |

## Data Policy

This skill **never stores data locally**. All requests go directly to the Neon API and results are returned to stdout. Your data stays on Neon servers.

## Credits
---
Built by [M. Abidi](https://www.linkedin.com/in/mohammad-ali-abidi) | [agxntsix.ai](https://www.agxntsix.ai)
[YouTube](https://youtube.com/@aiwithabidi) | [GitHub](https://github.com/aiwithabidi)
Part of the **AgxntSix Skill Suite** for OpenClaw agents.

📅 **Need help setting up OpenClaw for your business?** [Book a free consultation](https://cal.com/agxntsix/abidi-openclaw)


---

## Skill Companion Files

> Additional files collected from the skill directory layout.

### _meta.json

```json
{
  "owner": "aiwithabidi",
  "slug": "neon",
  "displayName": "Neon",
  "latest": {
    "version": "1.0.0",
    "publishedAt": 1772743964168,
    "commit": "https://github.com/openclaw/skills/commit/4fe312e175595af676578118d81e51f3b5f7339d"
  },
  "history": []
}

```

### scripts/neon.py

```python
#!/usr/bin/env python3
"""Neon CLI — comprehensive API integration for AI agents.

Full CRUD operations, search, reporting, and automation.
Zero dependencies beyond Python stdlib.
"""

import argparse
import json
import os
import sys
import urllib.request
import urllib.error
import urllib.parse
from datetime import datetime, timezone

API_BASE = "https://console.neon.tech/api/v2"


def get_token():
    """Get API token from environment."""
    token = os.environ.get("NEON_API_KEY", "")
    if not token:
        env_path = os.path.join(
            os.environ.get("WORKSPACE", os.path.expanduser("~/.openclaw/workspace")),
            ".env"
        )
        if os.path.exists(env_path):
            with open(env_path) as f:
                for line in f:
                    line = line.strip()
                    if line.startswith("NEON_API_KEY="):
                        token = line.split("=", 1)[1].strip().strip('"').strip("'")
                        break
    if not token:
        print(f"Error: NEON_API_KEY not set", file=sys.stderr)
        sys.exit(1)
    return token


def api(method, path, data=None, params=None):
    """Make an API request."""
    token = get_token()
    url = f"{API_BASE}{path}"
    if params:
        qs = urllib.parse.urlencode({k: v for k, v in params.items() if v is not None})
        if qs:
            url = f"{url}?{qs}"
    body = json.dumps(data).encode() if data else None
    req = urllib.request.Request(url, data=body, method=method)
    req.add_header("Authorization", f"Bearer {token}")
    req.add_header("Content-Type", "application/json")
    req.add_header("Accept", "application/json")
    try:
        resp = urllib.request.urlopen(req, timeout=30)
        raw = resp.read().decode()
        return json.loads(raw) if raw.strip() else {"ok": True}
    except urllib.error.HTTPError as e:
        err_body = e.read().decode()
        print(json.dumps({"error": True, "code": e.code, "message": err_body}), file=sys.stderr)
        sys.exit(1)


def output(data, human=False):
    """Output data as JSON or human-readable."""
    if human and isinstance(data, list):
        for item in data:
            if isinstance(item, dict):
                for k, v in item.items():
                    print(f"  {k}: {v}")
                print()
            else:
                print(item)
    elif human and isinstance(data, dict):
        for k, v in data.items():
            print(f"  {k}: {v}")
    else:
        print(json.dumps(data, indent=2, default=str))


def cmd_projects(args):
    """List projects."""
    params = {}
    if hasattr(args, 'limit') and args.limit:
        params["limit"] = args.limit
    if hasattr(args, 'id') and args.id:
        data = api("GET", f"/projects/{args.id}")
    else:
        data = api("GET", "/projects", params=params)
    output(data, getattr(args, 'human', False))

def cmd_project_get(args):
    """Get project details."""
    params = {}
    if hasattr(args, 'limit') and args.limit:
        params["limit"] = args.limit
    if hasattr(args, 'id') and args.id:
        data = api("GET", f"/project/{args.id}")
    else:
        data = api("GET", "/project/get", params=params)
    output(data, getattr(args, 'human', False))

def cmd_project_create(args):
    """Create a project."""
    params = {}
    if hasattr(args, 'limit') and args.limit:
        params["limit"] = args.limit
    if hasattr(args, 'id') and args.id:
        data = api("POST", f"/project/{args.id}")
    else:
        data = api("POST", "/project/create", params=params)
    output(data, getattr(args, 'human', False))

def cmd_project_delete(args):
    """Delete a project."""
    params = {}
    if hasattr(args, 'limit') and args.limit:
        params["limit"] = args.limit
    if hasattr(args, 'id') and args.id:
        data = api("DELETE", f"/project/{args.id}")
    else:
        data = api("DELETE", "/project/delete", params=params)
    output(data, getattr(args, 'human', False))

def cmd_branches(args):
    """List branches."""
    params = {}
    if hasattr(args, 'limit') and args.limit:
        params["limit"] = args.limit
    if hasattr(args, 'id') and args.id:
        data = api("GET", f"/branches/{args.id}")
    else:
        data = api("GET", "/branches", params=params)
    output(data, getattr(args, 'human', False))

def cmd_branch_create(args):
    """Create a branch."""
    params = {}
    if hasattr(args, 'limit') and args.limit:
        params["limit"] = args.limit
    if hasattr(args, 'id') and args.id:
        data = api("POST", f"/branch/{args.id}")
    else:
        data = api("POST", "/branch/create", params=params)
    output(data, getattr(args, 'human', False))

def cmd_branch_delete(args):
    """Delete a branch."""
    params = {}
    if hasattr(args, 'limit') and args.limit:
        params["limit"] = args.limit
    if hasattr(args, 'id') and args.id:
        data = api("DELETE", f"/branch/{args.id}")
    else:
        data = api("DELETE", "/branch/delete", params=params)
    output(data, getattr(args, 'human', False))

def cmd_branch_restore(args):
    """Restore branch to point in time."""
    params = {}
    if hasattr(args, 'limit') and args.limit:
        params["limit"] = args.limit
    if hasattr(args, 'id') and args.id:
        data = api("GET", f"/branch/{args.id}")
    else:
        data = api("GET", "/branch/restore", params=params)
    output(data, getattr(args, 'human', False))

def cmd_databases(args):
    """List databases."""
    params = {}
    if hasattr(args, 'limit') and args.limit:
        params["limit"] = args.limit
    if hasattr(args, 'id') and args.id:
        data = api("GET", f"/databases/{args.id}")
    else:
        data = api("GET", "/databases", params=params)
    output(data, getattr(args, 'human', False))

def cmd_database_create(args):
    """Create database."""
    params = {}
    if hasattr(args, 'limit') and args.limit:
        params["limit"] = args.limit
    if hasattr(args, 'id') and args.id:
        data = api("POST", f"/database/{args.id}")
    else:
        data = api("POST", "/database/create", params=params)
    output(data, getattr(args, 'human', False))

def cmd_roles(args):
    """List roles."""
    params = {}
    if hasattr(args, 'limit') and args.limit:
        params["limit"] = args.limit
    if hasattr(args, 'id') and args.id:
        data = api("GET", f"/roles/{args.id}")
    else:
        data = api("GET", "/roles", params=params)
    output(data, getattr(args, 'human', False))

def cmd_endpoints(args):
    """List endpoints."""
    params = {}
    if hasattr(args, 'limit') and args.limit:
        params["limit"] = args.limit
    if hasattr(args, 'id') and args.id:
        data = api("GET", f"/endpoints/{args.id}")
    else:
        data = api("GET", "/endpoints", params=params)
    output(data, getattr(args, 'human', False))

def cmd_connection_string(args):
    """Get connection string."""
    params = {}
    if hasattr(args, 'limit') and args.limit:
        params["limit"] = args.limit
    if hasattr(args, 'id') and args.id:
        data = api("GET", f"/connection/{args.id}")
    else:
        data = api("GET", "/connection/string", params=params)
    output(data, getattr(args, 'human', False))

def cmd_consumption(args):
    """Get consumption metrics."""
    params = {}
    if hasattr(args, 'limit') and args.limit:
        params["limit"] = args.limit
    if hasattr(args, 'id') and args.id:
        data = api("GET", f"/consumption/{args.id}")
    else:
        data = api("GET", "/consumption", params=params)
    output(data, getattr(args, 'human', False))

def cmd_operations(args):
    """List operations."""
    params = {}
    if hasattr(args, 'limit') and args.limit:
        params["limit"] = args.limit
    if hasattr(args, 'id') and args.id:
        data = api("GET", f"/operations/{args.id}")
    else:
        data = api("GET", "/operations", params=params)
    output(data, getattr(args, 'human', False))


COMMANDS = {
    "projects": cmd_projects,
    "project-get": cmd_project_get,
    "project-create": cmd_project_create,
    "project-delete": cmd_project_delete,
    "branches": cmd_branches,
    "branch-create": cmd_branch_create,
    "branch-delete": cmd_branch_delete,
    "branch-restore": cmd_branch_restore,
    "databases": cmd_databases,
    "database-create": cmd_database_create,
    "roles": cmd_roles,
    "endpoints": cmd_endpoints,
    "connection-string": cmd_connection_string,
    "consumption": cmd_consumption,
    "operations": cmd_operations,
}


def main():
    parser = argparse.ArgumentParser(
        description="Neon CLI — AI agent integration",
        formatter_class=argparse.RawDescriptionHelpFormatter,
    )
    parser.add_argument("command", choices=list(COMMANDS.keys()), help="Command to run")
    parser.add_argument("args", nargs="*", help="Command arguments")
    parser.add_argument("--human", action="store_true", help="Human-readable output")
    parser.add_argument("--limit", type=int, help="Limit results")
    parser.add_argument("--id", help="Resource ID")
    parser.add_argument("--from", dest="from_date", help="Start date")
    parser.add_argument("--to", dest="to_date", help="End date")
    parser.add_argument("--status", help="Filter by status")
    parser.add_argument("--sort", help="Sort field")
    parser.add_argument("--query", help="Search query")

    parsed = parser.parse_args()
    cmd_func = COMMANDS[parsed.command]
    cmd_func(parsed)


if __name__ == "__main__":
    main()

```