[project] name = "jdatamunch-mcp" version = "1.31.13" description = "Token-efficient MCP server for tabular data retrieval via CSV/Excel/Parquet/JSONL indexing" readme = "README.md" requires-python = ">=3.10" authors = [ { name = "J. Gravelle", email = "j@gravelle.us" }, ] license = "LicenseRef-jDataMunch-Dual-Use" license-files = ["LICENSE"] dependencies = [ "mcp>=1.10.0,<2.0.0", "charset-normalizer>=3.0.0", ] [project.urls] Homepage = "https://github.com/jgravelle/jdatamunch-mcp" Repository = "https://github.com/jgravelle/jdatamunch-mcp" "Bug Tracker" = "https://github.com/jgravelle/jdatamunch-mcp/issues" [project.optional-dependencies] excel = ["openpyxl>=3.1.0", "xlrd>=2.0.0"] parquet = ["pyarrow>=14.0.0"] anthropic = ["anthropic>=0.40.0"] gemini = ["google-generativeai>=0.8.0"] semantic = ["sentence-transformers>=2.2.0"] all = ["openpyxl>=3.1.0", "xlrd>=2.0.0", "pyarrow>=14.0.0", "anthropic>=0.40.0", "google-generativeai>=0.8.0", "sentence-transformers>=2.2.0"] [project.scripts] jdatamunch-mcp = "jdatamunch_mcp.server:main" [build-system] requires = ["hatchling"] build-backend = "hatchling.build" [tool.hatch.build.targets.sdist] # Build-time exclusion, NOT git exclusion. `.claude/settings.local.json` # is ignored via a GLOBAL gitignore, so `git status` never shows it and a # fresh clone never has it -- which is why the CI sdist guard grepping for # `.claude` cannot fire. It leaks only from a LOCAL build, and a local build # is how twine uploads happen. exclude = [".claude/"] [tool.hatch.build.targets.wheel] packages = ["src/jdatamunch_mcp"] [dependency-groups] dev = [ # Required by the `lint` job in .github/workflows/test.yml. Locally # `uv run ruff` fetches it on demand, which is exactly why its absence here # was invisible until CI ran: the job failed with "Failed to spawn: ruff" # on its very first run. "ruff>=0.6.0", "pytest>=9.0.2", "pytest-asyncio>=1.3.0", "pytest-cov>=7.0.0", # Writes the .xls fixture the xlrd parser tests read. xlrd itself ships in # the `excel` extra, so without this the .xls branch skipped even on CI -- # a skip is not a pass. Test-only: nothing in src imports xlwt. "xlwt>=1.3.0", ] [tool.pytest.ini_options] testpaths = ["tests"] asyncio_mode = "auto" [tool.ruff] target-version = "py310" [tool.ruff.lint] # ⚠⚠ EXPLICIT `select`. Ruff's DEFAULT rule set is not stable across versions, # and this repo has no `uv.lock` to pin ruff with, so `ignore`-only config means # the gate's strictness changes under you whenever ruff ships a release. # Measured 2026-08-07: config unchanged, ruff 0.16.2 resolved 446 findings # (YTT/ASYNC/S/BLE/B/UP/I) where the intended set gives 10. # # These four are pycodestyle E4/E7/E9 + pyflakes F: the high-signal correctness # rules (undefined names, unused imports, f-string bugs, duplicate keys, # redefinitions). Widening the set is a deliberate decision, not a ruff upgrade. select = ["E4", "E7", "E9", "F"] # Default rule set is pycodestyle E4/E7/E9 + pyflakes F. We keep the high-signal # correctness rules and grandfather the codes that reflect deliberate, pervasive # patterns here rather than defects. # # Added 2026-08-07 with v1.31.4 (and made to actually run in v1.31.5), # alongside jdocmunch-mcp. This repo was already # clean on F821 (undefined names); jdoc was not, and had shipped one. ignore = [ "E702", # multiple-statements-on-one-line-semicolon: 8 terse guards "F841", # local assigned but never used: 2 pre-existing dead locals, low risk ] [tool.ruff.lint.per-file-ignores] "__init__.py" = ["F401"]