hanzo-mcp 0.8.8__py3-none-any.whl → 0.8.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.

Files changed (154) hide show
  1. hanzo_mcp/__init__.py +1 -3
  2. hanzo_mcp/analytics/posthog_analytics.py +4 -17
  3. hanzo_mcp/bridge.py +9 -25
  4. hanzo_mcp/cli.py +8 -17
  5. hanzo_mcp/cli_enhanced.py +5 -14
  6. hanzo_mcp/cli_plugin.py +3 -9
  7. hanzo_mcp/config/settings.py +6 -20
  8. hanzo_mcp/config/tool_config.py +2 -4
  9. hanzo_mcp/core/base_agent.py +88 -88
  10. hanzo_mcp/core/model_registry.py +238 -210
  11. hanzo_mcp/dev_server.py +5 -15
  12. hanzo_mcp/prompts/__init__.py +2 -6
  13. hanzo_mcp/prompts/project_todo_reminder.py +3 -9
  14. hanzo_mcp/prompts/tool_explorer.py +1 -3
  15. hanzo_mcp/prompts/utils.py +7 -21
  16. hanzo_mcp/server.py +6 -7
  17. hanzo_mcp/tools/__init__.py +13 -29
  18. hanzo_mcp/tools/agent/__init__.py +2 -1
  19. hanzo_mcp/tools/agent/agent.py +10 -30
  20. hanzo_mcp/tools/agent/agent_tool.py +6 -17
  21. hanzo_mcp/tools/agent/agent_tool_v1_deprecated.py +15 -42
  22. hanzo_mcp/tools/agent/claude_desktop_auth.py +3 -9
  23. hanzo_mcp/tools/agent/cli_agent_base.py +7 -24
  24. hanzo_mcp/tools/agent/cli_tools.py +76 -75
  25. hanzo_mcp/tools/agent/code_auth.py +1 -3
  26. hanzo_mcp/tools/agent/code_auth_tool.py +2 -6
  27. hanzo_mcp/tools/agent/critic_tool.py +8 -24
  28. hanzo_mcp/tools/agent/iching_tool.py +12 -36
  29. hanzo_mcp/tools/agent/network_tool.py +7 -18
  30. hanzo_mcp/tools/agent/prompt.py +1 -5
  31. hanzo_mcp/tools/agent/review_tool.py +10 -25
  32. hanzo_mcp/tools/agent/swarm_alias.py +1 -3
  33. hanzo_mcp/tools/agent/swarm_tool.py +16 -41
  34. hanzo_mcp/tools/agent/swarm_tool_v1_deprecated.py +11 -39
  35. hanzo_mcp/tools/agent/unified_cli_tools.py +38 -38
  36. hanzo_mcp/tools/common/batch_tool.py +15 -45
  37. hanzo_mcp/tools/common/config_tool.py +9 -28
  38. hanzo_mcp/tools/common/context.py +1 -3
  39. hanzo_mcp/tools/common/critic_tool.py +1 -3
  40. hanzo_mcp/tools/common/decorators.py +2 -6
  41. hanzo_mcp/tools/common/enhanced_base.py +2 -6
  42. hanzo_mcp/tools/common/fastmcp_pagination.py +4 -12
  43. hanzo_mcp/tools/common/forgiving_edit.py +9 -28
  44. hanzo_mcp/tools/common/mode.py +1 -5
  45. hanzo_mcp/tools/common/paginated_base.py +3 -11
  46. hanzo_mcp/tools/common/paginated_response.py +10 -30
  47. hanzo_mcp/tools/common/pagination.py +3 -9
  48. hanzo_mcp/tools/common/permissions.py +3 -9
  49. hanzo_mcp/tools/common/personality.py +9 -34
  50. hanzo_mcp/tools/common/plugin_loader.py +3 -15
  51. hanzo_mcp/tools/common/stats.py +7 -19
  52. hanzo_mcp/tools/common/thinking_tool.py +1 -3
  53. hanzo_mcp/tools/common/tool_disable.py +2 -6
  54. hanzo_mcp/tools/common/tool_list.py +2 -6
  55. hanzo_mcp/tools/common/validation.py +1 -3
  56. hanzo_mcp/tools/config/config_tool.py +7 -13
  57. hanzo_mcp/tools/config/index_config.py +1 -3
  58. hanzo_mcp/tools/config/mode_tool.py +5 -15
  59. hanzo_mcp/tools/database/database_manager.py +3 -9
  60. hanzo_mcp/tools/database/graph.py +1 -3
  61. hanzo_mcp/tools/database/graph_add.py +3 -9
  62. hanzo_mcp/tools/database/graph_query.py +11 -34
  63. hanzo_mcp/tools/database/graph_remove.py +3 -9
  64. hanzo_mcp/tools/database/graph_search.py +6 -20
  65. hanzo_mcp/tools/database/graph_stats.py +11 -33
  66. hanzo_mcp/tools/database/sql.py +4 -12
  67. hanzo_mcp/tools/database/sql_query.py +6 -10
  68. hanzo_mcp/tools/database/sql_search.py +2 -6
  69. hanzo_mcp/tools/database/sql_stats.py +5 -15
  70. hanzo_mcp/tools/editor/neovim_command.py +1 -3
  71. hanzo_mcp/tools/editor/neovim_session.py +7 -13
  72. hanzo_mcp/tools/filesystem/__init__.py +2 -3
  73. hanzo_mcp/tools/filesystem/ast_multi_edit.py +14 -43
  74. hanzo_mcp/tools/filesystem/base.py +4 -12
  75. hanzo_mcp/tools/filesystem/batch_search.py +35 -115
  76. hanzo_mcp/tools/filesystem/content_replace.py +4 -12
  77. hanzo_mcp/tools/filesystem/diff.py +2 -10
  78. hanzo_mcp/tools/filesystem/directory_tree.py +9 -27
  79. hanzo_mcp/tools/filesystem/directory_tree_paginated.py +5 -15
  80. hanzo_mcp/tools/filesystem/edit.py +6 -18
  81. hanzo_mcp/tools/filesystem/find.py +3 -9
  82. hanzo_mcp/tools/filesystem/find_files.py +2 -6
  83. hanzo_mcp/tools/filesystem/git_search.py +9 -24
  84. hanzo_mcp/tools/filesystem/grep.py +9 -27
  85. hanzo_mcp/tools/filesystem/multi_edit.py +6 -18
  86. hanzo_mcp/tools/filesystem/read.py +8 -26
  87. hanzo_mcp/tools/filesystem/rules_tool.py +6 -17
  88. hanzo_mcp/tools/filesystem/search_tool.py +18 -62
  89. hanzo_mcp/tools/filesystem/symbols_tool.py +5 -15
  90. hanzo_mcp/tools/filesystem/tree.py +1 -3
  91. hanzo_mcp/tools/filesystem/watch.py +1 -3
  92. hanzo_mcp/tools/filesystem/write.py +1 -3
  93. hanzo_mcp/tools/jupyter/base.py +6 -20
  94. hanzo_mcp/tools/jupyter/jupyter.py +4 -12
  95. hanzo_mcp/tools/jupyter/notebook_edit.py +11 -35
  96. hanzo_mcp/tools/jupyter/notebook_read.py +2 -6
  97. hanzo_mcp/tools/llm/consensus_tool.py +8 -24
  98. hanzo_mcp/tools/llm/llm_manage.py +2 -6
  99. hanzo_mcp/tools/llm/llm_tool.py +17 -58
  100. hanzo_mcp/tools/llm/llm_unified.py +18 -59
  101. hanzo_mcp/tools/llm/provider_tools.py +1 -3
  102. hanzo_mcp/tools/lsp/lsp_tool.py +5 -17
  103. hanzo_mcp/tools/mcp/mcp_add.py +3 -5
  104. hanzo_mcp/tools/mcp/mcp_remove.py +1 -1
  105. hanzo_mcp/tools/mcp/mcp_stats.py +1 -3
  106. hanzo_mcp/tools/mcp/mcp_tool.py +9 -23
  107. hanzo_mcp/tools/memory/__init__.py +33 -40
  108. hanzo_mcp/tools/memory/knowledge_tools.py +7 -25
  109. hanzo_mcp/tools/memory/memory_tools.py +7 -19
  110. hanzo_mcp/tools/search/find_tool.py +10 -32
  111. hanzo_mcp/tools/search/unified_search.py +27 -81
  112. hanzo_mcp/tools/shell/__init__.py +2 -2
  113. hanzo_mcp/tools/shell/auto_background.py +2 -6
  114. hanzo_mcp/tools/shell/base.py +1 -5
  115. hanzo_mcp/tools/shell/base_process.py +5 -7
  116. hanzo_mcp/tools/shell/bash_session.py +7 -24
  117. hanzo_mcp/tools/shell/bash_session_executor.py +5 -15
  118. hanzo_mcp/tools/shell/bash_tool.py +3 -7
  119. hanzo_mcp/tools/shell/command_executor.py +26 -79
  120. hanzo_mcp/tools/shell/logs.py +4 -16
  121. hanzo_mcp/tools/shell/npx.py +2 -8
  122. hanzo_mcp/tools/shell/npx_tool.py +1 -3
  123. hanzo_mcp/tools/shell/pkill.py +4 -12
  124. hanzo_mcp/tools/shell/process_tool.py +2 -8
  125. hanzo_mcp/tools/shell/processes.py +5 -17
  126. hanzo_mcp/tools/shell/run_background.py +1 -3
  127. hanzo_mcp/tools/shell/run_command.py +1 -3
  128. hanzo_mcp/tools/shell/run_command_windows.py +1 -3
  129. hanzo_mcp/tools/shell/session_manager.py +2 -6
  130. hanzo_mcp/tools/shell/session_storage.py +2 -6
  131. hanzo_mcp/tools/shell/streaming_command.py +7 -23
  132. hanzo_mcp/tools/shell/uvx.py +4 -14
  133. hanzo_mcp/tools/shell/uvx_background.py +2 -6
  134. hanzo_mcp/tools/shell/uvx_tool.py +1 -3
  135. hanzo_mcp/tools/shell/zsh_tool.py +12 -20
  136. hanzo_mcp/tools/todo/todo.py +1 -3
  137. hanzo_mcp/tools/todo/todo_read.py +3 -9
  138. hanzo_mcp/tools/todo/todo_write.py +6 -18
  139. hanzo_mcp/tools/vector/__init__.py +3 -9
  140. hanzo_mcp/tools/vector/ast_analyzer.py +6 -20
  141. hanzo_mcp/tools/vector/git_ingester.py +10 -30
  142. hanzo_mcp/tools/vector/index_tool.py +3 -9
  143. hanzo_mcp/tools/vector/infinity_store.py +11 -30
  144. hanzo_mcp/tools/vector/mock_infinity.py +159 -0
  145. hanzo_mcp/tools/vector/project_manager.py +4 -12
  146. hanzo_mcp/tools/vector/vector.py +2 -6
  147. hanzo_mcp/tools/vector/vector_index.py +8 -8
  148. hanzo_mcp/tools/vector/vector_search.py +7 -21
  149. {hanzo_mcp-0.8.8.dist-info → hanzo_mcp-0.8.13.dist-info}/METADATA +2 -2
  150. hanzo_mcp-0.8.13.dist-info/RECORD +193 -0
  151. hanzo_mcp-0.8.8.dist-info/RECORD +0 -192
  152. {hanzo_mcp-0.8.8.dist-info → hanzo_mcp-0.8.13.dist-info}/WHEEL +0 -0
  153. {hanzo_mcp-0.8.8.dist-info → hanzo_mcp-0.8.13.dist-info}/entry_points.txt +0 -0
  154. {hanzo_mcp-0.8.8.dist-info → hanzo_mcp-0.8.13.dist-info}/top_level.txt +0 -0
hanzo_mcp/__init__.py CHANGED
@@ -16,9 +16,7 @@ import os
16
16
  import warnings
17
17
 
18
18
  # Suppress litellm deprecation warnings about event loop
19
- warnings.filterwarnings(
20
- "ignore", message="There is no current event loop", category=DeprecationWarning
21
- )
19
+ warnings.filterwarnings("ignore", message="There is no current event loop", category=DeprecationWarning)
22
20
 
23
21
  if os.environ.get("HANZO_MCP_TRANSPORT") == "stdio":
24
22
  try:
@@ -16,7 +16,6 @@ import traceback
16
16
  from typing import Any, Dict, TypeVar, Callable, Optional
17
17
  from datetime import datetime
18
18
  from dataclasses import dataclass
19
- from importlib.metadata import version, PackageNotFoundError
20
19
 
21
20
  # Try to import PostHog, but make it optional
22
21
  try:
@@ -27,12 +26,6 @@ except ImportError:
27
26
  POSTHOG_AVAILABLE = False
28
27
  Posthog = None
29
28
 
30
- # Get package version
31
- try:
32
- MCP_VERSION = version("hanzo-mcp")
33
- except PackageNotFoundError:
34
- MCP_VERSION = "0.8.7" # Fallback version
35
-
36
29
 
37
30
  F = TypeVar("F", bound=Callable[..., Any])
38
31
 
@@ -105,7 +98,7 @@ class Analytics:
105
98
  "timestamp": datetime.utcnow().isoformat(),
106
99
  "platform": platform.system(),
107
100
  "python_version": platform.python_version(),
108
- "mcp_version": MCP_VERSION,
101
+ "mcp_version": "0.6.13", # TODO: Get from package
109
102
  **(properties or {}),
110
103
  }
111
104
 
@@ -144,9 +137,7 @@ class Analytics:
144
137
 
145
138
  self.capture("tool_used", properties)
146
139
 
147
- def track_error(
148
- self, error: Exception, context: Optional[Dict[str, Any]] = None
149
- ) -> None:
140
+ def track_error(self, error: Exception, context: Optional[Dict[str, Any]] = None) -> None:
150
141
  """Track an error event."""
151
142
  if not self.config.capture_errors:
152
143
  return
@@ -166,9 +157,7 @@ class Analytics:
166
157
  return default
167
158
 
168
159
  try:
169
- return self._client.feature_enabled(
170
- flag_key, self.config.distinct_id, default=default
171
- )
160
+ return self._client.feature_enabled(flag_key, self.config.distinct_id, default=default)
172
161
  except Exception:
173
162
  return default
174
163
 
@@ -178,9 +167,7 @@ class Analytics:
178
167
  return default
179
168
 
180
169
  try:
181
- return self._client.get_feature_flag(
182
- flag_key, self.config.distinct_id, default=default
183
- )
170
+ return self._client.get_feature_flag(flag_key, self.config.distinct_id, default=default)
184
171
  except Exception:
185
172
  return default
186
173
 
hanzo_mcp/bridge.py CHANGED
@@ -134,9 +134,7 @@ class ClaudeBridge(FastMCP):
134
134
  """
135
135
  logger.info(f"Bridge {self.config.instance_id}: Task delegation")
136
136
 
137
- delegation_prompt = self._build_delegation_prompt(
138
- task, requirements, constraints
139
- )
137
+ delegation_prompt = self._build_delegation_prompt(task, requirements, constraints)
140
138
  result = await self._forward_to_claude(delegation_prompt)
141
139
 
142
140
  return {
@@ -178,9 +176,7 @@ class ClaudeBridge(FastMCP):
178
176
  }
179
177
 
180
178
  @self.tool()
181
- async def share_context_with_claude(
182
- key: str, value: Any, description: Optional[str] = None
183
- ) -> bool:
179
+ async def share_context_with_claude(key: str, value: Any, description: Optional[str] = None) -> bool:
184
180
  """Share context with another Claude instance.
185
181
 
186
182
  Args:
@@ -263,9 +259,7 @@ class ClaudeBridge(FastMCP):
263
259
  "shared_context_keys": list(self.shared_context.keys()),
264
260
  }
265
261
 
266
- def _build_review_prompt(
267
- self, code: str, description: str, focus_areas: Optional[List[str]]
268
- ) -> str:
262
+ def _build_review_prompt(self, code: str, description: str, focus_areas: Optional[List[str]]) -> str:
269
263
  """Build a code review prompt."""
270
264
  prompt = f"""
271
265
  Please review the following code:
@@ -293,9 +287,7 @@ class ClaudeBridge(FastMCP):
293
287
 
294
288
  return prompt
295
289
 
296
- def _build_delegation_prompt(
297
- self, task: str, requirements: List[str], constraints: Optional[List[str]]
298
- ) -> str:
290
+ def _build_delegation_prompt(self, task: str, requirements: List[str], constraints: Optional[List[str]]) -> str:
299
291
  """Build a task delegation prompt."""
300
292
  prompt = f"""
301
293
  Please complete the following task:
@@ -320,9 +312,7 @@ class ClaudeBridge(FastMCP):
320
312
 
321
313
  return prompt
322
314
 
323
- def _build_opinion_prompt(
324
- self, question: str, options: Optional[List[str]], criteria: Optional[List[str]]
325
- ) -> str:
315
+ def _build_opinion_prompt(self, question: str, options: Optional[List[str]], criteria: Optional[List[str]]) -> str:
326
316
  """Build an opinion request prompt."""
327
317
  prompt = f"""
328
318
  I need your opinion on the following:
@@ -334,7 +324,7 @@ class ClaudeBridge(FastMCP):
334
324
  prompt += f"""
335
325
 
336
326
  Options to consider:
337
- {chr(10).join(f"{i+1}. {opt}" for i, opt in enumerate(options))}
327
+ {chr(10).join(f"{i + 1}. {opt}" for i, opt in enumerate(options))}
338
328
  """
339
329
 
340
330
  if criteria:
@@ -351,9 +341,7 @@ class ClaudeBridge(FastMCP):
351
341
 
352
342
  return prompt
353
343
 
354
- async def _forward_to_claude(
355
- self, prompt: str, context: Optional[str] = None
356
- ) -> str:
344
+ async def _forward_to_claude(self, prompt: str, context: Optional[str] = None) -> str:
357
345
  """Forward a request to the target Claude instance.
358
346
 
359
347
  In production, this would make an actual API call to the Claude instance.
@@ -365,9 +353,7 @@ class ClaudeBridge(FastMCP):
365
353
  full_prompt = f"Context: {context}\n\n{prompt}"
366
354
 
367
355
  # Log the forwarding
368
- logger.info(
369
- f"Forwarding from instance {self.config.source_instance} to {self.config.target_instance}"
370
- )
356
+ logger.info(f"Forwarding from instance {self.config.source_instance} to {self.config.target_instance}")
371
357
  logger.debug(f"Prompt: {full_prompt[:200]}...")
372
358
 
373
359
  # In production, this would:
@@ -440,9 +426,7 @@ async def run_bridge_server(config: BridgeConfig):
440
426
 
441
427
  def main():
442
428
  """Main entry point for the bridge."""
443
- parser = argparse.ArgumentParser(
444
- description="MCP Bridge for Claude-to-Claude communication"
445
- )
429
+ parser = argparse.ArgumentParser(description="MCP Bridge for Claude-to-Claude communication")
446
430
  parser.add_argument(
447
431
  "--target-port",
448
432
  type=int,
hanzo_mcp/cli.py CHANGED
@@ -62,13 +62,12 @@ def main() -> None:
62
62
  # Avoid importing hanzo_mcp package just to get version (it can have side-effects).
63
63
  try:
64
64
  from importlib.metadata import version as _pkg_version # py3.8+
65
+
65
66
  _version = _pkg_version("hanzo-mcp")
66
67
  except Exception:
67
68
  _version = "unknown"
68
69
 
69
- parser = argparse.ArgumentParser(
70
- description="MCP server implementing Hanzo AI capabilities"
71
- )
70
+ parser = argparse.ArgumentParser(description="MCP server implementing Hanzo AI capabilities")
72
71
 
73
72
  parser.add_argument("--version", action="version", version=f"hanzo-mcp {_version}")
74
73
 
@@ -242,12 +241,8 @@ def main() -> None:
242
241
  port: int = cast(int, args.port)
243
242
  log_level: str = cast(str, args.log_level)
244
243
  project_dir: str | None = cast(str | None, args.project_dir)
245
- allowed_paths: list[str] = (
246
- cast(list[str], args.allowed_paths) if args.allowed_paths else []
247
- )
248
- project_paths: list[str] = (
249
- cast(list[str], args.project_paths) if args.project_paths else []
250
- )
244
+ allowed_paths: list[str] = cast(list[str], args.allowed_paths) if args.allowed_paths else []
245
+ project_paths: list[str] = cast(list[str], args.project_paths) if args.project_paths else []
251
246
 
252
247
  # Handle project_dir parameter (add to both allowed_paths and project_paths)
253
248
  if project_dir:
@@ -257,9 +252,7 @@ def main() -> None:
257
252
  project_paths.append(project_dir)
258
253
 
259
254
  if install:
260
- install_claude_desktop_config(
261
- name, allowed_paths, disable_write_tools, disable_search_tools, host, port
262
- )
255
+ install_claude_desktop_config(name, allowed_paths, disable_write_tools, disable_search_tools, host, port)
263
256
  return
264
257
 
265
258
  # Get logger
@@ -288,9 +281,9 @@ def main() -> None:
288
281
  format="%(asctime)s - %(name)s - %(levelname)s - %(message)s",
289
282
  )
290
283
 
291
- # If no allowed paths are specified, use the current directory
284
+ # If no allowed paths are specified, use the home directory
292
285
  if not allowed_paths:
293
- allowed_paths = [os.getcwd()]
286
+ allowed_paths = [os.path.expanduser("~")]
294
287
 
295
288
  # Run in dev mode if requested
296
289
  if dev:
@@ -404,9 +397,7 @@ def install_claude_desktop_config(
404
397
  args.append("--disable-search-tools")
405
398
 
406
399
  # Create config object
407
- config: dict[str, Any] = {
408
- "mcpServers": {name: {"command": script_path.as_posix(), "args": args}}
409
- }
400
+ config: dict[str, Any] = {"mcpServers": {name: {"command": script_path.as_posix(), "args": args}}}
410
401
 
411
402
  # Check if the file already exists
412
403
  if config_file.exists():
hanzo_mcp/cli_enhanced.py CHANGED
@@ -344,10 +344,7 @@ def apply_cli_overrides(args: argparse.Namespace) -> Dict[str, Any]:
344
344
  vector_config["enabled"] = True
345
345
  if hasattr(args, "vector_store_path") and args.vector_store_path:
346
346
  vector_config["data_path"] = args.vector_store_path
347
- if (
348
- hasattr(args, "embedding_model")
349
- and args.embedding_model != "text-embedding-3-small"
350
- ):
347
+ if hasattr(args, "embedding_model") and args.embedding_model != "text-embedding-3-small":
351
348
  vector_config["embedding_model"] = args.embedding_model
352
349
 
353
350
  if vector_config:
@@ -380,9 +377,7 @@ def list_tools(settings: HanzoMCPSettings) -> None:
380
377
 
381
378
  logger.info(f"\nTotal: {len(TOOL_REGISTRY)} tools")
382
379
  enabled_count = len(settings.get_enabled_tools())
383
- logger.info(
384
- f"Enabled: {enabled_count}, Disabled: {len(TOOL_REGISTRY) - enabled_count}"
385
- )
380
+ logger.info(f"Enabled: {enabled_count}, Disabled: {len(TOOL_REGISTRY) - enabled_count}")
386
381
 
387
382
 
388
383
  def main() -> None:
@@ -442,15 +437,11 @@ def main() -> None:
442
437
  agent_base_url=settings.agent.base_url,
443
438
  agent_max_iterations=settings.agent.max_iterations,
444
439
  agent_max_tool_uses=settings.agent.max_tool_uses,
445
- enable_agent_tool=settings.agent.enabled
446
- or settings.is_tool_enabled("dispatch_agent"),
440
+ enable_agent_tool=settings.agent.enabled or settings.is_tool_enabled("dispatch_agent"),
447
441
  disable_write_tools=not any(
448
- settings.is_tool_enabled(t)
449
- for t in ["write", "edit", "multi_edit", "content_replace"]
450
- ),
451
- disable_search_tools=not any(
452
- settings.is_tool_enabled(t) for t in ["grep", "grep_ast"]
442
+ settings.is_tool_enabled(t) for t in ["write", "edit", "multi_edit", "content_replace"]
453
443
  ),
444
+ disable_search_tools=not any(settings.is_tool_enabled(t) for t in ["grep", "grep_ast"]),
454
445
  host=settings.server.host,
455
446
  port=settings.server.port,
456
447
  enabled_tools=settings.enabled_tools, # Pass individual tool configuration
hanzo_mcp/cli_plugin.py CHANGED
@@ -53,9 +53,7 @@ Examples:
53
53
  create_plugin_template(output_dir, args.name)
54
54
  print(f"\n✅ Plugin template created successfully!")
55
55
  print(f"\nTo use your plugin:")
56
- print(
57
- f"1. Edit the tool implementation in {output_dir / f'{args.name}_tool.py'}"
58
- )
56
+ print(f"1. Edit the tool implementation in {output_dir / f'{args.name}_tool.py'}")
59
57
  print(f"2. Restart Hanzo MCP to load the plugin")
60
58
  print(f"3. Add '{args.name}' to your mode's tool list")
61
59
  except Exception as e:
@@ -81,13 +79,9 @@ Examples:
81
79
  print(f"\n {name}:")
82
80
  print(f" Source: {plugin.source_path}")
83
81
  if plugin.metadata:
84
- print(
85
- f" Version: {plugin.metadata.get('version', 'unknown')}"
86
- )
82
+ print(f" Version: {plugin.metadata.get('version', 'unknown')}")
87
83
  print(f" Author: {plugin.metadata.get('author', 'unknown')}")
88
- print(
89
- f" Description: {plugin.metadata.get('description', '')}"
90
- )
84
+ print(f" Description: {plugin.metadata.get('description', '')}")
91
85
  except Exception as e:
92
86
  print(f"❌ Error listing plugins: {e}", file=sys.stderr)
93
87
  sys.exit(1)
@@ -53,9 +53,7 @@ class ProjectConfig:
53
53
  tasks: List[Dict[str, Any]] = field(default_factory=list)
54
54
  enabled_tools: Dict[str, bool] = field(default_factory=dict)
55
55
  disabled_tools: List[str] = field(default_factory=list)
56
- mcp_servers: List[str] = field(
57
- default_factory=list
58
- ) # Names of enabled MCP servers for this project
56
+ mcp_servers: List[str] = field(default_factory=list) # Names of enabled MCP servers for this project
59
57
 
60
58
 
61
59
  @dataclass
@@ -109,9 +107,7 @@ class HanzoMCPSettings:
109
107
  # MCP Hub configuration
110
108
  mcp_servers: Dict[str, MCPServerConfig] = field(default_factory=dict)
111
109
  hub_enabled: bool = False
112
- trusted_servers: List[str] = field(
113
- default_factory=list
114
- ) # Whitelist of trusted server names
110
+ trusted_servers: List[str] = field(default_factory=list) # Whitelist of trusted server names
115
111
 
116
112
  # Project-specific configurations
117
113
  projects: Dict[str, ProjectConfig] = field(default_factory=dict)
@@ -123,9 +119,7 @@ class HanzoMCPSettings:
123
119
  def __post_init__(self):
124
120
  """Initialize default tool states if not specified."""
125
121
  if not self.enabled_tools:
126
- self.enabled_tools = {
127
- name: config.enabled for name, config in TOOL_REGISTRY.items()
128
- }
122
+ self.enabled_tools = {name: config.enabled for name, config in TOOL_REGISTRY.items()}
129
123
 
130
124
  # Apply disabled_tools list to enabled_tools dict
131
125
  for tool_name in self.disabled_tools:
@@ -139,9 +133,7 @@ class HanzoMCPSettings:
139
133
  return False
140
134
  return self.enabled_tools.get(
141
135
  tool_name,
142
- TOOL_REGISTRY.get(
143
- tool_name, type("obj", (object,), {"enabled": False})
144
- ).enabled,
136
+ TOOL_REGISTRY.get(tool_name, type("obj", (object,), {"enabled": False})).enabled,
145
137
  )
146
138
 
147
139
  def enable_tool(self, tool_name: str) -> bool:
@@ -399,11 +391,7 @@ def _load_from_env() -> Dict[str, Any]:
399
391
  config.setdefault("agent", {})["enabled"] = True
400
392
 
401
393
  # Check for MODE/PERSONALITY/HANZO_MODE
402
- if (
403
- mode := os.environ.get("HANZO_MODE")
404
- or os.environ.get("PERSONALITY")
405
- or os.environ.get("MODE")
406
- ):
394
+ if mode := os.environ.get("HANZO_MODE") or os.environ.get("PERSONALITY") or os.environ.get("MODE"):
407
395
  config["active_mode"] = mode
408
396
 
409
397
  # Check for other environment overrides
@@ -496,9 +484,7 @@ def save_settings(settings: HanzoMCPSettings, global_config: bool = True) -> Pat
496
484
  return config_path
497
485
 
498
486
 
499
- def _merge_config(
500
- base_settings: HanzoMCPSettings, config_dict: Dict[str, Any]
501
- ) -> HanzoMCPSettings:
487
+ def _merge_config(base_settings: HanzoMCPSettings, config_dict: Dict[str, Any]) -> HanzoMCPSettings:
502
488
  """Merge configuration dictionary into settings object."""
503
489
  # Convert to dict, merge, then convert back
504
490
  base_dict = asdict(base_settings)
@@ -105,7 +105,7 @@ TOOL_REGISTRY: Dict[str, ToolConfig] = {
105
105
  description="Edit Jupyter notebook cells (replace, insert, delete)",
106
106
  cli_flag="--disable-notebook-edit",
107
107
  ),
108
- # Task Management Tools (2)
108
+ # Todo Tools (2)
109
109
  "todo_read": ToolConfig(
110
110
  name="todo_read",
111
111
  category=ToolCategory.TODO,
@@ -204,6 +204,4 @@ def disable_tool(tool_name: str) -> bool:
204
204
 
205
205
  def is_tool_enabled(tool_name: str) -> bool:
206
206
  """Check if a tool is enabled."""
207
- return TOOL_REGISTRY.get(
208
- tool_name, ToolConfig("", ToolCategory.COMMON, False)
209
- ).enabled
207
+ return TOOL_REGISTRY.get(tool_name, ToolConfig("", ToolCategory.COMMON, False)).enabled