hanzo-mcp 0.6.10__py3-none-any.whl → 0.6.12__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.

hanzo_mcp/__init__.py CHANGED
@@ -1,3 +1,12 @@
1
1
  """Hanzo MCP - Implementation of Hanzo capabilities using MCP."""
2
2
 
3
- __version__ = "0.6.10"
3
+ # Configure FastMCP logging globally for stdio transport
4
+ import os
5
+ if os.environ.get("HANZO_MCP_TRANSPORT") == "stdio":
6
+ try:
7
+ from fastmcp.utilities.logging import configure_logging
8
+ configure_logging(level="ERROR")
9
+ except ImportError:
10
+ pass
11
+
12
+ __version__ = "0.6.12"
hanzo_mcp/cli.py CHANGED
@@ -2,6 +2,7 @@
2
2
 
3
3
  import argparse
4
4
  import json
5
+ import logging
5
6
  import os
6
7
  import signal
7
8
  import sys
@@ -13,13 +14,33 @@ from hanzo_mcp.server import HanzoMCPServer
13
14
 
14
15
  def main() -> None:
15
16
  """Run the CLI for the Hanzo MCP server."""
16
- # Set up signal handler to ensure clean exit
17
- def signal_handler(signum, frame):
18
- print("\nReceived interrupt signal, shutting down...")
19
- sys.exit(0)
20
17
 
21
- signal.signal(signal.SIGINT, signal_handler)
22
- signal.signal(signal.SIGTERM, signal_handler)
18
+ # Pre-parse arguments to check transport type early
19
+ import sys
20
+ early_parser = argparse.ArgumentParser(add_help=False)
21
+ early_parser.add_argument("--transport", choices=["stdio", "sse"], default="stdio")
22
+ early_args, _ = early_parser.parse_known_args()
23
+
24
+ # Configure logging VERY early based on transport
25
+ if early_args.transport == "stdio":
26
+ # Set environment variable for server to detect stdio mode
27
+ import os
28
+ os.environ["HANZO_MCP_TRANSPORT"] = "stdio"
29
+
30
+ # For stdio transport, disable ALL logging immediately
31
+ from fastmcp.utilities.logging import configure_logging
32
+ # Set to ERROR to suppress INFO/WARNING messages from FastMCP
33
+ configure_logging(level="ERROR")
34
+
35
+ # Also configure standard logging to ERROR level
36
+ logging.basicConfig(
37
+ level=logging.ERROR, # Only show errors
38
+ handlers=[] # No handlers for stdio to prevent protocol corruption
39
+ )
40
+
41
+ # Redirect stderr to devnull for stdio transport to prevent any output
42
+ import sys
43
+ sys.stderr = open(os.devnull, 'w')
23
44
 
24
45
  parser = argparse.ArgumentParser(
25
46
  description="MCP server implementing Hanzo AI capabilities"
@@ -212,6 +233,32 @@ def main() -> None:
212
233
  )
213
234
  return
214
235
 
236
+ # Get logger
237
+ logger = logging.getLogger(__name__)
238
+
239
+ # Set up signal handler to ensure clean exit
240
+ def signal_handler(signum, frame):
241
+ if transport != "stdio":
242
+ logger.info("\nReceived interrupt signal, shutting down...")
243
+ sys.exit(0)
244
+
245
+ signal.signal(signal.SIGINT, signal_handler)
246
+ signal.signal(signal.SIGTERM, signal_handler)
247
+
248
+ # Configure logging based on transport (stdio already configured early)
249
+ if transport != "stdio":
250
+ # For SSE transport, logging is fine
251
+ log_level_map = {
252
+ "DEBUG": logging.DEBUG,
253
+ "INFO": logging.INFO,
254
+ "WARNING": logging.WARNING,
255
+ "ERROR": logging.ERROR
256
+ }
257
+ logging.basicConfig(
258
+ level=log_level_map.get(log_level, logging.INFO),
259
+ format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
260
+ )
261
+
215
262
  # If no allowed paths are specified, use the current directory
216
263
  if not allowed_paths:
217
264
  allowed_paths = [os.getcwd()]
@@ -263,10 +310,11 @@ def main() -> None:
263
310
  # Transport will be automatically cast to Literal['stdio', 'sse'] by the server
264
311
  server.run(transport=transport)
265
312
  except KeyboardInterrupt:
266
- print("\nShutting down...")
313
+ if transport != "stdio":
314
+ logger.info("\nShutting down...")
267
315
  sys.exit(0)
268
316
  except Exception as e:
269
- print(f"Server error: {e}", file=sys.stderr)
317
+ logger.error(f"Server error: {e}")
270
318
  sys.exit(1)
271
319
 
272
320
 
@@ -342,27 +390,29 @@ def install_claude_desktop_config(
342
390
  existing_config["mcpServers"][name] = config["mcpServers"][name]
343
391
  config = existing_config
344
392
  except Exception as e:
345
- print(f"Error reading existing config: {e}")
346
- print("Creating new config file.")
393
+ logger = logging.getLogger(__name__)
394
+ logger.error(f"Error reading existing config: {e}")
395
+ logger.info("Creating new config file.")
347
396
 
348
397
  # Write the config file
349
398
  with open(config_file, mode="w") as f:
350
399
  json.dump(config, f, indent=2)
351
400
 
352
- print(f"Successfully installed {name} in Claude Desktop configuration.")
353
- print(f"Config file: {config_file}")
401
+ logger = logging.getLogger(__name__)
402
+ logger.info(f"Successfully installed {name} in Claude Desktop configuration.")
403
+ logger.info(f"Config file: {config_file}")
354
404
 
355
405
  if allowed_paths:
356
- print("\nAllowed paths:")
406
+ logger.info("\nAllowed paths:")
357
407
  for path in allowed_paths:
358
- print(f"- {path}")
408
+ logger.info(f"- {path}")
359
409
  else:
360
- print(f"\nDefault allowed path: {home}")
410
+ logger.info(f"\nDefault allowed path: {home}")
361
411
 
362
- print(
412
+ logger.info(
363
413
  "\nYou can modify allowed paths in the config file directly."
364
414
  )
365
- print("Restart Claude Desktop for changes to take effect.")
415
+ logger.info("Restart Claude Desktop for changes to take effect.")
366
416
 
367
417
 
368
418
  if __name__ == "__main__":
hanzo_mcp/cli_enhanced.py CHANGED
@@ -2,6 +2,7 @@
2
2
 
3
3
  import argparse
4
4
  import json
5
+ import logging
5
6
  import os
6
7
  import sys
7
8
  from pathlib import Path
@@ -344,8 +345,9 @@ def apply_cli_overrides(args: argparse.Namespace) -> Dict[str, Any]:
344
345
 
345
346
  def list_tools(settings: HanzoMCPSettings) -> None:
346
347
  """List all tools and their current status."""
347
- print("Hanzo MCP Tools Status:")
348
- print("=" * 50)
348
+ logger = logging.getLogger(__name__)
349
+ logger.info("Hanzo MCP Tools Status:")
350
+ logger.info("=" * 50)
349
351
 
350
352
  categories = {}
351
353
  for tool_name, tool_config in TOOL_REGISTRY.items():
@@ -358,14 +360,14 @@ def list_tools(settings: HanzoMCPSettings) -> None:
358
360
  categories[category].append((tool_name, status, tool_config.description))
359
361
 
360
362
  for category, tools in categories.items():
361
- print(f"\n{category.upper()} TOOLS:")
362
- print("-" * 30)
363
+ logger.info(f"\n{category.upper()} TOOLS:")
364
+ logger.info("-" * 30)
363
365
  for tool_name, status, description in tools:
364
- print(f" {status} {tool_name:<15} - {description}")
366
+ logger.info(f" {status} {tool_name:<15} - {description}")
365
367
 
366
- print(f"\nTotal: {len(TOOL_REGISTRY)} tools")
368
+ logger.info(f"\nTotal: {len(TOOL_REGISTRY)} tools")
367
369
  enabled_count = len(settings.get_enabled_tools())
368
- print(f"Enabled: {enabled_count}, Disabled: {len(TOOL_REGISTRY) - enabled_count}")
370
+ logger.info(f"Enabled: {enabled_count}, Disabled: {len(TOOL_REGISTRY) - enabled_count}")
369
371
 
370
372
 
371
373
  def main() -> None:
@@ -385,14 +387,15 @@ def main() -> None:
385
387
  settings = load_settings(project_dir=project_dir, config_overrides=config_overrides)
386
388
 
387
389
  # Handle configuration saving
390
+ logger = logging.getLogger(__name__)
388
391
  if hasattr(args, 'save_config') and args.save_config:
389
392
  saved_path = save_settings(settings, global_config=True)
390
- print(f"Configuration saved to: {saved_path}")
393
+ logger.info(f"Configuration saved to: {saved_path}")
391
394
  return
392
395
 
393
396
  if hasattr(args, 'save_project_config') and args.save_project_config:
394
397
  saved_path = save_settings(settings, global_config=False)
395
- print(f"Project configuration saved to: {saved_path}")
398
+ logger.info(f"Project configuration saved to: {saved_path}")
396
399
  return
397
400
 
398
401
  # Handle installation
@@ -364,7 +364,9 @@ def load_settings(
364
364
  global_config = json.load(f)
365
365
  settings = _merge_config(settings, global_config)
366
366
  except Exception as e:
367
- print(f"Warning: Failed to load global config: {e}")
367
+ import logging
368
+ logger = logging.getLogger(__name__)
369
+ logger.warning(f"Failed to load global config: {e}")
368
370
 
369
371
  # Load project config
370
372
  project_config_path = get_project_config_path(project_dir)
@@ -374,7 +376,9 @@ def load_settings(
374
376
  project_config = json.load(f)
375
377
  settings = _merge_config(settings, project_config)
376
378
  except Exception as e:
377
- print(f"Warning: Failed to load project config: {e}")
379
+ import logging
380
+ logger = logging.getLogger(__name__)
381
+ logger.warning(f"Failed to load project config: {e}")
378
382
 
379
383
  # Apply CLI overrides
380
384
  if config_overrides:
hanzo_mcp/dev_server.py CHANGED
@@ -1,6 +1,7 @@
1
1
  """Development server with hot reload for Hanzo MCP."""
2
2
 
3
3
  import asyncio
4
+ import logging
4
5
  import os
5
6
  import sys
6
7
  import time
@@ -67,8 +68,9 @@ class MCPReloadHandler(FileSystemEventHandler):
67
68
 
68
69
  self.last_reload = current_time
69
70
 
70
- print(f"\n🔄 File changed: {event.src_path}")
71
- print("🔄 Reloading MCP server...")
71
+ logger = logging.getLogger(__name__)
72
+ logger.info(f"\n🔄 File changed: {event.src_path}")
73
+ logger.info("🔄 Reloading MCP server...")
72
74
 
73
75
  self.restart_callback()
74
76
 
@@ -133,9 +135,10 @@ class DevServer:
133
135
  self.observer.schedule(handler, path, recursive=True)
134
136
 
135
137
  self.observer.start()
136
- print(f"👀 Watching for changes in: {package_dir}")
138
+ logger = logging.getLogger(__name__)
139
+ logger.info(f"👀 Watching for changes in: {package_dir}")
137
140
  if self.project_dir:
138
- print(f"👀 Also watching: {self.project_dir}")
141
+ logger.info(f"👀 Also watching: {self.project_dir}")
139
142
 
140
143
  def stop_file_watcher(self):
141
144
  """Stop the file watcher."""
@@ -146,18 +149,20 @@ class DevServer:
146
149
  def restart_server(self):
147
150
  """Restart the MCP server."""
148
151
  # Since MCP servers run in the same process, we need to handle this differently
149
- # For now, we'll print a message indicating a restart is needed
150
- print("\n⚠️ Server restart required. Please restart the MCP client to reload changes.")
151
- print("💡 Tip: In development, consider using the MCP test client for easier reloading.")
152
+ # For now, we'll log a message indicating a restart is needed
153
+ 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.")
152
156
 
153
157
  async def run_async(self, transport: str = "stdio"):
154
158
  """Run the development server asynchronously."""
155
159
  self.running = True
156
160
 
157
- print(f"\n🚀 Starting Hanzo MCP in development mode...")
158
- print(f"🔧 Hot reload enabled - watching for file changes")
159
- print(f"📁 Project: {self.project_dir or 'current directory'}")
160
- print(f"🌐 Transport: {transport}\n")
161
+ logger = logging.getLogger(__name__)
162
+ logger.info(f"\n🚀 Starting Hanzo MCP in development mode...")
163
+ logger.info(f"🔧 Hot reload enabled - watching for file changes")
164
+ logger.info(f"📁 Project: {self.project_dir or 'current directory'}")
165
+ logger.info(f"🌐 Transport: {transport}\n")
161
166
 
162
167
  # Start file watcher
163
168
  self.start_file_watcher()
@@ -170,11 +175,11 @@ class DevServer:
170
175
  server.run(transport=transport)
171
176
 
172
177
  except KeyboardInterrupt:
173
- print("\n\n🛑 Shutting down development server...")
178
+ logger.info("\n\n🛑 Shutting down development server...")
174
179
  finally:
175
180
  self.running = False
176
181
  self.stop_file_watcher()
177
- print("👋 Development server stopped")
182
+ logger.info("👋 Development server stopped")
178
183
 
179
184
  def run(self, transport: str = "stdio"):
180
185
  """Run the development server."""
hanzo_mcp/server.py CHANGED
@@ -1,6 +1,7 @@
1
1
  """MCP server implementing Hanzo capabilities."""
2
2
 
3
3
  import atexit
4
+ import logging
4
5
  import signal
5
6
  import threading
6
7
  import time
@@ -154,7 +155,10 @@ class HanzoMCPServer:
154
155
  # Register signal handlers for graceful shutdown
155
156
  def signal_handler(signum, frame):
156
157
  import sys
157
- print("\nShutting down gracefully...")
158
+ # Only log if not stdio transport
159
+ if hasattr(self, '_transport') and self._transport != 'stdio':
160
+ logger = logging.getLogger(__name__)
161
+ logger.info("\nShutting down gracefully...")
158
162
  self._cleanup_sessions()
159
163
  self._shutdown_event.set()
160
164
  sys.exit(0)
@@ -189,7 +193,10 @@ class HanzoMCPServer:
189
193
  try:
190
194
  cleared_count = SessionStorage.clear_all_sessions()
191
195
  if cleared_count > 0:
192
- print(f"Cleaned up {cleared_count} tmux sessions on shutdown")
196
+ # Only log if not stdio transport
197
+ if hasattr(self, '_transport') and self._transport != 'stdio':
198
+ logger = logging.getLogger(__name__)
199
+ logger.info(f"Cleaned up {cleared_count} tmux sessions on shutdown")
193
200
  except Exception:
194
201
  # Ignore cleanup errors during shutdown
195
202
  pass
@@ -201,6 +208,9 @@ class HanzoMCPServer:
201
208
  transport: The transport to use (stdio or sse)
202
209
  allowed_paths: list of paths that the server is allowed to access
203
210
  """
211
+ # Store transport for later use
212
+ self._transport = transport
213
+
204
214
  # Add allowed paths if provided
205
215
  allowed_paths_list = allowed_paths or []
206
216
  for path in allowed_paths_list:
@@ -124,7 +124,9 @@ def register_all_tools(
124
124
  )
125
125
  # Auto-detect projects from search paths
126
126
  detected_projects = project_manager.detect_projects(search_paths)
127
- print(f"Detected {len(detected_projects)} projects with LLM.md files")
127
+ import logging
128
+ logger = logging.getLogger(__name__)
129
+ logger.info(f"Detected {len(detected_projects)} projects with LLM.md files")
128
130
 
129
131
  filesystem_tools = register_filesystem_tools(
130
132
  mcp_server,
@@ -5,6 +5,7 @@ implementation with the new BashSession-based approach for better persistent exe
5
5
  """
6
6
 
7
7
  import asyncio
8
+ import logging
8
9
  import os
9
10
  import shlex
10
11
  import subprocess
@@ -64,16 +65,18 @@ class BashSessionExecutor:
64
65
  if data is not None:
65
66
  try:
66
67
  import json
67
-
68
+ logger = logging.getLogger(__name__)
68
69
  if isinstance(data, (dict, list)):
69
70
  data_str = json.dumps(data)
70
71
  else:
71
72
  data_str = str(data)
72
- print(f"DEBUG: {message}: {data_str}")
73
+ logger.debug(f"{message}: {data_str}")
73
74
  except Exception:
74
- print(f"DEBUG: {message}: {data}")
75
+ logger = logging.getLogger(__name__)
76
+ logger.debug(f"{message}: {data}")
75
77
  else:
76
- print(f"DEBUG: {message}")
78
+ logger = logging.getLogger(__name__)
79
+ logger.debug(f"{message}")
77
80
 
78
81
  def allow_command(self, command: str) -> None:
79
82
  """Allow a specific command that might otherwise be excluded.
@@ -183,16 +183,18 @@ class CommandExecutor:
183
183
  if data is not None:
184
184
  try:
185
185
  import json
186
-
186
+ logger = logging.getLogger(__name__)
187
187
  if isinstance(data, (dict, list)):
188
188
  data_str = json.dumps(data)
189
189
  else:
190
190
  data_str = str(data)
191
- print(f"DEBUG: {message}: {data_str}", file=sys.stderr)
191
+ logger.debug(f"{message}: {data_str}")
192
192
  except Exception:
193
- print(f"DEBUG: {message}: {data}", file=sys.stderr)
193
+ logger = logging.getLogger(__name__)
194
+ logger.debug(f"{message}: {data}")
194
195
  else:
195
- print(f"DEBUG: {message}", file=sys.stderr)
196
+ logger = logging.getLogger(__name__)
197
+ logger.debug(f"{message}")
196
198
 
197
199
  def is_command_allowed(self, command: str) -> bool:
198
200
  """Check if a command is allowed based on exclusion lists.
@@ -62,7 +62,9 @@ try:
62
62
  # Auto-detect projects from search paths for new manager
63
63
  if search_paths:
64
64
  detected_projects = project_manager.detect_projects(search_paths)
65
- print(f"Detected {len(detected_projects)} projects with LLM.md files")
65
+ import logging
66
+ logger = logging.getLogger(__name__)
67
+ logger.info(f"Detected {len(detected_projects)} projects with LLM.md files")
66
68
 
67
69
  # Register individual tools if enabled
68
70
  if tool_enabled.get("index", True):
@@ -85,7 +87,9 @@ except ImportError:
85
87
 
86
88
  def register_vector_tools(*args, **kwargs) -> list[BaseTool]:
87
89
  """Vector tools not available - missing dependencies."""
88
- print("Warning: Vector tools not available. Install infinity-embedded: pip install infinity-embedded")
90
+ import logging
91
+ logger = logging.getLogger(__name__)
92
+ logger.warning("Vector tools not available. Install infinity-embedded: pip install infinity-embedded")
89
93
  return []
90
94
 
91
95
 
@@ -94,7 +94,9 @@ class ASTAnalyzer:
94
94
  # Python parser
95
95
  self.parsers['python'] = tree_sitter.Language(tspython.language())
96
96
  except Exception as e:
97
- print(f"Warning: Could not initialize Python parser: {e}")
97
+ import logging
98
+ logger = logging.getLogger(__name__)
99
+ logger.warning(f"Could not initialize Python parser: {e}")
98
100
 
99
101
  def analyze_file(self, file_path: str) -> Optional[FileAST]:
100
102
  """Analyze a file and extract AST information and symbols.
@@ -127,7 +129,9 @@ class ASTAnalyzer:
127
129
  return self._analyze_generic_file(file_path, content, file_hash, language)
128
130
 
129
131
  except Exception as e:
130
- print(f"Error analyzing file {file_path}: {e}")
132
+ import logging
133
+ logger = logging.getLogger(__name__)
134
+ logger.error(f"Error analyzing file {file_path}: {e}")
131
135
  return None
132
136
 
133
137
  def _detect_language(self, path: Path) -> Optional[str]:
@@ -194,9 +198,13 @@ class ASTAnalyzer:
194
198
  ast_nodes = self._extract_tree_sitter_nodes(ts_tree.root_node, content)
195
199
 
196
200
  except SyntaxError as e:
197
- print(f"Syntax error in {file_path}: {e}")
201
+ import logging
202
+ logger = logging.getLogger(__name__)
203
+ logger.error(f"Syntax error in {file_path}: {e}")
198
204
  except Exception as e:
199
- print(f"Error parsing Python file {file_path}: {e}")
205
+ import logging
206
+ logger = logging.getLogger(__name__)
207
+ logger.error(f"Error parsing Python file {file_path}: {e}")
200
208
 
201
209
  return FileAST(
202
210
  file_path=file_path,
@@ -528,7 +528,9 @@ class InfinityVectorStore:
528
528
  return file_ast
529
529
 
530
530
  except Exception as e:
531
- print(f"Error searching AST nodes: {e}")
531
+ import logging
532
+ logger = logging.getLogger(__name__)
533
+ logger.error(f"Error searching AST nodes: {e}")
532
534
  return None
533
535
 
534
536
  def get_file_references(self, file_path: str) -> List[Dict[str, Any]]:
@@ -555,7 +557,9 @@ class InfinityVectorStore:
555
557
  return references
556
558
 
557
559
  except Exception as e:
558
- print(f"Error getting file references: {e}")
560
+ import logging
561
+ logger = logging.getLogger(__name__)
562
+ logger.error(f"Error getting file references: {e}")
559
563
  return []
560
564
 
561
565
  def search(
@@ -803,7 +807,9 @@ class InfinityVectorStore:
803
807
 
804
808
  return True
805
809
  except Exception as e:
806
- print(f"Error clearing vector store: {e}")
810
+ import logging
811
+ logger = logging.getLogger(__name__)
812
+ logger.error(f"Error clearing vector store: {e}")
807
813
  return False
808
814
 
809
815
  async def index_document(
@@ -294,7 +294,9 @@ class ProjectVectorManager:
294
294
  project_name = project_names[i]
295
295
  if isinstance(result, Exception):
296
296
  # Log error but continue
297
- print(f"Error searching project {project_name}: {result}")
297
+ import logging
298
+ logger = logging.getLogger(__name__)
299
+ logger.error(f"Error searching project {project_name}: {result}")
298
300
  combined_results[project_name] = []
299
301
  else:
300
302
  combined_results[project_name] = result
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: hanzo-mcp
3
- Version: 0.6.10
3
+ Version: 0.6.12
4
4
  Summary: The Zen of Hanzo MCP: One server to rule them all. The ultimate MCP that orchestrates all others.
5
5
  Author-email: Hanzo Industries Inc <dev@hanzo.ai>
6
6
  License: MIT
@@ -1,11 +1,11 @@
1
- hanzo_mcp/__init__.py,sha256=vz1uqGlh5NNvA4ruaOLYeiaN0kgtlI4AFCJZtB_doZw,90
1
+ hanzo_mcp/__init__.py,sha256=YvzSKP7uAofDDoy2Yj36r8eSZjOJfiyZevQqHRET8Ew,362
2
2
  hanzo_mcp/__main__.py,sha256=TY-sUBg0MJozJws4-e3_kT8mJVoYGKCk6G3gPGxjIBI,129
3
- hanzo_mcp/cli.py,sha256=j-n3YgOp9mBE3aNwAdXZX9f1uS9KE6ON0fLetauuk9E,11340
4
- hanzo_mcp/cli_enhanced.py,sha256=rqh9gqyjMuUznIlPTC5pcIGYZTKAScacMsDb1e68ReE,15819
5
- hanzo_mcp/dev_server.py,sha256=_Ti0P7y8VNK5z4NiZ1BN5L_KdWhWYJ4IG2U6GZObzyM,7869
6
- hanzo_mcp/server.py,sha256=1qbB4n_DrBHxXBef_mNmPSZqPqqQwCenm3M_vO3g6dg,8394
3
+ hanzo_mcp/cli.py,sha256=f9O-O4kfFGhJlWZFUs2PNnBKBt1Xv8teKaIhKDFFK3g,13297
4
+ hanzo_mcp/cli_enhanced.py,sha256=_YirFtkOT-hlu1OqHslgivafWxs6RQ1VJKfowywVoQY,15970
5
+ hanzo_mcp/dev_server.py,sha256=bmgVwIUQH_VoD15iyyldVkFl7Co7A4BcrkHnKq55Bbs,8137
6
+ hanzo_mcp/server.py,sha256=FoJWaDY0LRgtsO1gq6NBKGWy7urwkXuR30tA0KJCAR8,8874
7
7
  hanzo_mcp/config/__init__.py,sha256=iZYGSJMsC1c97gRFqgyowfP4XW480BBVRAQq1r-Dp7g,506
8
- hanzo_mcp/config/settings.py,sha256=F4ya4pHoxGACawPo4hd0bwfk6MwXvrTjH0WMBQpUN8I,16259
8
+ hanzo_mcp/config/settings.py,sha256=ctzcQa3Yk_3ACN8i8B_Hnvc_8aVad4GrKmdIQEEo0lA,16411
9
9
  hanzo_mcp/config/tool_config.py,sha256=AT5eJRZAL8VTLu5DCdoC_MkDxtufVE_QOj7Yp_Fyi8k,6317
10
10
  hanzo_mcp/prompts/__init__.py,sha256=Fp2Jr6SmUd6QmasOclgkTIb4qCzRSqtu3i-0d98XKEg,3992
11
11
  hanzo_mcp/prompts/compact_conversation.py,sha256=nvD068KEesiMcevxxMBeIJh6AqT7YHOqyH6RepRFFfA,4206
@@ -13,7 +13,7 @@ hanzo_mcp/prompts/create_release.py,sha256=1Z8xSTtz5vAm0rWFnERpFu7wIYExT4iXhM6nG
13
13
  hanzo_mcp/prompts/project_system.py,sha256=-W-PN-h-wW2F41-FM_OnLkX__4i40JpvF6lvW-3rjoM,8231
14
14
  hanzo_mcp/prompts/project_todo_reminder.py,sha256=otiBdmzxssBSb3MZZSQsjYDGLBqi1bM0HgraELP_Nf4,3645
15
15
  hanzo_mcp/prompts/utils.py,sha256=IwxIhzZfYJ2anToPulbrpcc07u4Dozo9ok6VE3BC_4A,9963
16
- hanzo_mcp/tools/__init__.py,sha256=cbsCiLlfsw69-dWMnv5sNUDcNcRAtyPI8PxRGAVe1QE,14236
16
+ hanzo_mcp/tools/__init__.py,sha256=KRHS8ijzc1NDqfPYJ0ZO-vwLlYzRtt0z8OXII4kf9Zw,14318
17
17
  hanzo_mcp/tools/agent/__init__.py,sha256=U4nchBrzKAnCn0ffbzOnN00zg-ZmXR6J8ZrdaBIWKQ8,1900
18
18
  hanzo_mcp/tools/agent/agent.py,sha256=xWYV6-ACIut_u2yiaobmN5szvoBOs8vre0opNKcKkmY,13541
19
19
  hanzo_mcp/tools/agent/agent_tool.py,sha256=A46xrkXGNBbNhSoZYfWyujswKDcIM04bZUKQPwlbAVw,21376
@@ -93,9 +93,9 @@ hanzo_mcp/tools/shell/__init__.py,sha256=d66Jo8BIA6Re__b3r9V_e8uGm8psplQ2SGf0XRS
93
93
  hanzo_mcp/tools/shell/base.py,sha256=Nx9rAE7CO9-Hr5k_qYKUtNFq4twI6Z-lOt0fpkS57i4,5832
94
94
  hanzo_mcp/tools/shell/base_process.py,sha256=KgXA98hFsbU5Y9E6mGLTTwQZowgHGpk5HSALxRICqDI,9495
95
95
  hanzo_mcp/tools/shell/bash_session.py,sha256=YPtdtC0pc6Q04RJqKUy0u0RPTbiT2IGtsvFqejK5Hu4,27271
96
- hanzo_mcp/tools/shell/bash_session_executor.py,sha256=zRnrzj4sdQOxO22XXBENT6k2dXt3LDk5fxjWjUYyU_Q,10723
96
+ hanzo_mcp/tools/shell/bash_session_executor.py,sha256=xqvnFZSdlRKuuQx7HKsS6axasZa6Lr8YnIlny2qwr1Q,10892
97
97
  hanzo_mcp/tools/shell/bash_unified.py,sha256=vWQbTCgZS9ucD3cMr_ZYlLuGCnmQljRITYKUI-qrJek,4883
98
- hanzo_mcp/tools/shell/command_executor.py,sha256=IuoRY48PMmpKHL5CFIExebjoiRRS5ZEl73UDzYTR3kU,36406
98
+ hanzo_mcp/tools/shell/command_executor.py,sha256=Tw0UGRHBYxizkr7UaB148gmUwthc0D6pI92aPFIqc4I,36509
99
99
  hanzo_mcp/tools/shell/logs.py,sha256=RahjkEHNwsKbnJ7cTAie70BSb9bV6T9Vf4JJluoZXYo,8468
100
100
  hanzo_mcp/tools/shell/npx.py,sha256=Bs5tKpyJMm6Yfrmuph0btbvSQGbDczR_YToP2iRqhHY,5083
101
101
  hanzo_mcp/tools/shell/npx_background.py,sha256=GNZOYV_jjA9pa7w-ZNy_oX7iSA_VfZRzVUr7dKunfjo,7120
@@ -117,19 +117,19 @@ hanzo_mcp/tools/todo/base.py,sha256=k0CFZy59YlLAJBVzVA4tr-qGkQ1l5yF04kcmziwQWec,
117
117
  hanzo_mcp/tools/todo/todo.py,sha256=y4LM8CIb94tK-lURnVer2WzctKPx_EWS0kEIM1Ut0Os,8218
118
118
  hanzo_mcp/tools/todo/todo_read.py,sha256=EWqXOeQANGQOJXKyMv-0GeJdq-d0HnslRM__LW6Jydg,4688
119
119
  hanzo_mcp/tools/todo/todo_write.py,sha256=nJG2By4FXHZm7NNreEfVYb3wPJbraVWjrdv_TqXqYFo,15394
120
- hanzo_mcp/tools/vector/__init__.py,sha256=6LxU1yeauhv5pQ-lhQuPrBDTC9c7Y6gCbZBBo-4r9HI,3853
121
- hanzo_mcp/tools/vector/ast_analyzer.py,sha256=2bUM9j9rCNARNXXF2cuFSp2ercwZAJWlAqeRIwn46Ck,15653
120
+ hanzo_mcp/tools/vector/__init__.py,sha256=7n7mUYruIINPtUdniy45qU0qI11dLvt07PqfEbNb_D0,4011
121
+ hanzo_mcp/tools/vector/ast_analyzer.py,sha256=0MraKxFbZqaPns0CUacCG84IX_DW_RxSfi7fvXT-MEY,15986
122
122
  hanzo_mcp/tools/vector/git_ingester.py,sha256=pR4_HRMT7trGhr1kGHASvhgm7Vjwh6UY-UVdXCNj07s,16367
123
123
  hanzo_mcp/tools/vector/index_tool.py,sha256=rMqv1WQMt18eikXdOzUNYyvWdR1gK_rIy4P769gGTak,12769
124
- hanzo_mcp/tools/vector/infinity_store.py,sha256=E3YotdY798HTPs4X2IMv-SOjt-VjCC2XAFaWPeSVUQU,28382
124
+ hanzo_mcp/tools/vector/infinity_store.py,sha256=yKiPVitpkk3Ud1Zb0O_q6IlsB0diVIvFxqKCZ2Pw8IY,28631
125
125
  hanzo_mcp/tools/vector/mock_infinity.py,sha256=QyU7FM2eTCP0BeuX8xhRe0En7hG9EFt-XzgDu-BefrI,4990
126
- hanzo_mcp/tools/vector/project_manager.py,sha256=xrkRl7niWjJrtSNaEOppkPzDFDw9FaEeOIbPY8D4wJw,13534
126
+ hanzo_mcp/tools/vector/project_manager.py,sha256=ML-ZeZTb1Pb5m-T0jF2LH0myTmG688uMR0nHRQBSNDY,13625
127
127
  hanzo_mcp/tools/vector/vector.py,sha256=EpKEDkRfSHsDfPewqRwNAulX0BndlK48p-sFSMtt3js,10179
128
128
  hanzo_mcp/tools/vector/vector_index.py,sha256=IqXoEfEk6TOOEThXw4obePZqfvBRiYL_LCrx8z35-h8,4403
129
129
  hanzo_mcp/tools/vector/vector_search.py,sha256=jwX1azf4V4seqJ2CIDloX3lJ5_hkUl7X5e2OOgGXQNk,9647
130
- hanzo_mcp-0.6.10.dist-info/licenses/LICENSE,sha256=mf1qZGFsPGskoPgytp9B-RsahfKvXsBpmaAbTLGTt8Y,1063
131
- hanzo_mcp-0.6.10.dist-info/METADATA,sha256=GNR-R4i3ig_7QB27wKAWhlIVBx3krHNEJAt2ki9AAmQ,11291
132
- hanzo_mcp-0.6.10.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
133
- hanzo_mcp-0.6.10.dist-info/entry_points.txt,sha256=Q_g5SzWk47z2b_rE_RgonVqk4-d8VQ6pqwMveYiXJuU,101
134
- hanzo_mcp-0.6.10.dist-info/top_level.txt,sha256=eGFANatA0MHWiVlpS56fTYRIShtibrSom1uXI6XU0GU,10
135
- hanzo_mcp-0.6.10.dist-info/RECORD,,
130
+ hanzo_mcp-0.6.12.dist-info/licenses/LICENSE,sha256=mf1qZGFsPGskoPgytp9B-RsahfKvXsBpmaAbTLGTt8Y,1063
131
+ hanzo_mcp-0.6.12.dist-info/METADATA,sha256=mWECTG9AjK-tKztANkIijYLOgxeCVl1zR25f4WEx_w0,11291
132
+ hanzo_mcp-0.6.12.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
133
+ hanzo_mcp-0.6.12.dist-info/entry_points.txt,sha256=Q_g5SzWk47z2b_rE_RgonVqk4-d8VQ6pqwMveYiXJuU,101
134
+ hanzo_mcp-0.6.12.dist-info/top_level.txt,sha256=eGFANatA0MHWiVlpS56fTYRIShtibrSom1uXI6XU0GU,10
135
+ hanzo_mcp-0.6.12.dist-info/RECORD,,