[project] name = "breedsim-mcp" version = "0.4.2" description = "MCP server for breeding-scheme simulation — returns distributions, never a single stochastic run" readme = "README.md" # GPL, not MIT. AlphaSimR itself is MIT, but rpy2 is GPLv2+ and we import it # directly, so the distributed combination must be GPL-compatible. license = "GPL-3.0-or-later" requires-python = ">=3.11" authors = [{ name = "Jaret Arnold" }] keywords = [ "mcp", "model-context-protocol", "plant-breeding", "simulation", "alphasimr", "quantitative-genetics", "genomic-selection", ] classifiers = [ "Development Status :: 3 - Alpha", "Intended Audience :: Science/Research", "License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", "Programming Language :: Python :: 3.13", "Topic :: Scientific/Engineering :: Bio-Informatics", ] dependencies = [ # 2.x only. The old 1.28.1 floor was a SECURITY floor rather than a feature # one, and every 2.x release clears it. The range MOVES rather than widening # to <3: this package imports mcp.server.mcpserver, which does not exist in # 1.x, so a range spanning both majors could resolve to a version that cannot # import the server. mcp 2.x requires Python >=3.10, below our >=3.11 floor. "mcp>=2,<3", # rpy2 >=3.6 needs a newer R than 4.3. Upstream's own docs for 3.6.x state # **R >= 4.5** (rpy2.github.io/doc/latest/html/overview.html) -- this comment # previously said 4.4, which was wrong and understated the gap. # # The mechanism is real and observed, not inferred: dependabot proposed # `<3.6` -> `<3.7` (PR #25), and all three test jobs died in # `openrlib.rlib.R_getVar(...)` with "The embedded R is not initialized." # against R 4.3. # # Deliberately NOT claiming which R the distros ship: CRAN publishes 4.5 # packages for current Ubuntu, so "Debian/Ubuntu ship 4.3" (also previously # asserted here) depends on whether you use the distro archive or CRAN's. # What is verified is that R 4.3.x is still widely in use and is what this # package is developed against. "rpy2>=3.5,<3.6", "numpy>=1.26", # pydantic raises PydanticUserError on stdlib TypedDict under Python < 3.12, # which breaks outputSchema generation on 3.11 only. "typing-extensions>=4.12", ] [project.urls] Homepage = "https://github.com/musharna/breedsim-mcp" Repository = "https://github.com/musharna/breedsim-mcp" Issues = "https://github.com/musharna/breedsim-mcp/issues" Changelog = "https://github.com/musharna/breedsim-mcp/blob/master/CHANGELOG.md" [project.scripts] breedsim-mcp = "breedsim_mcp.server:main" [build-system] requires = ["hatchling"] build-backend = "hatchling.build" [tool.hatch.build.targets.wheel] packages = ["src/breedsim_mcp"] [tool.hatch.build.targets.sdist] # hatchling's `packages` covers the WHEEL ONLY. Without an explicit allow-list # the sdist packs .claude/ and docs/. Verify with `tar tzf`, not `git ls-files`. include = [ "src/**", "tests/**", "README.md", "CHANGELOG.md", "CONTRIBUTING.md", "SECURITY.md", "LICENSE", "CITATION.cff", "NOTICE", "pyproject.toml", ] exclude = [".claude", "docs", "dist"] [tool.uv] # Do NOT build against a conda interpreter. conda ships its own libstdc++.so.6, # which shadows the system one and is older than system libicuuc requires, so # rpy2's dlopen of libR.so dies with "GLIBCXX_3.4.30 not found". A uv-managed # CPython links against the system C++ runtime and works. python-preference = "only-managed" [tool.ruff] # ruff formats Python code blocks embedded in Markdown; docs/ holds the design # and plan, whose quoted snippets are a record and must not be rewritten. extend-exclude = ["docs"] [dependency-groups] # jsonschema validates server.json against the registry's own published schema # (vendored at tests/server.schema.json) so registry-side constraints fail here # rather than in the publish workflow, which only runs once the tag is already # cut -- which is exactly how v0.4.0 shipped before being refused with a 422. dev = ["pytest>=8.0", "ruff>=0.6", "jsonschema>=4.0"] [tool.mutmut] source_paths = ["src"]