claude-mpm 3.9.11__py3-none-any.whl → 4.0.3__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.
Files changed (419) hide show
  1. claude_mpm/VERSION +1 -1
  2. claude_mpm/__init__.py +2 -2
  3. claude_mpm/__main__.py +3 -2
  4. claude_mpm/agents/__init__.py +85 -79
  5. claude_mpm/agents/agent_loader.py +464 -1003
  6. claude_mpm/agents/agent_loader_integration.py +45 -45
  7. claude_mpm/agents/agents_metadata.py +29 -30
  8. claude_mpm/agents/async_agent_loader.py +156 -138
  9. claude_mpm/agents/base_agent.json +1 -1
  10. claude_mpm/agents/base_agent_loader.py +179 -151
  11. claude_mpm/agents/frontmatter_validator.py +229 -130
  12. claude_mpm/agents/schema/agent_schema.json +1 -1
  13. claude_mpm/agents/system_agent_config.py +213 -147
  14. claude_mpm/agents/templates/__init__.py +13 -13
  15. claude_mpm/agents/templates/code_analyzer.json +2 -2
  16. claude_mpm/agents/templates/data_engineer.json +1 -1
  17. claude_mpm/agents/templates/documentation.json +23 -11
  18. claude_mpm/agents/templates/engineer.json +22 -6
  19. claude_mpm/agents/templates/memory_manager.json +1 -1
  20. claude_mpm/agents/templates/ops.json +2 -2
  21. claude_mpm/agents/templates/project_organizer.json +1 -1
  22. claude_mpm/agents/templates/qa.json +1 -1
  23. claude_mpm/agents/templates/refactoring_engineer.json +222 -0
  24. claude_mpm/agents/templates/research.json +20 -14
  25. claude_mpm/agents/templates/security.json +1 -1
  26. claude_mpm/agents/templates/ticketing.json +1 -1
  27. claude_mpm/agents/templates/version_control.json +1 -1
  28. claude_mpm/agents/templates/web_qa.json +3 -1
  29. claude_mpm/agents/templates/web_ui.json +2 -2
  30. claude_mpm/cli/__init__.py +79 -51
  31. claude_mpm/cli/__main__.py +3 -2
  32. claude_mpm/cli/commands/__init__.py +20 -20
  33. claude_mpm/cli/commands/agents.py +279 -247
  34. claude_mpm/cli/commands/aggregate.py +138 -157
  35. claude_mpm/cli/commands/cleanup.py +147 -147
  36. claude_mpm/cli/commands/config.py +93 -76
  37. claude_mpm/cli/commands/info.py +17 -16
  38. claude_mpm/cli/commands/mcp.py +140 -905
  39. claude_mpm/cli/commands/mcp_command_router.py +139 -0
  40. claude_mpm/cli/commands/mcp_config_commands.py +20 -0
  41. claude_mpm/cli/commands/mcp_install_commands.py +20 -0
  42. claude_mpm/cli/commands/mcp_server_commands.py +175 -0
  43. claude_mpm/cli/commands/mcp_tool_commands.py +34 -0
  44. claude_mpm/cli/commands/memory.py +239 -203
  45. claude_mpm/cli/commands/monitor.py +203 -81
  46. claude_mpm/cli/commands/run.py +380 -429
  47. claude_mpm/cli/commands/run_config_checker.py +160 -0
  48. claude_mpm/cli/commands/socketio_monitor.py +235 -0
  49. claude_mpm/cli/commands/tickets.py +305 -197
  50. claude_mpm/cli/parser.py +24 -1156
  51. claude_mpm/cli/parsers/__init__.py +29 -0
  52. claude_mpm/cli/parsers/agents_parser.py +136 -0
  53. claude_mpm/cli/parsers/base_parser.py +331 -0
  54. claude_mpm/cli/parsers/config_parser.py +85 -0
  55. claude_mpm/cli/parsers/mcp_parser.py +152 -0
  56. claude_mpm/cli/parsers/memory_parser.py +138 -0
  57. claude_mpm/cli/parsers/monitor_parser.py +104 -0
  58. claude_mpm/cli/parsers/run_parser.py +147 -0
  59. claude_mpm/cli/parsers/tickets_parser.py +203 -0
  60. claude_mpm/cli/ticket_cli.py +7 -3
  61. claude_mpm/cli/utils.py +55 -37
  62. claude_mpm/cli_module/__init__.py +6 -6
  63. claude_mpm/cli_module/args.py +188 -140
  64. claude_mpm/cli_module/commands.py +79 -70
  65. claude_mpm/cli_module/migration_example.py +38 -60
  66. claude_mpm/config/__init__.py +32 -25
  67. claude_mpm/config/agent_config.py +151 -119
  68. claude_mpm/config/experimental_features.py +71 -73
  69. claude_mpm/config/paths.py +94 -208
  70. claude_mpm/config/socketio_config.py +84 -73
  71. claude_mpm/constants.py +35 -18
  72. claude_mpm/core/__init__.py +9 -6
  73. claude_mpm/core/agent_name_normalizer.py +68 -71
  74. claude_mpm/core/agent_registry.py +372 -521
  75. claude_mpm/core/agent_session_manager.py +74 -63
  76. claude_mpm/core/base_service.py +116 -87
  77. claude_mpm/core/cache.py +119 -153
  78. claude_mpm/core/claude_runner.py +425 -1120
  79. claude_mpm/core/config.py +263 -168
  80. claude_mpm/core/config_aliases.py +69 -61
  81. claude_mpm/core/config_constants.py +292 -0
  82. claude_mpm/core/constants.py +57 -99
  83. claude_mpm/core/container.py +211 -178
  84. claude_mpm/core/exceptions.py +233 -89
  85. claude_mpm/core/factories.py +92 -54
  86. claude_mpm/core/framework_loader.py +378 -220
  87. claude_mpm/core/hook_manager.py +198 -83
  88. claude_mpm/core/hook_performance_config.py +136 -0
  89. claude_mpm/core/injectable_service.py +61 -55
  90. claude_mpm/core/interactive_session.py +165 -155
  91. claude_mpm/core/interfaces.py +221 -195
  92. claude_mpm/core/lazy.py +96 -96
  93. claude_mpm/core/logger.py +133 -107
  94. claude_mpm/core/logging_config.py +185 -157
  95. claude_mpm/core/minimal_framework_loader.py +20 -15
  96. claude_mpm/core/mixins.py +30 -29
  97. claude_mpm/core/oneshot_session.py +215 -181
  98. claude_mpm/core/optimized_agent_loader.py +134 -138
  99. claude_mpm/core/optimized_startup.py +159 -157
  100. claude_mpm/core/pm_hook_interceptor.py +85 -72
  101. claude_mpm/core/service_registry.py +103 -101
  102. claude_mpm/core/session_manager.py +97 -87
  103. claude_mpm/core/socketio_pool.py +212 -158
  104. claude_mpm/core/tool_access_control.py +58 -51
  105. claude_mpm/core/types.py +46 -24
  106. claude_mpm/core/typing_utils.py +166 -82
  107. claude_mpm/core/unified_agent_registry.py +721 -0
  108. claude_mpm/core/unified_config.py +550 -0
  109. claude_mpm/core/unified_paths.py +549 -0
  110. claude_mpm/dashboard/index.html +1 -1
  111. claude_mpm/dashboard/open_dashboard.py +51 -17
  112. claude_mpm/dashboard/static/css/dashboard.css +27 -8
  113. claude_mpm/dashboard/static/dist/components/agent-inference.js +2 -0
  114. claude_mpm/dashboard/static/dist/components/event-processor.js +2 -0
  115. claude_mpm/dashboard/static/dist/components/event-viewer.js +2 -0
  116. claude_mpm/dashboard/static/dist/components/export-manager.js +2 -0
  117. claude_mpm/dashboard/static/dist/components/file-tool-tracker.js +2 -0
  118. claude_mpm/dashboard/static/dist/components/hud-library-loader.js +2 -0
  119. claude_mpm/dashboard/static/dist/components/hud-manager.js +2 -0
  120. claude_mpm/dashboard/static/dist/components/hud-visualizer.js +2 -0
  121. claude_mpm/dashboard/static/dist/components/module-viewer.js +2 -0
  122. claude_mpm/dashboard/static/dist/components/session-manager.js +2 -0
  123. claude_mpm/dashboard/static/dist/components/socket-manager.js +2 -0
  124. claude_mpm/dashboard/static/dist/components/ui-state-manager.js +2 -0
  125. claude_mpm/dashboard/static/dist/components/working-directory.js +2 -0
  126. claude_mpm/dashboard/static/dist/dashboard.js +2 -0
  127. claude_mpm/dashboard/static/dist/socket-client.js +2 -0
  128. claude_mpm/dashboard/static/js/components/agent-inference.js +80 -76
  129. claude_mpm/dashboard/static/js/components/event-processor.js +71 -67
  130. claude_mpm/dashboard/static/js/components/event-viewer.js +74 -70
  131. claude_mpm/dashboard/static/js/components/export-manager.js +31 -28
  132. claude_mpm/dashboard/static/js/components/file-tool-tracker.js +106 -92
  133. claude_mpm/dashboard/static/js/components/hud-library-loader.js +11 -11
  134. claude_mpm/dashboard/static/js/components/hud-manager.js +73 -73
  135. claude_mpm/dashboard/static/js/components/hud-visualizer.js +163 -163
  136. claude_mpm/dashboard/static/js/components/module-viewer.js +305 -233
  137. claude_mpm/dashboard/static/js/components/session-manager.js +32 -29
  138. claude_mpm/dashboard/static/js/components/socket-manager.js +27 -20
  139. claude_mpm/dashboard/static/js/components/ui-state-manager.js +21 -18
  140. claude_mpm/dashboard/static/js/components/working-directory.js +74 -71
  141. claude_mpm/dashboard/static/js/dashboard.js +178 -453
  142. claude_mpm/dashboard/static/js/extension-error-handler.js +164 -0
  143. claude_mpm/dashboard/static/js/socket-client.js +120 -54
  144. claude_mpm/dashboard/templates/index.html +40 -50
  145. claude_mpm/experimental/cli_enhancements.py +60 -58
  146. claude_mpm/generators/__init__.py +1 -1
  147. claude_mpm/generators/agent_profile_generator.py +75 -65
  148. claude_mpm/hooks/__init__.py +1 -1
  149. claude_mpm/hooks/base_hook.py +33 -28
  150. claude_mpm/hooks/claude_hooks/__init__.py +1 -1
  151. claude_mpm/hooks/claude_hooks/connection_pool.py +120 -0
  152. claude_mpm/hooks/claude_hooks/event_handlers.py +743 -0
  153. claude_mpm/hooks/claude_hooks/hook_handler.py +415 -1331
  154. claude_mpm/hooks/claude_hooks/hook_wrapper.sh +4 -4
  155. claude_mpm/hooks/claude_hooks/memory_integration.py +221 -0
  156. claude_mpm/hooks/claude_hooks/response_tracking.py +348 -0
  157. claude_mpm/hooks/claude_hooks/tool_analysis.py +230 -0
  158. claude_mpm/hooks/memory_integration_hook.py +140 -100
  159. claude_mpm/hooks/tool_call_interceptor.py +89 -76
  160. claude_mpm/hooks/validation_hooks.py +57 -49
  161. claude_mpm/init.py +145 -121
  162. claude_mpm/models/__init__.py +9 -9
  163. claude_mpm/models/agent_definition.py +33 -23
  164. claude_mpm/models/agent_session.py +228 -200
  165. claude_mpm/scripts/__init__.py +1 -1
  166. claude_mpm/scripts/socketio_daemon.py +192 -75
  167. claude_mpm/scripts/socketio_server_manager.py +328 -0
  168. claude_mpm/scripts/start_activity_logging.py +25 -22
  169. claude_mpm/services/__init__.py +68 -43
  170. claude_mpm/services/agent_capabilities_service.py +271 -0
  171. claude_mpm/services/agents/__init__.py +23 -32
  172. claude_mpm/services/agents/deployment/__init__.py +3 -3
  173. claude_mpm/services/agents/deployment/agent_config_provider.py +310 -0
  174. claude_mpm/services/agents/deployment/agent_configuration_manager.py +359 -0
  175. claude_mpm/services/agents/deployment/agent_definition_factory.py +84 -0
  176. claude_mpm/services/agents/deployment/agent_deployment.py +415 -2113
  177. claude_mpm/services/agents/deployment/agent_discovery_service.py +387 -0
  178. claude_mpm/services/agents/deployment/agent_environment_manager.py +293 -0
  179. claude_mpm/services/agents/deployment/agent_filesystem_manager.py +387 -0
  180. claude_mpm/services/agents/deployment/agent_format_converter.py +453 -0
  181. claude_mpm/services/agents/deployment/agent_frontmatter_validator.py +161 -0
  182. claude_mpm/services/agents/deployment/agent_lifecycle_manager.py +345 -495
  183. claude_mpm/services/agents/deployment/agent_metrics_collector.py +279 -0
  184. claude_mpm/services/agents/deployment/agent_restore_handler.py +88 -0
  185. claude_mpm/services/agents/deployment/agent_template_builder.py +406 -0
  186. claude_mpm/services/agents/deployment/agent_validator.py +352 -0
  187. claude_mpm/services/agents/deployment/agent_version_manager.py +313 -0
  188. claude_mpm/services/agents/deployment/agent_versioning.py +6 -9
  189. claude_mpm/services/agents/deployment/agents_directory_resolver.py +79 -0
  190. claude_mpm/services/agents/deployment/async_agent_deployment.py +298 -234
  191. claude_mpm/services/agents/deployment/config/__init__.py +13 -0
  192. claude_mpm/services/agents/deployment/config/deployment_config.py +182 -0
  193. claude_mpm/services/agents/deployment/config/deployment_config_manager.py +200 -0
  194. claude_mpm/services/agents/deployment/deployment_config_loader.py +54 -0
  195. claude_mpm/services/agents/deployment/deployment_type_detector.py +124 -0
  196. claude_mpm/services/agents/deployment/facade/__init__.py +18 -0
  197. claude_mpm/services/agents/deployment/facade/async_deployment_executor.py +159 -0
  198. claude_mpm/services/agents/deployment/facade/deployment_executor.py +73 -0
  199. claude_mpm/services/agents/deployment/facade/deployment_facade.py +270 -0
  200. claude_mpm/services/agents/deployment/facade/sync_deployment_executor.py +178 -0
  201. claude_mpm/services/agents/deployment/interface_adapter.py +227 -0
  202. claude_mpm/services/agents/deployment/lifecycle_health_checker.py +85 -0
  203. claude_mpm/services/agents/deployment/lifecycle_performance_tracker.py +100 -0
  204. claude_mpm/services/agents/deployment/pipeline/__init__.py +32 -0
  205. claude_mpm/services/agents/deployment/pipeline/pipeline_builder.py +158 -0
  206. claude_mpm/services/agents/deployment/pipeline/pipeline_context.py +159 -0
  207. claude_mpm/services/agents/deployment/pipeline/pipeline_executor.py +169 -0
  208. claude_mpm/services/agents/deployment/pipeline/steps/__init__.py +19 -0
  209. claude_mpm/services/agents/deployment/pipeline/steps/agent_processing_step.py +195 -0
  210. claude_mpm/services/agents/deployment/pipeline/steps/base_step.py +119 -0
  211. claude_mpm/services/agents/deployment/pipeline/steps/configuration_step.py +79 -0
  212. claude_mpm/services/agents/deployment/pipeline/steps/target_directory_step.py +90 -0
  213. claude_mpm/services/agents/deployment/pipeline/steps/validation_step.py +100 -0
  214. claude_mpm/services/agents/deployment/processors/__init__.py +15 -0
  215. claude_mpm/services/agents/deployment/processors/agent_deployment_context.py +98 -0
  216. claude_mpm/services/agents/deployment/processors/agent_deployment_result.py +235 -0
  217. claude_mpm/services/agents/deployment/processors/agent_processor.py +258 -0
  218. claude_mpm/services/agents/deployment/refactored_agent_deployment_service.py +318 -0
  219. claude_mpm/services/agents/deployment/results/__init__.py +13 -0
  220. claude_mpm/services/agents/deployment/results/deployment_metrics.py +200 -0
  221. claude_mpm/services/agents/deployment/results/deployment_result_builder.py +249 -0
  222. claude_mpm/services/agents/deployment/strategies/__init__.py +25 -0
  223. claude_mpm/services/agents/deployment/strategies/base_strategy.py +119 -0
  224. claude_mpm/services/agents/deployment/strategies/project_strategy.py +150 -0
  225. claude_mpm/services/agents/deployment/strategies/strategy_selector.py +117 -0
  226. claude_mpm/services/agents/deployment/strategies/system_strategy.py +116 -0
  227. claude_mpm/services/agents/deployment/strategies/user_strategy.py +137 -0
  228. claude_mpm/services/agents/deployment/system_instructions_deployer.py +108 -0
  229. claude_mpm/services/agents/deployment/validation/__init__.py +19 -0
  230. claude_mpm/services/agents/deployment/validation/agent_validator.py +323 -0
  231. claude_mpm/services/agents/deployment/validation/deployment_validator.py +238 -0
  232. claude_mpm/services/agents/deployment/validation/template_validator.py +299 -0
  233. claude_mpm/services/agents/deployment/validation/validation_result.py +226 -0
  234. claude_mpm/services/agents/loading/__init__.py +2 -2
  235. claude_mpm/services/agents/loading/agent_profile_loader.py +259 -229
  236. claude_mpm/services/agents/loading/base_agent_manager.py +90 -81
  237. claude_mpm/services/agents/loading/framework_agent_loader.py +154 -129
  238. claude_mpm/services/agents/management/__init__.py +2 -2
  239. claude_mpm/services/agents/management/agent_capabilities_generator.py +72 -58
  240. claude_mpm/services/agents/management/agent_management_service.py +209 -156
  241. claude_mpm/services/agents/memory/__init__.py +9 -6
  242. claude_mpm/services/agents/memory/agent_memory_manager.py +218 -1152
  243. claude_mpm/services/agents/memory/agent_persistence_service.py +20 -16
  244. claude_mpm/services/agents/memory/analyzer.py +430 -0
  245. claude_mpm/services/agents/memory/content_manager.py +376 -0
  246. claude_mpm/services/agents/memory/template_generator.py +468 -0
  247. claude_mpm/services/agents/registry/__init__.py +7 -10
  248. claude_mpm/services/agents/registry/deployed_agent_discovery.py +122 -97
  249. claude_mpm/services/agents/registry/modification_tracker.py +351 -285
  250. claude_mpm/services/async_session_logger.py +187 -153
  251. claude_mpm/services/claude_session_logger.py +87 -72
  252. claude_mpm/services/command_handler_service.py +217 -0
  253. claude_mpm/services/communication/__init__.py +3 -2
  254. claude_mpm/services/core/__init__.py +50 -97
  255. claude_mpm/services/core/base.py +60 -53
  256. claude_mpm/services/core/interfaces/__init__.py +188 -0
  257. claude_mpm/services/core/interfaces/agent.py +351 -0
  258. claude_mpm/services/core/interfaces/communication.py +343 -0
  259. claude_mpm/services/core/interfaces/infrastructure.py +413 -0
  260. claude_mpm/services/core/interfaces/service.py +434 -0
  261. claude_mpm/services/core/interfaces.py +19 -944
  262. claude_mpm/services/event_aggregator.py +208 -170
  263. claude_mpm/services/exceptions.py +387 -308
  264. claude_mpm/services/framework_claude_md_generator/__init__.py +75 -79
  265. claude_mpm/services/framework_claude_md_generator/content_assembler.py +69 -60
  266. claude_mpm/services/framework_claude_md_generator/content_validator.py +65 -61
  267. claude_mpm/services/framework_claude_md_generator/deployment_manager.py +68 -49
  268. claude_mpm/services/framework_claude_md_generator/section_generators/__init__.py +34 -34
  269. claude_mpm/services/framework_claude_md_generator/section_generators/agents.py +25 -22
  270. claude_mpm/services/framework_claude_md_generator/section_generators/claude_pm_init.py +10 -10
  271. claude_mpm/services/framework_claude_md_generator/section_generators/core_responsibilities.py +4 -3
  272. claude_mpm/services/framework_claude_md_generator/section_generators/delegation_constraints.py +4 -3
  273. claude_mpm/services/framework_claude_md_generator/section_generators/environment_config.py +4 -3
  274. claude_mpm/services/framework_claude_md_generator/section_generators/footer.py +6 -5
  275. claude_mpm/services/framework_claude_md_generator/section_generators/header.py +8 -7
  276. claude_mpm/services/framework_claude_md_generator/section_generators/orchestration_principles.py +4 -3
  277. claude_mpm/services/framework_claude_md_generator/section_generators/role_designation.py +6 -5
  278. claude_mpm/services/framework_claude_md_generator/section_generators/subprocess_validation.py +9 -8
  279. claude_mpm/services/framework_claude_md_generator/section_generators/todo_task_tools.py +4 -3
  280. claude_mpm/services/framework_claude_md_generator/section_generators/troubleshooting.py +5 -4
  281. claude_mpm/services/framework_claude_md_generator/section_manager.py +28 -27
  282. claude_mpm/services/framework_claude_md_generator/version_manager.py +30 -28
  283. claude_mpm/services/hook_service.py +106 -114
  284. claude_mpm/services/infrastructure/__init__.py +7 -5
  285. claude_mpm/services/infrastructure/context_preservation.py +233 -199
  286. claude_mpm/services/infrastructure/daemon_manager.py +279 -0
  287. claude_mpm/services/infrastructure/logging.py +83 -76
  288. claude_mpm/services/infrastructure/monitoring.py +547 -404
  289. claude_mpm/services/mcp_gateway/__init__.py +30 -13
  290. claude_mpm/services/mcp_gateway/config/__init__.py +2 -2
  291. claude_mpm/services/mcp_gateway/config/config_loader.py +61 -56
  292. claude_mpm/services/mcp_gateway/config/config_schema.py +50 -41
  293. claude_mpm/services/mcp_gateway/config/configuration.py +82 -75
  294. claude_mpm/services/mcp_gateway/core/__init__.py +13 -20
  295. claude_mpm/services/mcp_gateway/core/base.py +80 -67
  296. claude_mpm/services/mcp_gateway/core/exceptions.py +60 -46
  297. claude_mpm/services/mcp_gateway/core/interfaces.py +87 -84
  298. claude_mpm/services/mcp_gateway/main.py +287 -137
  299. claude_mpm/services/mcp_gateway/registry/__init__.py +1 -1
  300. claude_mpm/services/mcp_gateway/registry/service_registry.py +97 -94
  301. claude_mpm/services/mcp_gateway/registry/tool_registry.py +135 -126
  302. claude_mpm/services/mcp_gateway/server/__init__.py +2 -2
  303. claude_mpm/services/mcp_gateway/server/mcp_gateway.py +105 -110
  304. claude_mpm/services/mcp_gateway/server/stdio_handler.py +105 -107
  305. claude_mpm/services/mcp_gateway/server/stdio_server.py +691 -0
  306. claude_mpm/services/mcp_gateway/tools/__init__.py +4 -2
  307. claude_mpm/services/mcp_gateway/tools/base_adapter.py +109 -119
  308. claude_mpm/services/mcp_gateway/tools/document_summarizer.py +283 -215
  309. claude_mpm/services/mcp_gateway/tools/hello_world.py +122 -120
  310. claude_mpm/services/mcp_gateway/tools/ticket_tools.py +652 -0
  311. claude_mpm/services/mcp_gateway/tools/unified_ticket_tool.py +606 -0
  312. claude_mpm/services/memory/__init__.py +2 -2
  313. claude_mpm/services/memory/builder.py +451 -362
  314. claude_mpm/services/memory/cache/__init__.py +2 -2
  315. claude_mpm/services/memory/cache/shared_prompt_cache.py +232 -194
  316. claude_mpm/services/memory/cache/simple_cache.py +107 -93
  317. claude_mpm/services/memory/indexed_memory.py +195 -193
  318. claude_mpm/services/memory/optimizer.py +267 -234
  319. claude_mpm/services/memory/router.py +571 -263
  320. claude_mpm/services/memory_hook_service.py +237 -0
  321. claude_mpm/services/port_manager.py +223 -0
  322. claude_mpm/services/project/__init__.py +3 -3
  323. claude_mpm/services/project/analyzer.py +451 -305
  324. claude_mpm/services/project/registry.py +262 -240
  325. claude_mpm/services/recovery_manager.py +287 -231
  326. claude_mpm/services/response_tracker.py +87 -67
  327. claude_mpm/services/runner_configuration_service.py +587 -0
  328. claude_mpm/services/session_management_service.py +304 -0
  329. claude_mpm/services/socketio/__init__.py +4 -4
  330. claude_mpm/services/socketio/client_proxy.py +174 -0
  331. claude_mpm/services/socketio/handlers/__init__.py +3 -3
  332. claude_mpm/services/socketio/handlers/base.py +44 -30
  333. claude_mpm/services/socketio/handlers/connection.py +145 -65
  334. claude_mpm/services/socketio/handlers/file.py +123 -108
  335. claude_mpm/services/socketio/handlers/git.py +607 -373
  336. claude_mpm/services/socketio/handlers/hook.py +170 -0
  337. claude_mpm/services/socketio/handlers/memory.py +4 -4
  338. claude_mpm/services/socketio/handlers/project.py +4 -4
  339. claude_mpm/services/socketio/handlers/registry.py +53 -38
  340. claude_mpm/services/socketio/server/__init__.py +18 -0
  341. claude_mpm/services/socketio/server/broadcaster.py +252 -0
  342. claude_mpm/services/socketio/server/core.py +399 -0
  343. claude_mpm/services/socketio/server/main.py +323 -0
  344. claude_mpm/services/socketio_client_manager.py +160 -133
  345. claude_mpm/services/socketio_server.py +36 -1885
  346. claude_mpm/services/subprocess_launcher_service.py +316 -0
  347. claude_mpm/services/system_instructions_service.py +258 -0
  348. claude_mpm/services/ticket_manager.py +19 -533
  349. claude_mpm/services/utility_service.py +285 -0
  350. claude_mpm/services/version_control/__init__.py +18 -21
  351. claude_mpm/services/version_control/branch_strategy.py +20 -10
  352. claude_mpm/services/version_control/conflict_resolution.py +37 -13
  353. claude_mpm/services/version_control/git_operations.py +52 -21
  354. claude_mpm/services/version_control/semantic_versioning.py +92 -53
  355. claude_mpm/services/version_control/version_parser.py +145 -125
  356. claude_mpm/services/version_service.py +270 -0
  357. claude_mpm/storage/__init__.py +2 -2
  358. claude_mpm/storage/state_storage.py +177 -181
  359. claude_mpm/ticket_wrapper.py +2 -2
  360. claude_mpm/utils/__init__.py +2 -2
  361. claude_mpm/utils/agent_dependency_loader.py +453 -243
  362. claude_mpm/utils/config_manager.py +157 -118
  363. claude_mpm/utils/console.py +1 -1
  364. claude_mpm/utils/dependency_cache.py +102 -107
  365. claude_mpm/utils/dependency_manager.py +52 -47
  366. claude_mpm/utils/dependency_strategies.py +131 -96
  367. claude_mpm/utils/environment_context.py +110 -102
  368. claude_mpm/utils/error_handler.py +75 -55
  369. claude_mpm/utils/file_utils.py +80 -67
  370. claude_mpm/utils/framework_detection.py +12 -11
  371. claude_mpm/utils/import_migration_example.py +12 -60
  372. claude_mpm/utils/imports.py +48 -45
  373. claude_mpm/utils/path_operations.py +100 -93
  374. claude_mpm/utils/robust_installer.py +172 -164
  375. claude_mpm/utils/session_logging.py +30 -23
  376. claude_mpm/utils/subprocess_utils.py +99 -61
  377. claude_mpm/validation/__init__.py +1 -1
  378. claude_mpm/validation/agent_validator.py +151 -111
  379. claude_mpm/validation/frontmatter_validator.py +92 -71
  380. {claude_mpm-3.9.11.dist-info → claude_mpm-4.0.3.dist-info}/METADATA +27 -1
  381. claude_mpm-4.0.3.dist-info/RECORD +402 -0
  382. {claude_mpm-3.9.11.dist-info → claude_mpm-4.0.3.dist-info}/entry_points.txt +1 -0
  383. {claude_mpm-3.9.11.dist-info → claude_mpm-4.0.3.dist-info}/licenses/LICENSE +1 -1
  384. claude_mpm/cli/commands/run_guarded.py +0 -511
  385. claude_mpm/config/memory_guardian_config.py +0 -325
  386. claude_mpm/config/memory_guardian_yaml.py +0 -335
  387. claude_mpm/core/config_paths.py +0 -150
  388. claude_mpm/core/memory_aware_runner.py +0 -353
  389. claude_mpm/dashboard/static/js/dashboard-original.js +0 -4134
  390. claude_mpm/deployment_paths.py +0 -261
  391. claude_mpm/hooks/claude_hooks/hook_handler_fixed.py +0 -454
  392. claude_mpm/models/state_models.py +0 -433
  393. claude_mpm/services/agent/__init__.py +0 -24
  394. claude_mpm/services/agent/deployment.py +0 -2548
  395. claude_mpm/services/agent/management.py +0 -598
  396. claude_mpm/services/agent/registry.py +0 -813
  397. claude_mpm/services/agents/registry/agent_registry.py +0 -813
  398. claude_mpm/services/communication/socketio.py +0 -1935
  399. claude_mpm/services/communication/websocket.py +0 -479
  400. claude_mpm/services/framework_claude_md_generator.py +0 -624
  401. claude_mpm/services/health_monitor.py +0 -893
  402. claude_mpm/services/infrastructure/graceful_degradation.py +0 -616
  403. claude_mpm/services/infrastructure/health_monitor.py +0 -775
  404. claude_mpm/services/infrastructure/memory_dashboard.py +0 -479
  405. claude_mpm/services/infrastructure/memory_guardian.py +0 -944
  406. claude_mpm/services/infrastructure/restart_protection.py +0 -642
  407. claude_mpm/services/infrastructure/state_manager.py +0 -774
  408. claude_mpm/services/mcp_gateway/manager.py +0 -334
  409. claude_mpm/services/optimized_hook_service.py +0 -542
  410. claude_mpm/services/project_analyzer.py +0 -864
  411. claude_mpm/services/project_registry.py +0 -608
  412. claude_mpm/services/standalone_socketio_server.py +0 -1300
  413. claude_mpm/services/ticket_manager_di.py +0 -318
  414. claude_mpm/services/ticketing_service_original.py +0 -510
  415. claude_mpm/utils/paths.py +0 -395
  416. claude_mpm/utils/platform_memory.py +0 -524
  417. claude_mpm-3.9.11.dist-info/RECORD +0 -306
  418. {claude_mpm-3.9.11.dist-info → claude_mpm-4.0.3.dist-info}/WHEEL +0 -0
  419. {claude_mpm-3.9.11.dist-info → claude_mpm-4.0.3.dist-info}/top_level.txt +0 -0
@@ -1,3 +1,5 @@
1
+ from pathlib import Path
2
+
1
3
  """
2
4
  MCP Gateway command implementation for claude-mpm.
3
5
 
@@ -9,77 +11,90 @@ that dispatches to specific subcommand handlers, maintaining consistency
9
11
  with other command modules like agents.py and memory.py.
10
12
  """
11
13
 
12
- import sys
13
- import json
14
14
  import asyncio
15
+ import json
16
+ import sys
15
17
  from pathlib import Path
16
- from typing import Optional, Dict, Any, List
18
+ from typing import Any, Dict, List, Optional
17
19
 
18
- from ...core.logger import get_logger
19
20
  from ...constants import MCPCommands
21
+ from ...core.logger import get_logger
20
22
 
21
23
 
22
24
  def manage_mcp(args):
23
25
  """
24
26
  Manage MCP Gateway server and tools.
25
-
27
+
26
28
  WHY: The MCP Gateway provides Model Context Protocol integration for Claude MPM,
27
29
  enabling tool invocation and external service integration. This command provides
28
30
  a unified interface for all MCP-related operations.
29
-
31
+
30
32
  DESIGN DECISION: When no subcommand is provided, we show the server status
31
33
  as the default action, giving users a quick overview of the MCP system state.
32
-
34
+
33
35
  Args:
34
36
  args: Parsed command line arguments with mcp_command attribute
35
37
  """
36
38
  logger = get_logger("cli.mcp")
37
-
39
+
40
+ # First check if MCP package is installed for any command
41
+ try:
42
+ import mcp
43
+ except ImportError:
44
+ if args.mcp_command != MCPCommands.INSTALL.value:
45
+ print("\nMCP package is not installed.", file=sys.stderr)
46
+ print("Please install it first:", file=sys.stderr)
47
+ print(" claude-mpm mcp install", file=sys.stderr)
48
+ print("\nOr manually:", file=sys.stderr)
49
+ print(" pip install mcp", file=sys.stderr)
50
+ return 1
51
+
38
52
  try:
39
- # Import MCP Gateway services with lazy loading
40
- from ...services.mcp_gateway import (
41
- MCPGateway,
42
- ToolRegistry,
43
- MCPConfiguration,
44
- MCPServiceRegistry
45
- )
46
-
53
+ # Import MCP Gateway services with error handling
54
+ try:
55
+ from ...services.mcp_gateway import (
56
+ MCPConfiguration,
57
+ MCPServiceRegistry,
58
+ ToolRegistry,
59
+ )
60
+ from ...services.mcp_gateway.server.mcp_gateway import MCPGateway
61
+ except ImportError as e:
62
+ # Provide minimal fallbacks for basic commands
63
+ logger.warning(f"Some MCP Gateway services not available: {e}")
64
+
65
+ # Allow install command to proceed
66
+ if args.mcp_command == MCPCommands.INSTALL.value:
67
+ MCPConfiguration = None
68
+ MCPServiceRegistry = None
69
+ ToolRegistry = None
70
+ MCPGateway = None
71
+ else:
72
+ print(
73
+ f"\nError: MCP Gateway services not fully available",
74
+ file=sys.stderr,
75
+ )
76
+ print(f"Details: {e}", file=sys.stderr)
77
+ print("\nTry running:", file=sys.stderr)
78
+ print(" claude-mpm mcp install", file=sys.stderr)
79
+ return 1
80
+
47
81
  if not args.mcp_command:
48
82
  # No subcommand - show status by default
49
- return _show_status(args, logger)
50
-
83
+ return _show_status(
84
+ args,
85
+ logger,
86
+ MCPConfiguration,
87
+ MCPServiceRegistry,
88
+ ToolRegistry,
89
+ MCPGateway,
90
+ )
91
+
51
92
  # Route to specific command handlers
52
- if args.mcp_command == MCPCommands.START.value:
53
- import asyncio
54
- return asyncio.run(_start_server(args, logger))
55
-
56
- elif args.mcp_command == MCPCommands.STOP.value:
57
- return _stop_server(args, logger)
58
-
59
- elif args.mcp_command == MCPCommands.STATUS.value:
60
- return _show_status(args, logger)
61
-
62
- elif args.mcp_command == MCPCommands.TOOLS.value:
63
- return _manage_tools(args, logger)
64
-
65
- elif args.mcp_command == MCPCommands.REGISTER.value:
66
- return _register_tool(args, logger)
67
-
68
- elif args.mcp_command == MCPCommands.TEST.value:
69
- return _test_tool(args, logger)
70
-
71
- elif args.mcp_command == MCPCommands.INSTALL.value:
72
- return _install_gateway(args, logger)
73
-
74
- elif args.mcp_command == MCPCommands.CONFIG.value:
75
- return _manage_config(args, logger)
76
-
77
- else:
78
- logger.error(f"Unknown MCP command: {args.mcp_command}")
79
- print(f"Unknown MCP command: {args.mcp_command}")
80
- _show_help()
81
- return 1
82
-
93
+ from .mcp_command_router import MCPCommandRouter
94
+
95
+ router = MCPCommandRouter(logger)
96
+ return router.route_command(args)
97
+
83
98
  except ImportError as e:
84
99
  logger.error(f"MCP Gateway services not available: {e}")
85
100
  print("Error: MCP Gateway services not available")
@@ -92,876 +107,96 @@ def manage_mcp(args):
92
107
  return 1
93
108
 
94
109
 
95
- def _show_help():
96
- """Show available MCP commands."""
97
- print("\nAvailable MCP commands:")
98
- print(" install - Install and configure MCP Gateway")
99
- print(" start - Start the MCP Gateway server")
100
- print(" stop - Stop the MCP Gateway server")
101
- print(" status - Check server and tool status")
102
- print(" tools - List and manage registered tools")
103
- print(" register - Register a new tool")
104
- print(" test - Test tool invocation")
105
- print(" config - View and manage configuration")
106
- print()
107
- print("Use 'claude-mpm mcp <command> --help' for more information")
110
+ # Command handlers moved to separate modules
108
111
 
109
112
 
110
- # Daemon mode removed - MCP servers should be simple stdio responders
113
+ # All command handler functions moved to separate modules
114
+ # - MCPServerCommands: start, stop, status, cleanup
115
+ # - MCPToolCommands: tools, register, test
116
+ # - MCPInstallCommands: install
117
+ # - MCPConfigCommands: config
111
118
 
112
119
 
113
- async def _start_server(args, logger):
120
+ def _show_status(
121
+ args, logger, MCPConfiguration, MCPServiceRegistry, ToolRegistry, MCPGateway
122
+ ):
114
123
  """
115
- Start the MCP Gateway using the global manager.
124
+ Show MCP Gateway status when no subcommand is provided.
116
125
 
117
- WHY: Users need to start the MCP gateway to enable tool invocation
118
- and external service integration in Claude sessions. We use the global
119
- manager to ensure only one instance runs per installation.
126
+ WHY: Users often want a quick overview of the MCP system state.
127
+ This provides server status, registered tools, and configuration info.
120
128
 
121
- Args:
122
- args: Command arguments with optional port and configuration
123
- logger: Logger instance
124
-
125
- Returns:
126
- int: Exit code (0 for success, non-zero for failure)
129
+ DESIGN DECISION: We show a comprehensive status including server state,
130
+ tool count, and configuration path to give users a complete picture.
127
131
  """
128
- from ...services.mcp_gateway.manager import (
129
- start_global_gateway,
130
- run_global_gateway,
131
- is_gateway_running,
132
- get_gateway_status
133
- )
134
-
135
- try:
136
- logger.info("Starting MCP Gateway")
137
-
138
- # Note: MCP gateways don't "run" as background services
139
- # They are stdio-based protocol handlers activated by MCP clients
132
+ print("📊 MCP Gateway Status")
133
+ print("=" * 50)
140
134
 
141
- # Get configuration values
142
- gateway_name = getattr(args, 'name', 'claude-mpm-gateway')
143
- version = getattr(args, 'version', '1.0.0')
144
-
145
- # Initialize the global gateway components
146
- logger.info(f"Initializing MCP gateway: {gateway_name}")
147
- if not await start_global_gateway(gateway_name, version):
148
- logger.error("Failed to initialize MCP gateway")
149
- print("Error: Failed to initialize MCP gateway")
150
- return 1
151
-
152
- # Run the gateway stdio handler
153
- logger.info("Starting MCP gateway stdio handler")
154
- print("MCP Gateway ready for Claude Desktop", file=sys.stderr)
155
- print("Listening for MCP protocol messages on stdin/stdout...", file=sys.stderr)
156
-
157
- await run_global_gateway()
158
-
159
- return 0
160
-
161
- except KeyboardInterrupt:
162
- print("\nServer interrupted by user")
163
- return 0
164
- except Exception as e:
165
- logger.error(f"Failed to start MCP server: {e}", exc_info=True)
166
- print(f"Error starting server: {e}")
167
- return 1
168
-
169
-
170
- def _stop_server(args, logger):
171
- """
172
- Stop the MCP Gateway server.
173
-
174
- WHY: Users need a clean way to stop the MCP server when it's no longer needed
175
- or when they need to restart it with different configuration.
176
-
177
- Args:
178
- args: Command arguments
179
- logger: Logger instance
180
-
181
- Returns:
182
- int: Exit code (0 for success, non-zero for failure)
183
- """
184
- try:
185
- # Check for running server process
186
- pid_file = Path.home() / ".claude-mpm" / "mcp_server.pid"
187
-
188
- if not pid_file.exists():
189
- print("No MCP server process found")
190
- return 0
191
-
192
- # Read PID and attempt to stop
193
- import signal
194
- import os
195
-
196
- with open(pid_file, 'r') as f:
197
- pid = int(f.read().strip())
198
-
199
- try:
200
- # Send termination signal
201
- os.kill(pid, signal.SIGTERM)
202
- print(f"Sent stop signal to MCP server (PID: {pid})")
203
-
204
- # Wait for graceful shutdown
205
- import time
206
- for _ in range(10):
207
- try:
208
- os.kill(pid, 0) # Check if process still exists
209
- time.sleep(0.5)
210
- except ProcessLookupError:
211
- break
212
- else:
213
- # Force kill if still running
214
- os.kill(pid, signal.SIGKILL)
215
- print("Force stopped MCP server")
216
-
217
- # Clean up PID file
218
- pid_file.unlink()
219
- print("MCP server stopped successfully")
220
- return 0
221
-
222
- except ProcessLookupError:
223
- # Process already stopped
224
- pid_file.unlink()
225
- print("MCP server was not running")
226
- return 0
227
-
228
- except Exception as e:
229
- logger.error(f"Failed to stop MCP server: {e}", exc_info=True)
230
- print(f"Error stopping server: {e}")
231
- return 1
232
-
233
-
234
- def _show_status(args, logger):
235
- """
236
- Show MCP Gateway server and tool status.
237
-
238
- WHY: Users need visibility into the current state of the MCP system,
239
- including server status, registered tools, and configuration.
240
-
241
- Args:
242
- args: Command arguments
243
- logger: Logger instance
244
-
245
- Returns:
246
- int: Exit code (0 for success, non-zero for failure)
247
- """
248
- from ...services.mcp_gateway import MCPServiceRegistry, ToolRegistry
249
-
135
+ # Check if MCP package is installed
250
136
  try:
251
- print("MCP Gateway Status")
252
- print("=" * 50)
253
-
254
- # Check gateway manager status
255
- from ...services.mcp_gateway.manager import get_gateway_status, is_gateway_running
256
-
257
- # MCP gateways are stdio-based protocol handlers, not background services
258
- print("Gateway Status: ℹ️ MCP protocol handler (stdio-based)")
259
- print(" • Activated on-demand by MCP clients (Claude Desktop)")
260
- print(" • No background processes - communicates via stdin/stdout")
261
- print(" • Ready for Claude Desktop integration")
262
- print(" • Test with: claude-mpm mcp test <tool_name>")
263
-
264
- print()
265
-
266
- # Show registered tools
267
- print("Registered Tools:")
268
- print("-" * 30)
269
-
270
- # Get tool registry with fallback to running server
271
- try:
272
- tool_registry = _create_tool_registry_with_fallback(logger)
273
- config_file = Path.home() / ".claude-mcp" / "mcp_config.yaml"
274
- config = _load_config_sync(config_file if config_file.exists() else None, logger)
275
- except ValueError as e:
276
- print(f"Configuration Error: {e}")
277
- return 1
278
- except Exception as e:
279
- logger.error(f"Failed to initialize: {e}")
280
- print(f"Error: Failed to initialize MCP components: {e}")
281
- return 1
282
-
283
- tools = tool_registry.list_tools()
284
- if tools:
285
- for tool in tools:
286
- print(f" ✅ {tool.name}: {tool.description}")
287
- else:
288
- print(" No tools registered")
289
-
290
- print()
291
-
292
- # Show configuration
293
- print("Configuration:")
294
- print("-" * 30)
295
-
296
- if config_file.exists():
297
- print(f" Config file: {config_file}")
298
- else:
299
- print(" Using default configuration")
300
-
301
- server_config = config.get("mcp", {}).get("server", {})
302
- tools_config = config.get("mcp", {}).get("tools", {})
303
- print(f" Server name: {server_config.get('name', 'claude-mpm-gateway')}")
304
- print(f" Version: {server_config.get('version', '1.0.0')}")
305
- print(f" Tools enabled: {'Yes' if tools_config.get('enabled', True) else 'No'}")
306
-
307
- # Show verbose details if requested
308
- if getattr(args, 'verbose', False):
309
- print()
310
- print("Service Registry:")
311
- print("-" * 30)
312
-
313
- registry = MCPServiceRegistry()
314
- services = registry.list_services()
315
-
316
- for service_id, service_info in services.items():
317
- print(f" {service_id}:")
318
- print(f" State: {service_info['state']}")
319
- print(f" Type: {service_info['type']}")
320
-
321
- return 0
322
-
323
- except Exception as e:
324
- logger.error(f"Failed to show MCP status: {e}", exc_info=True)
325
- print(f"Error checking status: {e}")
326
- return 1
327
-
328
-
329
- def _manage_tools(args, logger):
330
- """
331
- List and manage registered MCP tools.
332
-
333
- WHY: Users need to see what tools are available and manage their
334
- registration and configuration.
335
-
336
- Args:
337
- args: Command arguments with optional filters
338
- logger: Logger instance
339
-
340
- Returns:
341
- int: Exit code (0 for success, non-zero for failure)
342
- """
343
- from ...services.mcp_gateway import ToolRegistry
344
-
345
- try:
346
- # Check for subcommand
347
- action = getattr(args, 'tool_action', 'list')
348
-
349
- # Get tool registry with fallback to running server
350
- tool_registry = _create_tool_registry_with_fallback(logger)
351
-
352
- if action == 'list':
353
- # List all tools
354
- tools = tool_registry.list_tools()
355
-
356
- if not tools:
357
- print("No tools registered")
358
- return 0
359
-
360
- print("Registered MCP Tools:")
361
- print("=" * 50)
362
-
363
- # Group tools by category if available
364
- by_category = {}
365
- for tool in tools:
366
- category = getattr(tool, 'category', 'General')
367
- if category not in by_category:
368
- by_category[category] = []
369
- by_category[category].append(tool)
370
-
371
- for category, category_tools in sorted(by_category.items()):
372
- print(f"\n{category}:")
373
- print("-" * 30)
374
-
375
- for tool in category_tools:
376
- print(f" ✅ {tool.name}")
377
- print(f" {tool.description}")
378
-
379
- if getattr(args, 'verbose', False):
380
- # Show input schema
381
- print(f" Input Schema: {json.dumps(tool.input_schema, indent=8)}")
382
-
383
- elif action == 'enable':
384
- # Enable a tool
385
- tool_name = args.tool_name
386
- if tool_registry.enable_tool(tool_name):
387
- print(f"✅ Enabled tool: {tool_name}")
388
- return 0
389
- else:
390
- print(f"❌ Failed to enable tool: {tool_name}")
391
- return 1
392
-
393
- elif action == 'disable':
394
- # Disable a tool
395
- tool_name = args.tool_name
396
- if tool_registry.disable_tool(tool_name):
397
- print(f"✅ Disabled tool: {tool_name}")
398
- return 0
399
- else:
400
- print(f"❌ Failed to disable tool: {tool_name}")
401
- return 1
402
-
403
- else:
404
- print(f"Unknown tool action: {action}")
405
- return 1
406
-
407
- return 0
408
-
409
- except Exception as e:
410
- logger.error(f"Failed to manage tools: {e}", exc_info=True)
411
- print(f"Error managing tools: {e}")
412
- return 1
413
-
414
-
415
- def _register_tool(args, logger):
416
- """
417
- Register a new MCP tool.
418
-
419
- WHY: Users need to add custom tools to the MCP Gateway for use
420
- in Claude sessions.
421
-
422
- Args:
423
- args: Command arguments with tool definition
424
- logger: Logger instance
425
-
426
- Returns:
427
- int: Exit code (0 for success, non-zero for failure)
428
- """
429
- from ...services.mcp_gateway import ToolRegistry
430
- from ...services.mcp_gateway.core.interfaces import MCPToolDefinition
431
-
432
- try:
433
- # Get tool details from arguments
434
- tool_name = args.name
435
- tool_description = args.description
436
-
437
- # Parse input schema
438
- if args.schema_file:
439
- with open(args.schema_file, 'r') as f:
440
- input_schema = json.load(f)
441
- else:
442
- # Basic schema
443
- input_schema = {
444
- "type": "object",
445
- "properties": {},
446
- "required": []
447
- }
448
-
449
- # Create tool definition
450
- tool_def = MCPToolDefinition(
451
- name=tool_name,
452
- description=tool_description,
453
- input_schema=input_schema,
454
- enabled=True
455
- )
456
-
457
- # Register with tool registry
458
- tool_registry = ToolRegistry()
459
-
460
- if args.adapter:
461
- # Register with custom adapter
462
- logger.info(f"Registering tool with adapter: {args.adapter}")
463
- # Import and instantiate adapter
464
- # This would be extended based on adapter framework
465
- print(f"Custom adapter registration not yet implemented: {args.adapter}")
466
- return 1
467
- else:
468
- # Register as a simple tool
469
- success = tool_registry.register_tool(tool_def)
470
-
471
- if success:
472
- print(f"✅ Successfully registered tool: {tool_name}")
473
-
474
- # Save to configuration if requested
475
- if args.save:
476
- config_file = Path.home() / ".claude-mpm" / "mcp_config.yaml"
477
- # Update configuration with new tool
478
- print(f"Tool configuration saved to: {config_file}")
479
-
480
- return 0
481
- else:
482
- print(f"❌ Failed to register tool: {tool_name}")
483
- return 1
484
-
485
- except Exception as e:
486
- logger.error(f"Failed to register tool: {e}", exc_info=True)
487
- print(f"Error registering tool: {e}")
488
- return 1
137
+ import mcp
489
138
 
490
-
491
- def _test_tool(args, logger):
492
- """
493
- Test MCP tool invocation.
494
-
495
- WHY: Users need to verify that tools are working correctly before
496
- using them in Claude sessions.
497
-
498
- Args:
499
- args: Command arguments with tool name and test parameters
500
- logger: Logger instance
501
-
502
- Returns:
503
- int: Exit code (0 for success, non-zero for failure)
504
- """
505
- from ...services.mcp_gateway import ToolRegistry
506
- from ...services.mcp_gateway.core.interfaces import MCPToolInvocation
507
-
508
- try:
509
- # Get tool name and arguments
510
- tool_name = args.tool_name
511
-
512
- # Parse tool arguments
513
- if args.args_file:
514
- with open(args.args_file, 'r') as f:
515
- tool_args = json.load(f)
516
- elif args.args:
517
- tool_args = json.loads(args.args)
518
- else:
519
- tool_args = {}
520
-
521
- print(f"Testing tool: {tool_name}")
522
- print(f"Arguments: {json.dumps(tool_args, indent=2)}")
523
- print("-" * 50)
524
-
525
- # Get tool registry with fallback to running server
526
- tool_registry = _create_tool_registry_with_fallback(logger)
527
-
528
- # Create invocation request
529
- invocation = MCPToolInvocation(
530
- tool_name=tool_name,
531
- parameters=tool_args,
532
- context={"source": "cli_test"}
533
- )
534
-
535
- # Invoke tool
536
- result = asyncio.run(tool_registry.invoke_tool(invocation))
537
-
538
- if result.success:
539
- print("✅ Tool invocation successful!")
540
- print(f"Result: {json.dumps(result.data, indent=2)}")
541
- print(f"Execution time: {result.execution_time:.3f}s")
542
- else:
543
- print("❌ Tool invocation failed!")
544
- print(f"Error: {result.error}")
545
-
546
- return 0 if result.success else 1
547
-
548
- except Exception as e:
549
- logger.error(f"Failed to test tool: {e}", exc_info=True)
550
- print(f"Error testing tool: {e}")
139
+ print("✅ MCP package installed")
140
+ except ImportError:
141
+ print("❌ MCP package not installed")
142
+ print(" Run: claude-mpm mcp install")
551
143
  return 1
552
144
 
553
-
554
- def _install_gateway(args, logger):
555
- """
556
- Install and configure the MCP Gateway.
557
-
558
- WHY: Users need a simple way to set up the MCP Gateway with
559
- default configuration and tools.
560
-
561
- Args:
562
- args: Command arguments
563
- logger: Logger instance
564
-
565
- Returns:
566
- int: Exit code (0 for success, non-zero for failure)
567
- """
568
- try:
569
- print("Installing MCP Gateway...")
570
- print("=" * 50)
571
-
572
- # Create configuration directory
573
- config_dir = Path.home() / ".claude-mpm"
574
- config_dir.mkdir(exist_ok=True)
575
-
576
- # Create default configuration
577
- config_file = config_dir / "mcp_config.yaml"
578
-
579
- if config_file.exists() and not getattr(args, 'force', False):
580
- print(f"Configuration already exists: {config_file}")
581
- print("Use --force to overwrite")
582
- return 1
583
-
584
- # Default configuration
585
- default_config = {
586
- "server": {
587
- "name": "claude-mpm-mcp",
588
- "version": "1.0.0",
589
- "port": 8766,
590
- "mode": "stdio"
591
- },
592
- "tools": {
593
- "load_defaults": True,
594
- "custom_tools_dir": str(config_dir / "mcp_tools"),
595
- "enabled": [
596
- "echo",
597
- "calculator",
598
- "system_info"
599
- ]
600
- },
601
- "logging": {
602
- "level": "INFO",
603
- "file": str(config_dir / "logs" / "mcp_server.log")
604
- }
605
- }
606
-
607
- # Write configuration
608
- import yaml
609
- with open(config_file, 'w') as f:
610
- yaml.dump(default_config, f, default_flow_style=False)
611
-
612
- print(f"✅ Created configuration: {config_file}")
613
-
614
- # Create tools directory
615
- tools_dir = config_dir / "mcp_tools"
616
- tools_dir.mkdir(exist_ok=True)
617
- print(f"✅ Created tools directory: {tools_dir}")
618
-
619
- # Create logs directory
620
- logs_dir = config_dir / "logs"
621
- logs_dir.mkdir(exist_ok=True)
622
- print(f"✅ Created logs directory: {logs_dir}")
623
-
624
- # Test MCP package installation
145
+ # Show configuration status
146
+ print("\n📁 Configuration:")
147
+ config_path = Path.home() / ".claude" / "mcp_config.json"
148
+ if config_path.exists():
149
+ print(f" Config file: {config_path}")
625
150
  try:
626
- import mcp
627
- print("✅ MCP package is installed")
628
- except ImportError:
629
- print("⚠️ MCP package not found. Installing...")
630
- import subprocess
631
- result = subprocess.run(
632
- [sys.executable, "-m", "pip", "install", "mcp"],
633
- capture_output=True,
634
- text=True
635
- )
636
- if result.returncode == 0:
637
- print("✅ MCP package installed successfully")
638
- else:
639
- print(" Failed to install MCP package")
640
- print(result.stderr)
641
- return 1
642
-
643
- print()
644
- print("MCP Gateway installation complete!")
645
- print()
646
- print("Next steps:")
647
- print("1. Start the server: claude-mpm mcp start")
648
- print("2. Check status: claude-mpm mcp status")
649
- print("3. List tools: claude-mpm mcp tools")
650
-
651
- return 0
652
-
653
- except Exception as e:
654
- logger.error(f"Failed to install MCP Gateway: {e}", exc_info=True)
655
- print(f"Error during installation: {e}")
656
- return 1
657
-
658
-
659
- def _manage_config(args, logger):
660
- """
661
- View and manage MCP Gateway configuration.
662
-
663
- WHY: Users need to view and modify MCP configuration without
664
- manually editing YAML files.
665
-
666
- Args:
667
- args: Command arguments
668
- logger: Logger instance
669
-
670
- Returns:
671
- int: Exit code (0 for success, non-zero for failure)
672
- """
673
- try:
674
- config_file = Path.home() / ".claude-mpm" / "mcp_config.yaml"
675
-
676
- action = getattr(args, 'config_action', 'view')
677
-
678
- if action == 'view':
679
- # View current configuration
680
- if not config_file.exists():
681
- print("No configuration file found")
682
- print("Run 'claude-mpm mcp install' to create default configuration")
683
- return 1
684
-
685
- import yaml
686
- with open(config_file, 'r') as f:
687
- config = yaml.safe_load(f)
688
-
689
- print("MCP Gateway Configuration")
690
- print("=" * 50)
691
- print(yaml.dump(config, default_flow_style=False))
692
-
693
- elif action == 'edit':
694
- # Edit configuration
695
- if not config_file.exists():
696
- print("No configuration file found")
697
- return 1
698
-
699
- # Open in default editor
700
- import os
701
- import subprocess
702
-
703
- editor = os.environ.get('EDITOR', 'nano')
704
- subprocess.call([editor, str(config_file)])
705
-
706
- print("Configuration updated")
707
-
708
- elif action == 'reset':
709
- # Reset to default configuration
710
- if config_file.exists():
711
- # Backup existing configuration
712
- backup_file = config_file.with_suffix('.yaml.bak')
713
- config_file.rename(backup_file)
714
- print(f"Backed up existing configuration to: {backup_file}")
715
-
716
- # Run install to create default configuration
717
- args.force = True
718
- return _install_gateway(args, logger)
719
-
720
- else:
721
- print(f"Unknown config action: {action}")
722
- return 1
723
-
724
- return 0
725
-
726
- except Exception as e:
727
- logger.error(f"Failed to manage configuration: {e}", exc_info=True)
728
- print(f"Error managing configuration: {e}")
729
- return 1
730
-
731
-
732
- async def _load_default_tools(tool_registry, logger):
733
- """
734
- Load default MCP tools into the registry.
735
-
736
- WHY: We provide a set of default tools for common operations
737
- to get users started quickly.
738
-
739
- Args:
740
- tool_registry: ToolRegistry instance
741
- logger: Logger instance
742
- """
743
- try:
744
- # Import default tool adapters
745
- from ...services.mcp_gateway.tools.base_adapter import (
746
- EchoToolAdapter,
747
- CalculatorToolAdapter,
748
- SystemInfoToolAdapter
749
- )
750
-
751
- # Register default tools
752
- default_tools = [
753
- EchoToolAdapter(),
754
- CalculatorToolAdapter(),
755
- SystemInfoToolAdapter()
756
- ]
757
-
758
- for adapter in default_tools:
759
- await adapter.initialize()
760
- tool_registry.register_tool(adapter)
761
- tool_def = adapter.get_definition()
762
- logger.debug(f"Loaded default tool: {tool_def.name}")
763
-
764
- except Exception as e:
765
- logger.error(f"Failed to load default tools: {e}", exc_info=True)
766
- raise
767
-
768
-
769
- def _load_config_sync(config_path=None, logger=None):
770
- """
771
- Load MCP configuration synchronously with validation.
772
-
773
- Args:
774
- config_path: Optional path to configuration file
775
- logger: Optional logger for error reporting
776
-
777
- Returns:
778
- Dictionary with configuration data
779
-
780
- Raises:
781
- ValueError: If configuration is invalid
782
- """
783
- # Use default configuration structure
784
- default_config = {
785
- "mcp": {
786
- "server": {
787
- "name": "claude-mpm-gateway",
788
- "version": "1.0.0",
789
- "description": "Claude MPM MCP Gateway Server",
790
- },
791
- "tools": {
792
- "enabled": True,
793
- "auto_discover": True,
794
- },
795
- "logging": {
796
- "level": "INFO",
797
- }
798
- }
799
- }
800
-
801
- if config_path and Path(config_path).exists():
151
+ with open(config_path) as f:
152
+ config = json.load(f)
153
+ if "servers" in config:
154
+ print(f" Configured servers: {len(config.get('servers', {}))}")
155
+ except Exception as e:
156
+ print(f" ⚠️ Error reading config: {e}")
157
+ else:
158
+ print(f" No config file at {config_path}")
159
+
160
+ # Show Claude Desktop configuration
161
+ claude_config = (
162
+ Path.home()
163
+ / "Library"
164
+ / "Application Support"
165
+ / "Claude"
166
+ / "claude_desktop_config.json"
167
+ )
168
+ if claude_config.exists():
169
+ print(f"\n🖥️ Claude Desktop Config: {claude_config}")
802
170
  try:
803
- import yaml
804
- with open(config_path, 'r') as f:
805
- loaded_config = yaml.safe_load(f) or {}
806
-
807
- # Validate configuration structure
808
- if not isinstance(loaded_config, dict):
809
- raise ValueError("Configuration must be a dictionary")
810
-
811
- # Validate MCP section if present
812
- if "mcp" in loaded_config:
813
- mcp_config = loaded_config["mcp"]
814
- if not isinstance(mcp_config, dict):
815
- raise ValueError("mcp section must be a dictionary")
816
-
817
- # Validate server section
818
- if "server" in mcp_config:
819
- server_config = mcp_config["server"]
820
- if not isinstance(server_config, dict):
821
- raise ValueError("mcp.server section must be a dictionary")
822
-
823
- # Validate server name
824
- if "name" in server_config:
825
- if not isinstance(server_config["name"], str) or not server_config["name"].strip():
826
- raise ValueError("mcp.server.name must be a non-empty string")
827
-
828
- # Validate tools section
829
- if "tools" in mcp_config:
830
- tools_config = mcp_config["tools"]
831
- if not isinstance(tools_config, dict):
832
- raise ValueError("mcp.tools section must be a dictionary")
833
-
834
- if "enabled" in tools_config and not isinstance(tools_config["enabled"], bool):
835
- raise ValueError("mcp.tools.enabled must be a boolean")
836
-
837
- # Merge with defaults
838
- def merge_dict(base, overlay):
839
- for key, value in overlay.items():
840
- if key in base and isinstance(base[key], dict) and isinstance(value, dict):
841
- merge_dict(base[key], value)
842
- else:
843
- base[key] = value
844
-
845
- merge_dict(default_config, loaded_config)
846
-
847
- if logger:
848
- logger.info(f"Successfully loaded configuration from {config_path}")
849
-
850
- except yaml.YAMLError as e:
851
- error_msg = f"Invalid YAML in configuration file {config_path}: {e}"
852
- if logger:
853
- logger.error(error_msg)
854
- raise ValueError(error_msg)
855
- except ValueError as e:
856
- error_msg = f"Configuration validation error in {config_path}: {e}"
857
- if logger:
858
- logger.error(error_msg)
859
- raise
171
+ with open(claude_config) as f:
172
+ config = json.load(f)
173
+ mcp_servers = config.get("mcpServers", {})
174
+ if "claude-mpm" in mcp_servers:
175
+ print(" ✅ claude-mpm server configured")
176
+ else:
177
+ print(" ⚠️ claude-mpm server not configured")
178
+ print(" Run: claude-mpm mcp start (for instructions)")
860
179
  except Exception as e:
861
- error_msg = f"Failed to load configuration from {config_path}: {e}"
862
- if logger:
863
- logger.warning(error_msg)
864
- # Fall back to defaults for other errors
865
-
866
- return default_config
867
-
180
+ print(f" ⚠️ Error reading config: {e}")
181
+ else:
182
+ print("\n🖥️ Claude Desktop not configured for MCP")
183
+ print(" Run: claude-mpm mcp start (for instructions)")
868
184
 
869
- def _load_default_tools_sync(tool_registry, logger):
870
- """
871
- Load default MCP tools into the registry synchronously.
872
-
873
- Args:
874
- tool_registry: ToolRegistry instance
875
- logger: Logger instance
876
- """
877
- try:
878
- # Import default tool adapters
879
- from ...services.mcp_gateway.tools.base_adapter import (
880
- EchoToolAdapter,
881
- CalculatorToolAdapter,
882
- SystemInfoToolAdapter
883
- )
884
-
885
- # Register default tools
886
- default_tools = [
887
- EchoToolAdapter(),
888
- CalculatorToolAdapter(),
889
- SystemInfoToolAdapter()
890
- ]
891
-
892
- for adapter in default_tools:
893
- # Initialize synchronously (skip async parts for CLI)
894
- adapter._initialized = True
895
- tool_registry.register_tool(adapter)
896
- tool_def = adapter.get_definition()
897
- logger.debug(f"Loaded default tool: {tool_def.name}")
898
-
899
- except Exception as e:
900
- logger.error(f"Failed to load default tools: {e}", exc_info=True)
901
-
902
-
903
- def _get_server_tools_via_mcp(logger):
904
- """
905
- Get tools from running MCP server via MCP protocol.
906
-
907
- Returns:
908
- List of tool definitions or None if server not accessible
909
- """
910
- try:
911
- import json
912
- import subprocess
913
- import tempfile
914
-
915
- # Create a simple MCP client request
916
- request = {
917
- "jsonrpc": "2.0",
918
- "id": 1,
919
- "method": "tools/list",
920
- "params": {}
921
- }
922
-
923
- # Try to communicate with running server
924
- pid_file = Path.home() / ".claude-mcp" / "mcp_server.pid"
925
- if not pid_file.exists():
926
- return None
927
-
928
- # For now, return None since we need a proper MCP client implementation
929
- # This is a placeholder for future implementation
930
- return None
931
-
932
- except Exception as e:
933
- logger.debug(f"Could not connect to running server: {e}")
934
- return None
935
-
936
-
937
- def _create_tool_registry_with_fallback(logger):
938
- """
939
- Create tool registry, trying to connect to running server first.
940
-
941
- Args:
942
- logger: Logger instance
943
-
944
- Returns:
945
- ToolRegistry instance with tools loaded
946
- """
947
- from ...services.mcp_gateway import ToolRegistry
948
-
949
- # Create registry
950
- tool_registry = ToolRegistry()
951
-
952
- # Try to get tools from running server
953
- server_tools = _get_server_tools_via_mcp(logger)
954
-
955
- if server_tools:
956
- logger.debug("Connected to running MCP server")
957
- # TODO: Populate registry with server tools
958
- # For now, fall back to loading default tools
959
-
960
- # Fallback: Load default tools locally
961
- config_file = Path.home() / ".claude-mcp" / "mcp_config.yaml"
962
- config = _load_config_sync(config_file if config_file.exists() else None, logger)
963
-
964
- if config.get("mcp", {}).get("tools", {}).get("enabled", True):
965
- _load_default_tools_sync(tool_registry, logger)
966
-
967
- return tool_registry
185
+ # Show available tools count
186
+ if ToolRegistry:
187
+ try:
188
+ registry = ToolRegistry()
189
+ # Don't initialize fully, just check
190
+ print(f"\n🔧 Tools: Check with 'claude-mpm mcp tools'")
191
+ except:
192
+ print("\n🔧 Tools: Registry not available")
193
+
194
+ print("\n💡 Available Commands:")
195
+ print(" claude-mpm mcp install - Install MCP dependencies")
196
+ print(" claude-mpm mcp start - Start MCP server (stdio mode)")
197
+ print(" claude-mpm mcp start --instructions - Show setup instructions")
198
+ print(" claude-mpm mcp tools - List available tools")
199
+ print(" claude-mpm mcp test - Test tool invocation")
200
+ print(" claude-mpm mcp config - Manage configuration")
201
+
202
+ return 0