claude-mpm 3.9.9__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 (411) 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 +155 -0
  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 +90 -49
  31. claude_mpm/cli/__main__.py +3 -2
  32. claude_mpm/cli/commands/__init__.py +21 -18
  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 +143 -762
  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 -1150
  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 +217 -0
  69. claude_mpm/config/paths.py +94 -208
  70. claude_mpm/config/socketio_config.py +84 -73
  71. claude_mpm/constants.py +36 -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 +571 -0
  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 +40 -23
  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 +14 -21
  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 +97 -93
  298. claude_mpm/services/mcp_gateway/main.py +307 -127
  299. claude_mpm/services/mcp_gateway/registry/__init__.py +1 -1
  300. claude_mpm/services/mcp_gateway/registry/service_registry.py +100 -101
  301. claude_mpm/services/mcp_gateway/registry/tool_registry.py +135 -126
  302. claude_mpm/services/mcp_gateway/server/__init__.py +4 -4
  303. claude_mpm/services/mcp_gateway/server/{mcp_server.py → mcp_gateway.py} +149 -153
  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 +110 -121
  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 +20 -534
  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 +9 -0
  358. claude_mpm/storage/state_storage.py +552 -0
  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.9.dist-info → claude_mpm-4.0.3.dist-info}/METADATA +51 -2
  381. claude_mpm-4.0.3.dist-info/RECORD +402 -0
  382. {claude_mpm-3.9.9.dist-info → claude_mpm-4.0.3.dist-info}/entry_points.txt +1 -0
  383. {claude_mpm-3.9.9.dist-info → claude_mpm-4.0.3.dist-info}/licenses/LICENSE +1 -1
  384. claude_mpm/config/memory_guardian_config.py +0 -325
  385. claude_mpm/core/config_paths.py +0 -150
  386. claude_mpm/dashboard/static/js/dashboard-original.js +0 -4134
  387. claude_mpm/deployment_paths.py +0 -261
  388. claude_mpm/hooks/claude_hooks/hook_handler_fixed.py +0 -454
  389. claude_mpm/models/state_models.py +0 -433
  390. claude_mpm/services/agent/__init__.py +0 -24
  391. claude_mpm/services/agent/deployment.py +0 -2548
  392. claude_mpm/services/agent/management.py +0 -598
  393. claude_mpm/services/agent/registry.py +0 -813
  394. claude_mpm/services/agents/registry/agent_registry.py +0 -813
  395. claude_mpm/services/communication/socketio.py +0 -1935
  396. claude_mpm/services/communication/websocket.py +0 -479
  397. claude_mpm/services/framework_claude_md_generator.py +0 -624
  398. claude_mpm/services/health_monitor.py +0 -893
  399. claude_mpm/services/infrastructure/memory_guardian.py +0 -770
  400. claude_mpm/services/mcp_gateway/server/mcp_server_simple.py +0 -444
  401. claude_mpm/services/optimized_hook_service.py +0 -542
  402. claude_mpm/services/project_analyzer.py +0 -864
  403. claude_mpm/services/project_registry.py +0 -608
  404. claude_mpm/services/standalone_socketio_server.py +0 -1300
  405. claude_mpm/services/ticket_manager_di.py +0 -318
  406. claude_mpm/services/ticketing_service_original.py +0 -510
  407. claude_mpm/utils/paths.py +0 -395
  408. claude_mpm/utils/platform_memory.py +0 -524
  409. claude_mpm-3.9.9.dist-info/RECORD +0 -293
  410. {claude_mpm-3.9.9.dist-info → claude_mpm-4.0.3.dist-info}/WHEEL +0 -0
  411. {claude_mpm-3.9.9.dist-info → claude_mpm-4.0.3.dist-info}/top_level.txt +0 -0
@@ -7,22 +7,22 @@ Defines and validates the configuration schema for MCP Gateway.
7
7
  Part of ISS-0034: Infrastructure Setup - MCP Gateway Project Foundation
8
8
  """
9
9
 
10
- from typing import Any, Dict, List, Optional
11
10
  from dataclasses import dataclass
11
+ from typing import Any, Dict, List, Optional
12
12
 
13
13
 
14
14
  @dataclass
15
15
  class MCPConfigSchema:
16
16
  """
17
17
  Configuration schema definition for MCP Gateway.
18
-
18
+
19
19
  This class defines the structure and validation rules for
20
20
  MCP Gateway configuration.
21
21
  """
22
-
22
+
23
23
  # Schema version for migration support
24
24
  SCHEMA_VERSION = "1.0.0"
25
-
25
+
26
26
  # Configuration schema definition
27
27
  SCHEMA = {
28
28
  "mcp": {
@@ -43,21 +43,21 @@ class MCPConfigSchema:
43
43
  "type": {
44
44
  "type": "string",
45
45
  "required": True,
46
- "enum": ["stdio", "websocket", "http"]
46
+ "enum": ["stdio", "websocket", "http"],
47
47
  },
48
48
  "timeout": {
49
49
  "type": "number",
50
50
  "required": False,
51
51
  "min": 1,
52
- "max": 3600
52
+ "max": 3600,
53
53
  },
54
54
  "buffer_size": {
55
55
  "type": "integer",
56
56
  "required": False,
57
57
  "min": 1024,
58
- "max": 1048576
58
+ "max": 1048576,
59
59
  },
60
- }
60
+ },
61
61
  },
62
62
  "capabilities": {
63
63
  "type": "object",
@@ -66,9 +66,9 @@ class MCPConfigSchema:
66
66
  "tools": {"type": "boolean", "required": False},
67
67
  "resources": {"type": "boolean", "required": False},
68
68
  "prompts": {"type": "boolean", "required": False},
69
- }
69
+ },
70
70
  },
71
- }
71
+ },
72
72
  },
73
73
  "tools": {
74
74
  "type": "object",
@@ -79,21 +79,21 @@ class MCPConfigSchema:
79
79
  "discovery_paths": {
80
80
  "type": "array",
81
81
  "required": False,
82
- "items": {"type": "string"}
82
+ "items": {"type": "string"},
83
83
  },
84
84
  "timeout_default": {
85
85
  "type": "number",
86
86
  "required": False,
87
87
  "min": 1,
88
- "max": 300
88
+ "max": 300,
89
89
  },
90
90
  "max_concurrent": {
91
91
  "type": "integer",
92
92
  "required": False,
93
93
  "min": 1,
94
- "max": 100
94
+ "max": 100,
95
95
  },
96
- }
96
+ },
97
97
  },
98
98
  "logging": {
99
99
  "type": "object",
@@ -102,7 +102,7 @@ class MCPConfigSchema:
102
102
  "level": {
103
103
  "type": "string",
104
104
  "required": False,
105
- "enum": ["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"]
105
+ "enum": ["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"],
106
106
  },
107
107
  "file": {"type": "string", "required": False},
108
108
  "max_size": {"type": "string", "required": False},
@@ -110,14 +110,14 @@ class MCPConfigSchema:
110
110
  "type": "integer",
111
111
  "required": False,
112
112
  "min": 1,
113
- "max": 100
113
+ "max": 100,
114
114
  },
115
115
  "format": {
116
116
  "type": "string",
117
117
  "required": False,
118
- "enum": ["json", "text"]
118
+ "enum": ["json", "text"],
119
119
  },
120
- }
120
+ },
121
121
  },
122
122
  "security": {
123
123
  "type": "object",
@@ -129,44 +129,46 @@ class MCPConfigSchema:
129
129
  "type": "integer",
130
130
  "required": False,
131
131
  "min": 1024,
132
- "max": 104857600 # 100MB max
132
+ "max": 104857600, # 100MB max
133
133
  },
134
134
  "allowed_tools": {
135
135
  "type": "array",
136
136
  "required": False,
137
- "items": {"type": "string"}
137
+ "items": {"type": "string"},
138
138
  },
139
139
  "blocked_tools": {
140
140
  "type": "array",
141
141
  "required": False,
142
- "items": {"type": "string"}
142
+ "items": {"type": "string"},
143
143
  },
144
- }
144
+ },
145
145
  },
146
- }
146
+ },
147
147
  }
148
148
  }
149
149
 
150
150
 
151
- def validate_config(config: Dict[str, Any], schema: Optional[Dict[str, Any]] = None) -> List[str]:
151
+ def validate_config(
152
+ config: Dict[str, Any], schema: Optional[Dict[str, Any]] = None
153
+ ) -> List[str]:
152
154
  """
153
155
  Validate configuration against schema.
154
-
156
+
155
157
  Args:
156
158
  config: Configuration dictionary to validate
157
159
  schema: Schema to validate against (uses default if not provided)
158
-
160
+
159
161
  Returns:
160
162
  List of validation errors (empty if valid)
161
163
  """
162
164
  if schema is None:
163
165
  schema = MCPConfigSchema.SCHEMA
164
-
166
+
165
167
  errors = []
166
-
168
+
167
169
  def validate_value(value: Any, spec: Dict[str, Any], path: str) -> None:
168
170
  """Recursively validate a value against its specification."""
169
-
171
+
170
172
  # Check type
171
173
  expected_type = spec.get("type")
172
174
  if expected_type:
@@ -188,47 +190,54 @@ def validate_config(config: Dict[str, Any], schema: Optional[Dict[str, Any]] = N
188
190
  elif expected_type == "boolean" and not isinstance(value, bool):
189
191
  errors.append(f"{path}: Expected boolean, got {type(value).__name__}")
190
192
  return
191
-
193
+
192
194
  # Check enum values
193
195
  if "enum" in spec and value not in spec["enum"]:
194
- errors.append(f"{path}: Value '{value}' not in allowed values: {spec['enum']}")
195
-
196
+ errors.append(
197
+ f"{path}: Value '{value}' not in allowed values: {spec['enum']}"
198
+ )
199
+
196
200
  # Check numeric constraints
197
201
  if isinstance(value, (int, float)):
198
202
  if "min" in spec and value < spec["min"]:
199
- errors.append(f"{path}: Value {value} is less than minimum {spec['min']}")
203
+ errors.append(
204
+ f"{path}: Value {value} is less than minimum {spec['min']}"
205
+ )
200
206
  if "max" in spec and value > spec["max"]:
201
- errors.append(f"{path}: Value {value} is greater than maximum {spec['max']}")
202
-
207
+ errors.append(
208
+ f"{path}: Value {value} is greater than maximum {spec['max']}"
209
+ )
210
+
203
211
  # Validate object properties
204
212
  if expected_type == "object" and isinstance(value, dict):
205
213
  properties = spec.get("properties", {})
206
214
  for prop_name, prop_spec in properties.items():
207
215
  prop_path = f"{path}.{prop_name}"
208
-
216
+
209
217
  if prop_name in value:
210
218
  validate_value(value[prop_name], prop_spec, prop_path)
211
219
  elif prop_spec.get("required", False):
212
220
  errors.append(f"{prop_path}: Required field missing")
213
-
221
+
214
222
  # Validate array items
215
223
  if expected_type == "array" and isinstance(value, list):
216
224
  item_spec = spec.get("items", {})
217
225
  for i, item in enumerate(value):
218
226
  validate_value(item, item_spec, f"{path}[{i}]")
219
-
227
+
220
228
  # Start validation from root
221
229
  validate_value(config, {"type": "object", "properties": schema}, "config")
222
-
230
+
223
231
  return errors
224
232
 
225
233
 
226
234
  def generate_config_template() -> Dict[str, Any]:
227
235
  """
228
236
  Generate a configuration template with all possible options.
229
-
237
+
230
238
  Returns:
231
239
  Configuration template dictionary
232
240
  """
233
241
  from ..config.configuration import MCPConfiguration
234
- return MCPConfiguration.DEFAULT_CONFIG
242
+
243
+ return MCPConfiguration.DEFAULT_CONFIG
@@ -1,3 +1,5 @@
1
+ from pathlib import Path
2
+
1
3
  """
2
4
  MCP Gateway Configuration Implementation
3
5
  ========================================
@@ -9,27 +11,27 @@ Part of ISS-0034: Infrastructure Setup - MCP Gateway Project Foundation
9
11
 
10
12
  import os
11
13
  from typing import Any, Dict, Optional
12
- from pathlib import Path
14
+
13
15
  import yaml
14
16
 
15
- from claude_mpm.services.mcp_gateway.core.interfaces import IMCPConfiguration
16
17
  from claude_mpm.services.mcp_gateway.core.base import BaseMCPService
17
18
  from claude_mpm.services.mcp_gateway.core.exceptions import MCPConfigurationError
19
+ from claude_mpm.services.mcp_gateway.core.interfaces import IMCPConfiguration
18
20
 
19
21
 
20
22
  class MCPConfiguration(BaseMCPService, IMCPConfiguration):
21
23
  """
22
24
  MCP Gateway configuration management service.
23
-
25
+
24
26
  This service handles loading, validation, and access to MCP Gateway configuration.
25
27
  It supports YAML-based configuration files and environment variable overrides.
26
-
28
+
27
29
  WHY: Configuration is centralized in a service to ensure consistent access
28
30
  patterns, validation, and the ability to reload configuration at runtime.
29
31
  The service pattern also allows for dependency injection of configuration
30
32
  into other MCP services.
31
33
  """
32
-
34
+
33
35
  DEFAULT_CONFIG = {
34
36
  "mcp": {
35
37
  "server": {
@@ -44,7 +46,7 @@ class MCPConfiguration(BaseMCPService, IMCPConfiguration):
44
46
  "capabilities": {
45
47
  "tools": True,
46
48
  "resources": False, # Not yet implemented
47
- "prompts": False, # Not yet implemented
49
+ "prompts": False, # Not yet implemented
48
50
  },
49
51
  },
50
52
  "tools": {
@@ -73,11 +75,11 @@ class MCPConfiguration(BaseMCPService, IMCPConfiguration):
73
75
  },
74
76
  }
75
77
  }
76
-
78
+
77
79
  def __init__(self, config_path: Optional[Path] = None):
78
80
  """
79
81
  Initialize MCP configuration service.
80
-
82
+
81
83
  Args:
82
84
  config_path: Optional path to configuration file
83
85
  """
@@ -85,76 +87,76 @@ class MCPConfiguration(BaseMCPService, IMCPConfiguration):
85
87
  self._config_path = config_path
86
88
  self._config_data: Dict[str, Any] = {}
87
89
  self._is_loaded = False
88
-
90
+
89
91
  async def _do_initialize(self) -> bool:
90
92
  """
91
93
  Initialize the configuration service.
92
-
94
+
93
95
  Returns:
94
96
  True if initialization successful
95
97
  """
96
98
  # Start with default configuration
97
99
  self._config_data = self.DEFAULT_CONFIG.copy()
98
-
100
+
99
101
  # Load from file if path provided
100
102
  if self._config_path:
101
103
  if not self.load_config(self._config_path):
102
104
  return False
103
-
105
+
104
106
  # Apply environment variable overrides
105
107
  self._apply_env_overrides()
106
-
108
+
107
109
  # Validate configuration
108
110
  if not self.validate():
109
111
  return False
110
-
112
+
111
113
  self._is_loaded = True
112
114
  self.log_info("Configuration initialized successfully")
113
115
  return True
114
-
116
+
115
117
  def load_config(self, config_path: Path) -> bool:
116
118
  """
117
119
  Load configuration from a file.
118
-
120
+
119
121
  Args:
120
122
  config_path: Path to configuration file
121
-
123
+
122
124
  Returns:
123
125
  True if configuration loaded successfully
124
126
  """
125
127
  try:
126
128
  # Expand user path
127
129
  config_path = Path(config_path).expanduser()
128
-
130
+
129
131
  if not config_path.exists():
130
132
  self.log_warning(f"Configuration file not found: {config_path}")
131
133
  return True # Not an error, use defaults
132
-
133
- with open(config_path, 'r') as f:
134
- if config_path.suffix in ['.yaml', '.yml']:
134
+
135
+ with open(config_path, "r") as f:
136
+ if config_path.suffix in [".yaml", ".yml"]:
135
137
  loaded_config = yaml.safe_load(f) or {}
136
138
  else:
137
139
  raise MCPConfigurationError(
138
140
  f"Unsupported configuration file format: {config_path.suffix}"
139
141
  )
140
-
142
+
141
143
  # Merge with existing configuration
142
144
  self._merge_config(self._config_data, loaded_config)
143
145
  self._config_path = config_path
144
-
146
+
145
147
  self.log_info(f"Configuration loaded from {config_path}")
146
148
  return True
147
-
149
+
148
150
  except yaml.YAMLError as e:
149
151
  raise MCPConfigurationError(f"Failed to parse YAML configuration: {e}")
150
152
  except Exception as e:
151
153
  self.log_error(f"Failed to load configuration: {e}")
152
154
  return False
153
-
155
+
154
156
  def _merge_config(self, base: Dict[str, Any], overlay: Dict[str, Any]) -> None:
155
157
  """
156
158
  Recursively merge overlay configuration into base.
157
-
159
+
158
160
  Args:
159
161
  base: Base configuration dictionary
160
162
  overlay: Configuration to merge in
@@ -164,30 +166,32 @@ class MCPConfiguration(BaseMCPService, IMCPConfiguration):
164
166
  self._merge_config(base[key], value)
165
167
  else:
166
168
  base[key] = value
167
-
169
+
168
170
  def _apply_env_overrides(self) -> None:
169
171
  """
170
172
  Apply environment variable overrides to configuration.
171
-
173
+
172
174
  Environment variables follow the pattern: MCP_GATEWAY_<SECTION>_<KEY>
173
175
  For example: MCP_GATEWAY_SERVER_NAME=my-server
174
176
  """
175
177
  prefix = "MCP_GATEWAY_"
176
-
178
+
177
179
  for env_key, env_value in os.environ.items():
178
180
  if not env_key.startswith(prefix):
179
181
  continue
180
-
182
+
181
183
  # Parse environment variable into configuration path
182
- config_path = env_key[len(prefix):].lower().split('_')
183
-
184
+ config_path = env_key[len(prefix) :].lower().split("_")
185
+
184
186
  # Navigate to the configuration location
185
187
  current = self._config_data
186
188
  for i, part in enumerate(config_path[:-1]):
187
189
  if part not in current:
188
190
  current[part] = {}
189
191
  elif not isinstance(current[part], dict):
190
- self.log_warning(f"Cannot override non-dict config at {'.'.join(config_path[:i+1])}")
192
+ self.log_warning(
193
+ f"Cannot override non-dict config at {'.'.join(config_path[:i+1])}"
194
+ )
191
195
  break
192
196
  current = current[part]
193
197
  else:
@@ -196,46 +200,47 @@ class MCPConfiguration(BaseMCPService, IMCPConfiguration):
196
200
  # Try to parse as JSON for complex types
197
201
  try:
198
202
  import json
203
+
199
204
  current[key] = json.loads(env_value)
200
205
  except:
201
206
  # Fall back to string value
202
207
  current[key] = env_value
203
-
208
+
204
209
  self.log_debug(f"Applied environment override: {env_key}")
205
-
210
+
206
211
  def get(self, key: str, default: Any = None) -> Any:
207
212
  """
208
213
  Get configuration value by key.
209
-
214
+
210
215
  Args:
211
216
  key: Configuration key (supports dot notation, e.g., "mcp.server.name")
212
217
  default: Default value if key not found
213
-
218
+
214
219
  Returns:
215
220
  Configuration value or default
216
221
  """
217
- parts = key.split('.')
222
+ parts = key.split(".")
218
223
  current = self._config_data
219
-
224
+
220
225
  for part in parts:
221
226
  if isinstance(current, dict) and part in current:
222
227
  current = current[part]
223
228
  else:
224
229
  return default
225
-
230
+
226
231
  return current
227
-
232
+
228
233
  def set(self, key: str, value: Any) -> None:
229
234
  """
230
235
  Set configuration value.
231
-
236
+
232
237
  Args:
233
238
  key: Configuration key (supports dot notation)
234
239
  value: Configuration value
235
240
  """
236
- parts = key.split('.')
241
+ parts = key.split(".")
237
242
  current = self._config_data
238
-
243
+
239
244
  # Navigate to parent
240
245
  for part in parts[:-1]:
241
246
  if part not in current:
@@ -245,15 +250,15 @@ class MCPConfiguration(BaseMCPService, IMCPConfiguration):
245
250
  f"Cannot set value at {key}: parent is not a dictionary"
246
251
  )
247
252
  current = current[part]
248
-
253
+
249
254
  # Set the value
250
255
  current[parts[-1]] = value
251
256
  self.log_debug(f"Configuration updated: {key} = {value}")
252
-
257
+
253
258
  def validate(self) -> bool:
254
259
  """
255
260
  Validate the current configuration.
256
-
261
+
257
262
  Returns:
258
263
  True if configuration is valid
259
264
  """
@@ -264,66 +269,66 @@ class MCPConfiguration(BaseMCPService, IMCPConfiguration):
264
269
  "mcp.server.version",
265
270
  "mcp.server.communication.type",
266
271
  ]
267
-
272
+
268
273
  for field in required_fields:
269
274
  if self.get(field) is None:
270
275
  raise MCPConfigurationError(
271
276
  f"Required configuration field missing: {field}",
272
- config_key=field
277
+ config_key=field,
273
278
  )
274
-
279
+
275
280
  # Validate communication type
276
281
  comm_type = self.get("mcp.server.communication.type")
277
282
  if comm_type not in ["stdio", "websocket", "http"]:
278
283
  raise MCPConfigurationError(
279
284
  f"Invalid communication type: {comm_type}",
280
285
  config_key="mcp.server.communication.type",
281
- expected_type="stdio|websocket|http"
286
+ expected_type="stdio|websocket|http",
282
287
  )
283
-
288
+
284
289
  # Validate numeric fields
285
290
  timeout = self.get("mcp.server.communication.timeout")
286
291
  if not isinstance(timeout, (int, float)) or timeout <= 0:
287
292
  raise MCPConfigurationError(
288
293
  "Invalid timeout value",
289
294
  config_key="mcp.server.communication.timeout",
290
- expected_type="positive number"
295
+ expected_type="positive number",
291
296
  )
292
-
297
+
293
298
  self.log_debug("Configuration validation successful")
294
299
  return True
295
-
300
+
296
301
  except MCPConfigurationError:
297
302
  raise
298
303
  except Exception as e:
299
304
  self.log_error(f"Configuration validation failed: {e}")
300
305
  return False
301
-
306
+
302
307
  def get_server_config(self) -> Dict[str, Any]:
303
308
  """
304
309
  Get MCP server configuration.
305
-
310
+
306
311
  Returns:
307
312
  Server configuration dictionary
308
313
  """
309
314
  return self.get("mcp.server", {})
310
-
315
+
311
316
  def get_tools_config(self) -> Dict[str, Any]:
312
317
  """
313
318
  Get tools configuration.
314
-
319
+
315
320
  Returns:
316
321
  Tools configuration dictionary
317
322
  """
318
323
  return self.get("mcp.tools", {})
319
-
324
+
320
325
  def save_config(self, path: Optional[Path] = None) -> bool:
321
326
  """
322
327
  Save current configuration to file.
323
-
328
+
324
329
  Args:
325
330
  path: Path to save configuration (uses loaded path if not specified)
326
-
331
+
327
332
  Returns:
328
333
  True if save successful
329
334
  """
@@ -331,41 +336,43 @@ class MCPConfiguration(BaseMCPService, IMCPConfiguration):
331
336
  if not save_path:
332
337
  self.log_error("No path specified for saving configuration")
333
338
  return False
334
-
339
+
335
340
  try:
336
341
  save_path = Path(save_path).expanduser()
337
342
  save_path.parent.mkdir(parents=True, exist_ok=True)
338
-
339
- with open(save_path, 'w') as f:
340
- yaml.dump(self._config_data, f, default_flow_style=False, sort_keys=True)
341
-
343
+
344
+ with open(save_path, "w") as f:
345
+ yaml.dump(
346
+ self._config_data, f, default_flow_style=False, sort_keys=True
347
+ )
348
+
342
349
  self.log_info(f"Configuration saved to {save_path}")
343
350
  return True
344
-
351
+
345
352
  except Exception as e:
346
353
  self.log_error(f"Failed to save configuration: {e}")
347
354
  return False
348
-
355
+
349
356
  def reload(self) -> bool:
350
357
  """
351
358
  Reload configuration from file.
352
-
359
+
353
360
  Returns:
354
361
  True if reload successful
355
362
  """
356
363
  if not self._config_path:
357
364
  self.log_warning("No configuration file to reload")
358
365
  return True
359
-
366
+
360
367
  # Reset to defaults
361
368
  self._config_data = self.DEFAULT_CONFIG.copy()
362
-
369
+
363
370
  # Reload from file
364
371
  if not self.load_config(self._config_path):
365
372
  return False
366
-
373
+
367
374
  # Reapply environment overrides
368
375
  self._apply_env_overrides()
369
-
376
+
370
377
  # Revalidate
371
- return self.validate()
378
+ return self.validate()