Metadata-Version: 2.1
Name: sqldbagent
Version: 0.1.0
Summary: Service-first database intelligence platform for safe inspection and agent-ready exports
Keywords: sql,database,agent,langgraph,langchain,mcp,postgres,mssql
Author-Email: Will <you@example.com>
License: MIT
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Database
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Project-URL: Homepage, https://github.com/pr1m8/sqldbagent
Project-URL: Repository, https://github.com/pr1m8/sqldbagent
Project-URL: Issues, https://github.com/pr1m8/sqldbagent/issues
Project-URL: Documentation, https://github.com/pr1m8/sqldbagent/tree/main/docs
Requires-Python: >=3.13
Requires-Dist: pydantic>=2.12.5
Requires-Dist: pydantic-settings>=2.13.1
Requires-Dist: sqlalchemy>=2.0.48
Requires-Dist: aiosqlite>=0.21.0
Requires-Dist: greenlet>=3.3.2
Requires-Dist: sqlglot>=29.0.1
Requires-Dist: orjson>=3.11.8
Requires-Dist: tenacity>=9.1.4
Requires-Dist: networkx>=3.6.1
Requires-Dist: jinja2>=3.1.6
Requires-Dist: pyyaml>=6.0.3
Provides-Extra: dashboard
Requires-Dist: streamlit>=1.56.0; extra == "dashboard"
Requires-Dist: pandas>=3.0.2; extra == "dashboard"
Requires-Dist: plotly>=6.6.0; extra == "dashboard"
Provides-Extra: lint
Requires-Dist: ruff>=0.15.8; extra == "lint"
Requires-Dist: sqlfluff>=4.1.0; extra == "lint"
Requires-Dist: pre-commit>=4.5.1; extra == "lint"
Requires-Dist: commitizen>=4.9.1; extra == "lint"
Provides-Extra: langgraph
Requires-Dist: langgraph>=1.1.4; extra == "langgraph"
Requires-Dist: langgraph-sdk>=0.3.12; extra == "langgraph"
Requires-Dist: langgraph-checkpoint-postgres>=3.0.5; extra == "langgraph"
Requires-Dist: langgraph-cli[inmem]>=0.4.19; extra == "langgraph"
Provides-Extra: langchain
Requires-Dist: langchain>=1.2.14; extra == "langchain"
Requires-Dist: langchain-core>=1.2.24; extra == "langchain"
Requires-Dist: langchain-community>=0.4.1; extra == "langchain"
Requires-Dist: langsmith>=0.7.24; extra == "langchain"
Requires-Dist: langchain-openai; extra == "langchain"
Requires-Dist: langchain-anthropic; extra == "langchain"
Requires-Dist: langchain-qdrant>=1.1.0; extra == "langchain"
Requires-Dist: qdrant-client>=1.17.1; extra == "langchain"
Requires-Dist: langchain-text-splitters>=1.1.1; extra == "langchain"
Provides-Extra: mcp
Requires-Dist: fastmcp>=3.2.0; extra == "mcp"
Provides-Extra: docs
Requires-Dist: sphinx>=9.1.0; extra == "docs"
Requires-Dist: myst-parser>=5.0.0; extra == "docs"
Requires-Dist: furo>=2025.12.19; extra == "docs"
Requires-Dist: sphinxext-opengraph>=0.13.0; extra == "docs"
Requires-Dist: sphinx-last-updated-by-git>=0.3.8; extra == "docs"
Requires-Dist: sphinx-notfound-page>=1.1.0; extra == "docs"
Requires-Dist: sphinx-autodoc-typehints>=3.9.11; extra == "docs"
Requires-Dist: autodoc-pydantic>=2.2.0; extra == "docs"
Requires-Dist: sphinx-design>=0.7.0; extra == "docs"
Requires-Dist: sphinx-copybutton>=0.5.2; extra == "docs"
Requires-Dist: sphinxcontrib-mermaid>=2.0.1; extra == "docs"
Requires-Dist: sphinx-inline-tabs>=2025.12.21.14; extra == "docs"
Requires-Dist: sphinx-togglebutton>=0.4.5; extra == "docs"
Requires-Dist: sphinx-autobuild>=2025.8.25; extra == "docs"
Requires-Dist: linkify-it-py>=2.1.0; extra == "docs"
Provides-Extra: release
Requires-Dist: twine>=6.2.0; extra == "release"
Provides-Extra: test
Requires-Dist: pytest>=9.0.2; extra == "test"
Requires-Dist: pytest-asyncio>=1.3.0; extra == "test"
Requires-Dist: pytest-cov>=7.1.0; extra == "test"
Requires-Dist: pytest-mock>=3.15.1; extra == "test"
Requires-Dist: pytest-socket>=0.7.0; extra == "test"
Requires-Dist: pytest-benchmark>=5.2.3; extra == "test"
Requires-Dist: pytest-xdist>=3.8.0; extra == "test"
Requires-Dist: syrupy>=5.1.0; extra == "test"
Requires-Dist: hypothesis>=6.151.10; extra == "test"
Requires-Dist: langchain-tests>=1.1.5; extra == "test"
Provides-Extra: typecheck
Requires-Dist: mypy>=1.20.0; extra == "typecheck"
Provides-Extra: mssql
Requires-Dist: pyodbc>=5.3.0; extra == "mssql"
Requires-Dist: aioodbc>=0.5.0; extra == "mssql"
Provides-Extra: tui
Requires-Dist: textual>=8.2.1; extra == "tui"
Requires-Dist: rich>=14.3.3; extra == "tui"
Provides-Extra: cli
Requires-Dist: typer>=0.24.1; extra == "cli"
Requires-Dist: rich>=14.3.3; extra == "cli"
Provides-Extra: postgres
Requires-Dist: psycopg>=3.3.3; extra == "postgres"
Requires-Dist: alembic>=1.18.4; extra == "postgres"
Description-Content-Type: text/markdown

# sqldbagent

[![CI](https://github.com/pr1m8/sqldbagent/actions/workflows/ci.yml/badge.svg)](https://github.com/pr1m8/sqldbagent/actions/workflows/ci.yml)
[![Docs](https://github.com/pr1m8/sqldbagent/actions/workflows/docs.yml/badge.svg)](https://github.com/pr1m8/sqldbagent/actions/workflows/docs.yml)
[![Python 3.13](https://img.shields.io/badge/python-3.13-0f766e.svg)](https://www.python.org/downloads/)
[![PDM](https://img.shields.io/badge/deps-pdm-334155.svg)](https://pdm-project.org/)
[![License: MIT](https://img.shields.io/badge/license-MIT-115e59.svg)](LICENSE)

Safe database intelligence for agents, operators, and automation.

sqldbagent is a service-first platform for understanding relational databases through normalized metadata, durable artifacts, guarded querying, and agent-ready surfaces. It starts with Postgres and MSSQL, uses SQLite as a lightweight smoke/E2E target, and keeps the shared service layer authoritative across every interface.

## Why This Exists

Most database tooling gives you one of two extremes:

- a thin SQL shell with no meaningful safety boundary
- a one-off schema export with no reusable runtime context

sqldbagent is trying to sit in the middle:

- inspect and normalize database structure once
- store snapshots, profiles, docs, diagrams, prompts, and retrieval indexes durably
- let CLI workflows, dashboards, MCP tools, and LangGraph agents reuse that context
- keep all agent-facing SQL behind an explicit read-only safety layer

## Core Shape

The architecture rule is:

### Normalized Metadata Core In The Middle, Dialect Enrichers On The Edges

That means:

- shared models for databases, schemas, tables, views, columns, relationships, profiles, and snapshots
- Postgres and MSSQL adapters for dialect-specific introspection and execution details
- thin surfaces on top: CLI, dashboard, MCP, LangChain, and LangGraph

## Current Capabilities

- datasource config and engine factories through Pydantic Settings and `.env`
- normalized inspection of servers, schemas, tables, and views
- profiling with row counts, distinct/null stats, samples, storage hints, and entity heuristics
- guarded sync and async SQL execution
- snapshot persistence with per-datasource and per-schema storage
- snapshot diffing, docs export, Mermaid ER export, and prompt export
- Qdrant-backed retrieval over stored snapshot documents
- LangChain tools and LangGraph agent builders with middleware, checkpointing, and optional LangSmith tracing
- FastMCP server surface
- Streamlit dashboard chat surface over the same persisted agent stack

## Install

With PDM:

```bash
pdm install -G :all
```

With pip:

```bash
pip install "sqldbagent[cli,postgres,langchain,langgraph,mcp,dashboard,docs,test]"
```

## Local Demo

Bring up the local integration stack and migrate the demo database:

```bash
make up
make demo-migrate
```

Run the common workflow:

```bash
pdm run sqldbagent inspect tables postgres_demo --schema public
pdm run sqldbagent snapshot create postgres_demo public
pdm run sqldbagent prompt export postgres_demo public
make dashboard-demo
```

## Agent Stack

sqldbagent uses LangChain v1's `create_agent(...)` surface on top of LangGraph runtime primitives.

- state is seeded from stored snapshots
- middleware owns prompt injection, tool handling, summarization, HITL, and limits
- Postgres checkpointing is the durable thread path
- the dashboard uses a session-scoped memory saver when Postgres checkpointing is not enabled
- LangSmith tracing is optional and `.env`-driven

`langgraph.json` points at the local project root and `.env`, so `langgraph dev` uses the same package and tracing configuration as the rest of the repo.

## Documentation

Public docs live in [`docs/source`](docs/source), internal repo memory lives in [`docs/_internal`](docs/_internal), and the main contributor rules live in [`AGENTS.md`](AGENTS.md).

Useful entrypoints:

- [Getting Started](docs/source/getting-started.md)
- [Configuration](docs/source/configuration.md)
- [Agent Stack](docs/source/agent-stack.md)
- [Publishing](docs/source/publishing.md)

Build docs locally:

```bash
make docs
make docs-live
```

## Development

```bash
trunk check --fix
make test
make test-integration
make test-e2e
```

## Publishing

```bash
make build
make publish-check
make publish-testpypi
make publish-pypi
```

The repo also includes GitHub Actions workflows for CI, docs builds, and trusted-publisher PyPI releases on version tags.
