hanzo-mcp 0.8.11__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 (153) hide show
  1. hanzo_mcp/__init__.py +1 -3
  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 +2 -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 +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 +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_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 +1 -3
  104. hanzo_mcp/tools/mcp/mcp_stats.py +1 -3
  105. hanzo_mcp/tools/mcp/mcp_tool.py +9 -23
  106. hanzo_mcp/tools/memory/__init__.py +10 -27
  107. hanzo_mcp/tools/memory/knowledge_tools.py +7 -25
  108. hanzo_mcp/tools/memory/memory_tools.py +6 -18
  109. hanzo_mcp/tools/search/find_tool.py +10 -32
  110. hanzo_mcp/tools/search/unified_search.py +24 -78
  111. hanzo_mcp/tools/shell/__init__.py +2 -2
  112. hanzo_mcp/tools/shell/auto_background.py +2 -6
  113. hanzo_mcp/tools/shell/base.py +1 -5
  114. hanzo_mcp/tools/shell/base_process.py +5 -7
  115. hanzo_mcp/tools/shell/bash_session.py +7 -24
  116. hanzo_mcp/tools/shell/bash_session_executor.py +5 -15
  117. hanzo_mcp/tools/shell/bash_tool.py +3 -7
  118. hanzo_mcp/tools/shell/command_executor.py +26 -79
  119. hanzo_mcp/tools/shell/logs.py +4 -16
  120. hanzo_mcp/tools/shell/npx.py +2 -8
  121. hanzo_mcp/tools/shell/npx_tool.py +1 -3
  122. hanzo_mcp/tools/shell/pkill.py +4 -12
  123. hanzo_mcp/tools/shell/process_tool.py +2 -8
  124. hanzo_mcp/tools/shell/processes.py +5 -17
  125. hanzo_mcp/tools/shell/run_background.py +1 -3
  126. hanzo_mcp/tools/shell/run_command.py +1 -3
  127. hanzo_mcp/tools/shell/run_command_windows.py +1 -3
  128. hanzo_mcp/tools/shell/session_manager.py +2 -6
  129. hanzo_mcp/tools/shell/session_storage.py +2 -6
  130. hanzo_mcp/tools/shell/streaming_command.py +7 -23
  131. hanzo_mcp/tools/shell/uvx.py +4 -14
  132. hanzo_mcp/tools/shell/uvx_background.py +2 -6
  133. hanzo_mcp/tools/shell/uvx_tool.py +1 -3
  134. hanzo_mcp/tools/shell/zsh_tool.py +12 -20
  135. hanzo_mcp/tools/todo/todo.py +1 -3
  136. hanzo_mcp/tools/todo/todo_read.py +3 -9
  137. hanzo_mcp/tools/todo/todo_write.py +6 -18
  138. hanzo_mcp/tools/vector/__init__.py +3 -9
  139. hanzo_mcp/tools/vector/ast_analyzer.py +6 -20
  140. hanzo_mcp/tools/vector/git_ingester.py +10 -30
  141. hanzo_mcp/tools/vector/index_tool.py +3 -9
  142. hanzo_mcp/tools/vector/infinity_store.py +7 -27
  143. hanzo_mcp/tools/vector/mock_infinity.py +1 -3
  144. hanzo_mcp/tools/vector/project_manager.py +4 -12
  145. hanzo_mcp/tools/vector/vector.py +2 -6
  146. hanzo_mcp/tools/vector/vector_index.py +8 -8
  147. hanzo_mcp/tools/vector/vector_search.py +7 -21
  148. {hanzo_mcp-0.8.11.dist-info → hanzo_mcp-0.8.13.dist-info}/METADATA +2 -2
  149. hanzo_mcp-0.8.13.dist-info/RECORD +193 -0
  150. hanzo_mcp-0.8.11.dist-info/RECORD +0 -193
  151. {hanzo_mcp-0.8.11.dist-info → hanzo_mcp-0.8.13.dist-info}/WHEEL +0 -0
  152. {hanzo_mcp-0.8.11.dist-info → hanzo_mcp-0.8.13.dist-info}/entry_points.txt +0 -0
  153. {hanzo_mcp-0.8.11.dist-info → hanzo_mcp-0.8.13.dist-info}/top_level.txt +0 -0
@@ -71,9 +71,7 @@ class ProviderToolParams(TypedDict, total=False):
71
71
  class BaseProviderTool(BaseTool):
72
72
  """Base class for provider-specific LLM tools."""
73
73
 
74
- def __init__(
75
- self, provider: str, default_model: str, model_variants: Dict[str, str]
76
- ):
74
+ def __init__(self, provider: str, default_model: str, model_variants: Dict[str, str]):
77
75
  """Initialize provider tool.
78
76
 
79
77
  Args:
@@ -297,9 +297,7 @@ class LSPTool(BaseTool):
297
297
  self.logger.error(f"Installation error: {e}")
298
298
  return False
299
299
 
300
- async def _ensure_lsp_running(
301
- self, language: str, root_uri: str
302
- ) -> Optional[LSPServer]:
300
+ async def _ensure_lsp_running(self, language: str, root_uri: str) -> Optional[LSPServer]:
303
301
  """Ensure LSP server is running for language."""
304
302
  # Check if already running
305
303
  server_key = f"{language}:{root_uri}"
@@ -326,9 +324,7 @@ class LSPTool(BaseTool):
326
324
  cwd=root_uri,
327
325
  )
328
326
 
329
- server = LSPServer(
330
- language=language, process=process, config=config, root_uri=root_uri
331
- )
327
+ server = LSPServer(language=language, process=process, config=config, root_uri=root_uri)
332
328
 
333
329
  # Initialize LSP
334
330
  await self._initialize_lsp(server)
@@ -367,9 +363,7 @@ class LSPTool(BaseTool):
367
363
  await self._send_request(server, request)
368
364
  server.initialized = True
369
365
 
370
- async def _send_request(
371
- self, server: LSPServer, request: Dict[str, Any]
372
- ) -> Optional[Dict[str, Any]]:
366
+ async def _send_request(self, server: LSPServer, request: Dict[str, Any]) -> Optional[Dict[str, Any]]:
373
367
  """Send JSON-RPC request to LSP server."""
374
368
  if not server.process or server.process.returncode is not None:
375
369
  return None
@@ -426,11 +420,7 @@ class LSPTool(BaseTool):
426
420
  "status",
427
421
  ]
428
422
  if action not in valid_actions:
429
- return MCPResourceDocument(
430
- data={
431
- "error": f"Invalid action. Must be one of: {', '.join(valid_actions)}"
432
- }
433
- )
423
+ return MCPResourceDocument(data={"error": f"Invalid action. Must be one of: {', '.join(valid_actions)}"})
434
424
 
435
425
  # Get language from file
436
426
  language = self._get_language_from_file(file)
@@ -478,9 +468,7 @@ class LSPTool(BaseTool):
478
468
  )
479
469
 
480
470
  # Execute action
481
- result = await self._execute_lsp_action(
482
- server, action, file, line, character, new_name
483
- )
471
+ result = await self._execute_lsp_action(server, action, file, line, character, new_name)
484
472
 
485
473
  return MCPResourceDocument(data=result)
486
474
 
@@ -189,9 +189,7 @@ Use 'mcp_stats' to see all added servers and their status.
189
189
 
190
190
  full_command = shlex.split(command)
191
191
 
192
- await tool_ctx.info(
193
- f"Adding MCP server '{name}' with command: {' '.join(full_command)}"
194
- )
192
+ await tool_ctx.info(f"Adding MCP server '{name}' with command: {' '.join(full_command)}")
195
193
 
196
194
  # Create server configuration
197
195
  server_config = {
@@ -68,9 +68,7 @@ Example:
68
68
  servers = McpAddTool.get_servers()
69
69
 
70
70
  if not servers:
71
- return (
72
- "No MCP servers have been added yet.\n\nUse 'mcp_add' to add servers."
73
- )
71
+ return "No MCP servers have been added yet.\n\nUse 'mcp_add' to add servers."
74
72
 
75
73
  output = []
76
74
  output.append("=== MCP Server Statistics ===")
@@ -173,9 +173,7 @@ class MCPTool(BaseTool):
173
173
  def _auto_start_servers(self):
174
174
  """Auto-start servers configured for auto-start."""
175
175
  for name, server_config in self.config.get("servers", {}).items():
176
- if server_config.get("enabled", False) and server_config.get(
177
- "auto_start", False
178
- ):
176
+ if server_config.get("enabled", False) and server_config.get("auto_start", False):
179
177
  self._start_server(name, server_config)
180
178
 
181
179
  def _start_server(self, name: str, config: Dict[str, Any]) -> bool:
@@ -202,9 +200,7 @@ class MCPTool(BaseTool):
202
200
  cmd = [config["command"]] + config.get("args", [])
203
201
 
204
202
  # Create log directory
205
- log_dir = Path(
206
- self.config.get("log_dir", str(Path.home() / ".hanzo" / "mcp" / "logs"))
207
- )
203
+ log_dir = Path(self.config.get("log_dir", str(Path.home() / ".hanzo" / "mcp" / "logs")))
208
204
  log_dir.mkdir(parents=True, exist_ok=True)
209
205
 
210
206
  # Start process
@@ -307,11 +303,11 @@ Status: {enabled} enabled, {running} running"""
307
303
  elif action == "restart":
308
304
  return self._handle_restart(params.get("name"))
309
305
  elif action == "config":
310
- return self._handle_config(
311
- params.get("config_key"), params.get("config_value")
312
- )
306
+ return self._handle_config(params.get("config_key"), params.get("config_value"))
313
307
  else:
314
- return f"Error: Unknown action '{action}'. Valid actions: list, add, remove, enable, disable, restart, config"
308
+ return (
309
+ f"Error: Unknown action '{action}'. Valid actions: list, add, remove, enable, disable, restart, config"
310
+ )
315
311
 
316
312
  def _handle_list(self) -> str:
317
313
  """List all MCP servers."""
@@ -355,9 +351,7 @@ Status: {enabled} enabled, {running} running"""
355
351
  output.append(f"{name}: {status}")
356
352
  if config.get("description"):
357
353
  output.append(f" Description: {config['description']}")
358
- output.append(
359
- f" Command: {config['command']} {' '.join(config.get('args', []))}"
360
- )
354
+ output.append(f" Command: {config['command']} {' '.join(config.get('args', []))}")
361
355
 
362
356
  if config.get("env"):
363
357
  env_str = ", ".join([f"{k}={v}" for k, v in config["env"].items()])
@@ -498,11 +492,7 @@ Status: {enabled} enabled, {running} running"""
498
492
  else:
499
493
  return f"Configuration key '{key}' not found"
500
494
 
501
- return (
502
- json.dumps(current, indent=2)
503
- if isinstance(current, (dict, list))
504
- else str(current)
505
- )
495
+ return json.dumps(current, indent=2) if isinstance(current, (dict, list)) else str(current)
506
496
  else:
507
497
  # Set value
508
498
  # Navigate to parent
@@ -513,11 +503,7 @@ Status: {enabled} enabled, {running} running"""
513
503
  current = current[k]
514
504
 
515
505
  # Parse value if it looks like JSON
516
- if (
517
- isinstance(value, str)
518
- and value.startswith("{")
519
- or value.startswith("[")
520
- ):
506
+ if isinstance(value, str) and value.startswith("{") or value.startswith("["):
521
507
  try:
522
508
  value = json.loads(value)
523
509
  except Exception:
@@ -20,6 +20,7 @@ try:
20
20
  SummarizeToMemoryTool,
21
21
  ManageKnowledgeBasesTool,
22
22
  )
23
+
23
24
  MEMORY_TOOLS_AVAILABLE = True
24
25
  except ImportError:
25
26
  MEMORY_TOOLS_AVAILABLE = False
@@ -49,35 +50,17 @@ def register_memory_tools(
49
50
  return []
50
51
 
51
52
  # Create memory tools
52
- recall_tool = RecallMemoriesTool(
53
- user_id=user_id, project_id=project_id, **memory_config
54
- )
55
- create_tool = CreateMemoriesTool(
56
- user_id=user_id, project_id=project_id, **memory_config
57
- )
58
- update_tool = UpdateMemoriesTool(
59
- user_id=user_id, project_id=project_id, **memory_config
60
- )
61
- delete_tool = DeleteMemoriesTool(
62
- user_id=user_id, project_id=project_id, **memory_config
63
- )
64
- manage_tool = ManageMemoriesTool(
65
- user_id=user_id, project_id=project_id, **memory_config
66
- )
53
+ recall_tool = RecallMemoriesTool(user_id=user_id, project_id=project_id, **memory_config)
54
+ create_tool = CreateMemoriesTool(user_id=user_id, project_id=project_id, **memory_config)
55
+ update_tool = UpdateMemoriesTool(user_id=user_id, project_id=project_id, **memory_config)
56
+ delete_tool = DeleteMemoriesTool(user_id=user_id, project_id=project_id, **memory_config)
57
+ manage_tool = ManageMemoriesTool(user_id=user_id, project_id=project_id, **memory_config)
67
58
 
68
59
  # Create knowledge tools
69
- recall_facts_tool = RecallFactsTool(
70
- user_id=user_id, project_id=project_id, **memory_config
71
- )
72
- store_facts_tool = StoreFactsTool(
73
- user_id=user_id, project_id=project_id, **memory_config
74
- )
75
- summarize_tool = SummarizeToMemoryTool(
76
- user_id=user_id, project_id=project_id, **memory_config
77
- )
78
- manage_kb_tool = ManageKnowledgeBasesTool(
79
- user_id=user_id, project_id=project_id, **memory_config
80
- )
60
+ recall_facts_tool = RecallFactsTool(user_id=user_id, project_id=project_id, **memory_config)
61
+ store_facts_tool = StoreFactsTool(user_id=user_id, project_id=project_id, **memory_config)
62
+ summarize_tool = SummarizeToMemoryTool(user_id=user_id, project_id=project_id, **memory_config)
63
+ manage_kb_tool = ManageKnowledgeBasesTool(user_id=user_id, project_id=project_id, **memory_config)
81
64
 
82
65
  # Register tools
83
66
  ToolRegistry.register_tool(mcp_server, recall_tool)
@@ -140,15 +140,9 @@ recall_facts(queries=["company policies"], scope="global", limit=5)
140
140
  if fact.metadata and fact.metadata.get("kb_name"):
141
141
  kb_info = f" (KB: {fact.metadata['kb_name']})"
142
142
  formatted.append(f"{i}. {fact.content}{kb_info}")
143
- if (
144
- fact.metadata and len(fact.metadata) > 2
145
- ): # More than just type and kb_name
143
+ if fact.metadata and len(fact.metadata) > 2: # More than just type and kb_name
146
144
  # Show other metadata
147
- other_meta = {
148
- k: v
149
- for k, v in fact.metadata.items()
150
- if k not in ["type", "kb_name"]
151
- }
145
+ other_meta = {k: v for k, v in fact.metadata.items() if k not in ["type", "kb_name"]}
152
146
  if other_meta:
153
147
  formatted.append(f" Metadata: {other_meta}")
154
148
 
@@ -167,9 +161,7 @@ recall_facts(queries=["company policies"], scope="global", limit=5)
167
161
  scope: str = "project",
168
162
  limit: int = 10,
169
163
  ) -> str:
170
- return await tool_self.call(
171
- ctx, queries=queries, kb_name=kb_name, scope=scope, limit=limit
172
- )
164
+ return await tool_self.call(ctx, queries=queries, kb_name=kb_name, scope=scope, limit=limit)
173
165
 
174
166
 
175
167
  @final
@@ -265,9 +257,7 @@ store_facts(facts=["Company founded in 2020"], scope="global", kb_name="company_
265
257
  scope: str = "project",
266
258
  metadata: Optional[Dict[str, Any]] = None,
267
259
  ) -> str:
268
- return await tool_self.call(
269
- ctx, facts=facts, kb_name=kb_name, scope=scope, metadata=metadata
270
- )
260
+ return await tool_self.call(ctx, facts=facts, kb_name=kb_name, scope=scope, metadata=metadata)
271
261
 
272
262
 
273
263
  @final
@@ -323,11 +313,7 @@ summarize_to_memory(content="Company guidelines...", topic="Guidelines", scope="
323
313
 
324
314
  # Use the memory service to create a summary
325
315
  # This would typically use an LLM to summarize, but for now we'll store as-is
326
- summary = (
327
- f"Summary of {topic}:\n{content[:500]}..."
328
- if len(content) > 500
329
- else content
330
- )
316
+ summary = f"Summary of {topic}:\n{content[:500]}..." if len(content) > 500 else content
331
317
 
332
318
  # Store the summary as a memory
333
319
  from hanzo_memory.services.memory import get_memory_service
@@ -358,9 +344,7 @@ summarize_to_memory(content="Company guidelines...", topic="Guidelines", scope="
358
344
  if auto_facts:
359
345
  # In a real implementation, this would use LLM to extract key facts
360
346
  # For now, we'll just note it
361
- result += (
362
- "\n(Auto-fact extraction would extract key facts from the summary)"
363
- )
347
+ result += "\n(Auto-fact extraction would extract key facts from the summary)"
364
348
 
365
349
  return result
366
350
 
@@ -377,9 +361,7 @@ summarize_to_memory(content="Company guidelines...", topic="Guidelines", scope="
377
361
  scope: str = "project",
378
362
  auto_facts: bool = True,
379
363
  ) -> str:
380
- return await tool_self.call(
381
- ctx, content=content, topic=topic, scope=scope, auto_facts=auto_facts
382
- )
364
+ return await tool_self.call(ctx, content=content, topic=topic, scope=scope, auto_facts=auto_facts)
383
365
 
384
366
 
385
367
  @final
@@ -127,9 +127,7 @@ recall_memories(queries=["coding standards"], scope="global")
127
127
  tool_self = self
128
128
 
129
129
  @mcp_server.tool(name=self.name, description=self.description)
130
- async def recall_memories(
131
- ctx: MCPContext, queries: List[str], limit: int = 10, scope: str = "project"
132
- ) -> str:
130
+ async def recall_memories(ctx: MCPContext, queries: List[str], limit: int = 10, scope: str = "project") -> str:
133
131
  return await tool_self.call(ctx, queries=queries, limit=limit, scope=scope)
134
132
 
135
133
 
@@ -247,9 +245,7 @@ update_memories(updates=[
247
245
  # The hanzo-memory service doesn't have update implemented yet
248
246
  # When it's implemented, we would call:
249
247
  # success = self.service.update_memory(self.user_id, memory_id, content=statement)
250
- await tool_ctx.warning(
251
- f"Memory update not fully implemented in hanzo-memory yet: {memory_id}"
252
- )
248
+ await tool_ctx.warning(f"Memory update not fully implemented in hanzo-memory yet: {memory_id}")
253
249
  success_count += 1
254
250
 
255
251
  return f"Would update {success_count} of {len(updates)} memories (update not fully implemented in hanzo-memory yet)."
@@ -260,9 +256,7 @@ update_memories(updates=[
260
256
  tool_self = self
261
257
 
262
258
  @mcp_server.tool(name=self.name, description=self.description)
263
- async def update_memories(
264
- ctx: MCPContext, updates: List[Dict[str, str]]
265
- ) -> str:
259
+ async def update_memories(ctx: MCPContext, updates: List[Dict[str, str]]) -> str:
266
260
  return await tool_self.call(ctx, updates=updates)
267
261
 
268
262
 
@@ -398,13 +392,9 @@ manage_memories(
398
392
 
399
393
  if memory_id and statement:
400
394
  # Update not fully implemented in hanzo-memory yet
401
- await tool_ctx.warning(
402
- f"Memory update not fully implemented: {memory_id}"
403
- )
395
+ await tool_ctx.warning(f"Memory update not fully implemented: {memory_id}")
404
396
  success_count += 1
405
- results.append(
406
- f"Would update {success_count} memories (update pending implementation)"
407
- )
397
+ results.append(f"Would update {success_count} memories (update pending implementation)")
408
398
 
409
399
  # Delete memories
410
400
  if deletions:
@@ -433,6 +423,4 @@ manage_memories(
433
423
  updates: Optional[List[Dict[str, str]]] = None,
434
424
  deletions: Optional[List[str]] = None,
435
425
  ) -> str:
436
- return await tool_self.call(
437
- ctx, creations=creations, updates=updates, deletions=deletions
438
- )
426
+ return await tool_self.call(ctx, creations=creations, updates=updates, deletions=deletions)
@@ -257,9 +257,7 @@ class FindTool(BaseTool):
257
257
  # Resolve path
258
258
  root_path = Path(path).resolve()
259
259
  if not root_path.exists():
260
- return MCPResourceDocument(
261
- data={"error": f"Path does not exist: {path}", "results": []}
262
- )
260
+ return MCPResourceDocument(data={"error": f"Path does not exist: {path}", "results": []})
263
261
 
264
262
  # Get ignore patterns
265
263
  ignore_patterns = set()
@@ -270,9 +268,7 @@ class FindTool(BaseTool):
270
268
  min_size_bytes = self._parse_size(min_size) if min_size else None
271
269
  max_size_bytes = self._parse_size(max_size) if max_size else None
272
270
  modified_after_ts = self._parse_time(modified_after) if modified_after else None
273
- modified_before_ts = (
274
- self._parse_time(modified_before) if modified_before else None
275
- )
271
+ modified_before_ts = self._parse_time(modified_before) if modified_before else None
276
272
 
277
273
  # Collect matches
278
274
  matches = []
@@ -350,20 +346,14 @@ class FindTool(BaseTool):
350
346
  stats = {
351
347
  "total_found": total_results,
352
348
  "search_time_ms": int((time.time() - start_time) * 1000),
353
- "search_method": (
354
- "ffind" if FFIND_AVAILABLE and not in_content else "python"
355
- ),
349
+ "search_method": ("ffind" if FFIND_AVAILABLE and not in_content else "python"),
356
350
  "root_path": str(root_path),
357
351
  "filters_applied": {
358
352
  "pattern": pattern,
359
353
  "type": type,
360
- "size": (
361
- {"min": min_size, "max": max_size} if min_size or max_size else None
362
- ),
354
+ "size": ({"min": min_size, "max": max_size} if min_size or max_size else None),
363
355
  "modified": (
364
- {"after": modified_after, "before": modified_before}
365
- if modified_after or modified_before
366
- else None
356
+ {"after": modified_after, "before": modified_before} if modified_after or modified_before else None
367
357
  ),
368
358
  "max_depth": max_depth,
369
359
  "gitignore": respect_gitignore,
@@ -594,9 +584,7 @@ class FindTool(BaseTool):
594
584
  elif fuzzy:
595
585
  pattern_lower = pattern.lower() if not case_sensitive else pattern
596
586
  matcher = (
597
- lambda name: SequenceMatcher(
598
- None, pattern_lower, name.lower() if not case_sensitive else name
599
- ).ratio()
587
+ lambda name: SequenceMatcher(None, pattern_lower, name.lower() if not case_sensitive else name).ratio()
600
588
  > 0.6
601
589
  )
602
590
  else:
@@ -608,9 +596,7 @@ class FindTool(BaseTool):
608
596
  matcher = lambda name: fnmatch.fnmatch(name, pattern)
609
597
 
610
598
  # Walk directory tree
611
- for dirpath, dirnames, filenames in os.walk(
612
- str(root), followlinks=follow_symlinks
613
- ):
599
+ for dirpath, dirnames, filenames in os.walk(str(root), followlinks=follow_symlinks):
614
600
  # Check depth
615
601
  if max_depth is not None:
616
602
  depth = len(Path(dirpath).relative_to(root).parts)
@@ -621,11 +607,7 @@ class FindTool(BaseTool):
621
607
  # Filter directories to skip
622
608
  if respect_gitignore:
623
609
  dirnames[:] = [
624
- d
625
- for d in dirnames
626
- if not self._should_ignore(
627
- os.path.join(dirpath, d), ignore_patterns
628
- )
610
+ d for d in dirnames if not self._should_ignore(os.path.join(dirpath, d), ignore_patterns)
629
611
  ]
630
612
 
631
613
  # Check directories
@@ -662,9 +644,7 @@ class FindTool(BaseTool):
662
644
  match_found = True
663
645
  elif in_content:
664
646
  # Search in file content
665
- match_found = await self._search_in_file(
666
- full_path, pattern, case_sensitive
667
- )
647
+ match_found = await self._search_in_file(full_path, pattern, case_sensitive)
668
648
  else:
669
649
  match_found = False
670
650
 
@@ -686,9 +666,7 @@ class FindTool(BaseTool):
686
666
 
687
667
  return matches
688
668
 
689
- async def _search_in_file(
690
- self, file_path: str, pattern: str, case_sensitive: bool
691
- ) -> bool:
669
+ async def _search_in_file(self, file_path: str, pattern: str, case_sensitive: bool) -> bool:
692
670
  """Search for pattern in file content."""
693
671
  try:
694
672
  with open(file_path, "r", encoding="utf-8", errors="ignore") as f: