hanzo-mcp 0.3.8__py3-none-any.whl → 0.5.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of hanzo-mcp might be problematic. Click here for more details.

Files changed (93) hide show
  1. hanzo_mcp/__init__.py +1 -1
  2. hanzo_mcp/cli.py +118 -170
  3. hanzo_mcp/cli_enhanced.py +438 -0
  4. hanzo_mcp/config/__init__.py +19 -0
  5. hanzo_mcp/config/settings.py +449 -0
  6. hanzo_mcp/config/tool_config.py +197 -0
  7. hanzo_mcp/prompts/__init__.py +117 -0
  8. hanzo_mcp/prompts/compact_conversation.py +77 -0
  9. hanzo_mcp/prompts/create_release.py +38 -0
  10. hanzo_mcp/prompts/project_system.py +120 -0
  11. hanzo_mcp/prompts/project_todo_reminder.py +111 -0
  12. hanzo_mcp/prompts/utils.py +286 -0
  13. hanzo_mcp/server.py +117 -99
  14. hanzo_mcp/tools/__init__.py +121 -33
  15. hanzo_mcp/tools/agent/__init__.py +8 -11
  16. hanzo_mcp/tools/agent/agent_tool.py +290 -224
  17. hanzo_mcp/tools/agent/prompt.py +16 -13
  18. hanzo_mcp/tools/agent/tool_adapter.py +9 -9
  19. hanzo_mcp/tools/common/__init__.py +17 -16
  20. hanzo_mcp/tools/common/base.py +79 -110
  21. hanzo_mcp/tools/common/batch_tool.py +330 -0
  22. hanzo_mcp/tools/common/config_tool.py +396 -0
  23. hanzo_mcp/tools/common/context.py +26 -292
  24. hanzo_mcp/tools/common/permissions.py +12 -12
  25. hanzo_mcp/tools/common/thinking_tool.py +153 -0
  26. hanzo_mcp/tools/common/validation.py +1 -63
  27. hanzo_mcp/tools/filesystem/__init__.py +97 -57
  28. hanzo_mcp/tools/filesystem/base.py +32 -24
  29. hanzo_mcp/tools/filesystem/content_replace.py +114 -107
  30. hanzo_mcp/tools/filesystem/directory_tree.py +129 -105
  31. hanzo_mcp/tools/filesystem/edit.py +279 -0
  32. hanzo_mcp/tools/filesystem/grep.py +458 -0
  33. hanzo_mcp/tools/filesystem/grep_ast_tool.py +250 -0
  34. hanzo_mcp/tools/filesystem/multi_edit.py +362 -0
  35. hanzo_mcp/tools/filesystem/read.py +255 -0
  36. hanzo_mcp/tools/filesystem/unified_search.py +689 -0
  37. hanzo_mcp/tools/filesystem/write.py +156 -0
  38. hanzo_mcp/tools/jupyter/__init__.py +41 -29
  39. hanzo_mcp/tools/jupyter/base.py +66 -57
  40. hanzo_mcp/tools/jupyter/{edit_notebook.py → notebook_edit.py} +162 -139
  41. hanzo_mcp/tools/jupyter/notebook_read.py +152 -0
  42. hanzo_mcp/tools/shell/__init__.py +29 -20
  43. hanzo_mcp/tools/shell/base.py +87 -45
  44. hanzo_mcp/tools/shell/bash_session.py +731 -0
  45. hanzo_mcp/tools/shell/bash_session_executor.py +295 -0
  46. hanzo_mcp/tools/shell/command_executor.py +435 -384
  47. hanzo_mcp/tools/shell/run_command.py +284 -131
  48. hanzo_mcp/tools/shell/run_command_windows.py +328 -0
  49. hanzo_mcp/tools/shell/session_manager.py +196 -0
  50. hanzo_mcp/tools/shell/session_storage.py +325 -0
  51. hanzo_mcp/tools/todo/__init__.py +66 -0
  52. hanzo_mcp/tools/todo/base.py +319 -0
  53. hanzo_mcp/tools/todo/todo_read.py +148 -0
  54. hanzo_mcp/tools/todo/todo_write.py +378 -0
  55. hanzo_mcp/tools/vector/__init__.py +99 -0
  56. hanzo_mcp/tools/vector/ast_analyzer.py +459 -0
  57. hanzo_mcp/tools/vector/git_ingester.py +482 -0
  58. hanzo_mcp/tools/vector/infinity_store.py +731 -0
  59. hanzo_mcp/tools/vector/mock_infinity.py +162 -0
  60. hanzo_mcp/tools/vector/project_manager.py +361 -0
  61. hanzo_mcp/tools/vector/vector_index.py +116 -0
  62. hanzo_mcp/tools/vector/vector_search.py +225 -0
  63. hanzo_mcp-0.5.1.dist-info/METADATA +276 -0
  64. hanzo_mcp-0.5.1.dist-info/RECORD +68 -0
  65. {hanzo_mcp-0.3.8.dist-info → hanzo_mcp-0.5.1.dist-info}/WHEEL +1 -1
  66. hanzo_mcp/tools/agent/base_provider.py +0 -73
  67. hanzo_mcp/tools/agent/litellm_provider.py +0 -45
  68. hanzo_mcp/tools/agent/lmstudio_agent.py +0 -385
  69. hanzo_mcp/tools/agent/lmstudio_provider.py +0 -219
  70. hanzo_mcp/tools/agent/provider_registry.py +0 -120
  71. hanzo_mcp/tools/common/error_handling.py +0 -86
  72. hanzo_mcp/tools/common/logging_config.py +0 -115
  73. hanzo_mcp/tools/common/session.py +0 -91
  74. hanzo_mcp/tools/common/think_tool.py +0 -123
  75. hanzo_mcp/tools/common/version_tool.py +0 -120
  76. hanzo_mcp/tools/filesystem/edit_file.py +0 -287
  77. hanzo_mcp/tools/filesystem/get_file_info.py +0 -170
  78. hanzo_mcp/tools/filesystem/read_files.py +0 -199
  79. hanzo_mcp/tools/filesystem/search_content.py +0 -275
  80. hanzo_mcp/tools/filesystem/write_file.py +0 -162
  81. hanzo_mcp/tools/jupyter/notebook_operations.py +0 -514
  82. hanzo_mcp/tools/jupyter/read_notebook.py +0 -165
  83. hanzo_mcp/tools/project/__init__.py +0 -64
  84. hanzo_mcp/tools/project/analysis.py +0 -886
  85. hanzo_mcp/tools/project/base.py +0 -66
  86. hanzo_mcp/tools/project/project_analyze.py +0 -173
  87. hanzo_mcp/tools/shell/run_script.py +0 -215
  88. hanzo_mcp/tools/shell/script_tool.py +0 -244
  89. hanzo_mcp-0.3.8.dist-info/METADATA +0 -196
  90. hanzo_mcp-0.3.8.dist-info/RECORD +0 -53
  91. {hanzo_mcp-0.3.8.dist-info → hanzo_mcp-0.5.1.dist-info}/entry_points.txt +0 -0
  92. {hanzo_mcp-0.3.8.dist-info → hanzo_mcp-0.5.1.dist-info}/licenses/LICENSE +0 -0
  93. {hanzo_mcp-0.3.8.dist-info → hanzo_mcp-0.5.1.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,225 @@
1
+ """Vector search tool for semantic document retrieval."""
2
+
3
+ from typing import Dict, List, Optional, TypedDict, Unpack, final
4
+ import json
5
+ import asyncio
6
+
7
+ from fastmcp import Context as MCPContext
8
+ from pydantic import Field
9
+
10
+ from hanzo_mcp.tools.common.base import BaseTool
11
+ from hanzo_mcp.tools.common.permissions import PermissionManager
12
+
13
+ from .infinity_store import InfinityVectorStore
14
+ from .project_manager import ProjectVectorManager
15
+
16
+
17
+ class VectorSearchParams(TypedDict, total=False):
18
+ """Parameters for vector search operations."""
19
+
20
+ query: str
21
+ limit: Optional[int]
22
+ score_threshold: Optional[float]
23
+ include_content: Optional[bool]
24
+ file_filter: Optional[str]
25
+ project_filter: Optional[List[str]]
26
+ search_scope: Optional[str] # "all", "global", "current", or specific project name
27
+
28
+
29
+ @final
30
+ class VectorSearchTool(BaseTool):
31
+ """Tool for semantic search in the vector database."""
32
+
33
+ def __init__(self, permission_manager: PermissionManager, project_manager: ProjectVectorManager):
34
+ """Initialize the vector search tool.
35
+
36
+ Args:
37
+ permission_manager: Permission manager for access control
38
+ project_manager: Project-aware vector store manager
39
+ """
40
+ self.permission_manager = permission_manager
41
+ self.project_manager = project_manager
42
+
43
+ @property
44
+ def name(self) -> str:
45
+ """Get the tool name."""
46
+ return "vector_search"
47
+
48
+ @property
49
+ def description(self) -> str:
50
+ """Get the tool description."""
51
+ return """Search for documents using semantic similarity across project-aware vector databases.
52
+
53
+ Performs intelligent text search that understands meaning and context, not just keywords.
54
+ Can search across all projects, specific projects, or just the global database. Projects are
55
+ automatically detected based on LLM.md files.
56
+
57
+ Returns ranked results with similarity scores, project context, and document metadata."""
58
+
59
+ async def call(
60
+ self,
61
+ ctx: MCPContext,
62
+ **params: Unpack[VectorSearchParams],
63
+ ) -> str:
64
+ """Search for similar documents in the vector database.
65
+
66
+ Args:
67
+ ctx: MCP context
68
+ **params: Tool parameters
69
+
70
+ Returns:
71
+ Search results formatted as text
72
+ """
73
+ query = params.get("query")
74
+ if not query:
75
+ return "Error: query parameter is required"
76
+
77
+ limit = params.get("limit", 10)
78
+ score_threshold = params.get("score_threshold", 0.0)
79
+ include_content = params.get("include_content", True)
80
+ file_filter = params.get("file_filter")
81
+ project_filter = params.get("project_filter")
82
+ search_scope = params.get("search_scope", "all")
83
+
84
+ try:
85
+ # Determine search strategy based on scope
86
+ if search_scope == "all":
87
+ # Search across all projects
88
+ project_results = await self.project_manager.search_all_projects(
89
+ query=query,
90
+ limit_per_project=limit,
91
+ score_threshold=score_threshold,
92
+ include_global=True,
93
+ project_filter=project_filter,
94
+ )
95
+
96
+ # Combine and sort all results
97
+ all_results = []
98
+ for project_name, results in project_results.items():
99
+ for result in results:
100
+ # Add project info to metadata
101
+ result.document.metadata = result.document.metadata or {}
102
+ result.document.metadata["search_project"] = project_name
103
+ all_results.append(result)
104
+
105
+ # Sort by score and limit
106
+ all_results.sort(key=lambda x: x.score, reverse=True)
107
+ results = all_results[:limit]
108
+
109
+ elif search_scope == "global":
110
+ # Search only global store
111
+ global_store = self.project_manager._get_global_store()
112
+ results = global_store.search(
113
+ query=query,
114
+ limit=limit,
115
+ score_threshold=score_threshold,
116
+ )
117
+ for result in results:
118
+ result.document.metadata = result.document.metadata or {}
119
+ result.document.metadata["search_project"] = "global"
120
+
121
+ else:
122
+ # Search specific project or current context
123
+ if search_scope != "current":
124
+ # Search specific project by name
125
+ project_info = None
126
+ for proj_key, proj_info in self.project_manager.projects.items():
127
+ if proj_info.name == search_scope:
128
+ project_info = proj_info
129
+ break
130
+
131
+ if project_info:
132
+ vector_store = self.project_manager.get_vector_store(project_info)
133
+ results = vector_store.search(
134
+ query=query,
135
+ limit=limit,
136
+ score_threshold=score_threshold,
137
+ )
138
+ for result in results:
139
+ result.document.metadata = result.document.metadata or {}
140
+ result.document.metadata["search_project"] = project_info.name
141
+ else:
142
+ return f"Project '{search_scope}' not found"
143
+ else:
144
+ # For "current", try to detect from working directory
145
+ import os
146
+ current_dir = os.getcwd()
147
+ project_info = self.project_manager.get_project_for_path(current_dir)
148
+
149
+ if project_info:
150
+ vector_store = self.project_manager.get_vector_store(project_info)
151
+ results = vector_store.search(
152
+ query=query,
153
+ limit=limit,
154
+ score_threshold=score_threshold,
155
+ )
156
+ for result in results:
157
+ result.document.metadata = result.document.metadata or {}
158
+ result.document.metadata["search_project"] = project_info.name
159
+ else:
160
+ # Fall back to global store
161
+ global_store = self.project_manager._get_global_store()
162
+ results = global_store.search(
163
+ query=query,
164
+ limit=limit,
165
+ score_threshold=score_threshold,
166
+ )
167
+ for result in results:
168
+ result.document.metadata = result.document.metadata or {}
169
+ result.document.metadata["search_project"] = "global"
170
+
171
+ if not results:
172
+ return f"No results found for query: '{query}'"
173
+
174
+ # Filter by file if requested
175
+ if file_filter:
176
+ results = [r for r in results if file_filter in (r.document.file_path or "")]
177
+
178
+ # Format results
179
+ output_lines = [f"Found {len(results)} results for query: '{query}'\n"]
180
+
181
+ for i, result in enumerate(results, 1):
182
+ doc = result.document
183
+ score_percent = result.score * 100
184
+
185
+ # Header with score and metadata
186
+ project_name = doc.metadata.get("search_project", "unknown")
187
+ header = f"Result {i} (Score: {score_percent:.1f}%) - Project: {project_name}"
188
+ if doc.file_path:
189
+ header += f" - {doc.file_path}"
190
+ if doc.chunk_index is not None:
191
+ header += f" [Chunk {doc.chunk_index}]"
192
+
193
+ output_lines.append(header)
194
+ output_lines.append("-" * len(header))
195
+
196
+ # Add metadata if available
197
+ if doc.metadata:
198
+ relevant_metadata = {k: v for k, v in doc.metadata.items()
199
+ if k not in ['chunk_number', 'total_chunks', 'search_project']}
200
+ if relevant_metadata:
201
+ output_lines.append(f"Metadata: {json.dumps(relevant_metadata, indent=2)}")
202
+
203
+ # Add content if requested
204
+ if include_content:
205
+ content = doc.content
206
+ if len(content) > 500:
207
+ content = content[:500] + "..."
208
+ output_lines.append(f"Content:\n{content}")
209
+
210
+ output_lines.append("") # Empty line between results
211
+
212
+ return "\n".join(output_lines)
213
+
214
+ except Exception as e:
215
+ return f"Error searching vector database: {str(e)}"
216
+
217
+ def register(self, mcp_server) -> None:
218
+ """Register this tool with the MCP server.
219
+
220
+ Args:
221
+ mcp_server: The FastMCP server instance
222
+ """
223
+ # This is a placeholder - the actual registration would happen
224
+ # through the MCP server's tool registration mechanism
225
+ pass
@@ -0,0 +1,276 @@
1
+ Metadata-Version: 2.4
2
+ Name: hanzo-mcp
3
+ Version: 0.5.1
4
+ Summary: MCP implementation of Hanzo capabilities
5
+ Author-email: Hanzo Industries Inc <dev@hanzo.ai>
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/hanzoai/mcp
8
+ Project-URL: Bug Tracker, https://github.com/hanzoai/mcp/issues
9
+ Project-URL: Documentation, https://github.com/hanzoai/mcp/tree/main/docs
10
+ Keywords: mcp,claude,hanzo,code,agent
11
+ Classifier: Programming Language :: Python :: 3
12
+ Classifier: License :: OSI Approved :: MIT License
13
+ Classifier: Operating System :: OS Independent
14
+ Requires-Python: >=3.12
15
+ Description-Content-Type: text/markdown
16
+ License-File: LICENSE
17
+ Requires-Dist: mcp>=1.6.0
18
+ Requires-Dist: httpx>=0.27.0
19
+ Requires-Dist: uvicorn>=0.23.1
20
+ Requires-Dist: openai>=1.50.0
21
+ Requires-Dist: python-dotenv>=1.0.0
22
+ Requires-Dist: litellm>=1.40.14
23
+ Requires-Dist: grep-ast>=0.8.1
24
+ Provides-Extra: dev
25
+ Requires-Dist: pytest>=7.0.0; extra == "dev"
26
+ Requires-Dist: pytest-cov>=4.1.0; extra == "dev"
27
+ Requires-Dist: ruff>=0.1.0; extra == "dev"
28
+ Requires-Dist: black>=23.3.0; extra == "dev"
29
+ Requires-Dist: sphinx>=8.0.0; extra == "dev"
30
+ Requires-Dist: sphinx-rtd-theme>=1.3.0; extra == "dev"
31
+ Requires-Dist: myst-parser>=2.0.0; extra == "dev"
32
+ Provides-Extra: test
33
+ Requires-Dist: pytest>=7.0.0; extra == "test"
34
+ Requires-Dist: pytest-cov>=4.1.0; extra == "test"
35
+ Requires-Dist: pytest-mock>=3.10.0; extra == "test"
36
+ Requires-Dist: pytest-asyncio>=0.25.3; extra == "test"
37
+ Requires-Dist: twisted; extra == "test"
38
+ Provides-Extra: performance
39
+ Requires-Dist: ujson>=5.7.0; extra == "performance"
40
+ Requires-Dist: orjson>=3.9.0; extra == "performance"
41
+ Provides-Extra: publish
42
+ Requires-Dist: twine>=4.0.2; extra == "publish"
43
+ Requires-Dist: build>=1.0.3; extra == "publish"
44
+ Dynamic: license-file
45
+
46
+ # Hanzo MCP
47
+
48
+ [![Open in Hanzo.App](https://img.shields.io/badge/Open%20in-Hanzo.App-8A2BE2?style=for-the-badge&logo=rocket)](https://hanzo.app/launch?repo=https://github.com/hanzoai/mcp)
49
+ [![Add Feature with Hanzo Dev](https://img.shields.io/badge/Add%20Feature-Hanzo%20Dev-00D4AA?style=for-the-badge&logo=plus)](https://hanzo.app/dev?repo=https://github.com/hanzoai/mcp&action=feature)
50
+ [![Fix Bugs with Hanzo Dev](https://img.shields.io/badge/Fix%20Bugs-Hanzo%20Dev-FF6B6B?style=for-the-badge&logo=wrench)](https://hanzo.app/dev?repo=https://github.com/hanzoai/mcp&action=bugfix)
51
+
52
+ An implementation of Hanzo capabilities using the Model Context Protocol (MCP).
53
+
54
+ ## Overview
55
+
56
+ This project provides an MCP server that implements Hanzo-like functionality, allowing Claude to directly execute instructions for modifying and improving project files. By leveraging the Model Context Protocol, this implementation enables seamless integration with various MCP clients including Claude Desktop.
57
+
58
+ ![example](./docs/example.gif)
59
+
60
+ ## Features
61
+
62
+ - **Code Understanding**: Analyze and understand codebases through file access and pattern searching
63
+ - **Code Modification**: Make targeted edits to files with proper permission handling
64
+ - **Enhanced Command Execution**: Run commands and scripts in various languages with improved error handling and shell support
65
+ - **File Operations**: Manage files with proper security controls through shell commands
66
+ - **Code Discovery**: Find relevant files and code patterns across your project
67
+ - **Project Analysis**: Understand project structure, dependencies, and frameworks
68
+ - **Agent Delegation**: Delegate complex tasks to specialized sub-agents that can work concurrently
69
+ - **Multiple LLM Provider Support**: Configure any LiteLLM-compatible model for agent operations
70
+ - **Jupyter Notebook Support**: Read and edit Jupyter notebooks with full cell and output handling
71
+
72
+ ## Tools Implemented
73
+
74
+ ### Core File Operations
75
+ | Tool | Description |
76
+ | ----------------- | ----------------------------------------------------------------------------------- |
77
+ | `read` | Read one or multiple files with encoding detection and line range support |
78
+ | `write` | Create or overwrite files with content |
79
+ | `edit` | Make precise line-based edits to existing files |
80
+ | `multi_edit` | Make multiple edits to a single file in one atomic operation |
81
+ | `directory_tree` | Get a recursive tree view of directories with customizable depth and filters |
82
+ | `content_replace` | Replace patterns in file contents using regex |
83
+
84
+ ### Search & Analysis
85
+ | Tool | Description |
86
+ | ----------------- | ----------------------------------------------------------------------------------- |
87
+ | `grep` | Fast pattern search across files using ripgrep |
88
+ | `grep_ast` | AST-aware code search that understands code structure |
89
+ | `unified_search` | Intelligent multi-modal search combining text, vector, AST, and symbol search |
90
+ | `vector_search` | Semantic search across indexed documents and code |
91
+ | `vector_index` | Index documents and code in project-aware vector databases |
92
+
93
+ ### Shell & Commands
94
+ | Tool | Description |
95
+ | ----------------- | ----------------------------------------------------------------------------------- |
96
+ | `run_command` | Execute shell commands with timeout, environment control, and session support |
97
+
98
+ ### Jupyter Support
99
+ | Tool | Description |
100
+ | ----------------- | ----------------------------------------------------------------------------------- |
101
+ | `notebook_read` | Read Jupyter notebook cells with outputs and metadata |
102
+ | `notebook_edit` | Edit, insert, or delete cells in Jupyter notebooks |
103
+
104
+ ### Task Management
105
+ | Tool | Description |
106
+ | ----------------- | ----------------------------------------------------------------------------------- |
107
+ | `todo_read` | Read the current task list for tracking progress |
108
+ | `todo_write` | Create and manage structured task lists with status and priority |
109
+
110
+ ### Advanced Tools
111
+ | Tool | Description |
112
+ | ----------------- | ----------------------------------------------------------------------------------- |
113
+ | `think` | Structured space for complex reasoning and analysis without making changes |
114
+ | `dispatch_agent` | Launch specialized sub-agents for concurrent task execution |
115
+ | `batch` | Execute multiple tool calls in a single operation for performance |
116
+
117
+ For detailed documentation on all tools, see [TOOLS_DOCUMENTATION.md](./TOOLS_DOCUMENTATION.md).
118
+
119
+ ## Getting Started
120
+
121
+ ### 🚀 Try it Instantly in Hanzo.App
122
+
123
+ **No setup required!** Launch this project instantly in your browser:
124
+
125
+ [![Open in Hanzo.App](https://img.shields.io/badge/Launch%20Now-Hanzo.App-8A2BE2?style=for-the-badge&logo=rocket&logoColor=white)](https://hanzo.app/launch?repo=https://github.com/hanzoai/mcp)
126
+
127
+ ### Quick Install
128
+
129
+ ```bash
130
+ # Install using uv
131
+ uv pip install hanzo-mcp
132
+
133
+ # Or using pip
134
+ pip install hanzo-mcp
135
+ ```
136
+
137
+ ### Claude Desktop Integration
138
+
139
+ To install and configure hanzo-mcp for use with Claude Desktop:
140
+
141
+ ```bash
142
+ # Install the package globally
143
+ uv pip install hanzo-mcp
144
+
145
+ # Install configuration to Claude Desktop with default settings
146
+ hanzo-mcp --install
147
+ ```
148
+
149
+ For development, if you want to install your local version to Claude Desktop:
150
+
151
+ ```bash
152
+ # Clone and navigate to the repository
153
+ git clone https://github.com/hanzoai/mcp.git
154
+ cd mcp
155
+
156
+ # Install and configure for Claude Desktop
157
+ make install-desktop
158
+
159
+ # With custom paths and server name
160
+ make install-desktop ALLOWED_PATHS="/path/to/projects,/another/path" SERVER_NAME="hanzo"
161
+
162
+ # Disable write tools (useful if you prefer using your IDE for edits)
163
+ make install-desktop DISABLE_WRITE=1
164
+ ```
165
+
166
+ After installation, restart Claude Desktop. You'll see "hanzo" (or your custom server name) available in the MCP server dropdown.
167
+
168
+ For detailed installation and configuration instructions, please refer to the [documentation](./docs/).
169
+
170
+ Of course, you can also read [USEFUL_PROMPTS](./docs/USEFUL_PROMPTS.md) for some inspiration on how to use hanzo-mcp.
171
+
172
+ ## Security
173
+
174
+ This implementation follows best practices for securing access to your filesystem:
175
+
176
+ - Permission prompts for file modifications and command execution
177
+ - Restricted access to specified directories only
178
+ - Input validation and sanitization
179
+ - Proper error handling and reporting
180
+
181
+ ## Documentation
182
+
183
+ Comprehensive documentation is available in the [docs](./docs/) directory. You can build and view the documentation locally:
184
+
185
+ ```bash
186
+ # Build the documentation
187
+ make docs
188
+
189
+ # Start a local server to view the documentation
190
+ make docs-serve
191
+ ```
192
+
193
+ Then open http://localhost:8000/ in your browser to view the documentation.
194
+
195
+ ## Development
196
+
197
+ ### Setup Development Environment
198
+
199
+ ```bash
200
+ # Clone the repository
201
+ git clone https://github.com/hanzoai/mcp.git
202
+ cd mcp
203
+
204
+ # Install Python 3.13 using uv
205
+ make install-python
206
+
207
+ # Setup virtual environment and install dependencies
208
+ make setup
209
+
210
+ # Or install with development dependencies
211
+ make install-dev
212
+ ```
213
+
214
+ ### Testing
215
+
216
+ ```bash
217
+ # Run tests
218
+ make test
219
+
220
+ # Run tests with coverage
221
+ make test-cov
222
+ ```
223
+
224
+ ### Building and Publishing
225
+
226
+ ```bash
227
+ # Build package
228
+ make build
229
+
230
+ # Version bumping
231
+ make bump-patch # Increment patch version (0.1.x → 0.1.x+1)
232
+ make bump-minor # Increment minor version (0.x.0 → 0.x+1.0)
233
+ make bump-major # Increment major version (x.0.0 → x+1.0.0)
234
+
235
+ # Manual version bumping (alternative to make commands)
236
+ python -m scripts.bump_version patch # Increment patch version
237
+ python -m scripts.bump_version minor # Increment minor version
238
+ python -m scripts.bump_version major # Increment major version
239
+
240
+ # Publishing (creates git tag and pushes it to GitHub)
241
+ make publish # Publish using configured credentials in .pypirc
242
+ PYPI_TOKEN=your_token make publish # Publish with token from environment variable
243
+
244
+ # Publishing (creates git tag, pushes to GitHub, and publishes to PyPI)
245
+ make patch # Bump patch version, build, publish, create git tag, and push
246
+ make minor # Bump minor version, build, publish, create git tag, and push
247
+ make major # Bump major version, build, publish, create git tag, and push
248
+
249
+ # Publish to Test PyPI
250
+ make publish-test
251
+ ```
252
+
253
+ ### Contributing
254
+
255
+ **New contributors welcome!** 🎉 We've made it easy to contribute:
256
+
257
+ [![Contribute with Hanzo Dev](https://img.shields.io/badge/Contribute%20with-Hanzo%20Dev-00D4AA?style=for-the-badge&logo=code)](https://hanzo.app/dev?repo=https://github.com/hanzoai/mcp&action=contribute)
258
+
259
+ **Traditional approach:**
260
+
261
+ 1. Fork the repository
262
+ 2. Create a feature branch (`git checkout -b feature/amazing-feature`)
263
+ 3. Commit your changes (`git commit -m 'Add some amazing feature'`)
264
+ 4. Push to the branch (`git push origin feature/amazing-feature`)
265
+ 5. Open a Pull Request
266
+
267
+ **Or use Hanzo Dev for AI-assisted contributions:**
268
+ - [Launch in Hanzo.App](https://hanzo.app/launch?repo=https://github.com/hanzoai/mcp) for instant setup
269
+ - [Add new features](https://hanzo.app/dev?repo=https://github.com/hanzoai/mcp&action=feature) with AI assistance
270
+ - [Fix bugs automatically](https://hanzo.app/dev?repo=https://github.com/hanzoai/mcp&action=bugfix)
271
+
272
+ See [CONTRIBUTING.md](./CONTRIBUTING.md) for detailed guidelines.
273
+
274
+ ## License
275
+
276
+ This project is licensed under the MIT License - see the LICENSE file for details.
@@ -0,0 +1,68 @@
1
+ hanzo_mcp/__init__.py,sha256=0KU0gpacbuUqTpVgroypALQ6fncKjBbdh_l7rr_LYUI,89
2
+ hanzo_mcp/cli.py,sha256=fX8HtsD44elZhYre7Dn6RmH5lUt2AFRWz6ehGeoCkUY,9784
3
+ hanzo_mcp/cli_enhanced.py,sha256=rqh9gqyjMuUznIlPTC5pcIGYZTKAScacMsDb1e68ReE,15819
4
+ hanzo_mcp/server.py,sha256=mYiIcsAtQO2c_MGExYbzk5tj2U-MjcDWfTU5T22KuwQ,8107
5
+ hanzo_mcp/config/__init__.py,sha256=iZYGSJMsC1c97gRFqgyowfP4XW480BBVRAQq1r-Dp7g,506
6
+ hanzo_mcp/config/settings.py,sha256=F4ya4pHoxGACawPo4hd0bwfk6MwXvrTjH0WMBQpUN8I,16259
7
+ hanzo_mcp/config/tool_config.py,sha256=AT5eJRZAL8VTLu5DCdoC_MkDxtufVE_QOj7Yp_Fyi8k,6317
8
+ hanzo_mcp/prompts/__init__.py,sha256=L3eolRTyTohIp5JA0xv50TSFU4YSf_ycEEaODta7Ve0,3989
9
+ hanzo_mcp/prompts/compact_conversation.py,sha256=nvD068KEesiMcevxxMBeIJh6AqT7YHOqyH6RepRFFfA,4206
10
+ hanzo_mcp/prompts/create_release.py,sha256=1Z8xSTtz5vAm0rWFnERpFu7wIYExT4iXhM6nGmQaM-s,1374
11
+ hanzo_mcp/prompts/project_system.py,sha256=fQhOM6AGb6VIZQE_fSPDeS9slBGVkz_f_UbNNhxPRdw,7031
12
+ hanzo_mcp/prompts/project_todo_reminder.py,sha256=otiBdmzxssBSb3MZZSQsjYDGLBqi1bM0HgraELP_Nf4,3645
13
+ hanzo_mcp/prompts/utils.py,sha256=IwxIhzZfYJ2anToPulbrpcc07u4Dozo9ok6VE3BC_4A,9963
14
+ hanzo_mcp/tools/__init__.py,sha256=HqslpYbLiD1PjW8W2jy1Sc7D_U-R_Qjhr4_jitUjU70,7707
15
+ hanzo_mcp/tools/agent/__init__.py,sha256=MZ-LMIYptodQn1JpAEyNMbqRlioS4R8scgzNgsU189E,1897
16
+ hanzo_mcp/tools/agent/agent_tool.py,sha256=w-Oy2wPPTz79SCzmi7NsI8RU4eLbFKMTXDi-sFKrrbo,21268
17
+ hanzo_mcp/tools/agent/prompt.py,sha256=Wi9Z45hmQ92eUNZbOWzj9ZVCCr-fM1K9iyaRvTCAgrQ,4529
18
+ hanzo_mcp/tools/agent/tool_adapter.py,sha256=Od7VtD9qqDbgxhDHj0L-rohX4wOSMtYjZnU2BRuWSqI,2151
19
+ hanzo_mcp/tools/common/__init__.py,sha256=6LOEE9anSTsiPofgGNcD8CVHdU4SiaHjoQcRzNT2xos,921
20
+ hanzo_mcp/tools/common/base.py,sha256=HB7glx3O9eq2B8nHQu1FbRjtlQZM77CKB1lwMGb-CuE,5631
21
+ hanzo_mcp/tools/common/batch_tool.py,sha256=-FaZtH1cqd3xSHUrMaIvB664WEK0rKtTvzpUeEl0DhY,12073
22
+ hanzo_mcp/tools/common/config_tool.py,sha256=Tmjf4e6z_EfuOjS5acUQnzGo43GZxSqJC329FmQ5QFE,16241
23
+ hanzo_mcp/tools/common/context.py,sha256=XrgzJwPQP8ooKoReveezVgRyOSJe-zfD5-knhusBgbg,5175
24
+ hanzo_mcp/tools/common/permissions.py,sha256=LR1tuQAPMoaKvqNtHPRaiB0ZUb0Tbsg3e9L6vvd4FLU,7562
25
+ hanzo_mcp/tools/common/thinking_tool.py,sha256=pEBSymlJZJIS2X0pc-2VX2dUAPi4ho2un-wa69yYTD8,5142
26
+ hanzo_mcp/tools/common/validation.py,sha256=VV3VbDvYlAYl2Bi98xE7gFo0xnmqHHUGJGNPswm97qo,1694
27
+ hanzo_mcp/tools/filesystem/__init__.py,sha256=mFgBEZFGxdZNOdVjp5Mnt1Ro-dEmluPrT2-N3c6pP5w,5034
28
+ hanzo_mcp/tools/filesystem/base.py,sha256=qwxer1jHgPIfyaUeC4QLzR9pjGWJCLP2L3qggUAulFY,3807
29
+ hanzo_mcp/tools/filesystem/content_replace.py,sha256=hCiw9oQXS2_b6CjgC7XHOrRo5NH6H8zOFaSDS6Uwfgw,10015
30
+ hanzo_mcp/tools/filesystem/directory_tree.py,sha256=LZTJRmrDdSFpq9EpcTmVytimCp_glpCVKDxf7UCyq20,10755
31
+ hanzo_mcp/tools/filesystem/edit.py,sha256=PIlFsMjBG9WQw9IWC6dzLZly6UIBUcAUrohRkqyKFZY,10699
32
+ hanzo_mcp/tools/filesystem/grep.py,sha256=-JKrBUk04tmObvwPh8UvBpLOc27NNndNt6eR5qSkCLs,16818
33
+ hanzo_mcp/tools/filesystem/grep_ast_tool.py,sha256=F-HacdAISZI_jDGJrxIcZ-dyj3OG919JUVimpvgAZNA,8142
34
+ hanzo_mcp/tools/filesystem/multi_edit.py,sha256=j8ytsFVsdQqJ9AWCJMQa8kWHyH4UpbBdHRIc7XepEJc,14313
35
+ hanzo_mcp/tools/filesystem/read.py,sha256=uF1KdIAsKL8-oQiwOfL9-dkTzKOqQK0nKLVe6hW-5KE,8892
36
+ hanzo_mcp/tools/filesystem/unified_search.py,sha256=zSarczfFoImqtddJnfnv-OuhENN8hPKdgptxiopmqf8,29483
37
+ hanzo_mcp/tools/filesystem/write.py,sha256=dkbZ61kYGRTzKPVtMG8ETYw8YHyo6YXb1cLI70ePYcQ,4833
38
+ hanzo_mcp/tools/jupyter/__init__.py,sha256=IJnkx6vwxP2ZJOGvUxG25fhstlny-uFnNBLjGlUt5hs,2515
39
+ hanzo_mcp/tools/jupyter/base.py,sha256=oxTz_exSsYni2cQJvL4gHZtC4EG5EU_1-nWyEdc-ZQ8,10090
40
+ hanzo_mcp/tools/jupyter/notebook_edit.py,sha256=wKEEQJ36pfgB0JHQi2nV_X7ApXqy6HXZY9XO4lZ9Efg,11848
41
+ hanzo_mcp/tools/jupyter/notebook_read.py,sha256=t2fkP5wAp8SBBaWHrty-uWsnn6l5WO2zIqISVSHnQus,5293
42
+ hanzo_mcp/tools/shell/__init__.py,sha256=CcVnsAqSd8FLtVpkuHQK4cbKHWrac6o9enEIqNlxz4k,1951
43
+ hanzo_mcp/tools/shell/base.py,sha256=twbz3EuX64cwvNlcHraZ5CcEhDpUvMI5mLTZvMADtbQ,5821
44
+ hanzo_mcp/tools/shell/bash_session.py,sha256=YPtdtC0pc6Q04RJqKUy0u0RPTbiT2IGtsvFqejK5Hu4,27271
45
+ hanzo_mcp/tools/shell/bash_session_executor.py,sha256=zRnrzj4sdQOxO22XXBENT6k2dXt3LDk5fxjWjUYyU_Q,10723
46
+ hanzo_mcp/tools/shell/command_executor.py,sha256=IuoRY48PMmpKHL5CFIExebjoiRRS5ZEl73UDzYTR3kU,36406
47
+ hanzo_mcp/tools/shell/run_command.py,sha256=Io6LyLm8XWZKZ-Zjhx3L-H5vmdNGoqbkU9jJzwL7zLs,16137
48
+ hanzo_mcp/tools/shell/run_command_windows.py,sha256=MGXC76b0uYKhxg1-d9CijPP36ufRusgyq9Zurpo1vSc,15363
49
+ hanzo_mcp/tools/shell/session_manager.py,sha256=o8iS4PFCnq28vPqYtdtH9M8lfGyzyhtNL0hmNI13Uuc,6509
50
+ hanzo_mcp/tools/shell/session_storage.py,sha256=elnyFgn0FwsmVvoWAoJFAqiEeNaK4_yByT8-zXa6r-o,10141
51
+ hanzo_mcp/tools/todo/__init__.py,sha256=Ai-rlVWcy-CkJf1H2zIsbyx0wkxzWNLR3WAbGszbXKg,1720
52
+ hanzo_mcp/tools/todo/base.py,sha256=8sYZYAsFE5SjHRqynZCmCIKEobWB3aZwwSApg26keDo,10655
53
+ hanzo_mcp/tools/todo/todo_read.py,sha256=zXI9jn-kWXGSj88tI63yoAv-EWPDpkX1E6m0QfMUQHE,4759
54
+ hanzo_mcp/tools/todo/todo_write.py,sha256=fTAvrxrzkpdYwi7nYcJky2wjukChYsdXu5axqIUJg_c,15465
55
+ hanzo_mcp/tools/vector/__init__.py,sha256=McH23f6sKBT22rRfdyj0V_Okn1sq42-RNRRaZbeoE-4,3682
56
+ hanzo_mcp/tools/vector/ast_analyzer.py,sha256=2bUM9j9rCNARNXXF2cuFSp2ercwZAJWlAqeRIwn46Ck,15653
57
+ hanzo_mcp/tools/vector/git_ingester.py,sha256=VwHJYWzlpBTcmtUGoZLgEBTFFGoppewHqzXaPUM8Lk8,16214
58
+ hanzo_mcp/tools/vector/infinity_store.py,sha256=co8EZ3ohiivgwUAEkI31BzpmPe6E2lOeZEiJnjIosBQ,25287
59
+ hanzo_mcp/tools/vector/mock_infinity.py,sha256=QyU7FM2eTCP0BeuX8xhRe0En7hG9EFt-XzgDu-BefrI,4990
60
+ hanzo_mcp/tools/vector/project_manager.py,sha256=JZ6c0m4RWKbV4JjkxAI6ZgyOy2Ymk8-o4ficTLZrIo0,12500
61
+ hanzo_mcp/tools/vector/vector_index.py,sha256=Idp9w4g_7WVbIDY3oEX4-o7bWWQadeo3XC9lVtyS7Wg,4392
62
+ hanzo_mcp/tools/vector/vector_search.py,sha256=_LgoUNEyVHMFwVlCgJ-zJlCDNAiM4C1zKifqwPhMX6k,9516
63
+ hanzo_mcp-0.5.1.dist-info/licenses/LICENSE,sha256=mf1qZGFsPGskoPgytp9B-RsahfKvXsBpmaAbTLGTt8Y,1063
64
+ hanzo_mcp-0.5.1.dist-info/METADATA,sha256=PLxRkm_2YYNfg5GsATWOS2BWBuqVJ7by8tGvRAY93AI,11995
65
+ hanzo_mcp-0.5.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
66
+ hanzo_mcp-0.5.1.dist-info/entry_points.txt,sha256=aRKOKXtuQr-idSr-yH4efnRl2v8te94AcgN3ysqqSYs,49
67
+ hanzo_mcp-0.5.1.dist-info/top_level.txt,sha256=eGFANatA0MHWiVlpS56fTYRIShtibrSom1uXI6XU0GU,10
68
+ hanzo_mcp-0.5.1.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (79.0.1)
2
+ Generator: setuptools (80.9.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -1,73 +0,0 @@
1
- """Base model provider for agent delegation.
2
-
3
- Defines the interface for model providers.
4
- """
5
-
6
- import logging
7
- from abc import ABC, abstractmethod
8
- from typing import Any, Dict, List, Optional, Tuple
9
-
10
- logger = logging.getLogger(__name__)
11
-
12
-
13
- class BaseModelProvider(ABC):
14
- """Base class for model providers."""
15
-
16
- @abstractmethod
17
- async def initialize(self) -> None:
18
- """Initialize the provider."""
19
- pass
20
-
21
- @abstractmethod
22
- async def load_model(self, model_name: str, identifier: Optional[str] = None) -> str:
23
- """Load a model.
24
-
25
- Args:
26
- model_name: The name of the model to load
27
- identifier: Optional identifier for the model instance
28
-
29
- Returns:
30
- The identifier for the loaded model
31
- """
32
- pass
33
-
34
- @abstractmethod
35
- async def generate(
36
- self,
37
- model_id: str,
38
- prompt: str,
39
- system_prompt: Optional[str] = None,
40
- max_tokens: int = 4096,
41
- temperature: float = 0.7,
42
- top_p: float = 0.95,
43
- stop_sequences: Optional[List[str]] = None,
44
- ) -> Tuple[str, Dict[str, Any]]:
45
- """Generate a response from the model.
46
-
47
- Args:
48
- model_id: The identifier of the model to use
49
- prompt: The prompt to send to the model
50
- system_prompt: Optional system prompt to send to the model
51
- max_tokens: Maximum number of tokens to generate
52
- temperature: Sampling temperature
53
- top_p: Top-p sampling parameter
54
- stop_sequences: Optional list of strings that will stop generation
55
-
56
- Returns:
57
- A tuple of (generated text, metadata)
58
- """
59
- pass
60
-
61
- @abstractmethod
62
- async def unload_model(self, model_id: str) -> None:
63
- """Unload a model.
64
-
65
- Args:
66
- model_id: The identifier of the model to unload
67
- """
68
- pass
69
-
70
- @abstractmethod
71
- async def shutdown(self) -> None:
72
- """Shutdown the provider."""
73
- pass