hanzo-mcp 0.7.6__py3-none-any.whl → 0.8.0__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 (178) hide show
  1. hanzo_mcp/__init__.py +7 -1
  2. hanzo_mcp/__main__.py +1 -1
  3. hanzo_mcp/analytics/__init__.py +2 -2
  4. hanzo_mcp/analytics/posthog_analytics.py +76 -82
  5. hanzo_mcp/cli.py +31 -36
  6. hanzo_mcp/cli_enhanced.py +94 -72
  7. hanzo_mcp/cli_plugin.py +27 -17
  8. hanzo_mcp/config/__init__.py +2 -2
  9. hanzo_mcp/config/settings.py +112 -88
  10. hanzo_mcp/config/tool_config.py +32 -34
  11. hanzo_mcp/dev_server.py +66 -67
  12. hanzo_mcp/prompts/__init__.py +94 -12
  13. hanzo_mcp/prompts/enhanced_prompts.py +809 -0
  14. hanzo_mcp/prompts/example_custom_prompt.py +6 -5
  15. hanzo_mcp/prompts/project_todo_reminder.py +0 -1
  16. hanzo_mcp/prompts/tool_explorer.py +10 -7
  17. hanzo_mcp/server.py +17 -21
  18. hanzo_mcp/server_enhanced.py +15 -22
  19. hanzo_mcp/tools/__init__.py +56 -28
  20. hanzo_mcp/tools/agent/__init__.py +16 -19
  21. hanzo_mcp/tools/agent/agent.py +82 -65
  22. hanzo_mcp/tools/agent/agent_tool.py +152 -122
  23. hanzo_mcp/tools/agent/agent_tool_v1_deprecated.py +66 -62
  24. hanzo_mcp/tools/agent/clarification_protocol.py +55 -50
  25. hanzo_mcp/tools/agent/clarification_tool.py +11 -10
  26. hanzo_mcp/tools/agent/claude_cli_tool.py +21 -20
  27. hanzo_mcp/tools/agent/claude_desktop_auth.py +130 -144
  28. hanzo_mcp/tools/agent/cli_agent_base.py +59 -53
  29. hanzo_mcp/tools/agent/code_auth.py +102 -107
  30. hanzo_mcp/tools/agent/code_auth_tool.py +28 -27
  31. hanzo_mcp/tools/agent/codex_cli_tool.py +20 -19
  32. hanzo_mcp/tools/agent/critic_tool.py +86 -73
  33. hanzo_mcp/tools/agent/gemini_cli_tool.py +21 -20
  34. hanzo_mcp/tools/agent/grok_cli_tool.py +21 -20
  35. hanzo_mcp/tools/agent/iching_tool.py +404 -139
  36. hanzo_mcp/tools/agent/network_tool.py +89 -73
  37. hanzo_mcp/tools/agent/prompt.py +2 -1
  38. hanzo_mcp/tools/agent/review_tool.py +101 -98
  39. hanzo_mcp/tools/agent/swarm_alias.py +87 -0
  40. hanzo_mcp/tools/agent/swarm_tool.py +246 -161
  41. hanzo_mcp/tools/agent/swarm_tool_v1_deprecated.py +134 -92
  42. hanzo_mcp/tools/agent/tool_adapter.py +21 -11
  43. hanzo_mcp/tools/common/__init__.py +1 -1
  44. hanzo_mcp/tools/common/base.py +3 -5
  45. hanzo_mcp/tools/common/batch_tool.py +46 -39
  46. hanzo_mcp/tools/common/config_tool.py +120 -84
  47. hanzo_mcp/tools/common/context.py +1 -5
  48. hanzo_mcp/tools/common/context_fix.py +5 -3
  49. hanzo_mcp/tools/common/critic_tool.py +4 -8
  50. hanzo_mcp/tools/common/decorators.py +58 -56
  51. hanzo_mcp/tools/common/enhanced_base.py +29 -32
  52. hanzo_mcp/tools/common/fastmcp_pagination.py +91 -94
  53. hanzo_mcp/tools/common/forgiving_edit.py +91 -87
  54. hanzo_mcp/tools/common/mode.py +15 -17
  55. hanzo_mcp/tools/common/mode_loader.py +27 -24
  56. hanzo_mcp/tools/common/paginated_base.py +61 -53
  57. hanzo_mcp/tools/common/paginated_response.py +72 -79
  58. hanzo_mcp/tools/common/pagination.py +50 -53
  59. hanzo_mcp/tools/common/permissions.py +4 -4
  60. hanzo_mcp/tools/common/personality.py +186 -138
  61. hanzo_mcp/tools/common/plugin_loader.py +54 -54
  62. hanzo_mcp/tools/common/stats.py +65 -47
  63. hanzo_mcp/tools/common/test_helpers.py +31 -0
  64. hanzo_mcp/tools/common/thinking_tool.py +4 -8
  65. hanzo_mcp/tools/common/tool_disable.py +17 -12
  66. hanzo_mcp/tools/common/tool_enable.py +13 -14
  67. hanzo_mcp/tools/common/tool_list.py +36 -28
  68. hanzo_mcp/tools/common/truncate.py +23 -23
  69. hanzo_mcp/tools/config/__init__.py +4 -4
  70. hanzo_mcp/tools/config/config_tool.py +42 -29
  71. hanzo_mcp/tools/config/index_config.py +37 -34
  72. hanzo_mcp/tools/config/mode_tool.py +175 -55
  73. hanzo_mcp/tools/database/__init__.py +15 -12
  74. hanzo_mcp/tools/database/database_manager.py +77 -75
  75. hanzo_mcp/tools/database/graph.py +137 -91
  76. hanzo_mcp/tools/database/graph_add.py +30 -18
  77. hanzo_mcp/tools/database/graph_query.py +178 -102
  78. hanzo_mcp/tools/database/graph_remove.py +33 -28
  79. hanzo_mcp/tools/database/graph_search.py +97 -75
  80. hanzo_mcp/tools/database/graph_stats.py +91 -59
  81. hanzo_mcp/tools/database/sql.py +107 -79
  82. hanzo_mcp/tools/database/sql_query.py +30 -24
  83. hanzo_mcp/tools/database/sql_search.py +29 -25
  84. hanzo_mcp/tools/database/sql_stats.py +47 -35
  85. hanzo_mcp/tools/editor/neovim_command.py +25 -28
  86. hanzo_mcp/tools/editor/neovim_edit.py +21 -23
  87. hanzo_mcp/tools/editor/neovim_session.py +60 -54
  88. hanzo_mcp/tools/filesystem/__init__.py +31 -30
  89. hanzo_mcp/tools/filesystem/ast_multi_edit.py +329 -249
  90. hanzo_mcp/tools/filesystem/ast_tool.py +4 -4
  91. hanzo_mcp/tools/filesystem/base.py +1 -1
  92. hanzo_mcp/tools/filesystem/batch_search.py +316 -224
  93. hanzo_mcp/tools/filesystem/content_replace.py +4 -4
  94. hanzo_mcp/tools/filesystem/diff.py +71 -59
  95. hanzo_mcp/tools/filesystem/directory_tree.py +7 -7
  96. hanzo_mcp/tools/filesystem/directory_tree_paginated.py +49 -37
  97. hanzo_mcp/tools/filesystem/edit.py +4 -4
  98. hanzo_mcp/tools/filesystem/find.py +173 -80
  99. hanzo_mcp/tools/filesystem/find_files.py +73 -52
  100. hanzo_mcp/tools/filesystem/git_search.py +157 -104
  101. hanzo_mcp/tools/filesystem/grep.py +8 -8
  102. hanzo_mcp/tools/filesystem/multi_edit.py +4 -8
  103. hanzo_mcp/tools/filesystem/read.py +12 -10
  104. hanzo_mcp/tools/filesystem/rules_tool.py +59 -43
  105. hanzo_mcp/tools/filesystem/search_tool.py +263 -207
  106. hanzo_mcp/tools/filesystem/symbols_tool.py +94 -54
  107. hanzo_mcp/tools/filesystem/tree.py +35 -33
  108. hanzo_mcp/tools/filesystem/unix_aliases.py +13 -18
  109. hanzo_mcp/tools/filesystem/watch.py +37 -36
  110. hanzo_mcp/tools/filesystem/write.py +4 -8
  111. hanzo_mcp/tools/jupyter/__init__.py +4 -4
  112. hanzo_mcp/tools/jupyter/base.py +4 -5
  113. hanzo_mcp/tools/jupyter/jupyter.py +67 -47
  114. hanzo_mcp/tools/jupyter/notebook_edit.py +4 -4
  115. hanzo_mcp/tools/jupyter/notebook_read.py +4 -7
  116. hanzo_mcp/tools/llm/__init__.py +5 -7
  117. hanzo_mcp/tools/llm/consensus_tool.py +72 -52
  118. hanzo_mcp/tools/llm/llm_manage.py +101 -60
  119. hanzo_mcp/tools/llm/llm_tool.py +226 -166
  120. hanzo_mcp/tools/llm/provider_tools.py +25 -26
  121. hanzo_mcp/tools/lsp/__init__.py +1 -1
  122. hanzo_mcp/tools/lsp/lsp_tool.py +228 -143
  123. hanzo_mcp/tools/mcp/__init__.py +2 -3
  124. hanzo_mcp/tools/mcp/mcp_add.py +27 -25
  125. hanzo_mcp/tools/mcp/mcp_remove.py +7 -8
  126. hanzo_mcp/tools/mcp/mcp_stats.py +23 -22
  127. hanzo_mcp/tools/mcp/mcp_tool.py +129 -98
  128. hanzo_mcp/tools/memory/__init__.py +39 -21
  129. hanzo_mcp/tools/memory/knowledge_tools.py +124 -99
  130. hanzo_mcp/tools/memory/memory_tools.py +90 -108
  131. hanzo_mcp/tools/search/__init__.py +7 -2
  132. hanzo_mcp/tools/search/find_tool.py +297 -212
  133. hanzo_mcp/tools/search/unified_search.py +366 -314
  134. hanzo_mcp/tools/shell/__init__.py +8 -7
  135. hanzo_mcp/tools/shell/auto_background.py +56 -49
  136. hanzo_mcp/tools/shell/base.py +1 -1
  137. hanzo_mcp/tools/shell/base_process.py +75 -75
  138. hanzo_mcp/tools/shell/bash_session.py +2 -2
  139. hanzo_mcp/tools/shell/bash_session_executor.py +4 -4
  140. hanzo_mcp/tools/shell/bash_tool.py +24 -31
  141. hanzo_mcp/tools/shell/command_executor.py +12 -12
  142. hanzo_mcp/tools/shell/logs.py +43 -33
  143. hanzo_mcp/tools/shell/npx.py +13 -13
  144. hanzo_mcp/tools/shell/npx_background.py +24 -21
  145. hanzo_mcp/tools/shell/npx_tool.py +18 -22
  146. hanzo_mcp/tools/shell/open.py +19 -21
  147. hanzo_mcp/tools/shell/pkill.py +31 -26
  148. hanzo_mcp/tools/shell/process_tool.py +32 -32
  149. hanzo_mcp/tools/shell/processes.py +57 -58
  150. hanzo_mcp/tools/shell/run_background.py +24 -25
  151. hanzo_mcp/tools/shell/run_command.py +5 -5
  152. hanzo_mcp/tools/shell/run_command_windows.py +5 -5
  153. hanzo_mcp/tools/shell/session_storage.py +3 -3
  154. hanzo_mcp/tools/shell/streaming_command.py +141 -126
  155. hanzo_mcp/tools/shell/uvx.py +24 -25
  156. hanzo_mcp/tools/shell/uvx_background.py +35 -33
  157. hanzo_mcp/tools/shell/uvx_tool.py +18 -22
  158. hanzo_mcp/tools/todo/__init__.py +6 -2
  159. hanzo_mcp/tools/todo/todo.py +50 -37
  160. hanzo_mcp/tools/todo/todo_read.py +5 -8
  161. hanzo_mcp/tools/todo/todo_write.py +5 -7
  162. hanzo_mcp/tools/vector/__init__.py +40 -28
  163. hanzo_mcp/tools/vector/ast_analyzer.py +176 -143
  164. hanzo_mcp/tools/vector/git_ingester.py +170 -179
  165. hanzo_mcp/tools/vector/index_tool.py +96 -44
  166. hanzo_mcp/tools/vector/infinity_store.py +283 -228
  167. hanzo_mcp/tools/vector/mock_infinity.py +39 -40
  168. hanzo_mcp/tools/vector/project_manager.py +88 -78
  169. hanzo_mcp/tools/vector/vector.py +59 -42
  170. hanzo_mcp/tools/vector/vector_index.py +30 -27
  171. hanzo_mcp/tools/vector/vector_search.py +64 -45
  172. hanzo_mcp/types.py +6 -4
  173. {hanzo_mcp-0.7.6.dist-info → hanzo_mcp-0.8.0.dist-info}/METADATA +1 -1
  174. hanzo_mcp-0.8.0.dist-info/RECORD +185 -0
  175. hanzo_mcp-0.7.6.dist-info/RECORD +0 -182
  176. {hanzo_mcp-0.7.6.dist-info → hanzo_mcp-0.8.0.dist-info}/WHEEL +0 -0
  177. {hanzo_mcp-0.7.6.dist-info → hanzo_mcp-0.8.0.dist-info}/entry_points.txt +0 -0
  178. {hanzo_mcp-0.7.6.dist-info → hanzo_mcp-0.8.0.dist-info}/top_level.txt +0 -0
@@ -14,19 +14,20 @@ Focus on:
14
14
 
15
15
  Be constructive and specific in your feedback."""
16
16
 
17
+
17
18
  # You can also create dynamic prompts that take parameters
18
19
  def create_custom_analysis_prompt(file_path: str, analysis_type: str = "general"):
19
20
  """Create a dynamic analysis prompt for a specific file."""
20
-
21
+
21
22
  analysis_types = {
22
23
  "general": "Provide a general analysis including structure, purpose, and quality",
23
24
  "security": "Focus on security vulnerabilities and best practices",
24
25
  "performance": "Analyze performance bottlenecks and optimization opportunities",
25
- "refactor": "Suggest refactoring opportunities to improve code maintainability"
26
+ "refactor": "Suggest refactoring opportunities to improve code maintainability",
26
27
  }
27
-
28
+
28
29
  analysis_instruction = analysis_types.get(analysis_type, analysis_types["general"])
29
-
30
+
30
31
  return f"""Please analyze the file at {file_path}.
31
32
 
32
33
  {analysis_instruction}
@@ -37,4 +38,4 @@ Your analysis should include:
37
38
  3. Specific recommendations with code examples where applicable
38
39
  4. Priority ranking of any issues found
39
40
 
40
- Be thorough but concise in your analysis."""
41
+ Be thorough but concise in your analysis."""
@@ -3,7 +3,6 @@ from typing import Any
3
3
  # Import TodoStorage to access todo data
4
4
  from hanzo_mcp.tools.todo.base import TodoStorage
5
5
 
6
-
7
6
  PROJECT_TODO_EMPTY_REMINDER = """<system-reminder>This is a reminder that your todo list is currently empty. DO NOT mention this to me explicitly because i have already aware. If you are working on tasks that would benefit from a todo list please use the todo_write tool to create one. If not, please feel free to ignore.</system-reminder>"""
8
7
 
9
8
 
@@ -585,19 +585,22 @@ Tools NOT available in batch (require state/session):
585
585
  - think
586
586
  - todo_write"""
587
587
 
588
+
588
589
  def create_tool_category_prompt(category: str, tools: list[str]):
589
590
  """Create a dynamic prompt for a specific tool category."""
590
-
591
+
591
592
  tool_descriptions = {
592
593
  "filesystem": FILESYSTEM_TOOLS_HELP,
593
594
  "agent": AGENT_TOOLS_HELP,
594
595
  "shell": SHELL_TOOLS_HELP,
595
- "batch": BATCH_TOOL_EXAMPLES
596
+ "batch": BATCH_TOOL_EXAMPLES,
596
597
  }
597
-
598
- base_prompt = tool_descriptions.get(category, f"# {category.title()} Tools\n\nAvailable tools in this category:\n")
599
-
598
+
599
+ base_prompt = tool_descriptions.get(
600
+ category, f"# {category.title()} Tools\n\nAvailable tools in this category:\n"
601
+ )
602
+
600
603
  if category not in tool_descriptions:
601
604
  base_prompt += "\n".join(f"- **{tool}**: [Tool description]" for tool in tools)
602
-
603
- return base_prompt
605
+
606
+ return base_prompt
hanzo_mcp/server.py CHANGED
@@ -1,14 +1,14 @@
1
1
  """MCP server implementing Hanzo capabilities."""
2
2
 
3
3
  import atexit
4
- import logging
5
4
  import signal
5
+ import logging
6
6
  import threading
7
- import time
8
7
  import warnings
9
8
  from typing import Literal, cast, final
10
9
 
11
- # No need for warning suppression here as it's handled in the imports
10
+ # Suppress litellm deprecation warnings about event loop
11
+ warnings.filterwarnings("ignore", message="There is no current event loop", category=DeprecationWarning)
12
12
 
13
13
  try:
14
14
  from fastmcp import FastMCP
@@ -17,11 +17,9 @@ except ImportError:
17
17
  from mcp.server import FastMCP
18
18
 
19
19
  # Import our enhanced server
20
- from hanzo_mcp.server_enhanced import EnhancedFastMCP
21
-
22
- from hanzo_mcp.prompts import register_all_prompts
23
20
  from hanzo_mcp.tools import register_all_tools
24
-
21
+ from hanzo_mcp.prompts import register_all_prompts
22
+ from hanzo_mcp.server_enhanced import EnhancedFastMCP
25
23
  from hanzo_mcp.tools.common.permissions import PermissionManager
26
24
  from hanzo_mcp.tools.shell.session_storage import SessionStorage
27
25
 
@@ -126,7 +124,7 @@ class HanzoMCPServer:
126
124
  final_enabled_tools = self.enabled_tools.copy()
127
125
  for tool_name in self.disabled_tools:
128
126
  final_enabled_tools[tool_name] = False
129
-
127
+
130
128
  # Store the final processed tool configuration
131
129
  self.enabled_tools = final_enabled_tools
132
130
 
@@ -159,8 +157,9 @@ class HanzoMCPServer:
159
157
  # Register signal handlers for graceful shutdown
160
158
  def signal_handler(signum, frame):
161
159
  import sys
160
+
162
161
  # Only log if not stdio transport
163
- if hasattr(self, '_transport') and self._transport != 'stdio':
162
+ if hasattr(self, "_transport") and self._transport != "stdio":
164
163
  logger = logging.getLogger(__name__)
165
164
  logger.info("\nShutting down gracefully...")
166
165
  self._cleanup_sessions()
@@ -198,7 +197,7 @@ class HanzoMCPServer:
198
197
  cleared_count = SessionStorage.clear_all_sessions()
199
198
  if cleared_count > 0:
200
199
  # Only log if not stdio transport
201
- if hasattr(self, '_transport') and self._transport != 'stdio':
200
+ if hasattr(self, "_transport") and self._transport != "stdio":
202
201
  logger = logging.getLogger(__name__)
203
202
  logger.info(f"Cleaned up {cleared_count} tmux sessions on shutdown")
204
203
  except Exception:
@@ -214,7 +213,7 @@ class HanzoMCPServer:
214
213
  """
215
214
  # Store transport for later use
216
215
  self._transport = transport
217
-
216
+
218
217
  # Add allowed paths if provided
219
218
  allowed_paths_list = allowed_paths or []
220
219
  for path in allowed_paths_list:
@@ -232,30 +231,27 @@ def create_server(
232
231
  name: str = "hanzo-mcp",
233
232
  allowed_paths: list[str] | None = None,
234
233
  enable_all_tools: bool = False,
235
- **kwargs
234
+ **kwargs,
236
235
  ) -> HanzoMCPServer:
237
236
  """Create a Hanzo MCP server instance.
238
-
237
+
239
238
  Args:
240
239
  name: Server name
241
240
  allowed_paths: List of allowed file paths
242
241
  enable_all_tools: Enable all tools including agent tools
243
242
  **kwargs: Additional server configuration
244
-
243
+
245
244
  Returns:
246
245
  HanzoMCPServer instance
247
246
  """
248
247
  if enable_all_tools:
249
- kwargs['enable_agent_tool'] = True
250
-
251
- return HanzoMCPServer(
252
- name=name,
253
- allowed_paths=allowed_paths,
254
- **kwargs
255
- )
248
+ kwargs["enable_agent_tool"] = True
249
+
250
+ return HanzoMCPServer(name=name, allowed_paths=allowed_paths, **kwargs)
256
251
 
257
252
 
258
253
  def main():
259
254
  """Main entry point for the server."""
260
255
  from hanzo_mcp.cli import main as cli_main
256
+
261
257
  cli_main()
@@ -4,8 +4,7 @@ This module provides an enhanced FastMCP server that automatically
4
4
  applies context normalization to all registered tools.
5
5
  """
6
6
 
7
- from typing import Any, Callable
8
- from functools import wraps
7
+ from typing import Callable
9
8
 
10
9
  from mcp.server import FastMCP
11
10
 
@@ -14,56 +13,50 @@ from hanzo_mcp.tools.common.decorators import with_context_normalization
14
13
 
15
14
  class EnhancedFastMCP(FastMCP):
16
15
  """Enhanced FastMCP server with automatic context normalization.
17
-
16
+
18
17
  This server automatically wraps all tool registrations with context
19
18
  normalization, ensuring that tools work properly when called externally
20
19
  with serialized context parameters.
21
20
  """
22
-
23
- def tool(
24
- self,
25
- name: str | None = None,
26
- description: str | None = None
27
- ) -> Callable:
21
+
22
+ def tool(self, name: str | None = None, description: str | None = None) -> Callable:
28
23
  """Enhanced tool decorator that includes automatic context normalization.
29
-
24
+
30
25
  Args:
31
26
  name: Tool name (defaults to function name)
32
27
  description: Tool description
33
-
28
+
34
29
  Returns:
35
30
  Decorator function that registers the tool with context normalization
36
31
  """
37
32
  # Get the original decorator from parent class
38
- original_decorator = super().tool(
39
- name=name,
40
- description=description
41
- )
42
-
33
+ original_decorator = super().tool(name=name, description=description)
34
+
43
35
  # Create our enhanced decorator
44
36
  def enhanced_decorator(func: Callable) -> Callable:
45
37
  # Apply context normalization first
46
38
  # Check if function has ctx parameter
47
39
  import inspect
40
+
48
41
  sig = inspect.signature(func)
49
- if 'ctx' in sig.parameters:
42
+ if "ctx" in sig.parameters:
50
43
  normalized_func = with_context_normalization(func)
51
44
  else:
52
45
  normalized_func = func
53
-
46
+
54
47
  # Then apply the original decorator
55
48
  return original_decorator(normalized_func)
56
-
49
+
57
50
  return enhanced_decorator
58
51
 
59
52
 
60
53
  def create_enhanced_server(name: str = "hanzo") -> EnhancedFastMCP:
61
54
  """Create an enhanced MCP server with automatic context normalization.
62
-
55
+
63
56
  Args:
64
57
  name: Server name
65
-
58
+
66
59
  Returns:
67
60
  Enhanced FastMCP server instance
68
61
  """
69
- return EnhancedFastMCP(name)
62
+ return EnhancedFastMCP(name)
@@ -11,39 +11,50 @@ to delegate tasks to sub-agents for concurrent execution and specialized process
11
11
 
12
12
  from mcp.server import FastMCP
13
13
 
14
+ from hanzo_mcp.tools.todo import register_todo_tools
14
15
  from hanzo_mcp.tools.agent import register_agent_tools
15
- from hanzo_mcp.tools.common import register_batch_tool, register_thinking_tool, register_critic_tool
16
+ from hanzo_mcp.tools.shell import register_shell_tools
17
+ from hanzo_mcp.tools.common import (
18
+ register_batch_tool,
19
+ register_critic_tool,
20
+ register_thinking_tool,
21
+ )
22
+ from hanzo_mcp.tools.vector import register_vector_tools
23
+ from hanzo_mcp.tools.jupyter import register_jupyter_tools
24
+ from hanzo_mcp.tools.database import DatabaseManager, register_database_tools
25
+ from hanzo_mcp.tools.filesystem import register_filesystem_tools
16
26
  from hanzo_mcp.tools.common.base import BaseTool
27
+ from hanzo_mcp.tools.common.stats import StatsTool
28
+ from hanzo_mcp.tools.common.tool_list import ToolListTool
17
29
  from hanzo_mcp.tools.common.permissions import PermissionManager
18
30
  from hanzo_mcp.tools.common.tool_enable import ToolEnableTool
19
31
  from hanzo_mcp.tools.common.tool_disable import ToolDisableTool
20
- from hanzo_mcp.tools.common.tool_list import ToolListTool
21
- from hanzo_mcp.tools.common.stats import StatsTool
22
- from hanzo_mcp.tools.filesystem import register_filesystem_tools
23
- from hanzo_mcp.tools.jupyter import register_jupyter_tools
24
- from hanzo_mcp.tools.shell import register_shell_tools
25
- from hanzo_mcp.tools.todo import register_todo_tools
26
- from hanzo_mcp.tools.vector import register_vector_tools
27
- from hanzo_mcp.tools.database import register_database_tools, DatabaseManager
28
32
 
29
33
  # Try to import memory tools, but don't fail if hanzo-memory is not installed
30
34
  try:
31
35
  from hanzo_mcp.tools.memory import register_memory_tools
36
+
32
37
  MEMORY_TOOLS_AVAILABLE = True
33
38
  except ImportError:
34
39
  MEMORY_TOOLS_AVAILABLE = False
35
40
  register_memory_tools = None
36
- from hanzo_mcp.tools.mcp import MCPTool, McpAddTool, McpRemoveTool, McpStatsTool
41
+ from hanzo_mcp.tools.llm import (
42
+ LLMTool,
43
+ ConsensusTool,
44
+ LLMManageTool,
45
+ create_provider_tools,
46
+ )
47
+ from hanzo_mcp.tools.mcp import MCPTool, McpAddTool, McpStatsTool, McpRemoveTool
37
48
  from hanzo_mcp.tools.editor import NeovimEditTool, NeovimCommandTool, NeovimSessionTool
38
- from hanzo_mcp.tools.llm import LLMTool, LLMTool, ConsensusTool, LLMManageTool, create_provider_tools
49
+ from hanzo_mcp.tools.common.mode import activate_mode_from_env
39
50
  from hanzo_mcp.tools.config.mode_tool import mode_tool
40
51
  from hanzo_mcp.tools.common.mode_loader import ModeLoader
41
- from hanzo_mcp.tools.common.mode import activate_mode_from_env
42
52
  from hanzo_mcp.tools.common.plugin_loader import load_user_plugins
43
53
 
44
54
  # Try to import LSP tool
45
55
  try:
46
56
  from hanzo_mcp.tools.lsp import LSPTool, create_lsp_tool
57
+
47
58
  LSP_TOOL_AVAILABLE = True
48
59
  except ImportError:
49
60
  LSP_TOOL_AVAILABLE = False
@@ -84,7 +95,7 @@ def register_all_tools(
84
95
  vector_config: Vector store configuration (default: None)
85
96
  use_mode: Whether to use mode system for tool configuration (default: True)
86
97
  force_mode: Force a specific mode to be active (default: None)
87
-
98
+
88
99
  Returns:
89
100
  List of registered BaseTool instances
90
101
  """
@@ -95,11 +106,15 @@ def register_all_tools(
95
106
  try:
96
107
  plugins = load_user_plugins()
97
108
  import logging
109
+
98
110
  logger = logging.getLogger(__name__)
99
111
  if plugins:
100
- logger.info(f"Loaded {len(plugins)} user plugin tools: {', '.join(plugins.keys())}")
112
+ logger.info(
113
+ f"Loaded {len(plugins)} user plugin tools: {', '.join(plugins.keys())}"
114
+ )
101
115
  except Exception as e:
102
116
  import logging
117
+
103
118
  logger = logging.getLogger(__name__)
104
119
  logger.warning(f"Failed to load user plugins: {e}")
105
120
  plugins = {}
@@ -110,8 +125,7 @@ def register_all_tools(
110
125
  activate_mode_from_env()
111
126
 
112
127
  tool_config = ModeLoader.get_enabled_tools_from_mode(
113
- base_enabled_tools=enabled_tools,
114
- force_mode=force_mode
128
+ base_enabled_tools=enabled_tools, force_mode=force_mode
115
129
  )
116
130
  # Apply mode environment variables
117
131
  ModeLoader.apply_environment_from_mode()
@@ -146,18 +160,26 @@ def register_all_tools(
146
160
  }
147
161
 
148
162
  # Create project manager if vector tools, batch_search, or unified_search are enabled
149
- if any(vector_enabled.values()) or filesystem_enabled.get("batch_search", False) or filesystem_enabled.get("search", False):
163
+ if (
164
+ any(vector_enabled.values())
165
+ or filesystem_enabled.get("batch_search", False)
166
+ or filesystem_enabled.get("search", False)
167
+ ):
150
168
  if vector_config:
151
169
  from hanzo_mcp.tools.vector.project_manager import ProjectVectorManager
170
+
152
171
  search_paths = [str(path) for path in permission_manager.allowed_paths]
153
172
  project_manager = ProjectVectorManager(
154
173
  global_db_path=vector_config.get("data_path"),
155
- embedding_model=vector_config.get("embedding_model", "text-embedding-3-small"),
174
+ embedding_model=vector_config.get(
175
+ "embedding_model", "text-embedding-3-small"
176
+ ),
156
177
  dimension=vector_config.get("dimension", 1536),
157
178
  )
158
179
  # Auto-detect projects from search paths
159
180
  detected_projects = project_manager.detect_projects(search_paths)
160
181
  import logging
182
+
161
183
  logger = logging.getLogger(__name__)
162
184
  logger.info(f"Detected {len(detected_projects)} projects with LLM.md files")
163
185
 
@@ -178,7 +200,9 @@ def register_all_tools(
178
200
  }
179
201
 
180
202
  if any(jupyter_enabled.values()):
181
- jupyter_tools = register_jupyter_tools(mcp_server, permission_manager, enabled_tools=jupyter_enabled)
203
+ jupyter_tools = register_jupyter_tools(
204
+ mcp_server, permission_manager, enabled_tools=jupyter_enabled
205
+ )
182
206
  for tool in jupyter_tools:
183
207
  all_tools[tool.name] = tool
184
208
 
@@ -189,7 +213,11 @@ def register_all_tools(
189
213
  all_tools[tool.name] = tool
190
214
 
191
215
  # Register agent tools if enabled
192
- agent_enabled = enable_agent_tool or is_tool_enabled("agent", False) or is_tool_enabled("dispatch_agent", False)
216
+ agent_enabled = (
217
+ enable_agent_tool
218
+ or is_tool_enabled("agent", False)
219
+ or is_tool_enabled("dispatch_agent", False)
220
+ )
193
221
  swarm_enabled = is_tool_enabled("swarm", False)
194
222
 
195
223
  if agent_enabled or swarm_enabled:
@@ -205,9 +233,12 @@ def register_all_tools(
205
233
  )
206
234
  # Filter based on what's enabled
207
235
  for tool in agent_tools:
208
- if tool.name == "agent" and agent_enabled:
209
- all_tools[tool.name] = tool
210
- elif tool.name == "swarm" and swarm_enabled:
236
+ if (
237
+ tool.name == "agent"
238
+ and agent_enabled
239
+ or tool.name == "swarm"
240
+ and swarm_enabled
241
+ ):
211
242
  all_tools[tool.name] = tool
212
243
  elif tool.name in ["claude", "codex", "gemini", "grok", "code_auth"]:
213
244
  # CLI tools and auth are always included when agent tools are enabled
@@ -415,10 +446,7 @@ def register_all_tools(
415
446
  if any(memory_enabled.values()) and MEMORY_TOOLS_AVAILABLE:
416
447
  try:
417
448
  memory_tools = register_memory_tools(
418
- mcp_server,
419
- permission_manager,
420
- user_id="default",
421
- project_id="default"
449
+ mcp_server, permission_manager, user_id="default", project_id="default"
422
450
  )
423
451
  # Filter based on enabled state
424
452
  for tool in memory_tools:
@@ -446,6 +474,6 @@ def register_all_tools(
446
474
  logger.info(f"Registered plugin tool: {plugin_name}")
447
475
  except Exception as e:
448
476
  logger.error(f"Failed to register plugin tool {plugin_name}: {e}")
449
-
477
+
450
478
  # Return all registered tools
451
479
  return list(all_tools.values())
@@ -4,22 +4,20 @@ This module provides tools that allow Claude to delegate tasks to sub-agents,
4
4
  enabling concurrent execution of multiple operations and specialized processing.
5
5
  """
6
6
 
7
- import os
8
7
  from mcp.server import FastMCP
9
8
 
9
+ from hanzo_mcp.tools.common.base import BaseTool, ToolRegistry
10
+
10
11
  # Import the main implementations (using hanzo-agents SDK)
11
12
  from hanzo_mcp.tools.agent.agent_tool import AgentTool
12
13
  from hanzo_mcp.tools.agent.swarm_tool import SwarmTool
13
-
14
- from hanzo_mcp.tools.agent.claude_cli_tool import ClaudeCLITool
15
- from hanzo_mcp.tools.agent.codex_cli_tool import CodexCLITool
16
- from hanzo_mcp.tools.agent.gemini_cli_tool import GeminiCLITool
14
+ from hanzo_mcp.tools.agent.network_tool import NetworkTool
15
+ from hanzo_mcp.tools.common.permissions import PermissionManager
17
16
  from hanzo_mcp.tools.agent.grok_cli_tool import GrokCLITool
18
17
  from hanzo_mcp.tools.agent.code_auth_tool import CodeAuthTool
19
- from hanzo_mcp.tools.agent.network_tool import NetworkTool, LocalSwarmTool
20
- from hanzo_mcp.tools.common.base import BaseTool, ToolRegistry
21
-
22
- from hanzo_mcp.tools.common.permissions import PermissionManager
18
+ from hanzo_mcp.tools.agent.codex_cli_tool import CodexCLITool
19
+ from hanzo_mcp.tools.agent.claude_cli_tool import ClaudeCLITool
20
+ from hanzo_mcp.tools.agent.gemini_cli_tool import GeminiCLITool
23
21
 
24
22
 
25
23
  def register_agent_tools(
@@ -58,7 +56,7 @@ def register_agent_tools(
58
56
  max_iterations=agent_max_iterations,
59
57
  max_tool_uses=agent_max_tool_uses,
60
58
  )
61
-
59
+
62
60
  # Create swarm tool
63
61
  swarm_tool = SwarmTool(
64
62
  permission_manager=permission_manager,
@@ -69,36 +67,35 @@ def register_agent_tools(
69
67
  agent_max_iterations=agent_max_iterations,
70
68
  agent_max_tool_uses=agent_max_tool_uses,
71
69
  )
72
-
73
-
70
+
74
71
  # Create CLI agent tools
75
72
  claude_cli_tool = ClaudeCLITool(
76
73
  permission_manager=permission_manager,
77
74
  model=agent_model, # Can override default Sonnet
78
75
  )
79
-
76
+
80
77
  codex_cli_tool = CodexCLITool(
81
78
  permission_manager=permission_manager,
82
79
  model=agent_model if agent_model and "gpt" in agent_model else None,
83
80
  )
84
-
81
+
85
82
  gemini_cli_tool = GeminiCLITool(
86
83
  permission_manager=permission_manager,
87
84
  model=agent_model if agent_model and "gemini" in agent_model else None,
88
85
  )
89
-
86
+
90
87
  grok_cli_tool = GrokCLITool(
91
88
  permission_manager=permission_manager,
92
89
  model=agent_model if agent_model and "grok" in agent_model else None,
93
90
  )
94
-
91
+
95
92
  # Create auth management tool
96
93
  code_auth_tool = CodeAuthTool()
97
-
94
+
98
95
  # Create network tool
99
96
  network_tool = NetworkTool(
100
97
  permission_manager=permission_manager,
101
- default_mode="hybrid" # Prefer local, fallback to cloud
98
+ default_mode="hybrid", # Prefer local, fallback to cloud
102
99
  )
103
100
 
104
101
  # Register tools
@@ -113,7 +110,7 @@ def register_agent_tools(
113
110
 
114
111
  # Return list of registered tools
115
112
  return [
116
- agent_tool,
113
+ agent_tool,
117
114
  swarm_tool,
118
115
  network_tool,
119
116
  claude_cli_tool,