Files
zeekay 5636caf58c feat: add REPL, IDE tools and ZAP protocol
- hanzo-tools-repl: Multi-language REPL with Jupyter kernel backend
  - Supports Python, Node.js/TypeScript, Bash, Ruby, Go, Rust
  - Persistent sessions for stateful evaluation
  - History and completion support

- hanzo-tools-ide: IDE integration for VS Code, Cursor, JetBrains
  - Full editor control (open, edit, navigate, refactor)
  - Terminal integration
  - Diagnostics and quick fixes
  - WebSocket bridge to IDE extensions

- ZAP Protocol (proto/zap/):
  - MCP superset for agentic operations
  - Streaming, REPL sessions, IDE integration
  - Browser DevTools support
  - Extension bridge specification

- hanzo-mcp v0.11.7:
  - Added [repl], [ide], [interactive] extras
2026-01-22 15:47:55 -08:00

245 lines
6.2 KiB
TOML

[build-system]
requires = ["setuptools>=61.0.0", "wheel"]
build-backend = "setuptools.build_meta"
[project]
name = "hanzo-mcp"
version = "0.11.7"
description = "The Zen of Hanzo MCP: One server to rule them all. The ultimate MCP that orchestrates all others."
readme = "README.md"
requires-python = ">=3.12"
license = { text = "MIT" }
authors = [{ name = "Hanzo Industries Inc", email = "[email protected]" }]
classifiers = [
"Programming Language :: Python :: 3",
"License :: OSI Approved :: MIT License",
"Operating System :: OS Independent",
]
keywords = ["mcp", "claude", "hanzo", "code", "agent"]
dependencies = [
# Core MCP dependencies
"mcp>=1.25.0",
"fastmcp>=2.14.4",
"pydantic>=2.12.5",
"pydantic-settings>=2.12.0",
"typing-extensions>=4.13.0",
# Unified async I/O (includes aiofiles + uvloop)
"hanzo-async>=0.1.0",
# Hanzo tool infrastructure (all tools)
"hanzo-tools>=0.3.0",
"hanzo-tools-fs>=0.1.0",
"hanzo-tools-shell>=0.6.1",
"hanzo-tools-browser>=0.2.1", # Extension-first routing
"hanzo-tools-memory>=0.1.0",
"hanzo-tools-todo>=0.1.0",
"hanzo-tools-reasoning>=0.1.0",
"hanzo-tools-lsp>=0.1.0",
"hanzo-tools-computer>=0.1.0",
"hanzo-tools-config>=0.1.0",
"hanzo-tools-refactor>=0.1.0",
"hanzo-tools-llm>=0.1.0",
"hanzo-tools-agent>=0.3.1",
"hanzo-tools-api>=0.3.1",
"hanzo-persona>=1.0.0",
"uvloop>=0.22.1",
]
# For local development, install hanzo-tools-* packages from pkg/
# pip install -e ../hanzo-tools ../hanzo-tools-fs etc.
# Or when published, add them back as dependencies
[project.urls]
"Homepage" = "https://github.com/hanzoai/mcp"
"Bug Tracker" = "https://github.com/hanzoai/mcp/issues"
"Documentation" = "https://mcp.hanzo.ai"
[project.optional-dependencies]
# NOTE: hanzo-tools-* packages are installed separately from pkg/
# Use: pip install -e ../hanzo-tools -e ../hanzo-tools-fs etc.
# When published to PyPI, these extras will work:
# filesystem = ["hanzo-tools-fs>=0.1.0"]
# shell = ["hanzo-tools-shell>=0.1.0"]
# etc.
# Memory tools with full backend support
memory = [
"hanzo-tools-memory[full]>=0.2.0",
"sqlite-vec>=0.1.0",
"fastembed>=0.4.0",
]
# Interactive REPL with multi-language Jupyter kernels
repl = [
"hanzo-tools-repl>=0.1.0",
"jupyter-client>=8.6.0",
"ipykernel>=6.29.0",
]
# IDE integration (VS Code, Cursor, JetBrains)
ide = [
"hanzo-tools-ide>=0.1.0",
"websockets>=12.0",
]
# Full interactive suite (REPL + IDE + Browser)
interactive = [
"hanzo-mcp[repl,ide]",
"hanzo-tools-browser>=0.2.1",
]
# Development
dev = [
"pytest>=7.0.0",
"pytest-cov>=4.1.0",
"ruff>=0.14.0",
"black>=23.3.0",
"mypy>=1.10.0",
"types-aiofiles>=23.2.0",
"types-psutil>=5.9.5",
"types-setuptools>=69.5.0",
]
docs = ["sphinx>=8.0.0", "sphinx-rtd-theme>=3.0.0", "myst-parser>=4.0.0", "sphinx-copybutton>=0.5.0"]
test = [
"pytest>=7.0.0",
"pytest-cov>=4.1.0",
"pytest-mock>=3.10.0",
"pytest-asyncio>=0.26.0",
]
performance = ["ujson>=5.7.0", "orjson>=3.9.0"] # uvloop now standard
publish = ["twine>=4.0.2", "build>=1.0.3"]
[project.scripts]
hanzo-mcp = "hanzo_mcp.cli:main"
hanzo-mcp-dev = "hanzo_mcp.dev_server:run_dev_server"
hanzo-plugin = "hanzo_mcp.cli_plugin:main"
hanzo-dev = "hanzo_mcp.dev_tools:main"
hanzo-unified = "hanzo_mcp.unified_backend:main"
[tool.setuptools.packages.find]
where = ["."]
include = ["hanzo_mcp*"]
[tool.setuptools.package-data]
hanzo_mcp = ["py.typed"]
[tool.basedpyright]
include = ["hanzo_mcp"]
[tool.pytest.ini_options]
# Configuration for pytest
addopts = "--no-header --no-summary"
asyncio_mode = "auto"
asyncio_default_fixture_loop_scope = "function"
# Note: --cov-fail-under=96.3 will be added after achieving target coverage
markers = [
"asyncio: mark test as using asyncio",
"requires_hanzo_agents: mark test as requiring hanzo-agents SDK",
"requires_memory_tools: mark test as requiring hanzo-memory package",
"slow: mark test as slow running",
"integration: mark test as integration test",
]
testpaths = ["tests"]
python_files = ["test_*.py", "*_test.py"]
python_classes = ["Test*"]
python_functions = ["test_*"]
[tool.pytest_asyncio]
mode = "auto"
default_loop_scope = "function"
[tool.mypy]
python_version = "3.12"
strict = true
warn_return_any = true
warn_unused_configs = true
disallow_untyped_defs = true
disallow_any_generics = true
check_untyped_defs = true
no_implicit_optional = true
warn_redundant_casts = true
warn_unused_ignores = true
warn_no_return = true
warn_unreachable = true
strict_equality = true
show_error_codes = true
show_column_numbers = true
pretty = true
# Per-module options
[[tool.mypy.overrides]]
module = [
"bashlex.*",
"grep_ast.*",
"libtmux.*",
"litellm.*",
"nbformat.*",
"ffind.*",
"fastmcp.*",
"mcp.*",
"hanzo_agents.*",
"hanzo_memory.*",
"personalities.*",
]
ignore_missing_imports = true
[tool.coverage.run]
source = ["hanzo_mcp"]
omit = [
"*/tests/*",
"*/__pycache__/*",
"*/site-packages/*",
"*/venv/*",
"*/migrations/*",
]
[tool.coverage.report]
precision = 2
show_missing = true
skip_covered = false
fail_under = 96.3
exclude_lines = [
"pragma: no cover",
"def __repr__",
"if self.debug:",
"if __name__ == .__main__.:",
"raise AssertionError",
"raise NotImplementedError",
"if TYPE_CHECKING:",
"@abstractmethod",
]
[tool.coverage.html]
directory = "htmlcov"
[tool.ruff]
exclude = [
".git",
".venv",
"venv",
"__pycache__",
"build",
"dist",
"*.egg-info",
"node_modules",
"vscode-extension",
]
[tool.ruff.lint]
select = ["E", "F", "I", "B"]
ignore = [
"E501", # Line too long
"B017", # Blind exception test
"B023", # Function definition loop variable
"B904", # Raise without from in except
"E741", # Ambiguous variable name
"E402", # Module level import not at top
"F401", # Unused imports (handled by tests themselves)
"F821", # Undefined name (tests may have conditional imports)
"F841", # Local variable assigned but never used
"B007", # Loop control variable not used
]
[tool.ruff.lint.per-file-ignores]
"tests/*" = ["F401", "F821", "F841", "B007"] # Relax rules for test files
"*/__init__.py" = ["F401"] # Allow unused imports in __init__.py