hanzo-mcp 0.7.6__tar.gz → 0.8.0__tar.gz

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 (231) hide show
  1. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/PKG-INFO +1 -1
  2. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/__init__.py +7 -1
  3. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/__main__.py +1 -1
  4. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/analytics/__init__.py +2 -2
  5. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/analytics/posthog_analytics.py +76 -82
  6. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/cli.py +31 -36
  7. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/cli_enhanced.py +94 -72
  8. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/cli_plugin.py +27 -17
  9. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/config/__init__.py +2 -2
  10. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/config/settings.py +112 -88
  11. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/config/tool_config.py +32 -34
  12. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/dev_server.py +66 -67
  13. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/prompts/__init__.py +94 -12
  14. hanzo_mcp-0.8.0/hanzo_mcp/prompts/enhanced_prompts.py +809 -0
  15. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/prompts/example_custom_prompt.py +6 -5
  16. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/prompts/project_todo_reminder.py +0 -1
  17. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/prompts/tool_explorer.py +10 -7
  18. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/server.py +17 -21
  19. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/server_enhanced.py +15 -22
  20. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/tools/__init__.py +56 -28
  21. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/tools/agent/__init__.py +16 -19
  22. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/tools/agent/agent.py +82 -65
  23. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/tools/agent/agent_tool.py +152 -122
  24. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/tools/agent/agent_tool_v1_deprecated.py +66 -62
  25. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/tools/agent/clarification_protocol.py +55 -50
  26. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/tools/agent/clarification_tool.py +11 -10
  27. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/tools/agent/claude_cli_tool.py +21 -20
  28. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/tools/agent/claude_desktop_auth.py +130 -144
  29. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/tools/agent/cli_agent_base.py +59 -53
  30. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/tools/agent/code_auth.py +102 -107
  31. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/tools/agent/code_auth_tool.py +28 -27
  32. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/tools/agent/codex_cli_tool.py +20 -19
  33. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/tools/agent/critic_tool.py +86 -73
  34. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/tools/agent/gemini_cli_tool.py +21 -20
  35. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/tools/agent/grok_cli_tool.py +21 -20
  36. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/tools/agent/iching_tool.py +404 -139
  37. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/tools/agent/network_tool.py +89 -73
  38. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/tools/agent/prompt.py +2 -1
  39. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/tools/agent/review_tool.py +101 -98
  40. hanzo_mcp-0.8.0/hanzo_mcp/tools/agent/swarm_alias.py +87 -0
  41. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/tools/agent/swarm_tool.py +246 -161
  42. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/tools/agent/swarm_tool_v1_deprecated.py +134 -92
  43. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/tools/agent/tool_adapter.py +21 -11
  44. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/tools/common/base.py +3 -5
  45. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/tools/common/batch_tool.py +46 -39
  46. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/tools/common/config_tool.py +120 -84
  47. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/tools/common/context.py +1 -5
  48. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/tools/common/context_fix.py +5 -3
  49. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/tools/common/critic_tool.py +4 -8
  50. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/tools/common/decorators.py +58 -56
  51. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/tools/common/enhanced_base.py +29 -32
  52. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/tools/common/fastmcp_pagination.py +91 -94
  53. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/tools/common/forgiving_edit.py +91 -87
  54. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/tools/common/mode.py +15 -17
  55. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/tools/common/mode_loader.py +27 -24
  56. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/tools/common/paginated_base.py +61 -53
  57. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/tools/common/paginated_response.py +72 -79
  58. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/tools/common/pagination.py +50 -53
  59. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/tools/common/permissions.py +4 -4
  60. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/tools/common/personality.py +186 -138
  61. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/tools/common/plugin_loader.py +54 -54
  62. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/tools/common/stats.py +65 -47
  63. hanzo_mcp-0.8.0/hanzo_mcp/tools/common/test_helpers.py +31 -0
  64. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/tools/common/thinking_tool.py +4 -8
  65. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/tools/common/tool_disable.py +17 -12
  66. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/tools/common/tool_enable.py +13 -14
  67. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/tools/common/tool_list.py +36 -28
  68. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/tools/common/truncate.py +23 -23
  69. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/tools/config/__init__.py +4 -4
  70. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/tools/config/config_tool.py +42 -29
  71. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/tools/config/index_config.py +37 -34
  72. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/tools/config/mode_tool.py +175 -55
  73. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/tools/database/__init__.py +15 -12
  74. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/tools/database/database_manager.py +77 -75
  75. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/tools/database/graph.py +137 -91
  76. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/tools/database/graph_add.py +30 -18
  77. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/tools/database/graph_query.py +178 -102
  78. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/tools/database/graph_remove.py +33 -28
  79. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/tools/database/graph_search.py +97 -75
  80. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/tools/database/graph_stats.py +91 -59
  81. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/tools/database/sql.py +107 -79
  82. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/tools/database/sql_query.py +30 -24
  83. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/tools/database/sql_search.py +29 -25
  84. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/tools/database/sql_stats.py +47 -35
  85. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/tools/editor/neovim_command.py +25 -28
  86. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/tools/editor/neovim_edit.py +21 -23
  87. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/tools/editor/neovim_session.py +60 -54
  88. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/tools/filesystem/__init__.py +31 -30
  89. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/tools/filesystem/ast_multi_edit.py +329 -249
  90. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/tools/filesystem/ast_tool.py +4 -4
  91. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/tools/filesystem/batch_search.py +316 -224
  92. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/tools/filesystem/content_replace.py +4 -4
  93. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/tools/filesystem/diff.py +71 -59
  94. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/tools/filesystem/directory_tree.py +7 -7
  95. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/tools/filesystem/directory_tree_paginated.py +49 -37
  96. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/tools/filesystem/edit.py +4 -4
  97. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/tools/filesystem/find.py +173 -80
  98. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/tools/filesystem/find_files.py +73 -52
  99. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/tools/filesystem/git_search.py +157 -104
  100. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/tools/filesystem/grep.py +8 -8
  101. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/tools/filesystem/multi_edit.py +4 -8
  102. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/tools/filesystem/read.py +12 -10
  103. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/tools/filesystem/rules_tool.py +59 -43
  104. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/tools/filesystem/search_tool.py +263 -207
  105. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/tools/filesystem/symbols_tool.py +94 -54
  106. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/tools/filesystem/tree.py +35 -33
  107. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/tools/filesystem/unix_aliases.py +13 -18
  108. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/tools/filesystem/watch.py +37 -36
  109. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/tools/filesystem/write.py +4 -8
  110. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/tools/jupyter/__init__.py +4 -4
  111. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/tools/jupyter/base.py +4 -5
  112. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/tools/jupyter/jupyter.py +67 -47
  113. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/tools/jupyter/notebook_edit.py +4 -4
  114. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/tools/jupyter/notebook_read.py +4 -7
  115. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/tools/llm/__init__.py +5 -7
  116. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/tools/llm/consensus_tool.py +72 -52
  117. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/tools/llm/llm_manage.py +101 -60
  118. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/tools/llm/llm_tool.py +226 -166
  119. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/tools/llm/provider_tools.py +25 -26
  120. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/tools/lsp/__init__.py +1 -1
  121. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/tools/lsp/lsp_tool.py +228 -143
  122. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/tools/mcp/__init__.py +2 -3
  123. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/tools/mcp/mcp_add.py +27 -25
  124. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/tools/mcp/mcp_remove.py +7 -8
  125. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/tools/mcp/mcp_stats.py +23 -22
  126. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/tools/mcp/mcp_tool.py +129 -98
  127. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/tools/memory/__init__.py +39 -21
  128. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/tools/memory/knowledge_tools.py +124 -99
  129. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/tools/memory/memory_tools.py +90 -108
  130. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/tools/search/__init__.py +7 -2
  131. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/tools/search/find_tool.py +297 -212
  132. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/tools/search/unified_search.py +366 -314
  133. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/tools/shell/__init__.py +8 -7
  134. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/tools/shell/auto_background.py +56 -49
  135. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/tools/shell/base.py +1 -1
  136. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/tools/shell/base_process.py +75 -75
  137. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/tools/shell/bash_session.py +2 -2
  138. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/tools/shell/bash_session_executor.py +4 -4
  139. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/tools/shell/bash_tool.py +24 -31
  140. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/tools/shell/command_executor.py +12 -12
  141. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/tools/shell/logs.py +43 -33
  142. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/tools/shell/npx.py +13 -13
  143. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/tools/shell/npx_background.py +24 -21
  144. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/tools/shell/npx_tool.py +18 -22
  145. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/tools/shell/open.py +19 -21
  146. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/tools/shell/pkill.py +31 -26
  147. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/tools/shell/process_tool.py +32 -32
  148. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/tools/shell/processes.py +57 -58
  149. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/tools/shell/run_background.py +24 -25
  150. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/tools/shell/run_command.py +5 -5
  151. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/tools/shell/run_command_windows.py +5 -5
  152. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/tools/shell/session_storage.py +3 -3
  153. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/tools/shell/streaming_command.py +141 -126
  154. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/tools/shell/uvx.py +24 -25
  155. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/tools/shell/uvx_background.py +35 -33
  156. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/tools/shell/uvx_tool.py +18 -22
  157. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/tools/todo/__init__.py +6 -2
  158. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/tools/todo/todo.py +50 -37
  159. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/tools/todo/todo_read.py +5 -8
  160. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/tools/todo/todo_write.py +5 -7
  161. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/tools/vector/__init__.py +40 -28
  162. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/tools/vector/ast_analyzer.py +176 -143
  163. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/tools/vector/git_ingester.py +170 -179
  164. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/tools/vector/index_tool.py +96 -44
  165. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/tools/vector/infinity_store.py +283 -228
  166. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/tools/vector/mock_infinity.py +39 -40
  167. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/tools/vector/project_manager.py +88 -78
  168. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/tools/vector/vector.py +59 -42
  169. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/tools/vector/vector_index.py +30 -27
  170. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/tools/vector/vector_search.py +64 -45
  171. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/types.py +6 -4
  172. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp.egg-info/PKG-INFO +1 -1
  173. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp.egg-info/SOURCES.txt +6 -0
  174. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/pyproject.toml +1 -1
  175. hanzo_mcp-0.8.0/tests/test_agent_tools_ci.py +171 -0
  176. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/tests/test_async_support.py +1 -0
  177. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/tests/test_batch_tool_edge_cases.py +79 -90
  178. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/tests/test_cli.py +103 -107
  179. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/tests/test_cli_agents.py +93 -83
  180. hanzo_mcp-0.8.0/tests/test_e2e_demo.py +207 -0
  181. hanzo_mcp-0.8.0/tests/test_e2e_simple.py +86 -0
  182. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/tests/test_failure_cases.py +50 -49
  183. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/tests/test_find_tool_ffind.py +103 -106
  184. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/tests/test_find_tool_integration.py +83 -146
  185. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/tests/test_find_tool_registration.py +33 -42
  186. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/tests/test_git_ingestion.py +168 -129
  187. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/tests/test_hanzo_agents_integration.py +24 -21
  188. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/tests/test_hanzo_mcp_integration.py +79 -89
  189. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/tests/test_hanzo_mcp_local.py +56 -80
  190. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/tests/test_hanzo_mcp_simple.py +51 -55
  191. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/tests/test_hanzo_network_integration.py +164 -182
  192. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/tests/test_litellm_warnings.py +18 -15
  193. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/tests/test_lsp_tool.py +36 -47
  194. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/tests/test_manual.py +36 -31
  195. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/tests/test_memory_basic.py +28 -18
  196. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/tests/test_memory_edge_cases.py +189 -183
  197. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/tests/test_memory_simple.py +7 -11
  198. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/tests/test_memory_tools.py +85 -60
  199. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/tests/test_memory_tools_comprehensive.py +305 -273
  200. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/tests/test_memory_utils.py +8 -4
  201. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/tests/test_new_tools.py +153 -183
  202. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/tests/test_performance.py +154 -145
  203. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/tests/test_search.py +153 -135
  204. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/tests/test_search_quality.py +201 -138
  205. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/tests/test_shell_features.py +62 -70
  206. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/tests/test_simple.py +64 -58
  207. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/tests/test_stdio_protocol.py +37 -43
  208. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/tests/test_stdio_simple.py +15 -13
  209. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/tests/test_streaming_command.py +64 -70
  210. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/tests/test_swarm_simple.py +73 -61
  211. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/tests/test_tools_suite.py +220 -241
  212. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/tests/test_unified_search.py +48 -75
  213. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/tests/test_utils.py +72 -58
  214. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/tests/test_vector_store.py +97 -99
  215. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/tests/test_web3_integration.py +113 -126
  216. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/README.md +0 -0
  217. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/prompts/compact_conversation.py +0 -0
  218. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/prompts/create_release.py +0 -0
  219. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/prompts/project_system.py +0 -0
  220. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/prompts/utils.py +0 -0
  221. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/tools/common/__init__.py +1 -1
  222. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/tools/common/validation.py +0 -0
  223. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/tools/editor/__init__.py +0 -0
  224. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/tools/filesystem/base.py +1 -1
  225. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/tools/shell/session_manager.py +0 -0
  226. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp/tools/todo/base.py +0 -0
  227. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp.egg-info/dependency_links.txt +0 -0
  228. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp.egg-info/entry_points.txt +0 -0
  229. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp.egg-info/requires.txt +0 -0
  230. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/hanzo_mcp.egg-info/top_level.txt +0 -0
  231. {hanzo_mcp-0.7.6 → hanzo_mcp-0.8.0}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: hanzo-mcp
3
- Version: 0.7.6
3
+ Version: 0.8.0
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
@@ -2,11 +2,17 @@
2
2
 
3
3
  # Configure FastMCP logging globally for stdio transport
4
4
  import os
5
+ import warnings
6
+
7
+ # Suppress litellm deprecation warnings about event loop
8
+ warnings.filterwarnings("ignore", message="There is no current event loop", category=DeprecationWarning)
9
+
5
10
  if os.environ.get("HANZO_MCP_TRANSPORT") == "stdio":
6
11
  try:
7
12
  from fastmcp.utilities.logging import configure_logging
13
+
8
14
  configure_logging(level="ERROR")
9
15
  except ImportError:
10
16
  pass
11
17
 
12
- __version__ = "0.6.13"
18
+ __version__ = "0.7.7"
@@ -3,4 +3,4 @@
3
3
  from hanzo_mcp.cli import main
4
4
 
5
5
  if __name__ == "__main__":
6
- main()
6
+ main()
@@ -1,5 +1,5 @@
1
1
  """Analytics module for Hanzo MCP using PostHog."""
2
2
 
3
- from .posthog_analytics import Analytics, track_event, track_tool_usage, track_error
3
+ from .posthog_analytics import Analytics, track_error, track_event, track_tool_usage
4
4
 
5
- __all__ = ["Analytics", "track_event", "track_tool_usage", "track_error"]
5
+ __all__ = ["Analytics", "track_event", "track_tool_usage", "track_error"]
@@ -9,29 +9,31 @@ This module provides analytics tracking for:
9
9
 
10
10
  import os
11
11
  import time
12
+ import asyncio
13
+ import platform
12
14
  import functools
13
15
  import traceback
14
- from typing import Dict, Any, Optional, Callable, TypeVar
16
+ from typing import Any, Dict, TypeVar, Callable, Optional
15
17
  from datetime import datetime
16
- import platform
17
- import asyncio
18
18
  from dataclasses import dataclass
19
19
 
20
20
  # Try to import PostHog, but make it optional
21
21
  try:
22
22
  from posthog import Posthog
23
+
23
24
  POSTHOG_AVAILABLE = True
24
25
  except ImportError:
25
26
  POSTHOG_AVAILABLE = False
26
27
  Posthog = None
27
28
 
28
29
 
29
- F = TypeVar('F', bound=Callable[..., Any])
30
+ F = TypeVar("F", bound=Callable[..., Any])
30
31
 
31
32
 
32
33
  @dataclass
33
34
  class AnalyticsConfig:
34
35
  """Configuration for analytics."""
36
+
35
37
  api_key: Optional[str] = None
36
38
  host: str = "https://us.i.posthog.com"
37
39
  enabled: bool = True
@@ -39,56 +41,57 @@ class AnalyticsConfig:
39
41
  capture_errors: bool = True
40
42
  capture_performance: bool = True
41
43
  distinct_id: Optional[str] = None
42
-
44
+
43
45
 
44
46
  class Analytics:
45
47
  """Main analytics class for Hanzo MCP."""
46
-
48
+
47
49
  def __init__(self, config: Optional[AnalyticsConfig] = None):
48
50
  """Initialize analytics with configuration."""
49
51
  self.config = config or AnalyticsConfig()
50
52
  self._client = None
51
-
53
+
52
54
  # Load from environment if not provided
53
55
  if not self.config.api_key:
54
56
  self.config.api_key = os.environ.get("POSTHOG_API_KEY")
55
-
57
+
56
58
  if not self.config.distinct_id:
57
59
  # Use machine ID or generate one
58
60
  self.config.distinct_id = self._get_distinct_id()
59
-
61
+
60
62
  # Initialize PostHog if available and configured
61
63
  if POSTHOG_AVAILABLE and self.config.api_key and self.config.enabled:
62
64
  self._client = Posthog(
63
65
  self.config.api_key,
64
66
  host=self.config.host,
65
67
  debug=self.config.debug,
66
- enable_exception_autocapture=self.config.capture_errors
68
+ enable_exception_autocapture=self.config.capture_errors,
67
69
  )
68
-
70
+
69
71
  def _get_distinct_id(self) -> str:
70
72
  """Get a distinct ID for this installation."""
71
73
  # Try to get from environment
72
74
  distinct_id = os.environ.get("HANZO_DISTINCT_ID")
73
75
  if distinct_id:
74
76
  return distinct_id
75
-
77
+
76
78
  # Use hostname + username as fallback
77
79
  import socket
78
80
  import getpass
81
+
79
82
  hostname = socket.gethostname()
80
83
  username = getpass.getuser()
81
84
  return f"{hostname}:{username}"
82
-
85
+
83
86
  def is_enabled(self) -> bool:
84
87
  """Check if analytics is enabled."""
85
88
  return bool(self._client and self.config.enabled)
86
-
89
+
87
90
  def capture(self, event: str, properties: Optional[Dict[str, Any]] = None) -> None:
88
91
  """Capture an analytics event."""
89
92
  if not self.is_enabled():
90
93
  return
91
-
94
+
92
95
  try:
93
96
  # Add common properties
94
97
  props = {
@@ -96,97 +99,84 @@ class Analytics:
96
99
  "platform": platform.system(),
97
100
  "python_version": platform.python_version(),
98
101
  "mcp_version": "0.6.13", # TODO: Get from package
99
- **(properties or {})
102
+ **(properties or {}),
100
103
  }
101
-
102
- self._client.capture(
103
- self.config.distinct_id,
104
- event,
105
- properties=props
106
- )
104
+
105
+ self._client.capture(self.config.distinct_id, event, properties=props)
107
106
  except Exception as e:
108
107
  if self.config.debug:
109
108
  print(f"Analytics error: {e}")
110
-
109
+
111
110
  def identify(self, properties: Optional[Dict[str, Any]] = None) -> None:
112
111
  """Identify the current user/installation."""
113
112
  if not self.is_enabled():
114
113
  return
115
-
114
+
116
115
  try:
117
- self._client.identify(
118
- self.config.distinct_id,
119
- properties=properties or {}
120
- )
116
+ self._client.identify(self.config.distinct_id, properties=properties or {})
121
117
  except Exception as e:
122
118
  if self.config.debug:
123
119
  print(f"Analytics identify error: {e}")
124
-
125
- def track_tool_usage(self,
126
- tool_name: str,
127
- duration_ms: Optional[float] = None,
128
- success: bool = True,
129
- error: Optional[str] = None,
130
- metadata: Optional[Dict[str, Any]] = None) -> None:
120
+
121
+ def track_tool_usage(
122
+ self,
123
+ tool_name: str,
124
+ duration_ms: Optional[float] = None,
125
+ success: bool = True,
126
+ error: Optional[str] = None,
127
+ metadata: Optional[Dict[str, Any]] = None,
128
+ ) -> None:
131
129
  """Track tool usage event."""
132
- properties = {
133
- "tool_name": tool_name,
134
- "success": success,
135
- **(metadata or {})
136
- }
137
-
130
+ properties = {"tool_name": tool_name, "success": success, **(metadata or {})}
131
+
138
132
  if duration_ms is not None:
139
133
  properties["duration_ms"] = duration_ms
140
-
134
+
141
135
  if error:
142
136
  properties["error"] = str(error)
143
-
137
+
144
138
  self.capture("tool_used", properties)
145
-
146
- def track_error(self,
147
- error: Exception,
148
- context: Optional[Dict[str, Any]] = None) -> None:
139
+
140
+ def track_error(
141
+ self, error: Exception, context: Optional[Dict[str, Any]] = None
142
+ ) -> None:
149
143
  """Track an error event."""
150
144
  if not self.config.capture_errors:
151
145
  return
152
-
146
+
153
147
  properties = {
154
148
  "error_type": type(error).__name__,
155
149
  "error_message": str(error),
156
150
  "error_traceback": traceback.format_exc(),
157
- **(context or {})
151
+ **(context or {}),
158
152
  }
159
-
153
+
160
154
  self.capture("error_occurred", properties)
161
-
155
+
162
156
  def feature_enabled(self, flag_key: str, default: bool = False) -> bool:
163
157
  """Check if a feature flag is enabled."""
164
158
  if not self.is_enabled():
165
159
  return default
166
-
160
+
167
161
  try:
168
162
  return self._client.feature_enabled(
169
- flag_key,
170
- self.config.distinct_id,
171
- default=default
163
+ flag_key, self.config.distinct_id, default=default
172
164
  )
173
165
  except Exception:
174
166
  return default
175
-
167
+
176
168
  def get_feature_flag(self, flag_key: str, default: Any = None) -> Any:
177
169
  """Get feature flag value."""
178
170
  if not self.is_enabled():
179
171
  return default
180
-
172
+
181
173
  try:
182
174
  return self._client.get_feature_flag(
183
- flag_key,
184
- self.config.distinct_id,
185
- default=default
175
+ flag_key, self.config.distinct_id, default=default
186
176
  )
187
177
  except Exception:
188
178
  return default
189
-
179
+
190
180
  def flush(self) -> None:
191
181
  """Flush any pending events."""
192
182
  if self.is_enabled():
@@ -194,7 +184,7 @@ class Analytics:
194
184
  self._client.flush()
195
185
  except Exception:
196
186
  pass
197
-
187
+
198
188
  def shutdown(self) -> None:
199
189
  """Shutdown analytics client."""
200
190
  if self.is_enabled():
@@ -233,6 +223,7 @@ def track_error(error: Exception, context: Optional[Dict[str, Any]] = None) -> N
233
223
 
234
224
  def with_analytics(tool_name: str):
235
225
  """Decorator to track tool usage with analytics."""
226
+
236
227
  def decorator(func: F) -> F:
237
228
  @functools.wraps(func)
238
229
  async def async_wrapper(*args, **kwargs):
@@ -251,9 +242,9 @@ def with_analytics(tool_name: str):
251
242
  tool_name,
252
243
  duration_ms=duration_ms,
253
244
  success=error is None,
254
- error=str(error) if error else None
245
+ error=str(error) if error else None,
255
246
  )
256
-
247
+
257
248
  @functools.wraps(func)
258
249
  def sync_wrapper(*args, **kwargs):
259
250
  start_time = time.time()
@@ -271,20 +262,21 @@ def with_analytics(tool_name: str):
271
262
  tool_name,
272
263
  duration_ms=duration_ms,
273
264
  success=error is None,
274
- error=str(error) if error else None
265
+ error=str(error) if error else None,
275
266
  )
276
-
267
+
277
268
  # Return appropriate wrapper based on function type
278
269
  if asyncio.iscoroutinefunction(func):
279
270
  return async_wrapper
280
271
  else:
281
272
  return sync_wrapper
282
-
273
+
283
274
  return decorator
284
275
 
285
276
 
286
277
  def feature_flag(flag_key: str, default: bool = False):
287
278
  """Decorator to conditionally enable features based on flags."""
279
+
288
280
  def decorator(func: F) -> F:
289
281
  @functools.wraps(func)
290
282
  def wrapper(*args, **kwargs):
@@ -292,40 +284,42 @@ def feature_flag(flag_key: str, default: bool = False):
292
284
  return func(*args, **kwargs)
293
285
  else:
294
286
  raise NotImplementedError(f"Feature '{flag_key}' is not enabled")
287
+
295
288
  return wrapper
289
+
296
290
  return decorator
297
291
 
298
292
 
299
293
  # Tool usage context manager
300
294
  class ToolUsageTracker:
301
295
  """Context manager for tracking tool usage."""
302
-
296
+
303
297
  def __init__(self, tool_name: str, metadata: Optional[Dict[str, Any]] = None):
304
298
  self.tool_name = tool_name
305
299
  self.metadata = metadata or {}
306
300
  self.start_time = None
307
301
  self.error = None
308
-
302
+
309
303
  def __enter__(self):
310
304
  self.start_time = time.time()
311
305
  return self
312
-
306
+
313
307
  def __exit__(self, exc_type, exc_val, exc_tb):
314
308
  duration_ms = (time.time() - self.start_time) * 1000
315
309
  success = exc_type is None
316
-
310
+
317
311
  if exc_type:
318
312
  self.error = str(exc_val)
319
313
  track_error(exc_val, {"tool": self.tool_name, **self.metadata})
320
-
314
+
321
315
  track_tool_usage(
322
316
  self.tool_name,
323
317
  duration_ms=duration_ms,
324
318
  success=success,
325
319
  error=self.error,
326
- metadata=self.metadata
320
+ metadata=self.metadata,
327
321
  )
328
-
322
+
329
323
  # Don't suppress exceptions
330
324
  return False
331
325
 
@@ -333,32 +327,32 @@ class ToolUsageTracker:
333
327
  # Async context manager version
334
328
  class AsyncToolUsageTracker:
335
329
  """Async context manager for tracking tool usage."""
336
-
330
+
337
331
  def __init__(self, tool_name: str, metadata: Optional[Dict[str, Any]] = None):
338
332
  self.tool_name = tool_name
339
333
  self.metadata = metadata or {}
340
334
  self.start_time = None
341
335
  self.error = None
342
-
336
+
343
337
  async def __aenter__(self):
344
338
  self.start_time = time.time()
345
339
  return self
346
-
340
+
347
341
  async def __aexit__(self, exc_type, exc_val, exc_tb):
348
342
  duration_ms = (time.time() - self.start_time) * 1000
349
343
  success = exc_type is None
350
-
344
+
351
345
  if exc_type:
352
346
  self.error = str(exc_val)
353
347
  track_error(exc_val, {"tool": self.tool_name, **self.metadata})
354
-
348
+
355
349
  track_tool_usage(
356
350
  self.tool_name,
357
351
  duration_ms=duration_ms,
358
352
  success=success,
359
353
  error=self.error,
360
- metadata=self.metadata
354
+ metadata=self.metadata,
361
355
  )
362
-
356
+
363
357
  # Don't suppress exceptions
364
- return False
358
+ return False
@@ -1,57 +1,59 @@
1
1
  """Command-line interface for the Hanzo AI server."""
2
2
 
3
- import argparse
4
- import json
5
- import logging
6
3
  import os
7
- import signal
8
4
  import sys
9
- from pathlib import Path
5
+ import json
6
+ import signal
7
+ import logging
8
+ import argparse
10
9
  from typing import Any, cast
10
+ from pathlib import Path
11
11
 
12
12
  from hanzo_mcp.server import HanzoMCPServer
13
13
 
14
14
 
15
15
  def main() -> None:
16
16
  """Run the CLI for the Hanzo AI server."""
17
-
17
+
18
18
  # Pre-parse arguments to check transport type early
19
19
  import sys
20
+
20
21
  early_parser = argparse.ArgumentParser(add_help=False)
21
22
  early_parser.add_argument("--transport", choices=["stdio", "sse"], default="stdio")
22
23
  early_args, _ = early_parser.parse_known_args()
23
-
24
+
24
25
  # Configure logging VERY early based on transport
25
26
  if early_args.transport == "stdio":
26
27
  # Set environment variable for server to detect stdio mode
27
28
  import os
29
+
28
30
  os.environ["HANZO_MCP_TRANSPORT"] = "stdio"
29
-
31
+
30
32
  # For stdio transport, disable ALL logging immediately
31
33
  from fastmcp.utilities.logging import configure_logging
34
+
32
35
  # Set to ERROR to suppress INFO/WARNING messages from FastMCP
33
36
  configure_logging(level="ERROR")
34
-
37
+
35
38
  # Also configure standard logging to ERROR level
36
39
  logging.basicConfig(
37
40
  level=logging.ERROR, # Only show errors
38
- handlers=[] # No handlers for stdio to prevent protocol corruption
41
+ handlers=[], # No handlers for stdio to prevent protocol corruption
39
42
  )
40
-
43
+
41
44
  # Redirect stderr to devnull for stdio transport to prevent any output
42
45
  import sys
43
- sys.stderr = open(os.devnull, 'w')
44
-
46
+
47
+ sys.stderr = open(os.devnull, "w")
48
+
45
49
  from hanzo_mcp import __version__
46
-
50
+
47
51
  parser = argparse.ArgumentParser(
48
52
  description="MCP server implementing Hanzo AI capabilities"
49
53
  )
50
-
54
+
51
55
  parser.add_argument(
52
- "--version",
53
- action="version",
54
- version=f"hanzo-mcp {__version__}"
56
+ "--version", action="version", version=f"hanzo-mcp {__version__}"
55
57
  )
56
58
 
57
59
  _ = parser.add_argument(
@@ -188,7 +190,7 @@ def main() -> None:
188
190
  action="store_true",
189
191
  help="Run in development mode with hot reload",
190
192
  )
191
-
193
+
192
194
  _ = parser.add_argument(
193
195
  "--install",
194
196
  action="store_true",
@@ -232,27 +234,22 @@ def main() -> None:
232
234
 
233
235
  if install:
234
236
  install_claude_desktop_config(
235
- name,
236
- allowed_paths,
237
- disable_write_tools,
238
- disable_search_tools,
239
- host,
240
- port
237
+ name, allowed_paths, disable_write_tools, disable_search_tools, host, port
241
238
  )
242
239
  return
243
240
 
244
241
  # Get logger
245
242
  logger = logging.getLogger(__name__)
246
-
243
+
247
244
  # Set up signal handler to ensure clean exit
248
245
  def signal_handler(signum, frame):
249
246
  if transport != "stdio":
250
247
  logger.info("\nReceived interrupt signal, shutting down...")
251
248
  sys.exit(0)
252
-
249
+
253
250
  signal.signal(signal.SIGINT, signal_handler)
254
251
  signal.signal(signal.SIGTERM, signal_handler)
255
-
252
+
256
253
  # Configure logging based on transport (stdio already configured early)
257
254
  if transport != "stdio":
258
255
  # For SSE transport, logging is fine
@@ -260,11 +257,11 @@ def main() -> None:
260
257
  "DEBUG": logging.DEBUG,
261
258
  "INFO": logging.INFO,
262
259
  "WARNING": logging.WARNING,
263
- "ERROR": logging.ERROR
260
+ "ERROR": logging.ERROR,
264
261
  }
265
262
  logging.basicConfig(
266
263
  level=log_level_map.get(log_level, logging.INFO),
267
- format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
264
+ format="%(asctime)s - %(name)s - %(levelname)s - %(message)s",
268
265
  )
269
266
 
270
267
  # If no allowed paths are specified, use the current directory
@@ -274,7 +271,7 @@ def main() -> None:
274
271
  # Run in dev mode if requested
275
272
  if dev:
276
273
  from hanzo_mcp.dev_server import DevServer
277
-
274
+
278
275
  dev_server = DevServer(
279
276
  name=name,
280
277
  allowed_paths=allowed_paths,
@@ -315,7 +312,7 @@ def main() -> None:
315
312
  host=host,
316
313
  port=port,
317
314
  )
318
-
315
+
319
316
  try:
320
317
  # Transport will be automatically cast to Literal['stdio', 'sse'] by the server
321
318
  server.run(transport=transport)
@@ -378,7 +375,7 @@ def install_claude_desktop_config(
378
375
  # Add tool disable flags if specified
379
376
  if disable_write_tools:
380
377
  args.append("--disable-write-tools")
381
-
378
+
382
379
  if disable_search_tools:
383
380
  args.append("--disable-search-tools")
384
381
 
@@ -419,9 +416,7 @@ def install_claude_desktop_config(
419
416
  else:
420
417
  logger.info(f"\nDefault allowed path: {home}")
421
418
 
422
- logger.info(
423
- "\nYou can modify allowed paths in the config file directly."
424
- )
419
+ logger.info("\nYou can modify allowed paths in the config file directly.")
425
420
  logger.info("Restart Claude Desktop for changes to take effect.")
426
421
 
427
422