[project] name = "pgops-mcp" version = "0.1.9" description = "Production-grade MCP server: safe, audited PostgreSQL operations + Docker environment awareness for AI agents." readme = "README.md" requires-python = ">=3.12" license = "MIT" license-files = ["LICENSE"] authors = [{ name = "Arsh Zakee Chowhan" }] keywords = ["mcp", "model-context-protocol", "postgres", "postgresql", "database", "docker"] # pgops-mcp is an MCP *server*, not a Python library: nothing here is meant to be # imported by other code, and `pgops.*` carries no API stability promise. PyPI is the # delivery channel — it is what makes `uvx pgops-mcp` work, and the MCP Registry stores # only metadata and needs a real package to point at. Hence "Application", and no # "Libraries :: Python Modules" topic, which would advertise an import surface that # does not exist. classifiers = [ "Development Status :: 4 - Beta", "Environment :: Console", "Intended Audience :: Developers", "Intended Audience :: System Administrators", "Operating System :: OS Independent", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.12", "Topic :: Database", "Topic :: Database :: Database Engines/Servers", "Topic :: System :: Systems Administration", ] dependencies = [ "fastmcp>=2.3,<4.0", "asyncpg>=0.29", "sqlparse>=0.5", # Required, not optional: six of the seventeen tools (env.*, container.*) import it, # and it previously reached the venv only as a transitive dependency of # testcontainers — a dev-only package. A user installing from PyPI would have had # every environment tool fail on ImportError. "docker>=7.0", ] # Rendered as the sidebar on the PyPI project page. The README alone is not enough # there: PyPI renders it with no notion of the repository it came from, so a reader who # wants the tool reference or the setup guide has nowhere to click. Names matter — # PyPI gives "Documentation", "Changelog", "Source" and "Issues" recognised icons. [project.urls] Homepage = "https://github.com/arzharch/pgops-mcp" Documentation = "https://github.com/arzharch/pgops-mcp/blob/main/docs/GETTING_STARTED.md" "Tool reference" = "https://github.com/arzharch/pgops-mcp/blob/main/docs/API.md" "Setup guide" = "https://github.com/arzharch/pgops-mcp/blob/main/SETUP.md" Changelog = "https://github.com/arzharch/pgops-mcp/blob/main/CHANGELOG.md" Source = "https://github.com/arzharch/pgops-mcp" Issues = "https://github.com/arzharch/pgops-mcp/issues" [project.scripts] pgops-mcp = "pgops.__main__:main" [project.optional-dependencies] otel = [ "opentelemetry-sdk>=1.25", "opentelemetry-exporter-otlp-proto-grpc>=1.25", "aiohttp>=3.9", ] dev = [ "pytest>=8.0", "pytest-asyncio>=0.23", "testcontainers[postgres]>=4.0", # Property-based tests of the safety core. Test-only — it was previously declared as # a runtime dependency (with a non-existent `[dev]` extra), which shipped a testing # library to every user of the server. "hypothesis>=6.165", # Validates server.json against the vendored MCP Registry schema, so a manifest that # would be rejected at publish time fails in CI instead. "jsonschema>=4.0", "ruff>=0.5", "mypy>=1.10", ] [build-system] requires = ["uv_build>=0.7,<1.0"] build-backend = "uv_build" [tool.uv.build-backend] module-name = "pgops" [tool.pytest.ini_options] asyncio_mode = "auto" testpaths = ["tests"] markers = [ "slow: spawns the server as a subprocess (stdio transport end-to-end)", "live: boots a real HTTP server and evaluates it end-to-end incl. benchmarks; run explicitly with -m live", ] [tool.ruff] line-length = 100 target-version = "py312" [tool.mypy] strict = true [[tool.mypy.overrides]] module = "asyncpg.*" ignore_missing_imports = true [[tool.mypy.overrides]] module = "sqlparse.*" ignore_missing_imports = true [[tool.mypy.overrides]] module = "docker.*" ignore_missing_imports = true # Optional at runtime and absent from the default dev environment: observability.py # imports these lazily and degrades to a no-op when they are missing, which is the whole # design. Without these overrides `mypy src` fails for anyone who has not installed the # `otel` extra — including CI, which syncs only `--extra dev`. [[tool.mypy.overrides]] module = "opentelemetry.*" ignore_missing_imports = true [[tool.mypy.overrides]] module = "aiohttp.*" ignore_missing_imports = true