[build-system] requires = ["hatchling"] build-backend = "hatchling.build" [project] name = "db-conn-mcp" version = "0.7.1" description = "A dead-simple, self-hosted MCP server for securely querying databases via AI agents." readme = "README.md" requires-python = ">=3.12" license = { text = "MIT" } authors = [{ name = "db-conn-mcp contributors" }] keywords = ["mcp", "model-context-protocol", "postgresql", "database", "ai-agent"] classifiers = [ "Development Status :: 3 - Alpha", "Intended Audience :: Developers", "License :: OSI Approved :: MIT License", "Programming Language :: Python :: 3.12", "Programming Language :: Python :: 3.13", "Programming Language :: Python :: 3.14", "Topic :: Database", ] # Single source of truth for dependencies (Rule 4 — no requirements.txt). dependencies = [ # <2.0.0: SDK 2.0 removed mcp.server.fastmcp (the FastMCP API this server is # built on). Migrating to SDK 2.x is tracked separately. "mcp>=1.0.0,<2.0.0", "asyncpg>=0.29.0", "pydantic>=2.0.0", # Codex stores its MCP config as TOML. There is no TOML *writer* in the stdlib # at any Python version (`tomllib` parses only), and ~/.codex/config.toml is a # hand-maintained file — tomlkit is the only option that preserves the user's # comments and layout on a read-merge-write. Pure Python, no transitive deps. "tomlkit>=0.13.0", # The GUI imports these directly; today they arrive via mcp, but our own import # must not depend on a transitive pin. "starlette>=0.40", "uvicorn>=0.30", "httpx>=0.27", ] [project.optional-dependencies] dev = [ # Pinned exactly, not floored: a linter/formatter is not semver-stable in what # it flags, so a range lets CI enforce rules a developer cannot reproduce # locally. Bump this deliberately, with the resulting fixes in the same change. "ruff==0.16.2", "pytest>=8.0.0", "pytest-asyncio>=0.24.0", "build>=1.2.0", ] # Enables the doctor's `process_staleness` check; the check degrades to # `skipped` when it is absent, so it stays out of the hard dependencies. doctor = ["psutil>=5.9.0"] [project.scripts] db-conn-mcp = "db_conn_mcp.cli:main" [project.urls] Homepage = "https://github.com/Idle-Sync/db-conn-mcp" Repository = "https://github.com/Idle-Sync/db-conn-mcp" Issues = "https://github.com/Idle-Sync/db-conn-mcp/issues" # Renders as a "Changelog" link on the PyPI project page. Changelog = "https://github.com/Idle-Sync/db-conn-mcp/blob/main/CHANGELOG.md" [tool.hatch.build.targets.wheel] packages = ["src/db_conn_mcp"] # ---- Ruff: strict, consistent linting + formatting (Rule 2) ---- [tool.ruff] line-length = 100 target-version = "py312" src = ["src", "tests"] # Ruff 0.16+ also formats Python blocks inside Markdown. We don't want that here: # doc snippets are illustrative (sometimes abbreviated or deliberately aligned), # and docs/superpowers/ holds dated historical artifacts that must stay verbatim. extend-exclude = ["*.md"] [tool.ruff.lint] # A pragmatic-but-strict selection: pycodestyle, pyflakes, isort, bugbear, # comprehensions, pyupgrade, simplify, and pep8-naming. select = ["E", "F", "I", "B", "C4", "UP", "SIM", "N", "W"] ignore = [] [tool.ruff.lint.per-file-ignores] "tests/**/*.py" = ["S101"] # asserts are expected in tests [tool.ruff.format] quote-style = "double" indent-style = "space" # ---- Pytest ---- [tool.pytest.ini_options] asyncio_mode = "auto" testpaths = ["tests"]