hanzo-mcp 0.8.11__py3-none-any.whl → 0.8.14__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 +2 -4
  2. hanzo_mcp/analytics/posthog_analytics.py +3 -9
  3. hanzo_mcp/bridge.py +9 -25
  4. hanzo_mcp/cli.py +6 -15
  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 +1 -3
  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 +13 -6
  17. hanzo_mcp/tools/__init__.py +10 -24
  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 +5 -15
  21. hanzo_mcp/tools/agent/agent_tool_v1_deprecated.py +14 -41
  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 +75 -74
  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 +9 -29
  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 +38 -11
  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 +6 -18
  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_edit.py +2 -2
  72. hanzo_mcp/tools/editor/neovim_session.py +7 -13
  73. hanzo_mcp/tools/filesystem/__init__.py +2 -3
  74. hanzo_mcp/tools/filesystem/ast_multi_edit.py +14 -43
  75. hanzo_mcp/tools/filesystem/base.py +4 -12
  76. hanzo_mcp/tools/filesystem/batch_search.py +35 -115
  77. hanzo_mcp/tools/filesystem/content_replace.py +4 -12
  78. hanzo_mcp/tools/filesystem/diff.py +2 -10
  79. hanzo_mcp/tools/filesystem/directory_tree.py +9 -27
  80. hanzo_mcp/tools/filesystem/directory_tree_paginated.py +5 -15
  81. hanzo_mcp/tools/filesystem/edit.py +6 -18
  82. hanzo_mcp/tools/filesystem/find.py +3 -9
  83. hanzo_mcp/tools/filesystem/find_files.py +2 -6
  84. hanzo_mcp/tools/filesystem/git_search.py +9 -24
  85. hanzo_mcp/tools/filesystem/grep.py +9 -27
  86. hanzo_mcp/tools/filesystem/multi_edit.py +6 -18
  87. hanzo_mcp/tools/filesystem/read.py +8 -26
  88. hanzo_mcp/tools/filesystem/rules_tool.py +6 -17
  89. hanzo_mcp/tools/filesystem/search_tool.py +18 -62
  90. hanzo_mcp/tools/filesystem/symbols_tool.py +5 -15
  91. hanzo_mcp/tools/filesystem/tree.py +1 -3
  92. hanzo_mcp/tools/filesystem/watch.py +1 -3
  93. hanzo_mcp/tools/filesystem/write.py +1 -3
  94. hanzo_mcp/tools/jupyter/base.py +6 -20
  95. hanzo_mcp/tools/jupyter/jupyter.py +4 -12
  96. hanzo_mcp/tools/jupyter/notebook_edit.py +11 -35
  97. hanzo_mcp/tools/jupyter/notebook_read.py +2 -6
  98. hanzo_mcp/tools/llm/consensus_tool.py +8 -24
  99. hanzo_mcp/tools/llm/llm_manage.py +2 -6
  100. hanzo_mcp/tools/llm/llm_tool.py +17 -58
  101. hanzo_mcp/tools/llm/llm_unified.py +18 -59
  102. hanzo_mcp/tools/llm/provider_tools.py +1 -3
  103. hanzo_mcp/tools/lsp/lsp_tool.py +5 -17
  104. hanzo_mcp/tools/mcp/mcp_add.py +1 -3
  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 +10 -27
  108. hanzo_mcp/tools/memory/knowledge_tools.py +7 -25
  109. hanzo_mcp/tools/memory/memory_tools.py +6 -18
  110. hanzo_mcp/tools/search/find_tool.py +10 -32
  111. hanzo_mcp/tools/search/unified_search.py +24 -78
  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 +33 -86
  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 +7 -27
  144. hanzo_mcp/tools/vector/mock_infinity.py +1 -3
  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.11.dist-info → hanzo_mcp-0.8.14.dist-info}/METADATA +2 -2
  150. hanzo_mcp-0.8.14.dist-info/RECORD +193 -0
  151. hanzo_mcp-0.8.11.dist-info/RECORD +0 -193
  152. {hanzo_mcp-0.8.11.dist-info → hanzo_mcp-0.8.14.dist-info}/WHEEL +0 -0
  153. {hanzo_mcp-0.8.11.dist-info → hanzo_mcp-0.8.14.dist-info}/entry_points.txt +0 -0
  154. {hanzo_mcp-0.8.11.dist-info → hanzo_mcp-0.8.14.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:
@@ -28,4 +26,4 @@ if os.environ.get("HANZO_MCP_TRANSPORT") == "stdio":
28
26
  except ImportError:
29
27
  pass
30
28
 
31
- __version__ = "0.8.4"
29
+ __version__ = "0.8.13"
@@ -137,9 +137,7 @@ class Analytics:
137
137
 
138
138
  self.capture("tool_used", properties)
139
139
 
140
- def track_error(
141
- self, error: Exception, context: Optional[Dict[str, Any]] = None
142
- ) -> None:
140
+ def track_error(self, error: Exception, context: Optional[Dict[str, Any]] = None) -> None:
143
141
  """Track an error event."""
144
142
  if not self.config.capture_errors:
145
143
  return
@@ -159,9 +157,7 @@ class Analytics:
159
157
  return default
160
158
 
161
159
  try:
162
- return self._client.feature_enabled(
163
- flag_key, self.config.distinct_id, default=default
164
- )
160
+ return self._client.feature_enabled(flag_key, self.config.distinct_id, default=default)
165
161
  except Exception:
166
162
  return default
167
163
 
@@ -171,9 +167,7 @@ class Analytics:
171
167
  return default
172
168
 
173
169
  try:
174
- return self._client.get_feature_flag(
175
- flag_key, self.config.distinct_id, default=default
176
- )
170
+ return self._client.get_feature_flag(flag_key, self.config.distinct_id, default=default)
177
171
  except Exception:
178
172
  return default
179
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
@@ -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)
@@ -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