claude-mpm 5.1.9__py3-none-any.whl → 5.4.48__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of claude-mpm might be problematic. Click here for more details.

Files changed (248) hide show
  1. claude_mpm/VERSION +1 -1
  2. claude_mpm/__init__.py +4 -0
  3. claude_mpm/agents/BASE_AGENT.md +164 -0
  4. claude_mpm/agents/CLAUDE_MPM_TEACHER_OUTPUT_STYLE.md +1 -1
  5. claude_mpm/agents/MEMORY.md +1 -1
  6. claude_mpm/agents/PM_INSTRUCTIONS.md +843 -900
  7. claude_mpm/agents/WORKFLOW.md +5 -254
  8. claude_mpm/agents/agent_loader.py +13 -44
  9. claude_mpm/agents/base_agent.json +1 -1
  10. claude_mpm/agents/frontmatter_validator.py +2 -2
  11. claude_mpm/agents/templates/circuit-breakers.md +138 -1
  12. claude_mpm/cli/__main__.py +4 -0
  13. claude_mpm/cli/chrome_devtools_installer.py +175 -0
  14. claude_mpm/cli/commands/agent_state_manager.py +18 -27
  15. claude_mpm/cli/commands/agents.py +9 -40
  16. claude_mpm/cli/commands/auto_configure.py +210 -25
  17. claude_mpm/cli/commands/config.py +88 -2
  18. claude_mpm/cli/commands/configure.py +1098 -159
  19. claude_mpm/cli/commands/configure_agent_display.py +25 -6
  20. claude_mpm/cli/commands/mpm_init/core.py +225 -46
  21. claude_mpm/cli/commands/mpm_init/knowledge_extractor.py +481 -0
  22. claude_mpm/cli/commands/mpm_init/prompts.py +280 -0
  23. claude_mpm/cli/commands/postmortem.py +1 -1
  24. claude_mpm/cli/commands/profile.py +277 -0
  25. claude_mpm/cli/commands/skills.py +218 -197
  26. claude_mpm/cli/commands/summarize.py +413 -0
  27. claude_mpm/cli/executor.py +21 -3
  28. claude_mpm/cli/interactive/agent_wizard.py +2 -2
  29. claude_mpm/cli/parsers/agents_parser.py +0 -9
  30. claude_mpm/cli/parsers/auto_configure_parser.py +0 -138
  31. claude_mpm/cli/parsers/base_parser.py +12 -0
  32. claude_mpm/cli/parsers/config_parser.py +153 -83
  33. claude_mpm/cli/parsers/profile_parser.py +148 -0
  34. claude_mpm/cli/parsers/skills_parser.py +0 -5
  35. claude_mpm/cli/startup.py +876 -149
  36. claude_mpm/commands/mpm-config.md +28 -0
  37. claude_mpm/commands/mpm-doctor.md +9 -22
  38. claude_mpm/commands/mpm-help.md +5 -287
  39. claude_mpm/commands/mpm-init.md +81 -507
  40. claude_mpm/commands/mpm-monitor.md +15 -402
  41. claude_mpm/commands/mpm-organize.md +120 -0
  42. claude_mpm/commands/mpm-postmortem.md +6 -108
  43. claude_mpm/commands/mpm-session-resume.md +12 -363
  44. claude_mpm/commands/mpm-status.md +5 -69
  45. claude_mpm/commands/mpm-ticket-view.md +52 -495
  46. claude_mpm/commands/mpm-version.md +5 -107
  47. claude_mpm/config/agent_sources.py +27 -0
  48. claude_mpm/core/config.py +2 -4
  49. claude_mpm/core/framework/formatters/content_formatter.py +3 -13
  50. claude_mpm/core/framework/loaders/agent_loader.py +8 -5
  51. claude_mpm/core/framework/loaders/instruction_loader.py +52 -11
  52. claude_mpm/core/framework_loader.py +4 -2
  53. claude_mpm/core/logger.py +13 -0
  54. claude_mpm/core/optimized_startup.py +59 -0
  55. claude_mpm/core/shared/config_loader.py +1 -1
  56. claude_mpm/core/socketio_pool.py +3 -3
  57. claude_mpm/core/unified_agent_registry.py +5 -15
  58. claude_mpm/dashboard/static/svelte-build/_app/env.js +1 -0
  59. claude_mpm/dashboard/static/svelte-build/_app/immutable/assets/0.B_FtCwCQ.css +1 -0
  60. claude_mpm/dashboard/static/svelte-build/_app/immutable/assets/2.Cl_eSA4x.css +1 -0
  61. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BgChzWQ1.js +1 -0
  62. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CIXEwuWe.js +1 -0
  63. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CWc5urbQ.js +1 -0
  64. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DMkZpdF2.js +2 -0
  65. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DjhvlsAc.js +1 -0
  66. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/N4qtv3Hx.js +2 -0
  67. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/uj46x2Wr.js +1 -0
  68. claude_mpm/dashboard/static/svelte-build/_app/immutable/entry/app.DTL5mJO-.js +2 -0
  69. claude_mpm/dashboard/static/svelte-build/_app/immutable/entry/start.DzuEhzqh.js +1 -0
  70. claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/0.CAGBuiOw.js +1 -0
  71. claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/1.DFLC8jdE.js +1 -0
  72. claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/2.DPvEihJJ.js +10 -0
  73. claude_mpm/dashboard/static/svelte-build/_app/version.json +1 -0
  74. claude_mpm/dashboard/static/svelte-build/favicon.svg +7 -0
  75. claude_mpm/dashboard/static/svelte-build/index.html +36 -0
  76. claude_mpm/hooks/claude_hooks/__pycache__/__init__.cpython-311.pyc +0 -0
  77. claude_mpm/hooks/claude_hooks/__pycache__/correlation_manager.cpython-311.pyc +0 -0
  78. claude_mpm/hooks/claude_hooks/__pycache__/event_handlers.cpython-311.pyc +0 -0
  79. claude_mpm/hooks/claude_hooks/__pycache__/hook_handler.cpython-311.pyc +0 -0
  80. claude_mpm/hooks/claude_hooks/__pycache__/installer.cpython-311.pyc +0 -0
  81. claude_mpm/hooks/claude_hooks/__pycache__/memory_integration.cpython-311.pyc +0 -0
  82. claude_mpm/hooks/claude_hooks/__pycache__/response_tracking.cpython-311.pyc +0 -0
  83. claude_mpm/hooks/claude_hooks/__pycache__/tool_analysis.cpython-311.pyc +0 -0
  84. claude_mpm/hooks/claude_hooks/correlation_manager.py +60 -0
  85. claude_mpm/hooks/claude_hooks/event_handlers.py +211 -78
  86. claude_mpm/hooks/claude_hooks/hook_handler.py +155 -1
  87. claude_mpm/hooks/claude_hooks/installer.py +33 -10
  88. claude_mpm/hooks/claude_hooks/memory_integration.py +26 -9
  89. claude_mpm/hooks/claude_hooks/response_tracking.py +2 -3
  90. claude_mpm/hooks/claude_hooks/services/__pycache__/__init__.cpython-311.pyc +0 -0
  91. claude_mpm/hooks/claude_hooks/services/__pycache__/connection_manager.cpython-311.pyc +0 -0
  92. claude_mpm/hooks/claude_hooks/services/__pycache__/connection_manager_http.cpython-311.pyc +0 -0
  93. claude_mpm/hooks/claude_hooks/services/__pycache__/duplicate_detector.cpython-311.pyc +0 -0
  94. claude_mpm/hooks/claude_hooks/services/__pycache__/state_manager.cpython-311.pyc +0 -0
  95. claude_mpm/hooks/claude_hooks/services/__pycache__/subagent_processor.cpython-311.pyc +0 -0
  96. claude_mpm/hooks/claude_hooks/services/connection_manager.py +30 -6
  97. claude_mpm/hooks/kuzu_memory_hook.py +5 -5
  98. claude_mpm/hooks/memory_integration_hook.py +46 -1
  99. claude_mpm/init.py +63 -19
  100. claude_mpm/models/git_repository.py +3 -3
  101. claude_mpm/scripts/claude-hook-handler.sh +58 -18
  102. claude_mpm/scripts/launch_monitor.py +93 -13
  103. claude_mpm/services/agents/agent_builder.py +3 -3
  104. claude_mpm/services/agents/agent_recommendation_service.py +278 -0
  105. claude_mpm/services/agents/agent_review_service.py +280 -0
  106. claude_mpm/services/agents/cache_git_manager.py +6 -6
  107. claude_mpm/services/agents/deployment/agent_deployment.py +29 -7
  108. claude_mpm/services/agents/deployment/agent_discovery_service.py +4 -5
  109. claude_mpm/services/agents/deployment/agent_format_converter.py +23 -13
  110. claude_mpm/services/agents/deployment/agent_template_builder.py +32 -20
  111. claude_mpm/services/agents/deployment/agents_directory_resolver.py +2 -2
  112. claude_mpm/services/agents/deployment/async_agent_deployment.py +31 -27
  113. claude_mpm/services/agents/deployment/local_template_deployment.py +3 -1
  114. claude_mpm/services/agents/deployment/multi_source_deployment_service.py +247 -35
  115. claude_mpm/services/agents/deployment/remote_agent_discovery_service.py +392 -87
  116. claude_mpm/services/agents/git_source_manager.py +53 -4
  117. claude_mpm/services/agents/loading/base_agent_manager.py +1 -13
  118. claude_mpm/services/agents/recommender.py +5 -3
  119. claude_mpm/services/agents/single_tier_deployment_service.py +2 -2
  120. claude_mpm/services/agents/sources/git_source_sync_service.py +120 -7
  121. claude_mpm/services/agents/startup_sync.py +22 -2
  122. claude_mpm/services/agents/toolchain_detector.py +10 -6
  123. claude_mpm/services/analysis/__init__.py +11 -1
  124. claude_mpm/services/analysis/clone_detector.py +1030 -0
  125. claude_mpm/services/command_deployment_service.py +81 -10
  126. claude_mpm/services/diagnostics/checks/agent_check.py +2 -2
  127. claude_mpm/services/diagnostics/checks/agent_sources_check.py +1 -1
  128. claude_mpm/services/event_bus/config.py +3 -1
  129. claude_mpm/services/git/git_operations_service.py +101 -16
  130. claude_mpm/services/monitor/daemon.py +9 -2
  131. claude_mpm/services/monitor/daemon_manager.py +39 -3
  132. claude_mpm/services/monitor/management/lifecycle.py +8 -1
  133. claude_mpm/services/monitor/server.py +698 -22
  134. claude_mpm/services/pm_skills_deployer.py +711 -0
  135. claude_mpm/services/profile_manager.py +331 -0
  136. claude_mpm/services/self_upgrade_service.py +120 -12
  137. claude_mpm/services/skills/__init__.py +3 -0
  138. claude_mpm/services/skills/git_skill_source_manager.py +130 -2
  139. claude_mpm/services/skills/selective_skill_deployer.py +704 -0
  140. claude_mpm/services/skills/skill_to_agent_mapper.py +406 -0
  141. claude_mpm/services/skills_deployer.py +127 -9
  142. claude_mpm/services/socketio/dashboard_server.py +1 -0
  143. claude_mpm/services/socketio/event_normalizer.py +51 -6
  144. claude_mpm/services/socketio/server/core.py +386 -108
  145. claude_mpm/services/version_control/git_operations.py +103 -0
  146. claude_mpm/skills/skill_manager.py +92 -3
  147. claude_mpm/utils/agent_dependency_loader.py +14 -2
  148. claude_mpm/utils/agent_filters.py +17 -44
  149. claude_mpm/utils/migration.py +4 -4
  150. claude_mpm/utils/robust_installer.py +47 -3
  151. {claude_mpm-5.1.9.dist-info → claude_mpm-5.4.48.dist-info}/METADATA +53 -87
  152. {claude_mpm-5.1.9.dist-info → claude_mpm-5.4.48.dist-info}/RECORD +157 -197
  153. claude_mpm-5.4.48.dist-info/entry_points.txt +5 -0
  154. claude_mpm-5.4.48.dist-info/licenses/LICENSE +94 -0
  155. claude_mpm-5.4.48.dist-info/licenses/LICENSE-FAQ.md +153 -0
  156. claude_mpm/agents/BASE_AGENT_TEMPLATE.md +0 -292
  157. claude_mpm/agents/BASE_DOCUMENTATION.md +0 -53
  158. claude_mpm/agents/BASE_OPS.md +0 -219
  159. claude_mpm/agents/BASE_PM.md +0 -480
  160. claude_mpm/agents/BASE_PROMPT_ENGINEER.md +0 -787
  161. claude_mpm/agents/BASE_QA.md +0 -167
  162. claude_mpm/agents/BASE_RESEARCH.md +0 -53
  163. claude_mpm/agents/base_agent_loader.py +0 -601
  164. claude_mpm/cli/commands/agents_detect.py +0 -380
  165. claude_mpm/cli/commands/agents_recommend.py +0 -309
  166. claude_mpm/cli/ticket_cli.py +0 -35
  167. claude_mpm/commands/mpm-agents-auto-configure.md +0 -278
  168. claude_mpm/commands/mpm-agents-detect.md +0 -177
  169. claude_mpm/commands/mpm-agents-list.md +0 -131
  170. claude_mpm/commands/mpm-agents-recommend.md +0 -223
  171. claude_mpm/commands/mpm-config-view.md +0 -150
  172. claude_mpm/commands/mpm-ticket-organize.md +0 -304
  173. claude_mpm/dashboard/analysis_runner.py +0 -455
  174. claude_mpm/dashboard/index.html +0 -13
  175. claude_mpm/dashboard/open_dashboard.py +0 -66
  176. claude_mpm/dashboard/static/css/activity.css +0 -1958
  177. claude_mpm/dashboard/static/css/connection-status.css +0 -370
  178. claude_mpm/dashboard/static/css/dashboard.css +0 -4701
  179. claude_mpm/dashboard/static/js/components/activity-tree.js +0 -1871
  180. claude_mpm/dashboard/static/js/components/agent-hierarchy.js +0 -777
  181. claude_mpm/dashboard/static/js/components/agent-inference.js +0 -956
  182. claude_mpm/dashboard/static/js/components/build-tracker.js +0 -333
  183. claude_mpm/dashboard/static/js/components/code-simple.js +0 -857
  184. claude_mpm/dashboard/static/js/components/connection-debug.js +0 -654
  185. claude_mpm/dashboard/static/js/components/diff-viewer.js +0 -891
  186. claude_mpm/dashboard/static/js/components/event-processor.js +0 -542
  187. claude_mpm/dashboard/static/js/components/event-viewer.js +0 -1155
  188. claude_mpm/dashboard/static/js/components/export-manager.js +0 -368
  189. claude_mpm/dashboard/static/js/components/file-change-tracker.js +0 -443
  190. claude_mpm/dashboard/static/js/components/file-change-viewer.js +0 -690
  191. claude_mpm/dashboard/static/js/components/file-tool-tracker.js +0 -724
  192. claude_mpm/dashboard/static/js/components/file-viewer.js +0 -580
  193. claude_mpm/dashboard/static/js/components/hud-library-loader.js +0 -211
  194. claude_mpm/dashboard/static/js/components/hud-manager.js +0 -671
  195. claude_mpm/dashboard/static/js/components/hud-visualizer.js +0 -1718
  196. claude_mpm/dashboard/static/js/components/module-viewer.js +0 -2764
  197. claude_mpm/dashboard/static/js/components/session-manager.js +0 -579
  198. claude_mpm/dashboard/static/js/components/socket-manager.js +0 -368
  199. claude_mpm/dashboard/static/js/components/ui-state-manager.js +0 -749
  200. claude_mpm/dashboard/static/js/components/unified-data-viewer.js +0 -1824
  201. claude_mpm/dashboard/static/js/components/working-directory.js +0 -920
  202. claude_mpm/dashboard/static/js/connection-manager.js +0 -536
  203. claude_mpm/dashboard/static/js/dashboard.js +0 -1914
  204. claude_mpm/dashboard/static/js/extension-error-handler.js +0 -164
  205. claude_mpm/dashboard/static/js/socket-client.js +0 -1474
  206. claude_mpm/dashboard/static/js/tab-isolation-fix.js +0 -185
  207. claude_mpm/dashboard/static/socket.io.min.js +0 -7
  208. claude_mpm/dashboard/static/socket.io.v4.8.1.backup.js +0 -7
  209. claude_mpm/dashboard/templates/code_simple.html +0 -153
  210. claude_mpm/dashboard/templates/index.html +0 -606
  211. claude_mpm/dashboard/test_dashboard.html +0 -372
  212. claude_mpm/scripts/mcp_server.py +0 -75
  213. claude_mpm/scripts/mcp_wrapper.py +0 -39
  214. claude_mpm/services/mcp_gateway/__init__.py +0 -159
  215. claude_mpm/services/mcp_gateway/auto_configure.py +0 -369
  216. claude_mpm/services/mcp_gateway/config/__init__.py +0 -17
  217. claude_mpm/services/mcp_gateway/config/config_loader.py +0 -296
  218. claude_mpm/services/mcp_gateway/config/config_schema.py +0 -243
  219. claude_mpm/services/mcp_gateway/config/configuration.py +0 -429
  220. claude_mpm/services/mcp_gateway/core/__init__.py +0 -43
  221. claude_mpm/services/mcp_gateway/core/base.py +0 -312
  222. claude_mpm/services/mcp_gateway/core/exceptions.py +0 -253
  223. claude_mpm/services/mcp_gateway/core/interfaces.py +0 -443
  224. claude_mpm/services/mcp_gateway/core/process_pool.py +0 -977
  225. claude_mpm/services/mcp_gateway/core/singleton_manager.py +0 -315
  226. claude_mpm/services/mcp_gateway/core/startup_verification.py +0 -316
  227. claude_mpm/services/mcp_gateway/main.py +0 -589
  228. claude_mpm/services/mcp_gateway/registry/__init__.py +0 -12
  229. claude_mpm/services/mcp_gateway/registry/service_registry.py +0 -412
  230. claude_mpm/services/mcp_gateway/registry/tool_registry.py +0 -489
  231. claude_mpm/services/mcp_gateway/server/__init__.py +0 -15
  232. claude_mpm/services/mcp_gateway/server/mcp_gateway.py +0 -414
  233. claude_mpm/services/mcp_gateway/server/stdio_handler.py +0 -372
  234. claude_mpm/services/mcp_gateway/server/stdio_server.py +0 -712
  235. claude_mpm/services/mcp_gateway/tools/__init__.py +0 -36
  236. claude_mpm/services/mcp_gateway/tools/base_adapter.py +0 -485
  237. claude_mpm/services/mcp_gateway/tools/document_summarizer.py +0 -789
  238. claude_mpm/services/mcp_gateway/tools/external_mcp_services.py +0 -654
  239. claude_mpm/services/mcp_gateway/tools/health_check_tool.py +0 -456
  240. claude_mpm/services/mcp_gateway/tools/hello_world.py +0 -551
  241. claude_mpm/services/mcp_gateway/tools/kuzu_memory_service.py +0 -555
  242. claude_mpm/services/mcp_gateway/utils/__init__.py +0 -14
  243. claude_mpm/services/mcp_gateway/utils/package_version_checker.py +0 -160
  244. claude_mpm/services/mcp_gateway/utils/update_preferences.py +0 -170
  245. claude_mpm-5.1.9.dist-info/entry_points.txt +0 -10
  246. claude_mpm-5.1.9.dist-info/licenses/LICENSE +0 -21
  247. {claude_mpm-5.1.9.dist-info → claude_mpm-5.4.48.dist-info}/WHEEL +0 -0
  248. {claude_mpm-5.1.9.dist-info → claude_mpm-5.4.48.dist-info}/top_level.txt +0 -0
@@ -1,43 +0,0 @@
1
- """
2
- MCP Gateway Core Module
3
- =======================
4
-
5
- Core interfaces and base classes for the MCP Gateway service.
6
- """
7
-
8
- from .base import BaseMCPService
9
- from .exceptions import (
10
- MCPCommunicationError,
11
- MCPConfigurationError,
12
- MCPException,
13
- MCPServerError,
14
- MCPToolNotFoundError,
15
- MCPValidationError,
16
- )
17
- from .interfaces import (
18
- IMCPCommunication,
19
- IMCPConfiguration,
20
- IMCPGateway,
21
- IMCPLifecycle,
22
- IMCPToolAdapter,
23
- IMCPToolRegistry,
24
- )
25
-
26
- __all__ = [
27
- # Base classes
28
- "BaseMCPService",
29
- "IMCPCommunication",
30
- "IMCPConfiguration",
31
- # Interfaces
32
- "IMCPGateway",
33
- "IMCPLifecycle",
34
- "IMCPToolAdapter",
35
- "IMCPToolRegistry",
36
- "MCPCommunicationError",
37
- "MCPConfigurationError",
38
- # Exceptions
39
- "MCPException",
40
- "MCPServerError",
41
- "MCPToolNotFoundError",
42
- "MCPValidationError",
43
- ]
@@ -1,312 +0,0 @@
1
- """
2
- MCP Gateway Base Classes
3
- ========================
4
-
5
- Base implementations for MCP Gateway services.
6
-
7
- Part of ISS-0034: Infrastructure Setup - MCP Gateway Project Foundation
8
- """
9
-
10
- import asyncio
11
- from typing import Any, Dict, Optional
12
-
13
- from claude_mpm.core.enums import ServiceState
14
- from claude_mpm.services.core.base import BaseService
15
-
16
-
17
- class BaseMCPService(BaseService):
18
- """
19
- Base class for all MCP Gateway services.
20
-
21
- Extends the claude-mpm BaseService with MCP-specific functionality
22
- including state management, health monitoring, and async lifecycle support.
23
-
24
- WHY: We extend BaseService to maintain consistency with the claude-mpm
25
- architecture while adding MCP-specific capabilities. This ensures all
26
- MCP services integrate seamlessly with the existing service container
27
- and dependency injection system.
28
- """
29
-
30
- def __init__(
31
- self,
32
- service_name: Optional[str] = None,
33
- config: Optional[Dict[str, Any]] = None,
34
- ):
35
- """
36
- Initialize MCP service.
37
-
38
- Args:
39
- service_name: Name of the service for logging
40
- config: Service-specific configuration
41
- """
42
- super().__init__(service_name or "MCPService", config)
43
- self._state = ServiceState.UNINITIALIZED
44
- self._health_status = {
45
- "healthy": False,
46
- "state": self._state.value,
47
- "last_check": None,
48
- "details": {},
49
- }
50
- self._state_lock = asyncio.Lock()
51
- self._initialization_task = None
52
- self._shutdown_task = None
53
-
54
- async def initialize(self) -> bool:
55
- """
56
- Initialize the MCP service.
57
-
58
- This method manages state transitions and ensures thread-safe initialization.
59
- Subclasses should override _do_initialize() for custom initialization logic.
60
-
61
- Returns:
62
- True if initialization successful, False otherwise
63
- """
64
- async with self._state_lock:
65
- if self._state not in [
66
- ServiceState.UNINITIALIZED,
67
- ServiceState.STOPPED,
68
- ]:
69
- self.log_warning(f"Cannot initialize from state {self._state.value}")
70
- return False
71
-
72
- self._state = ServiceState.INITIALIZING
73
- self.log_info("Initializing MCP service")
74
-
75
- try:
76
- # Call subclass initialization
77
- success = await self._do_initialize()
78
-
79
- async with self._state_lock:
80
- if success:
81
- self._state = ServiceState.INITIALIZED
82
- self._initialized = True
83
- self._health_status["healthy"] = True
84
- self._health_status["state"] = self._state.value
85
- self.log_info("MCP service initialized successfully")
86
- else:
87
- self._state = ServiceState.ERROR
88
- self._health_status["healthy"] = False
89
- self._health_status["state"] = self._state.value
90
- self.log_error("MCP service initialization failed")
91
-
92
- return success
93
-
94
- except Exception as e:
95
- async with self._state_lock:
96
- self._state = ServiceState.ERROR
97
- self._health_status["healthy"] = False
98
- self._health_status["state"] = self._state.value
99
- self._health_status["details"]["error"] = str(e)
100
-
101
- self.log_error(f"Exception during initialization: {e}")
102
- return False
103
-
104
- async def _do_initialize(self) -> bool:
105
- """
106
- Perform actual initialization logic.
107
-
108
- Subclasses should override this method to implement custom initialization.
109
-
110
- Returns:
111
- True if initialization successful
112
- """
113
- # Default implementation - subclasses should override
114
- return True
115
-
116
- async def start(self) -> bool:
117
- """
118
- Start the MCP service.
119
-
120
- Returns:
121
- True if startup successful
122
- """
123
- async with self._state_lock:
124
- if self._state != ServiceState.INITIALIZED:
125
- self.log_warning(f"Cannot start from state {self._state.value}")
126
- return False
127
-
128
- self._state = ServiceState.STARTING
129
- self.log_info("Starting MCP service")
130
-
131
- try:
132
- success = await self._do_start()
133
-
134
- async with self._state_lock:
135
- if success:
136
- self._state = ServiceState.RUNNING
137
- self._health_status["healthy"] = True
138
- self._health_status["state"] = self._state.value
139
- self.log_info("MCP service started successfully")
140
- else:
141
- self._state = ServiceState.ERROR
142
- self._health_status["healthy"] = False
143
- self._health_status["state"] = self._state.value
144
- self.log_error("MCP service startup failed")
145
-
146
- return success
147
-
148
- except Exception as e:
149
- async with self._state_lock:
150
- self._state = ServiceState.ERROR
151
- self._health_status["healthy"] = False
152
- self._health_status["state"] = self._state.value
153
- self._health_status["details"]["error"] = str(e)
154
-
155
- self.log_error(f"Exception during startup: {e}")
156
- return False
157
-
158
- async def _do_start(self) -> bool:
159
- """
160
- Perform actual startup logic.
161
-
162
- Subclasses should override this method to implement custom startup.
163
-
164
- Returns:
165
- True if startup successful
166
- """
167
- # Default implementation - subclasses should override
168
- return True
169
-
170
- async def shutdown(self) -> None:
171
- """
172
- Shutdown the MCP service gracefully.
173
-
174
- This method manages state transitions and ensures clean shutdown.
175
- Subclasses should override _do_shutdown() for custom shutdown logic.
176
- """
177
- async with self._state_lock:
178
- if self._state in [ServiceState.STOPPED, ServiceState.STOPPING]:
179
- self.log_warning(f"Already in state {self._state.value}")
180
- return
181
-
182
- self._state = ServiceState.STOPPING
183
- self.log_info("Shutting down MCP service")
184
-
185
- try:
186
- await self._do_shutdown()
187
-
188
- async with self._state_lock:
189
- self._state = ServiceState.STOPPED
190
- self._shutdown = True
191
- self._health_status["healthy"] = False
192
- self._health_status["state"] = self._state.value
193
- self.log_info("MCP service shutdown complete")
194
-
195
- except Exception as e:
196
- async with self._state_lock:
197
- self._state = ServiceState.ERROR
198
- self._health_status["healthy"] = False
199
- self._health_status["state"] = self._state.value
200
- self._health_status["details"]["error"] = str(e)
201
-
202
- self.log_error(f"Exception during shutdown: {e}")
203
-
204
- async def _do_shutdown(self) -> None:
205
- """
206
- Perform actual shutdown logic.
207
-
208
- Subclasses should override this method to implement custom shutdown.
209
- """
210
- # Default implementation - subclasses should override
211
-
212
- async def restart(self) -> bool:
213
- """
214
- Restart the MCP service.
215
-
216
- Returns:
217
- True if restart successful
218
- """
219
- self.log_info("Restarting MCP service")
220
-
221
- # Shutdown if running
222
- if self._state == ServiceState.RUNNING:
223
- await self.shutdown()
224
-
225
- # Re-initialize
226
- if not await self.initialize():
227
- return False
228
-
229
- # Start again
230
- return await self.start()
231
-
232
- def get_state(self) -> str:
233
- """
234
- Get current service state.
235
-
236
- Returns:
237
- Service state string
238
- """
239
- return self._state.value
240
-
241
- def is_healthy(self) -> bool:
242
- """
243
- Check if service is healthy.
244
-
245
- Returns:
246
- True if service is healthy
247
- """
248
- return self._health_status["healthy"]
249
-
250
- def get_health_status(self) -> Dict[str, Any]:
251
- """
252
- Get detailed health status.
253
-
254
- Returns:
255
- Health status information
256
- """
257
- return self._health_status.copy()
258
-
259
- def update_health_status(
260
- self, healthy: bool, details: Optional[Dict[str, Any]] = None
261
- ) -> None:
262
- """
263
- Update health status.
264
-
265
- Args:
266
- healthy: Whether service is healthy
267
- details: Additional health details
268
- """
269
- from datetime import datetime, timezone
270
-
271
- self._health_status["healthy"] = healthy
272
- self._health_status["last_check"] = datetime.now(timezone.utc).isoformat()
273
-
274
- if details:
275
- self._health_status["details"].update(details)
276
-
277
- # Additional logging methods for MCP-specific events
278
- def log_mcp_event(
279
- self, event_type: str, data: Optional[Dict[str, Any]] = None
280
- ) -> None:
281
- """
282
- Log an MCP-specific event.
283
-
284
- Args:
285
- event_type: Type of MCP event
286
- data: Event data
287
- """
288
- message = f"MCP Event: {event_type}"
289
- if data:
290
- message += f" - {data}"
291
- self.log_info(message)
292
-
293
- def log_tool_invocation(
294
- self, tool_name: str, success: bool, duration: Optional[float] = None
295
- ) -> None:
296
- """
297
- Log a tool invocation.
298
-
299
- Args:
300
- tool_name: Name of the tool invoked
301
- success: Whether invocation was successful
302
- duration: Execution duration in seconds
303
- """
304
- status = "successful" if success else "failed"
305
- message = f"Tool invocation: {tool_name} {status}"
306
- if duration:
307
- message += f" ({duration:.3f}s)"
308
-
309
- if success:
310
- self.log_info(message)
311
- else:
312
- self.log_warning(message)
@@ -1,253 +0,0 @@
1
- """
2
- MCP Gateway Exception Classes
3
- =============================
4
-
5
- Custom exceptions for MCP Gateway operations.
6
-
7
- Part of ISS-0034: Infrastructure Setup - MCP Gateway Project Foundation
8
- """
9
-
10
- from typing import Any, Dict, Optional
11
-
12
-
13
- class MCPException(Exception):
14
- """
15
- Base exception for all MCP Gateway errors.
16
-
17
- WHY: We create a base exception to allow catching all MCP-related
18
- errors in a single except block while still being able to handle
19
- specific error types when needed.
20
- """
21
-
22
- def __init__(self, message: str, details: Optional[Dict[str, Any]] = None):
23
- """
24
- Initialize MCP exception.
25
-
26
- Args:
27
- message: Error message
28
- details: Additional error details
29
- """
30
- super().__init__(message)
31
- self.message = message
32
- self.details = details or {}
33
-
34
- def __str__(self) -> str:
35
- """String representation of the exception."""
36
- if self.details:
37
- return f"{self.message} - Details: {self.details}"
38
- return self.message
39
-
40
-
41
- class MCPConfigurationError(MCPException):
42
- """
43
- Raised when MCP configuration is invalid or cannot be loaded.
44
-
45
- Common scenarios:
46
- - Missing required configuration fields
47
- - Invalid configuration values
48
- - Configuration file not found
49
- - YAML parsing errors
50
- """
51
-
52
- def __init__(
53
- self,
54
- message: str,
55
- config_key: Optional[str] = None,
56
- expected_type: Optional[str] = None,
57
- ):
58
- """
59
- Initialize configuration error.
60
-
61
- Args:
62
- message: Error message
63
- config_key: Configuration key that caused the error
64
- expected_type: Expected type for the configuration value
65
- """
66
- details = {}
67
- if config_key:
68
- details["config_key"] = config_key
69
- if expected_type:
70
- details["expected_type"] = expected_type
71
-
72
- super().__init__(message, details)
73
-
74
-
75
- class MCPToolNotFoundError(MCPException):
76
- """
77
- Raised when a requested tool is not found in the registry.
78
-
79
- This error occurs when:
80
- - Attempting to invoke a non-existent tool
81
- - Trying to unregister a tool that isn't registered
82
- - Searching for a tool that doesn't exist
83
- """
84
-
85
- def __init__(self, tool_name: str, available_tools: Optional[list] = None):
86
- """
87
- Initialize tool not found error.
88
-
89
- Args:
90
- tool_name: Name of the tool that wasn't found
91
- available_tools: List of available tool names for reference
92
- """
93
- message = f"Tool '{tool_name}' not found in registry"
94
- details = {"tool_name": tool_name}
95
-
96
- if available_tools:
97
- details["available_tools"] = available_tools
98
- message += f". Available tools: {', '.join(available_tools)}"
99
-
100
- super().__init__(message, details)
101
-
102
-
103
- class MCPServerError(MCPException):
104
- """
105
- Raised when MCP server encounters an error.
106
-
107
- Common scenarios:
108
- - Server initialization failure
109
- - Port binding issues
110
- - Server crash during operation
111
- - Invalid server state transitions
112
- """
113
-
114
- def __init__(
115
- self,
116
- message: str,
117
- server_state: Optional[str] = None,
118
- error_code: Optional[int] = None,
119
- ):
120
- """
121
- Initialize server error.
122
-
123
- Args:
124
- message: Error message
125
- server_state: Current server state when error occurred
126
- error_code: Numeric error code if applicable
127
- """
128
- details = {}
129
- if server_state:
130
- details["server_state"] = server_state
131
- if error_code:
132
- details["error_code"] = error_code
133
-
134
- super().__init__(message, details)
135
-
136
-
137
- class MCPCommunicationError(MCPException):
138
- """
139
- Raised when communication with MCP client fails.
140
-
141
- This includes:
142
- - Stdio communication failures
143
- - Message parsing errors
144
- - Protocol violations
145
- - Timeout errors
146
- """
147
-
148
- def __init__(
149
- self,
150
- message: str,
151
- direction: Optional[str] = None,
152
- raw_data: Optional[str] = None,
153
- ):
154
- """
155
- Initialize communication error.
156
-
157
- Args:
158
- message: Error message
159
- direction: Direction of communication ("send" or "receive")
160
- raw_data: Raw data that caused the error (for debugging)
161
- """
162
- details = {}
163
- if direction:
164
- details["direction"] = direction
165
- if raw_data and len(raw_data) < 1000: # Limit raw data size in exceptions
166
- details["raw_data"] = raw_data
167
- elif raw_data:
168
- details["raw_data"] = raw_data[:1000] + "... (truncated)"
169
-
170
- super().__init__(message, details)
171
-
172
-
173
- class MCPValidationError(MCPException):
174
- """
175
- Raised when validation fails.
176
-
177
- Used for:
178
- - Tool parameter validation
179
- - Schema validation
180
- - Input validation
181
- - Response validation
182
- """
183
-
184
- def __init__(
185
- self,
186
- message: str,
187
- field: Optional[str] = None,
188
- expected: Optional[Any] = None,
189
- actual: Optional[Any] = None,
190
- ):
191
- """
192
- Initialize validation error.
193
-
194
- Args:
195
- message: Error message
196
- field: Field that failed validation
197
- expected: Expected value or type
198
- actual: Actual value received
199
- """
200
- details = {}
201
- if field:
202
- details["field"] = field
203
- if expected is not None:
204
- details["expected"] = str(expected)
205
- if actual is not None:
206
- details["actual"] = str(actual)
207
-
208
- super().__init__(message, details)
209
-
210
-
211
- class MCPTimeoutError(MCPException):
212
- """
213
- Raised when an operation times out.
214
-
215
- Common scenarios:
216
- - Tool invocation timeout
217
- - Server startup timeout
218
- - Communication timeout
219
- """
220
-
221
- def __init__(self, operation: str, timeout_seconds: float):
222
- """
223
- Initialize timeout error.
224
-
225
- Args:
226
- operation: Operation that timed out
227
- timeout_seconds: Timeout duration in seconds
228
- """
229
- message = f"Operation '{operation}' timed out after {timeout_seconds} seconds"
230
- details = {"operation": operation, "timeout_seconds": timeout_seconds}
231
- super().__init__(message, details)
232
-
233
-
234
- class MCPAuthenticationError(MCPException):
235
- """
236
- Raised when authentication fails.
237
-
238
- For future use when MCP supports authentication.
239
- """
240
-
241
- def __init__(self, message: str, auth_method: Optional[str] = None):
242
- """
243
- Initialize authentication error.
244
-
245
- Args:
246
- message: Error message
247
- auth_method: Authentication method that failed
248
- """
249
- details = {}
250
- if auth_method:
251
- details["auth_method"] = auth_method
252
-
253
- super().__init__(message, details)