hanzo-mcp 0.6.12__py3-none-any.whl → 0.6.13__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.
- hanzo_mcp/__init__.py +2 -2
- hanzo_mcp/cli.py +2 -2
- hanzo_mcp/cli_enhanced.py +4 -4
- hanzo_mcp/cli_plugin.py +91 -0
- hanzo_mcp/config/__init__.py +1 -1
- hanzo_mcp/config/settings.py +69 -6
- hanzo_mcp/config/tool_config.py +2 -2
- hanzo_mcp/dev_server.py +3 -3
- hanzo_mcp/prompts/project_system.py +1 -1
- hanzo_mcp/server.py +6 -2
- hanzo_mcp/server_enhanced.py +69 -0
- hanzo_mcp/tools/__init__.py +75 -29
- hanzo_mcp/tools/agent/__init__.py +1 -1
- hanzo_mcp/tools/agent/agent_tool.py +2 -2
- hanzo_mcp/tools/common/__init__.py +15 -1
- hanzo_mcp/tools/common/base.py +4 -4
- hanzo_mcp/tools/common/batch_tool.py +1 -1
- hanzo_mcp/tools/common/config_tool.py +2 -2
- hanzo_mcp/tools/common/context.py +2 -2
- hanzo_mcp/tools/common/context_fix.py +26 -0
- hanzo_mcp/tools/common/critic_tool.py +196 -0
- hanzo_mcp/tools/common/decorators.py +208 -0
- hanzo_mcp/tools/common/enhanced_base.py +106 -0
- hanzo_mcp/tools/common/mode.py +116 -0
- hanzo_mcp/tools/common/mode_loader.py +105 -0
- hanzo_mcp/tools/common/permissions.py +1 -1
- hanzo_mcp/tools/common/personality.py +936 -0
- hanzo_mcp/tools/common/plugin_loader.py +287 -0
- hanzo_mcp/tools/common/stats.py +4 -4
- hanzo_mcp/tools/common/tool_list.py +1 -1
- hanzo_mcp/tools/common/validation.py +1 -1
- hanzo_mcp/tools/config/__init__.py +3 -1
- hanzo_mcp/tools/config/config_tool.py +1 -1
- hanzo_mcp/tools/config/mode_tool.py +209 -0
- hanzo_mcp/tools/database/__init__.py +1 -1
- hanzo_mcp/tools/editor/__init__.py +1 -1
- hanzo_mcp/tools/filesystem/__init__.py +19 -14
- hanzo_mcp/tools/filesystem/batch_search.py +3 -3
- hanzo_mcp/tools/filesystem/diff.py +2 -2
- hanzo_mcp/tools/filesystem/rules_tool.py +235 -0
- hanzo_mcp/tools/filesystem/{unified_search.py → search_tool.py} +12 -12
- hanzo_mcp/tools/filesystem/{symbols_unified.py → symbols_tool.py} +104 -5
- hanzo_mcp/tools/filesystem/watch.py +3 -2
- hanzo_mcp/tools/jupyter/__init__.py +2 -2
- hanzo_mcp/tools/jupyter/jupyter.py +1 -1
- hanzo_mcp/tools/llm/__init__.py +3 -3
- hanzo_mcp/tools/llm/llm_tool.py +648 -143
- hanzo_mcp/tools/mcp/__init__.py +2 -2
- hanzo_mcp/tools/mcp/{mcp_unified.py → mcp_tool.py} +3 -3
- hanzo_mcp/tools/shell/__init__.py +6 -6
- hanzo_mcp/tools/shell/base_process.py +4 -2
- hanzo_mcp/tools/shell/bash_session_executor.py +1 -1
- hanzo_mcp/tools/shell/{bash_unified.py → bash_tool.py} +1 -1
- hanzo_mcp/tools/shell/command_executor.py +2 -2
- hanzo_mcp/tools/shell/{npx_unified.py → npx_tool.py} +1 -1
- hanzo_mcp/tools/shell/open.py +2 -2
- hanzo_mcp/tools/shell/{process_unified.py → process_tool.py} +1 -1
- hanzo_mcp/tools/shell/run_command_windows.py +1 -1
- hanzo_mcp/tools/shell/uvx.py +47 -2
- hanzo_mcp/tools/shell/uvx_background.py +47 -2
- hanzo_mcp/tools/shell/{uvx_unified.py → uvx_tool.py} +1 -1
- hanzo_mcp/tools/todo/__init__.py +14 -19
- hanzo_mcp/tools/todo/todo.py +22 -1
- hanzo_mcp/tools/vector/__init__.py +1 -1
- hanzo_mcp/tools/vector/infinity_store.py +2 -2
- hanzo_mcp/tools/vector/project_manager.py +1 -1
- hanzo_mcp-0.6.13.dist-info/METADATA +359 -0
- {hanzo_mcp-0.6.12.dist-info → hanzo_mcp-0.6.13.dist-info}/RECORD +72 -64
- {hanzo_mcp-0.6.12.dist-info → hanzo_mcp-0.6.13.dist-info}/entry_points.txt +1 -0
- hanzo_mcp/tools/common/palette.py +0 -344
- hanzo_mcp/tools/common/palette_loader.py +0 -108
- hanzo_mcp/tools/config/palette_tool.py +0 -179
- hanzo_mcp/tools/llm/llm_unified.py +0 -851
- hanzo_mcp-0.6.12.dist-info/METADATA +0 -339
- {hanzo_mcp-0.6.12.dist-info → hanzo_mcp-0.6.13.dist-info}/WHEEL +0 -0
- {hanzo_mcp-0.6.12.dist-info → hanzo_mcp-0.6.13.dist-info}/licenses/LICENSE +0 -0
- {hanzo_mcp-0.6.12.dist-info → hanzo_mcp-0.6.13.dist-info}/top_level.txt +0 -0
hanzo_mcp/tools/mcp/__init__.py
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"""MCP management tools."""
|
|
2
2
|
|
|
3
|
-
from hanzo_mcp.tools.mcp.
|
|
3
|
+
from hanzo_mcp.tools.mcp.mcp_tool import MCPTool
|
|
4
4
|
|
|
5
5
|
# Legacy imports
|
|
6
6
|
from hanzo_mcp.tools.mcp.mcp_add import McpAddTool
|
|
@@ -8,7 +8,7 @@ from hanzo_mcp.tools.mcp.mcp_remove import McpRemoveTool
|
|
|
8
8
|
from hanzo_mcp.tools.mcp.mcp_stats import McpStatsTool
|
|
9
9
|
|
|
10
10
|
__all__ = [
|
|
11
|
-
"
|
|
11
|
+
"MCPTool",
|
|
12
12
|
"McpAddTool",
|
|
13
13
|
"McpRemoveTool",
|
|
14
14
|
"McpStatsTool",
|
|
@@ -74,7 +74,7 @@ ConfigValue = Annotated[
|
|
|
74
74
|
AutoStart = Annotated[
|
|
75
75
|
bool,
|
|
76
76
|
Field(
|
|
77
|
-
description="Auto-start server when Hanzo
|
|
77
|
+
description="Auto-start server when Hanzo AI starts",
|
|
78
78
|
default=True,
|
|
79
79
|
),
|
|
80
80
|
]
|
|
@@ -93,8 +93,8 @@ class MCPParams(TypedDict, total=False):
|
|
|
93
93
|
|
|
94
94
|
|
|
95
95
|
@final
|
|
96
|
-
class
|
|
97
|
-
"""
|
|
96
|
+
class MCPTool(BaseTool):
|
|
97
|
+
"""Tool for managing MCP servers."""
|
|
98
98
|
|
|
99
99
|
# Config file
|
|
100
100
|
CONFIG_FILE = Path.home() / ".hanzo" / "mcp" / "servers.json"
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
"""Shell tools package for Hanzo
|
|
1
|
+
"""Shell tools package for Hanzo AI.
|
|
2
2
|
|
|
3
3
|
This package provides tools for executing shell commands and scripts.
|
|
4
4
|
"""
|
|
@@ -8,11 +8,11 @@ from mcp.server import FastMCP
|
|
|
8
8
|
from hanzo_mcp.tools.common.base import BaseTool, ToolRegistry
|
|
9
9
|
from hanzo_mcp.tools.common.permissions import PermissionManager
|
|
10
10
|
|
|
11
|
-
# Import
|
|
12
|
-
from hanzo_mcp.tools.shell.
|
|
13
|
-
from hanzo_mcp.tools.shell.
|
|
14
|
-
from hanzo_mcp.tools.shell.
|
|
15
|
-
from hanzo_mcp.tools.shell.
|
|
11
|
+
# Import tools
|
|
12
|
+
from hanzo_mcp.tools.shell.bash_tool import bash_tool
|
|
13
|
+
from hanzo_mcp.tools.shell.npx_tool import npx_tool
|
|
14
|
+
from hanzo_mcp.tools.shell.uvx_tool import uvx_tool
|
|
15
|
+
from hanzo_mcp.tools.shell.process_tool import process_tool
|
|
16
16
|
from hanzo_mcp.tools.shell.open import open_tool
|
|
17
17
|
|
|
18
18
|
# Export all tool classes
|
|
@@ -130,7 +130,8 @@ class BaseProcessTool(BaseTool):
|
|
|
130
130
|
"""
|
|
131
131
|
# Check permissions if manager is available
|
|
132
132
|
if self.permission_manager and cwd:
|
|
133
|
-
self.permission_manager.
|
|
133
|
+
if not self.permission_manager.is_path_allowed(str(cwd)):
|
|
134
|
+
raise PermissionError(f"Access denied to path: {cwd}")
|
|
134
135
|
|
|
135
136
|
# Get command arguments
|
|
136
137
|
cmd_args = self.get_command_args(command, **kwargs)
|
|
@@ -179,7 +180,8 @@ class BaseProcessTool(BaseTool):
|
|
|
179
180
|
"""
|
|
180
181
|
# Check permissions if manager is available
|
|
181
182
|
if self.permission_manager and cwd:
|
|
182
|
-
self.permission_manager.
|
|
183
|
+
if not self.permission_manager.is_path_allowed(str(cwd)):
|
|
184
|
+
raise PermissionError(f"Access denied to path: {cwd}")
|
|
183
185
|
|
|
184
186
|
# Generate process ID and log file
|
|
185
187
|
process_id = f"{self.get_tool_name()}_{uuid.uuid4().hex[:8]}"
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
"""Command executor tools for Hanzo
|
|
1
|
+
"""Command executor tools for Hanzo AI.
|
|
2
2
|
|
|
3
3
|
This module provides tools for executing shell commands and scripts with
|
|
4
4
|
comprehensive error handling, permissions checking, and progress tracking.
|
|
@@ -22,7 +22,7 @@ from hanzo_mcp.tools.shell.base import CommandResult
|
|
|
22
22
|
|
|
23
23
|
@final
|
|
24
24
|
class CommandExecutor:
|
|
25
|
-
"""Command executor tools for Hanzo
|
|
25
|
+
"""Command executor tools for Hanzo AI.
|
|
26
26
|
|
|
27
27
|
This class provides tools for executing shell commands and scripts with
|
|
28
28
|
comprehensive error handling, permissions checking, and progress tracking.
|
hanzo_mcp/tools/shell/open.py
CHANGED
hanzo_mcp/tools/shell/uvx.py
CHANGED
|
@@ -129,11 +129,56 @@ For long-running servers, use uvx_background instead.
|
|
|
129
129
|
|
|
130
130
|
# Check if uvx is available
|
|
131
131
|
if not shutil.which("uvx"):
|
|
132
|
-
|
|
132
|
+
await tool_ctx.info("uvx not found, attempting to install...")
|
|
133
|
+
|
|
134
|
+
# Try to auto-install uvx
|
|
135
|
+
install_cmd = "curl -LsSf https://astral.sh/uv/install.sh | sh"
|
|
136
|
+
|
|
137
|
+
try:
|
|
138
|
+
# Run installation
|
|
139
|
+
install_result = subprocess.run(
|
|
140
|
+
install_cmd,
|
|
141
|
+
shell=True,
|
|
142
|
+
capture_output=True,
|
|
143
|
+
text=True,
|
|
144
|
+
timeout=60
|
|
145
|
+
)
|
|
146
|
+
|
|
147
|
+
if install_result.returncode == 0:
|
|
148
|
+
await tool_ctx.info("uvx installed successfully!")
|
|
149
|
+
|
|
150
|
+
# Add to PATH for current session
|
|
151
|
+
import os
|
|
152
|
+
home = os.path.expanduser("~")
|
|
153
|
+
os.environ["PATH"] = f"{home}/.cargo/bin:{os.environ.get('PATH', '')}"
|
|
154
|
+
|
|
155
|
+
# Check again
|
|
156
|
+
if not shutil.which("uvx"):
|
|
157
|
+
return """Error: uvx installed but not found in PATH.
|
|
158
|
+
Please add ~/.cargo/bin to your PATH and restart your shell.
|
|
159
|
+
|
|
160
|
+
Add to ~/.zshrc or ~/.bashrc:
|
|
161
|
+
export PATH="$HOME/.cargo/bin:$PATH"
|
|
162
|
+
"""
|
|
163
|
+
else:
|
|
164
|
+
return f"""Error: Failed to install uvx automatically.
|
|
165
|
+
|
|
166
|
+
Install manually with:
|
|
133
167
|
curl -LsSf https://astral.sh/uv/install.sh | sh
|
|
134
168
|
|
|
135
169
|
Or on macOS:
|
|
136
|
-
brew install uv
|
|
170
|
+
brew install uv
|
|
171
|
+
|
|
172
|
+
Error details: {install_result.stderr}"""
|
|
173
|
+
|
|
174
|
+
except subprocess.TimeoutExpired:
|
|
175
|
+
return """Error: Installation timed out. Install uvx manually with:
|
|
176
|
+
curl -LsSf https://astral.sh/uv/install.sh | sh"""
|
|
177
|
+
except Exception as e:
|
|
178
|
+
return f"""Error: Failed to auto-install uvx: {str(e)}
|
|
179
|
+
|
|
180
|
+
Install manually with:
|
|
181
|
+
curl -LsSf https://astral.sh/uv/install.sh | sh"""
|
|
137
182
|
|
|
138
183
|
# Build command
|
|
139
184
|
cmd = ["uvx"]
|
|
@@ -150,11 +150,56 @@ Use 'processes' to list running processes and 'pkill' to stop them.
|
|
|
150
150
|
|
|
151
151
|
# Check if uvx is available
|
|
152
152
|
if not shutil.which("uvx"):
|
|
153
|
-
|
|
153
|
+
await tool_ctx.info("uvx not found, attempting to install...")
|
|
154
|
+
|
|
155
|
+
# Try to auto-install uvx
|
|
156
|
+
install_cmd = "curl -LsSf https://astral.sh/uv/install.sh | sh"
|
|
157
|
+
|
|
158
|
+
try:
|
|
159
|
+
# Run installation
|
|
160
|
+
install_result = subprocess.run(
|
|
161
|
+
install_cmd,
|
|
162
|
+
shell=True,
|
|
163
|
+
capture_output=True,
|
|
164
|
+
text=True,
|
|
165
|
+
timeout=60
|
|
166
|
+
)
|
|
167
|
+
|
|
168
|
+
if install_result.returncode == 0:
|
|
169
|
+
await tool_ctx.info("uvx installed successfully!")
|
|
170
|
+
|
|
171
|
+
# Add to PATH for current session
|
|
172
|
+
import os
|
|
173
|
+
home = os.path.expanduser("~")
|
|
174
|
+
os.environ["PATH"] = f"{home}/.cargo/bin:{os.environ.get('PATH', '')}"
|
|
175
|
+
|
|
176
|
+
# Check again
|
|
177
|
+
if not shutil.which("uvx"):
|
|
178
|
+
return """Error: uvx installed but not found in PATH.
|
|
179
|
+
Please add ~/.cargo/bin to your PATH and restart your shell.
|
|
180
|
+
|
|
181
|
+
Add to ~/.zshrc or ~/.bashrc:
|
|
182
|
+
export PATH="$HOME/.cargo/bin:$PATH"
|
|
183
|
+
"""
|
|
184
|
+
else:
|
|
185
|
+
return f"""Error: Failed to install uvx automatically.
|
|
186
|
+
|
|
187
|
+
Install manually with:
|
|
154
188
|
curl -LsSf https://astral.sh/uv/install.sh | sh
|
|
155
189
|
|
|
156
190
|
Or on macOS:
|
|
157
|
-
brew install uv
|
|
191
|
+
brew install uv
|
|
192
|
+
|
|
193
|
+
Error details: {install_result.stderr}"""
|
|
194
|
+
|
|
195
|
+
except subprocess.TimeoutExpired:
|
|
196
|
+
return """Error: Installation timed out. Install uvx manually with:
|
|
197
|
+
curl -LsSf https://astral.sh/uv/install.sh | sh"""
|
|
198
|
+
except Exception as e:
|
|
199
|
+
return f"""Error: Failed to auto-install uvx: {str(e)}
|
|
200
|
+
|
|
201
|
+
Install manually with:
|
|
202
|
+
curl -LsSf https://astral.sh/uv/install.sh | sh"""
|
|
158
203
|
|
|
159
204
|
# Build command
|
|
160
205
|
cmd = ["uvx"]
|
hanzo_mcp/tools/todo/__init__.py
CHANGED
|
@@ -1,19 +1,17 @@
|
|
|
1
|
-
"""Todo tools package for Hanzo
|
|
1
|
+
"""Todo tools package for Hanzo AI.
|
|
2
2
|
|
|
3
|
-
This package provides
|
|
4
|
-
|
|
3
|
+
This package provides a unified todo management tool for organizing tasks
|
|
4
|
+
within Claude Desktop sessions.
|
|
5
5
|
"""
|
|
6
6
|
|
|
7
7
|
from mcp.server import FastMCP
|
|
8
8
|
|
|
9
9
|
from hanzo_mcp.tools.common.base import BaseTool, ToolRegistry
|
|
10
|
-
from hanzo_mcp.tools.todo.
|
|
11
|
-
from hanzo_mcp.tools.todo.todo_write import TodoWriteTool
|
|
10
|
+
from hanzo_mcp.tools.todo.todo import TodoTool
|
|
12
11
|
|
|
13
12
|
# Export all tool classes
|
|
14
13
|
__all__ = [
|
|
15
|
-
"
|
|
16
|
-
"TodoWriteTool",
|
|
14
|
+
"TodoTool",
|
|
17
15
|
"get_todo_tools",
|
|
18
16
|
"register_todo_tools",
|
|
19
17
|
]
|
|
@@ -26,8 +24,7 @@ def get_todo_tools() -> list[BaseTool]:
|
|
|
26
24
|
List of todo tool instances
|
|
27
25
|
"""
|
|
28
26
|
return [
|
|
29
|
-
|
|
30
|
-
TodoWriteTool(),
|
|
27
|
+
TodoTool(),
|
|
31
28
|
]
|
|
32
29
|
|
|
33
30
|
|
|
@@ -44,23 +41,21 @@ def register_todo_tools(
|
|
|
44
41
|
Returns:
|
|
45
42
|
List of registered tools
|
|
46
43
|
"""
|
|
47
|
-
# Define tool mapping
|
|
44
|
+
# Define tool mapping - single unified todo tool
|
|
48
45
|
tool_classes = {
|
|
49
|
-
"
|
|
50
|
-
"todo_write": TodoWriteTool,
|
|
46
|
+
"todo": TodoTool,
|
|
51
47
|
}
|
|
52
|
-
|
|
48
|
+
|
|
53
49
|
tools = []
|
|
54
|
-
|
|
50
|
+
|
|
55
51
|
if enabled_tools:
|
|
56
52
|
# Use individual tool configuration
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
tools.append(tool_class())
|
|
53
|
+
# Support both old names and new name for backward compatibility
|
|
54
|
+
if enabled_tools.get("todo", True) or enabled_tools.get("todo_read", True) or enabled_tools.get("todo_write", True):
|
|
55
|
+
tools.append(TodoTool())
|
|
61
56
|
else:
|
|
62
57
|
# Use all tools (backward compatibility)
|
|
63
58
|
tools = get_todo_tools()
|
|
64
|
-
|
|
59
|
+
|
|
65
60
|
ToolRegistry.register_tools(mcp_server, tools)
|
|
66
61
|
return tools
|
hanzo_mcp/tools/todo/todo.py
CHANGED
|
@@ -260,6 +260,27 @@ todo --filter in_progress
|
|
|
260
260
|
self.write_todos([])
|
|
261
261
|
return f"Cleared all {count} todo(s)"
|
|
262
262
|
|
|
263
|
+
@override
|
|
263
264
|
def register(self, mcp_server) -> None:
|
|
264
265
|
"""Register this tool with the MCP server."""
|
|
265
|
-
|
|
266
|
+
tool_self = self # Create a reference to self for use in the closure
|
|
267
|
+
|
|
268
|
+
@mcp_server.tool(name=self.name, description=self.description)
|
|
269
|
+
async def todo(
|
|
270
|
+
action: Action = "list",
|
|
271
|
+
content: Content = None,
|
|
272
|
+
id: TodoId = None,
|
|
273
|
+
status: Status = None,
|
|
274
|
+
priority: Priority = None,
|
|
275
|
+
filter: Filter = None,
|
|
276
|
+
ctx: MCPContext = None,
|
|
277
|
+
) -> str:
|
|
278
|
+
return await tool_self.call(
|
|
279
|
+
ctx,
|
|
280
|
+
action=action,
|
|
281
|
+
content=content,
|
|
282
|
+
id=id,
|
|
283
|
+
status=status,
|
|
284
|
+
priority=priority,
|
|
285
|
+
filter=filter,
|
|
286
|
+
)
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
"""Infinity vector database integration for Hanzo
|
|
1
|
+
"""Infinity vector database integration for Hanzo AI."""
|
|
2
2
|
|
|
3
3
|
import json
|
|
4
4
|
import hashlib
|
|
@@ -45,7 +45,7 @@ class SymbolSearchResult:
|
|
|
45
45
|
|
|
46
46
|
@dataclass
|
|
47
47
|
class UnifiedSearchResult:
|
|
48
|
-
"""
|
|
48
|
+
"""Search result combining text, vector, and symbol search."""
|
|
49
49
|
type: str # 'document', 'symbol', 'reference'
|
|
50
50
|
content: str
|
|
51
51
|
file_path: str
|