Files
Shanghua Gao 1f3ff54204 Release tooluniverse 1.5.0
Minor release: since 1.4.1, ToolUniverse added AlphaGenome Atlas
(precomputed variant-effect) support with 10 operations, ~48 new tool
families (DHS Program, EBI sequence tools, DeepSpotM, MolGlueDB, and many
more), corresponding updates across ~18 skills, and fixed two tool-registry
duplicate-name collisions (OpenMeteo_get_air_quality, UniProt_get_proteome).
All backward-compatible additions/fixes, so minor rather than patch.

Bump pyproject.toml, mcpb/pyproject.toml, mcpb/manifest.json, and the
tooluniverse entry in uv.lock together, per the packaging-dependencies test
(tests/unit/test_packaging_dependencies.py::test_release_versions_move_together).

uv.lock's tooluniverse version line was hand-patched (not `uv lock`) to avoid
bundling an unrelated, unreviewed dependency re-resolution (a plain `uv lock`
run pulled in a torch 2.8->2.14 major bump plus several new transitive
packages) into a release commit.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-16 17:33:58 -04:00

264 lines
9.4 KiB
TOML

[build-system]
requires = ["setuptools", "wheel"]
build-backend = "setuptools.build_meta"
[project]
name = "tooluniverse"
version = "1.5.0"
description = "A comprehensive collection of scientific tools for Agentic AI, offering integration with the ToolUniverse SDK and MCP Server to support advanced scientific workflows."
authors = [
{ name = "Shanghua Gao", email = "shanghuagao@gmail.com" }
]
dependencies = [
"requests>=2.32.0",
"boltz-api>=0.46.0,<0.47.0",
"numpy>=2.2.0",
"sympy>=1.12.0", # Symbolic mathematics for Python executor
"graphql-core>=3.2.0",
"fastapi>=0.116.0",
"uvicorn>=0.36.0",
"pydantic>=2.11.0",
"epam.indigo>=1.34.0",
"networkx>=3.4.0",
# openai / google-genai are NOT here on purpose: they are optional extras
# (`tooluniverse[openai]`, `tooluniverse[gemini]`), both covered by [all].
"pyyaml>=6.0.0",
"mcp[cli]>=1.29.0,<2.0.0",
"fastmcp>=3.4.5,<4.0.0",
"xmltodict>=1.0.0",
"lxml>=6.0.0",
"huggingface_hub>=0.34.0",
"jsonpath-ng>=1.6.0",
"rcsb-api>=1.4.0",
# Imported at module scope by mcp_client_tool.py for the websocket
# transport. It reached installs only as a transitive of fastmcp's
# `fastmcp-slim[server]` extra, so a reshuffle upstream would have broken
# the client with no local change. No upper bound on purpose: the
# google-genai cap is what pushes downstream resolvers onto stale
# tooluniverse releases (issue #526), and that stays inside its extra.
"websockets>=13.0",
# `from urllib3.util.retry import Retry` in uspto_tool.py and
# `urllib3.disable_warnings` in euhealth/euhealth_live.py. requests already
# requires urllib3>=1.26,<3, so this adds no new constraint; it just stops
# a direct import from depending on another package's dependency.
"urllib3>=1.26",
# Imported by dose_response, survival, nca, drug_synergy, metaboanalyst,
# timer and two remote tools. It was previously reaching installs only as a
# transitive of that `fitz` placeholder (which required nibabel, nipype,
# pyxnat, scipy and more), so removing it left these modules without their
# dependency. It stays listed in the graph/visualization extras as well.
"scipy>=1.7.0",
"pandas>=2.2.3",
"openpyxl>=3.1.0", # Read .xlsx bulk downloads (CellMarker, dataset tools)
"setuptools>=70.0.0", # Fix pkg_resources deprecation warnings
"pdfplumber>=0.11.0",
"playwright>=1.55.0",
"faiss-cpu==1.12.0",
"flask>=2.0.0",
"aiohttp",
"beautifulsoup4>=4.12.0",
"python-dotenv>=1.0.0",
# MarkItDown (~32 MB: SpeechRecognition, youtube-transcript-api, pydub,
# azure-ai-documentintelligence). The broad converter set is deliberate:
# unified_guideline_tools.py imports markitdown at module scope and
# convert_to_markdown takes an unconstrained URI with no format allowlist.
#
# These are MarkItDown's own converter extras listed one by one instead of
# its `all` extra, and that difference is load-bearing (issue #527):
# * `all` pins youtube-transcript-api~=1.0.0, and every 1.0.x release
# declares Requires-Python <3.14, which transitively capped the Python
# versions tooluniverse could be installed on. The `youtube-transcription`
# extra leaves that dependency unpinned, so 1.2.3+ (Requires-Python
# <3.15) resolves and the cap is gone.
# * Since markitdown 0.1.6 `all` also requires
# azure-ai-contentunderstanding>=1.2.0b1, which has no stable release on
# PyPI, so default resolvers silently backtrack `markitdown[all]` to
# 0.1.5. Naming the extras keeps installs on current MarkItDown.
# Add `az-content-understanding` back once that dependency ships a stable
# release; adding it today makes the whole requirement unresolvable.
"markitdown[audio-transcription,az-doc-intel,docx,outlook,pdf,pptx,xls,xlsx,youtube-transcription]>=0.1.0",
"psutil>=5.9.0",
"ddgs>=9.0.0",
"pip>=25.3",
"jsonschema>=4.23.0",
]
requires-python = ">=3.10"
readme = "README.md"
[project.optional-dependencies]
pdf = [
# PyMuPDF is AGPL-3.0 or commercially licensed. Keep it opt-in and out of
# the aggregate `all` extra so default Apache-2.0 installations do not pull
# it in implicitly.
"pymupdf>=1.24.3",
]
ocr = [
# Scanned-PDF text extraction for the USPTO downloader. EasyOCR pulls in
# PyTorch, a very large addition none of the other 600+ tools need, so keep
# it opt-in like `pdf` and out of the aggregate `all` extra.
"easyocr>=1.7",
"python-docx>=1.1",
]
# LLM provider SDKs. Both are imported lazily inside the client constructors in
# llm_clients.py (AzureOpenAIClient, OpenAICompatibleClient, OpenRouterClient,
# VLLMClient, GeminiClient) and in database_setup/embedder.py — never at module
# scope — so tooluniverse imports and runs fine without them, and a constructor
# reached without its extra raises a clear RuntimeError. Unlike `pdf` these ARE
# in the aggregate `all` extra, so `tooluniverse[all]` keeps today's behavior.
# They are separate extras rather than one combined group so that an
# OpenAI-only user is not subjected to google-genai's `websockets` upper bound,
# which is the constraint that can push a downstream universal resolver onto a
# much older tooluniverse instead of reporting a conflict (issue #526).
openai = [
"openai>=1.107.0",
]
gemini = [
"google-genai>=1.36.0",
]
client = [
"requests>=2.32.0",
"pydantic>=2.11.0",
]
smolagents = [
"smolagents>=1.22.0",
"gradio>=4.0.0", # Required for GradioUI web interface
]
# Single-cell and spatial transcriptomics tools
singlecell = [
"cellxgene-census>=1.10.0", # CELLxGENE Census API
"tiledbsoma>=1.15.3", # Required for spatial data
]
dev = [
"pytest>=7.0",
"pytest-cov>=4.0",
"pytest-timeout>=2.3.1",
"pytest-mock>=3.14.0",
"pytest-asyncio>=0.21.0",
"pre-commit>=2.0",
"pytest-xdist>=3.0",
"pytest-html>=3.0",
"requests-mock>=1.12.1",
"ruff>=0.14.5",
# tests/unit/test_gemini_client.py constructs a real google.genai Client, so
# the provider SDKs stay part of `[dev]` now that they left the base set.
# This keeps `pip install -e .[dev] && pytest` green, as CI runs exactly that.
"tooluniverse[openai,gemini]",
]
docs = [
"sphinx>=4.0",
"furo>=2024.8.6",
"pydata-sphinx-theme>=0.15.0",
"sphinx-rtd-theme>=1.0",
"shibuya>=0.10.0",
"myst-parser>=0.18",
"linkify-it-py>=2.0.0",
"sphinx-autobuild>=2021.3.14",
"sphinx-copybutton>=0.5.0",
"sphinx-tabs>=3.5.0",
"sphinx-design>=0.3.0",
"sphinx-notfound-page>=0.8",
"sphinx-autodoc-typehints>=1.12.0",
"sphinx-reredirects>=0.1.5",
]
embedding = [
"sentence-transformers>=5.1.0",
"faiss-cpu==1.12.0",
"huggingface_hub>=0.34.0",
]
ml = [
"admet-ai>=1.2.0",
"sentence-transformers>=5.1.0",
"faiss-cpu==1.12.0",
"huggingface_hub>=0.34.0",
]
graph = [
"flask>=2.0.0",
"matplotlib>=3.5.0",
"plotly>=5.0.0",
"scipy>=1.7.0",
"pydot>=1.4.0",
"pygraphviz>=1.7",
"jinja2>=3.0.0",
"werkzeug>=2.0.0",
]
visualization = [
"py3Dmol>=2.0.0",
"rdkit>=2023.9.1",
"plotly>=5.18.0",
"kaleido>=0.2.1",
"scipy>=1.7.0",
"matplotlib>=3.5.0",
"networkx>=3.4.0",
]
space = [
"huggingface_hub>=0.34.0",
"pyyaml>=6.0.0",
"requests>=2.32.0",
]
bioinformatics = [
"biopython>=1.80",
"freesasa>=2.2.0",
]
# circuit: install manually with `pip install git+https://github.com/tooluniverse/circuit.git`
all = [
"tooluniverse[dev,docs,graph,visualization,space,embedding,ml,bioinformatics,openai,gemini]",
]
build = [
"pyinstaller>=6.0.0",
]
[project.urls]
Homepage = "https://github.com/mims-harvard/ToolUniverse"
[project.scripts]
tu = "tooluniverse_cli_entry:main"
tooluniverse = "tooluniverse.smcp_server:run_default_stdio_server"
tooluniverse-mcp = "tooluniverse.smcp_server:run_http_server"
tooluniverse-smcp = "tooluniverse.smcp_server:run_smcp_server"
tooluniverse-smcp-server = "tooluniverse.smcp_server:run_http_server"
tooluniverse-smcp-stdio = "tooluniverse.smcp_server:run_stdio_server"
# HTTP API Server for ToolUniverse class methods
tooluniverse-http-api = "tooluniverse.http_api_server_cli:run_http_api_server"
generate-mcp-tools = "tooluniverse.generate_mcp_tools:run_generate"
# Human Expert Feedback System
tooluniverse-expert-feedback = "tooluniverse.remote.expert_feedback.human_expert_mcp_tools:main"
tooluniverse-expert-feedback-web = "tooluniverse.remote.expert_feedback.start_web_interface:main"
tu-datastore = "tooluniverse.database_setup.cli:main"
# Literature Search Web UIs (Under testing)
# tooluniverse-regular-search = "tooluniverse.web_tools.literature_search_ui.regular_search_app:main"
# tooluniverse-agent-search = "tooluniverse.web_tools.literature_search_ui.agent_search_app:main"
# tooluniverse-wide-research = "tooluniverse.web_tools.literature_search_ui.simple_app:main"
# Health Check Tool
tooluniverse-doctor = "tooluniverse.doctor:main"
[tool.setuptools]
py-modules = ["tooluniverse_cli_entry"]
[tool.setuptools.packages.find]
where = ["src"]
[tool.setuptools.package-data]
tooluniverse = ["data/*", "data/packages/*"]
[dependency-groups]
dev = [
"tooluniverse[dev,embedding]",
]
[tool.uv.sources]
tooluniverse = { workspace = true }
[tool.ruff]
line-length = 88
exclude = [
".venv",
"docs",
"examples",
"skills",
"temp_docs_and_tests",
]
unsafe-fixes = true
[tool.ruff.lint]
ignore = ["E203", "E402", "E501", "F401", "F541"]