hanzo-mcp 0.7.7__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 +6 -0
  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.7.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.7.dist-info/RECORD +0 -182
  176. {hanzo_mcp-0.7.7.dist-info → hanzo_mcp-0.8.0.dist-info}/WHEEL +0 -0
  177. {hanzo_mcp-0.7.7.dist-info → hanzo_mcp-0.8.0.dist-info}/entry_points.txt +0 -0
  178. {hanzo_mcp-0.7.7.dist-info → hanzo_mcp-0.8.0.dist-info}/top_level.txt +0 -0
@@ -1,12 +1,13 @@
1
1
  """Tool configuration definitions for Hanzo AI."""
2
2
 
3
3
  from enum import Enum
4
- from typing import Dict, List, Optional
4
+ from typing import Dict, List
5
5
  from dataclasses import dataclass
6
6
 
7
7
 
8
8
  class ToolCategory(str, Enum):
9
9
  """Categories of tools available in Hanzo AI."""
10
+
10
11
  FILESYSTEM = "filesystem"
11
12
  SHELL = "shell"
12
13
  JUPYTER = "jupyter"
@@ -19,13 +20,14 @@ class ToolCategory(str, Enum):
19
20
  @dataclass
20
21
  class ToolConfig:
21
22
  """Configuration for an individual tool."""
23
+
22
24
  name: str
23
25
  category: ToolCategory
24
26
  enabled: bool = True
25
27
  description: str = ""
26
28
  requires_permissions: bool = True
27
29
  cli_flag: str = ""
28
-
30
+
29
31
  def __post_init__(self):
30
32
  """Generate CLI flag if not provided."""
31
33
  if not self.cli_flag:
@@ -39,138 +41,132 @@ TOOL_REGISTRY: Dict[str, ToolConfig] = {
39
41
  name="read",
40
42
  category=ToolCategory.FILESYSTEM,
41
43
  description="Read file contents with line numbers and truncation support",
42
- cli_flag="--disable-read"
44
+ cli_flag="--disable-read",
43
45
  ),
44
46
  "write": ToolConfig(
45
- name="write",
47
+ name="write",
46
48
  category=ToolCategory.FILESYSTEM,
47
49
  description="Write content to files, create new files or overwrite existing ones",
48
- cli_flag="--disable-write"
50
+ cli_flag="--disable-write",
49
51
  ),
50
52
  "edit": ToolConfig(
51
53
  name="edit",
52
- category=ToolCategory.FILESYSTEM,
54
+ category=ToolCategory.FILESYSTEM,
53
55
  description="Make precise string replacements in files with validation",
54
- cli_flag="--disable-edit"
56
+ cli_flag="--disable-edit",
55
57
  ),
56
58
  "multi_edit": ToolConfig(
57
59
  name="multi_edit",
58
60
  category=ToolCategory.FILESYSTEM,
59
- description="Perform multiple edits to a single file in one operation",
60
- cli_flag="--disable-multi-edit"
61
+ description="Perform multiple edits to a single file in one operation",
62
+ cli_flag="--disable-multi-edit",
61
63
  ),
62
64
  "directory_tree": ToolConfig(
63
65
  name="directory_tree",
64
66
  category=ToolCategory.FILESYSTEM,
65
67
  description="Display directory structure as a tree",
66
- cli_flag="--disable-directory-tree"
68
+ cli_flag="--disable-directory-tree",
67
69
  ),
68
70
  "grep": ToolConfig(
69
71
  name="grep",
70
72
  category=ToolCategory.FILESYSTEM,
71
73
  description="Fast content search using ripgrep or fallback Python implementation",
72
- cli_flag="--disable-grep"
74
+ cli_flag="--disable-grep",
73
75
  ),
74
76
  "ast": ToolConfig(
75
- name="ast",
77
+ name="ast",
76
78
  category=ToolCategory.FILESYSTEM,
77
79
  description="Search source code with AST context using tree-sitter",
78
- cli_flag="--disable-ast"
80
+ cli_flag="--disable-ast",
79
81
  ),
80
82
  "content_replace": ToolConfig(
81
83
  name="content_replace",
82
84
  category=ToolCategory.FILESYSTEM,
83
85
  description="Bulk text replacement across multiple files",
84
- cli_flag="--disable-content-replace"
86
+ cli_flag="--disable-content-replace",
85
87
  ),
86
-
87
88
  # Shell Tools (1)
88
89
  "run_command": ToolConfig(
89
90
  name="run_command",
90
91
  category=ToolCategory.SHELL,
91
92
  description="Execute shell commands with session support",
92
- cli_flag="--disable-run-command"
93
+ cli_flag="--disable-run-command",
93
94
  ),
94
-
95
95
  # Jupyter Tools (2)
96
96
  "notebook_read": ToolConfig(
97
97
  name="notebook_read",
98
98
  category=ToolCategory.JUPYTER,
99
99
  description="Read Jupyter notebook files (.ipynb)",
100
- cli_flag="--disable-notebook-read"
100
+ cli_flag="--disable-notebook-read",
101
101
  ),
102
102
  "notebook_edit": ToolConfig(
103
103
  name="notebook_edit",
104
104
  category=ToolCategory.JUPYTER,
105
105
  description="Edit Jupyter notebook cells (replace, insert, delete)",
106
- cli_flag="--disable-notebook-edit"
106
+ cli_flag="--disable-notebook-edit",
107
107
  ),
108
-
109
108
  # Todo Tools (2)
110
109
  "todo_read": ToolConfig(
111
110
  name="todo_read",
112
111
  category=ToolCategory.TODO,
113
112
  description="Read the current todo list for a session",
114
- cli_flag="--disable-todo-read"
113
+ cli_flag="--disable-todo-read",
115
114
  ),
116
115
  "todo_write": ToolConfig(
117
- name="todo_write",
116
+ name="todo_write",
118
117
  category=ToolCategory.TODO,
119
118
  description="Create and manage structured task lists",
120
- cli_flag="--disable-todo-write"
119
+ cli_flag="--disable-todo-write",
121
120
  ),
122
-
123
121
  # Agent Tools (3)
124
122
  "dispatch_agent": ToolConfig(
125
123
  name="dispatch_agent",
126
124
  category=ToolCategory.AGENT,
127
125
  enabled=False, # Disabled by default
128
126
  description="Delegate tasks to sub-agents for concurrent/specialized processing",
129
- cli_flag="--enable-dispatch-agent"
127
+ cli_flag="--enable-dispatch-agent",
130
128
  ),
131
129
  "swarm": ToolConfig(
132
130
  name="swarm",
133
131
  category=ToolCategory.AGENT,
134
132
  enabled=False, # Disabled by default
135
133
  description="Execute multiple agent tasks in parallel across different files",
136
- cli_flag="--enable-swarm"
134
+ cli_flag="--enable-swarm",
137
135
  ),
138
136
  "hierarchical_swarm": ToolConfig(
139
137
  name="hierarchical_swarm",
140
138
  category=ToolCategory.AGENT,
141
139
  enabled=False, # Disabled by default
142
140
  description="Execute hierarchical agent swarms with Claude Code integration",
143
- cli_flag="--enable-hierarchical-swarm"
141
+ cli_flag="--enable-hierarchical-swarm",
144
142
  ),
145
-
146
143
  # Common Tools (3)
147
144
  "think": ToolConfig(
148
145
  name="think",
149
146
  category=ToolCategory.COMMON,
150
147
  description="Provide structured thinking space for complex reasoning",
151
- cli_flag="--disable-think"
148
+ cli_flag="--disable-think",
152
149
  ),
153
150
  "batch": ToolConfig(
154
151
  name="batch",
155
152
  category=ToolCategory.COMMON,
156
153
  description="Execute multiple tools in parallel or serial",
157
- cli_flag="--disable-batch"
154
+ cli_flag="--disable-batch",
158
155
  ),
159
-
160
156
  # Vector Tools (2)
161
157
  "vector_index": ToolConfig(
162
158
  name="vector_index",
163
159
  category=ToolCategory.VECTOR,
164
160
  enabled=False, # Disabled by default
165
161
  description="Index documents in local vector database for semantic search",
166
- cli_flag="--enable-vector-index"
162
+ cli_flag="--enable-vector-index",
167
163
  ),
168
164
  "vector_search": ToolConfig(
169
165
  name="vector_search",
170
166
  category=ToolCategory.VECTOR,
171
167
  enabled=False, # Disabled by default
172
168
  description="Search documents using semantic similarity in vector database",
173
- cli_flag="--enable-vector-search"
169
+ cli_flag="--enable-vector-search",
174
170
  ),
175
171
  }
176
172
 
@@ -208,4 +204,6 @@ def disable_tool(tool_name: str) -> bool:
208
204
 
209
205
  def is_tool_enabled(tool_name: str) -> bool:
210
206
  """Check if a tool is enabled."""
211
- return TOOL_REGISTRY.get(tool_name, ToolConfig("", ToolCategory.COMMON, False)).enabled
207
+ return TOOL_REGISTRY.get(
208
+ tool_name, ToolConfig("", ToolCategory.COMMON, False)
209
+ ).enabled
hanzo_mcp/dev_server.py CHANGED
@@ -1,12 +1,10 @@
1
1
  """Development server with hot reload for Hanzo AI."""
2
2
 
3
+ import time
3
4
  import asyncio
4
5
  import logging
5
- import os
6
- import sys
7
- import time
6
+ from typing import Set, Optional
8
7
  from pathlib import Path
9
- from typing import Optional, Set
10
8
 
11
9
  import watchdog.events
12
10
  import watchdog.observers
@@ -17,77 +15,87 @@ from hanzo_mcp.server import HanzoMCPServer
17
15
 
18
16
  class MCPReloadHandler(FileSystemEventHandler):
19
17
  """Handler for file system events that triggers MCP server reload."""
20
-
18
+
21
19
  def __init__(self, restart_callback, ignore_patterns: Optional[Set[str]] = None):
22
20
  """Initialize the reload handler.
23
-
21
+
24
22
  Args:
25
23
  restart_callback: Function to call when files change
26
24
  ignore_patterns: Set of patterns to ignore
27
25
  """
28
26
  self.restart_callback = restart_callback
29
27
  self.ignore_patterns = ignore_patterns or {
30
- "__pycache__", ".pyc", ".pyo", ".git", ".pytest_cache",
31
- ".mypy_cache", ".ruff_cache", ".coverage", "*.log",
32
- ".env", ".venv", "venv", "node_modules"
28
+ "__pycache__",
29
+ ".pyc",
30
+ ".pyo",
31
+ ".git",
32
+ ".pytest_cache",
33
+ ".mypy_cache",
34
+ ".ruff_cache",
35
+ ".coverage",
36
+ "*.log",
37
+ ".env",
38
+ ".venv",
39
+ "venv",
40
+ "node_modules",
33
41
  }
34
42
  self.last_reload = 0
35
43
  self.reload_delay = 0.5 # Debounce delay in seconds
36
-
44
+
37
45
  def should_ignore(self, path: str) -> bool:
38
46
  """Check if a path should be ignored."""
39
47
  path_obj = Path(path)
40
-
48
+
41
49
  # Check against ignore patterns
42
50
  for pattern in self.ignore_patterns:
43
51
  if pattern in str(path_obj):
44
52
  return True
45
53
  if path_obj.name.endswith(pattern):
46
54
  return True
47
-
55
+
48
56
  # Only watch Python files and config files
49
57
  if path_obj.is_file():
50
58
  allowed_extensions = {".py", ".json", ".yaml", ".yml", ".toml"}
51
59
  if path_obj.suffix not in allowed_extensions:
52
60
  return True
53
-
61
+
54
62
  return False
55
-
63
+
56
64
  def on_any_event(self, event):
57
65
  """Handle any file system event."""
58
66
  if event.is_directory:
59
67
  return
60
-
68
+
61
69
  if self.should_ignore(event.src_path):
62
70
  return
63
-
71
+
64
72
  # Debounce rapid changes
65
73
  current_time = time.time()
66
74
  if current_time - self.last_reload < self.reload_delay:
67
75
  return
68
-
76
+
69
77
  self.last_reload = current_time
70
-
78
+
71
79
  logger = logging.getLogger(__name__)
72
80
  logger.info(f"\n🔄 File changed: {event.src_path}")
73
81
  logger.info("🔄 Reloading MCP server...")
74
-
82
+
75
83
  self.restart_callback()
76
84
 
77
85
 
78
86
  class DevServer:
79
87
  """Development server with hot reload capability."""
80
-
88
+
81
89
  def __init__(
82
90
  self,
83
91
  name: str = "hanzo-dev",
84
92
  allowed_paths: Optional[list[str]] = None,
85
93
  project_paths: Optional[list[str]] = None,
86
94
  project_dir: Optional[str] = None,
87
- **kwargs
95
+ **kwargs,
88
96
  ):
89
97
  """Initialize the development server.
90
-
98
+
91
99
  Args:
92
100
  name: Server name
93
101
  allowed_paths: Allowed paths for the server
@@ -103,7 +111,7 @@ class DevServer:
103
111
  self.server_process = None
104
112
  self.observer = None
105
113
  self.running = False
106
-
114
+
107
115
  def create_server(self) -> HanzoMCPServer:
108
116
  """Create a new MCP server instance."""
109
117
  return HanzoMCPServer(
@@ -111,76 +119,80 @@ class DevServer:
111
119
  allowed_paths=self.allowed_paths,
112
120
  project_paths=self.project_paths,
113
121
  project_dir=self.project_dir,
114
- **self.server_kwargs
122
+ **self.server_kwargs,
115
123
  )
116
-
124
+
117
125
  def start_file_watcher(self):
118
126
  """Start watching for file changes."""
119
127
  # Watch the hanzo_mcp package directory
120
128
  package_dir = Path(__file__).parent
121
-
129
+
122
130
  # Create observer and handler
123
131
  self.observer = watchdog.observers.Observer()
124
132
  handler = MCPReloadHandler(self.restart_server)
125
-
133
+
126
134
  # Watch the package directory
127
135
  self.observer.schedule(handler, str(package_dir), recursive=True)
128
-
136
+
129
137
  # Also watch any project directories
130
138
  if self.project_dir:
131
139
  self.observer.schedule(handler, self.project_dir, recursive=True)
132
-
140
+
133
141
  for path in self.allowed_paths:
134
142
  if Path(path).is_dir() and path not in [str(package_dir), self.project_dir]:
135
143
  self.observer.schedule(handler, path, recursive=True)
136
-
144
+
137
145
  self.observer.start()
138
146
  logger = logging.getLogger(__name__)
139
147
  logger.info(f"👀 Watching for changes in: {package_dir}")
140
148
  if self.project_dir:
141
149
  logger.info(f"👀 Also watching: {self.project_dir}")
142
-
150
+
143
151
  def stop_file_watcher(self):
144
152
  """Stop the file watcher."""
145
153
  if self.observer and self.observer.is_alive():
146
154
  self.observer.stop()
147
155
  self.observer.join(timeout=2)
148
-
156
+
149
157
  def restart_server(self):
150
158
  """Restart the MCP server."""
151
159
  # Since MCP servers run in the same process, we need to handle this differently
152
160
  # For now, we'll log a message indicating a restart is needed
153
161
  logger = logging.getLogger(__name__)
154
- logger.warning("\n⚠️ Server restart required. Please restart the MCP client to reload changes.")
155
- logger.info("💡 Tip: In development, consider using the MCP test client for easier reloading.")
156
-
162
+ logger.warning(
163
+ "\n⚠️ Server restart required. Please restart the MCP client to reload changes."
164
+ )
165
+ logger.info(
166
+ "💡 Tip: In development, consider using the MCP test client for easier reloading."
167
+ )
168
+
157
169
  async def run_async(self, transport: str = "stdio"):
158
170
  """Run the development server asynchronously."""
159
171
  self.running = True
160
-
172
+
161
173
  logger = logging.getLogger(__name__)
162
174
  logger.info(f"\n🚀 Starting Hanzo AI in development mode...")
163
175
  logger.info(f"🔧 Hot reload enabled - watching for file changes")
164
176
  logger.info(f"📁 Project: {self.project_dir or 'current directory'}")
165
177
  logger.info(f"🌐 Transport: {transport}\n")
166
-
178
+
167
179
  # Start file watcher
168
180
  self.start_file_watcher()
169
-
181
+
170
182
  try:
171
183
  # Create and run server
172
184
  server = self.create_server()
173
-
185
+
174
186
  # Run the server (this will block)
175
187
  server.run(transport=transport)
176
-
188
+
177
189
  except KeyboardInterrupt:
178
190
  logger.info("\n\n🛑 Shutting down development server...")
179
191
  finally:
180
192
  self.running = False
181
193
  self.stop_file_watcher()
182
194
  logger.info("👋 Development server stopped")
183
-
195
+
184
196
  def run(self, transport: str = "stdio"):
185
197
  """Run the development server."""
186
198
  try:
@@ -193,48 +205,35 @@ class DevServer:
193
205
  def run_dev_server():
194
206
  """Entry point for development server."""
195
207
  import argparse
196
-
197
- parser = argparse.ArgumentParser(description="Run Hanzo AI in development mode with hot reload")
198
- parser.add_argument(
199
- "--name",
200
- type=str,
201
- default="hanzo-dev",
202
- help="Name of the MCP server"
208
+
209
+ parser = argparse.ArgumentParser(
210
+ description="Run Hanzo AI in development mode with hot reload"
203
211
  )
204
212
  parser.add_argument(
205
- "--project-dir",
206
- type=str,
207
- help="Project directory to serve"
213
+ "--name", type=str, default="hanzo-dev", help="Name of the MCP server"
208
214
  )
215
+ parser.add_argument("--project-dir", type=str, help="Project directory to serve")
209
216
  parser.add_argument(
210
217
  "--allowed-path",
211
218
  type=str,
212
219
  action="append",
213
220
  dest="allowed_paths",
214
- help="Additional allowed paths (can be specified multiple times)"
221
+ help="Additional allowed paths (can be specified multiple times)",
215
222
  )
216
223
  parser.add_argument(
217
224
  "--transport",
218
225
  type=str,
219
226
  default="stdio",
220
227
  choices=["stdio", "sse"],
221
- help="Transport type (default: stdio)"
228
+ help="Transport type (default: stdio)",
222
229
  )
223
230
  parser.add_argument(
224
- "--host",
225
- type=str,
226
- default="127.0.0.1",
227
- help="Host for SSE transport"
231
+ "--host", type=str, default="127.0.0.1", help="Host for SSE transport"
228
232
  )
229
- parser.add_argument(
230
- "--port",
231
- type=int,
232
- default=3000,
233
- help="Port for SSE transport"
234
- )
235
-
233
+ parser.add_argument("--port", type=int, default=3000, help="Port for SSE transport")
234
+
236
235
  args = parser.parse_args()
237
-
236
+
238
237
  # Create and run dev server
239
238
  dev_server = DevServer(
240
239
  name=args.name,
@@ -243,9 +242,9 @@ def run_dev_server():
243
242
  host=args.host,
244
243
  port=args.port,
245
244
  )
246
-
245
+
247
246
  dev_server.run(transport=args.transport)
248
247
 
249
248
 
250
249
  if __name__ == "__main__":
251
- run_dev_server()
250
+ run_dev_server()
@@ -2,25 +2,36 @@ import os
2
2
 
3
3
  from mcp.server import FastMCP
4
4
 
5
- from hanzo_mcp.prompts.compact_conversation import COMPACT_CONVERSATION_PROMPT
6
- from hanzo_mcp.prompts.create_release import CREATE_RELEASE_PROMPT
7
- from hanzo_mcp.prompts.project_system import PROJECT_SYSTEM_PROMPT
8
- from hanzo_mcp.prompts.project_todo_reminder import (
9
- PROJECT_TODO_EMPTY_REMINDER,
10
- get_project_todo_reminder,
11
- )
12
5
  from hanzo_mcp.prompts.utils import (
13
- get_directory_structure,
14
- get_git_info,
15
6
  get_os_info,
7
+ get_git_info,
8
+ get_directory_structure,
16
9
  )
17
10
  from hanzo_mcp.prompts.tool_explorer import (
18
- TOOL_EXPLORER_PROMPT,
19
- FILESYSTEM_TOOLS_HELP,
20
11
  AGENT_TOOLS_HELP,
21
12
  SHELL_TOOLS_HELP,
22
13
  BATCH_TOOL_EXAMPLES,
23
- create_tool_category_prompt,
14
+ TOOL_EXPLORER_PROMPT,
15
+ FILESYSTEM_TOOLS_HELP,
16
+ )
17
+ from hanzo_mcp.prompts.create_release import CREATE_RELEASE_PROMPT
18
+ from hanzo_mcp.prompts.project_system import PROJECT_SYSTEM_PROMPT
19
+ from hanzo_mcp.prompts.enhanced_prompts import (
20
+ QUICK_START_PROMPT,
21
+ LSP_TOOLS_HELP_PROMPT,
22
+ PAGINATION_GUIDE_PROMPT,
23
+ PERFORMANCE_TIPS_PROMPT,
24
+ MEMORY_VECTOR_HELP_PROMPT,
25
+ CONFIGURATION_GUIDE_PROMPT,
26
+ DATABASE_TOOLS_HELP_PROMPT,
27
+ NETWORK_AGENT_GUIDE_PROMPT,
28
+ TROUBLESHOOTING_GUIDE_PROMPT,
29
+ SECURITY_BEST_PRACTICES_PROMPT,
30
+ )
31
+ from hanzo_mcp.prompts.compact_conversation import COMPACT_CONVERSATION_PROMPT
32
+ from hanzo_mcp.prompts.project_todo_reminder import (
33
+ PROJECT_TODO_EMPTY_REMINDER,
34
+ get_project_todo_reminder,
24
35
  )
25
36
 
26
37
  CONTINUE_FROM_LAST_SESSION_PROMPT = """<system-reminder>
@@ -140,6 +151,77 @@ def register_all_prompts(
140
151
  """
141
152
  return BATCH_TOOL_EXAMPLES
142
153
 
154
+ # Enhanced prompts for better discoverability
155
+ @mcp_server.prompt(name="Quick start guide")
156
+ def quick_start() -> str:
157
+ """
158
+ Common workflows and recipes for getting started quickly.
159
+ """
160
+ return QUICK_START_PROMPT
161
+
162
+ @mcp_server.prompt(name="Pagination guide")
163
+ def pagination_guide() -> str:
164
+ """
165
+ How to use pagination for large result sets.
166
+ """
167
+ return PAGINATION_GUIDE_PROMPT
168
+
169
+ @mcp_server.prompt(name="Memory and vector tools help")
170
+ def memory_vector_help() -> str:
171
+ """
172
+ Guide for semantic search and memory tools.
173
+ """
174
+ return MEMORY_VECTOR_HELP_PROMPT
175
+
176
+ @mcp_server.prompt(name="Database tools help")
177
+ def database_help() -> str:
178
+ """
179
+ SQL and graph database operations guide.
180
+ """
181
+ return DATABASE_TOOLS_HELP_PROMPT
182
+
183
+ @mcp_server.prompt(name="LSP tools help")
184
+ def lsp_help() -> str:
185
+ """
186
+ Language Server Protocol features and code intelligence.
187
+ """
188
+ return LSP_TOOLS_HELP_PROMPT
189
+
190
+ @mcp_server.prompt(name="Configuration guide")
191
+ def config_guide() -> str:
192
+ """
193
+ How to configure tools, presets, and settings.
194
+ """
195
+ return CONFIGURATION_GUIDE_PROMPT
196
+
197
+ @mcp_server.prompt(name="Network agent guide")
198
+ def network_guide() -> str:
199
+ """
200
+ Distributed AI orchestration with network/swarm tools.
201
+ """
202
+ return NETWORK_AGENT_GUIDE_PROMPT
203
+
204
+ @mcp_server.prompt(name="Performance tips")
205
+ def performance_tips() -> str:
206
+ """
207
+ Optimization strategies for better performance.
208
+ """
209
+ return PERFORMANCE_TIPS_PROMPT
210
+
211
+ @mcp_server.prompt(name="Security best practices")
212
+ def security_practices() -> str:
213
+ """
214
+ Safe usage patterns and security guidelines.
215
+ """
216
+ return SECURITY_BEST_PRACTICES_PROMPT
217
+
218
+ @mcp_server.prompt(name="Troubleshooting guide")
219
+ def troubleshooting() -> str:
220
+ """
221
+ Common issues and their solutions.
222
+ """
223
+ return TROUBLESHOOTING_GUIDE_PROMPT
224
+
143
225
  if projects is None:
144
226
  return
145
227