claude-mpm 3.9.8__py3-none-any.whl → 3.9.9__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 (44) hide show
  1. claude_mpm/VERSION +1 -1
  2. claude_mpm/agents/base_agent.json +1 -1
  3. claude_mpm/cli/__init__.py +3 -1
  4. claude_mpm/cli/commands/__init__.py +3 -1
  5. claude_mpm/cli/commands/cleanup.py +21 -1
  6. claude_mpm/cli/commands/mcp.py +821 -0
  7. claude_mpm/cli/parser.py +148 -1
  8. claude_mpm/config/memory_guardian_config.py +325 -0
  9. claude_mpm/constants.py +13 -0
  10. claude_mpm/hooks/claude_hooks/hook_handler.py +76 -19
  11. claude_mpm/models/state_models.py +433 -0
  12. claude_mpm/services/communication/__init__.py +2 -2
  13. claude_mpm/services/communication/socketio.py +18 -16
  14. claude_mpm/services/infrastructure/__init__.py +4 -1
  15. claude_mpm/services/infrastructure/logging.py +3 -3
  16. claude_mpm/services/infrastructure/memory_guardian.py +770 -0
  17. claude_mpm/services/mcp_gateway/__init__.py +28 -12
  18. claude_mpm/services/mcp_gateway/main.py +326 -0
  19. claude_mpm/services/mcp_gateway/registry/__init__.py +6 -3
  20. claude_mpm/services/mcp_gateway/registry/service_registry.py +397 -0
  21. claude_mpm/services/mcp_gateway/registry/tool_registry.py +477 -0
  22. claude_mpm/services/mcp_gateway/server/__init__.py +9 -3
  23. claude_mpm/services/mcp_gateway/server/mcp_server.py +430 -0
  24. claude_mpm/services/mcp_gateway/server/mcp_server_simple.py +444 -0
  25. claude_mpm/services/mcp_gateway/server/stdio_handler.py +373 -0
  26. claude_mpm/services/mcp_gateway/tools/__init__.py +16 -3
  27. claude_mpm/services/mcp_gateway/tools/base_adapter.py +497 -0
  28. claude_mpm/services/mcp_gateway/tools/document_summarizer.py +729 -0
  29. claude_mpm/services/mcp_gateway/tools/hello_world.py +551 -0
  30. claude_mpm/utils/file_utils.py +293 -0
  31. claude_mpm/utils/platform_memory.py +524 -0
  32. claude_mpm/utils/subprocess_utils.py +305 -0
  33. {claude_mpm-3.9.8.dist-info → claude_mpm-3.9.9.dist-info}/METADATA +3 -1
  34. {claude_mpm-3.9.8.dist-info → claude_mpm-3.9.9.dist-info}/RECORD +39 -28
  35. claude_mpm/agents/templates/.claude-mpm/memories/README.md +0 -36
  36. claude_mpm/agents/templates/.claude-mpm/memories/engineer_agent.md +0 -39
  37. claude_mpm/agents/templates/.claude-mpm/memories/qa_agent.md +0 -38
  38. claude_mpm/agents/templates/.claude-mpm/memories/research_agent.md +0 -39
  39. claude_mpm/agents/templates/.claude-mpm/memories/version_control_agent.md +0 -38
  40. /claude_mpm/agents/templates/{research_memory_efficient.json → backup/research_memory_efficient.json} +0 -0
  41. {claude_mpm-3.9.8.dist-info → claude_mpm-3.9.9.dist-info}/WHEEL +0 -0
  42. {claude_mpm-3.9.8.dist-info → claude_mpm-3.9.9.dist-info}/entry_points.txt +0 -0
  43. {claude_mpm-3.9.8.dist-info → claude_mpm-3.9.9.dist-info}/licenses/LICENSE +0 -0
  44. {claude_mpm-3.9.8.dist-info → claude_mpm-3.9.9.dist-info}/top_level.txt +0 -0
@@ -49,17 +49,29 @@ def __getattr__(name):
49
49
  elif name == "MCPServer":
50
50
  from .server.mcp_server import MCPServer
51
51
  return MCPServer
52
- elif name == "MCPServerManager":
53
- from .server.server_manager import MCPServerManager
54
- return MCPServerManager
52
+ elif name == "StdioHandler":
53
+ from .server.stdio_handler import StdioHandler
54
+ return StdioHandler
55
+ elif name == "AlternativeStdioHandler":
56
+ from .server.stdio_handler import AlternativeStdioHandler
57
+ return AlternativeStdioHandler
55
58
 
56
59
  # Tool registry and adapters
57
- elif name == "MCPToolRegistry":
58
- from .tools.tool_registry import MCPToolRegistry
59
- return MCPToolRegistry
60
- elif name == "ToolAdapter":
61
- from .tools.tool_adapter import ToolAdapter
62
- return ToolAdapter
60
+ elif name == "ToolRegistry":
61
+ from .registry.tool_registry import ToolRegistry
62
+ return ToolRegistry
63
+ elif name == "BaseToolAdapter":
64
+ from .tools.base_adapter import BaseToolAdapter
65
+ return BaseToolAdapter
66
+ elif name == "EchoToolAdapter":
67
+ from .tools.base_adapter import EchoToolAdapter
68
+ return EchoToolAdapter
69
+ elif name == "CalculatorToolAdapter":
70
+ from .tools.base_adapter import CalculatorToolAdapter
71
+ return CalculatorToolAdapter
72
+ elif name == "SystemInfoToolAdapter":
73
+ from .tools.base_adapter import SystemInfoToolAdapter
74
+ return SystemInfoToolAdapter
63
75
 
64
76
  # Configuration management
65
77
  elif name == "MCPConfiguration":
@@ -101,11 +113,15 @@ __all__ = [
101
113
 
102
114
  # Server implementations
103
115
  "MCPServer",
104
- "MCPServerManager",
116
+ "StdioHandler",
117
+ "AlternativeStdioHandler",
105
118
 
106
119
  # Tool management
107
- "MCPToolRegistry",
108
- "ToolAdapter",
120
+ "ToolRegistry",
121
+ "BaseToolAdapter",
122
+ "EchoToolAdapter",
123
+ "CalculatorToolAdapter",
124
+ "SystemInfoToolAdapter",
109
125
 
110
126
  # Configuration
111
127
  "MCPConfiguration",
@@ -0,0 +1,326 @@
1
+ """
2
+ MCP Gateway Main Entry Point
3
+ =============================
4
+
5
+ Main entry point for running the MCP Gateway server.
6
+ Orchestrates server initialization, tool registration, and lifecycle management.
7
+
8
+ Part of ISS-0035: MCP Server Implementation - Core Server and Tool Registry
9
+ """
10
+
11
+ import asyncio
12
+ import sys
13
+ import signal
14
+ from pathlib import Path
15
+ from typing import Optional, List
16
+ import argparse
17
+ import logging
18
+
19
+ from claude_mpm.services.mcp_gateway.server.mcp_server import MCPServer
20
+ from claude_mpm.services.mcp_gateway.server.stdio_handler import StdioHandler
21
+ from claude_mpm.services.mcp_gateway.registry.tool_registry import ToolRegistry
22
+ from claude_mpm.services.mcp_gateway.tools.base_adapter import (
23
+ EchoToolAdapter,
24
+ CalculatorToolAdapter,
25
+ SystemInfoToolAdapter
26
+ )
27
+ from claude_mpm.services.mcp_gateway.tools.document_summarizer import DocumentSummarizerTool
28
+ from claude_mpm.services.mcp_gateway.config.configuration import MCPConfiguration
29
+ from claude_mpm.core.logger import get_logger
30
+
31
+
32
+ class MCPGateway:
33
+ """
34
+ Main MCP Gateway orchestrator.
35
+
36
+ WHY: This class coordinates all MCP components, managing their lifecycle
37
+ and ensuring proper initialization, startup, and shutdown sequences.
38
+
39
+ DESIGN DECISIONS:
40
+ - Use dependency injection to wire components together
41
+ - Implement graceful shutdown on SIGINT/SIGTERM
42
+ - Support both configuration file and CLI arguments
43
+ - Provide comprehensive logging for debugging
44
+ """
45
+
46
+ def __init__(self, config_path: Optional[Path] = None):
47
+ """
48
+ Initialize the MCP Gateway.
49
+
50
+ Args:
51
+ config_path: Optional path to configuration file
52
+ """
53
+ self.logger = get_logger(self.__class__.__name__)
54
+ self.config_path = config_path
55
+
56
+ # Core components
57
+ self.server: Optional[MCPServer] = None
58
+ self.registry: Optional[ToolRegistry] = None
59
+ self.communication: Optional[StdioHandler] = None
60
+ self.configuration: Optional[MCPConfiguration] = None
61
+
62
+ # Shutdown handling
63
+ self._shutdown_event = asyncio.Event()
64
+ self._setup_signal_handlers()
65
+
66
+ def _setup_signal_handlers(self) -> None:
67
+ """Setup signal handlers for graceful shutdown."""
68
+ def signal_handler(sig, frame):
69
+ self.logger.info(f"Received signal {sig}, initiating shutdown...")
70
+ self._shutdown_event.set()
71
+
72
+ signal.signal(signal.SIGINT, signal_handler)
73
+ signal.signal(signal.SIGTERM, signal_handler)
74
+
75
+ async def initialize(self) -> bool:
76
+ """
77
+ Initialize all MCP Gateway components.
78
+
79
+ Returns:
80
+ True if initialization successful
81
+ """
82
+ try:
83
+ self.logger.info("Initializing MCP Gateway")
84
+
85
+ # Load configuration
86
+ self.configuration = MCPConfiguration()
87
+ if self.config_path and self.config_path.exists():
88
+ if not self.configuration.load_config(self.config_path):
89
+ self.logger.error("Failed to load configuration")
90
+ return False
91
+
92
+ # Initialize tool registry
93
+ self.registry = ToolRegistry()
94
+ if not await self.registry.initialize():
95
+ self.logger.error("Failed to initialize tool registry")
96
+ return False
97
+
98
+ # Register built-in tools
99
+ await self._register_builtin_tools()
100
+
101
+ # Initialize communication handler
102
+ self.communication = StdioHandler()
103
+ if not await self.communication.initialize():
104
+ self.logger.error("Failed to initialize communication handler")
105
+ return False
106
+
107
+ # Initialize MCP server
108
+ server_name = self.configuration.get("server.name", "claude-mpm-mcp")
109
+ version = self.configuration.get("server.version", "1.0.0")
110
+ self.server = MCPServer(server_name=server_name, version=version)
111
+
112
+ # Wire dependencies
113
+ self.server.set_tool_registry(self.registry)
114
+ self.server.set_communication(self.communication)
115
+
116
+ if not await self.server.initialize():
117
+ self.logger.error("Failed to initialize MCP server")
118
+ return False
119
+
120
+ self.logger.info("MCP Gateway initialized successfully")
121
+ return True
122
+
123
+ except Exception as e:
124
+ self.logger.error(f"Failed to initialize MCP Gateway: {e}")
125
+ return False
126
+
127
+ async def _register_builtin_tools(self) -> None:
128
+ """Register built-in tools with the registry."""
129
+ self.logger.info("Registering built-in tools")
130
+
131
+ # Create tool adapters
132
+ tools = [
133
+ EchoToolAdapter(),
134
+ CalculatorToolAdapter(),
135
+ SystemInfoToolAdapter(),
136
+ DocumentSummarizerTool() # ISS-0037: Document summarizer for memory optimization
137
+ ]
138
+
139
+ # Register each tool
140
+ for tool in tools:
141
+ try:
142
+ # Initialize the tool
143
+ if await tool.initialize():
144
+ # Register with the registry
145
+ if self.registry.register_tool(tool, category="builtin"):
146
+ self.logger.info(f"Registered tool: {tool.get_definition().name}")
147
+ else:
148
+ self.logger.warning(f"Failed to register tool: {tool.get_definition().name}")
149
+ else:
150
+ self.logger.warning(f"Failed to initialize tool: {tool.get_definition().name}")
151
+ except Exception as e:
152
+ self.logger.error(f"Error registering tool {tool.get_definition().name}: {e}")
153
+
154
+ async def start(self) -> bool:
155
+ """
156
+ Start the MCP Gateway server.
157
+
158
+ Returns:
159
+ True if startup successful
160
+ """
161
+ try:
162
+ self.logger.info("Starting MCP Gateway")
163
+
164
+ if not self.server:
165
+ self.logger.error("Server not initialized")
166
+ return False
167
+
168
+ if not await self.server.start():
169
+ self.logger.error("Failed to start MCP server")
170
+ return False
171
+
172
+ self.logger.info("MCP Gateway started successfully")
173
+ return True
174
+
175
+ except Exception as e:
176
+ self.logger.error(f"Failed to start MCP Gateway: {e}")
177
+ return False
178
+
179
+ async def run(self) -> None:
180
+ """
181
+ Run the MCP Gateway main loop.
182
+
183
+ This method blocks until shutdown is requested.
184
+ """
185
+ try:
186
+ self.logger.info("MCP Gateway running")
187
+
188
+ # Wait for shutdown signal
189
+ await self._shutdown_event.wait()
190
+
191
+ self.logger.info("Shutdown signal received")
192
+
193
+ except Exception as e:
194
+ self.logger.error(f"Error in MCP Gateway main loop: {e}")
195
+ raise
196
+
197
+ async def shutdown(self) -> None:
198
+ """Shutdown the MCP Gateway gracefully."""
199
+ try:
200
+ self.logger.info("Shutting down MCP Gateway")
201
+
202
+ # Shutdown server
203
+ if self.server:
204
+ await self.server.shutdown()
205
+
206
+ # Shutdown registry (which will shutdown all tools)
207
+ if self.registry:
208
+ await self.registry.shutdown()
209
+
210
+ # Shutdown communication handler
211
+ if self.communication:
212
+ await self.communication.shutdown()
213
+
214
+ self.logger.info("MCP Gateway shutdown complete")
215
+
216
+ except Exception as e:
217
+ self.logger.error(f"Error during shutdown: {e}")
218
+
219
+
220
+ async def main(args: argparse.Namespace) -> int:
221
+ """
222
+ Main entry point for the MCP Gateway.
223
+
224
+ Args:
225
+ args: Command line arguments
226
+
227
+ Returns:
228
+ Exit code (0 for success, 1 for failure)
229
+ """
230
+ # Setup logging
231
+ log_level = logging.DEBUG if args.debug else logging.INFO
232
+ logging.basicConfig(
233
+ level=log_level,
234
+ format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
235
+ )
236
+
237
+ # Create gateway instance
238
+ config_path = Path(args.config) if args.config else None
239
+ gateway = MCPGateway(config_path=config_path)
240
+
241
+ try:
242
+ # Initialize
243
+ if not await gateway.initialize():
244
+ logging.error("Failed to initialize MCP Gateway")
245
+ return 1
246
+
247
+ # Start
248
+ if not await gateway.start():
249
+ logging.error("Failed to start MCP Gateway")
250
+ return 1
251
+
252
+ # Run until shutdown
253
+ await gateway.run()
254
+
255
+ # Graceful shutdown
256
+ await gateway.shutdown()
257
+
258
+ return 0
259
+
260
+ except Exception as e:
261
+ logging.error(f"Unhandled exception: {e}")
262
+ await gateway.shutdown()
263
+ return 1
264
+
265
+
266
+ def parse_arguments() -> argparse.Namespace:
267
+ """
268
+ Parse command line arguments.
269
+
270
+ Returns:
271
+ Parsed arguments
272
+ """
273
+ parser = argparse.ArgumentParser(
274
+ description="Claude MPM MCP Gateway Server",
275
+ formatter_class=argparse.RawDescriptionHelpFormatter,
276
+ epilog="""
277
+ Examples:
278
+ # Run with default configuration
279
+ python -m claude_mpm.services.mcp_gateway.main
280
+
281
+ # Run with custom configuration file
282
+ python -m claude_mpm.services.mcp_gateway.main --config /path/to/config.yaml
283
+
284
+ # Run with debug logging
285
+ python -m claude_mpm.services.mcp_gateway.main --debug
286
+
287
+ # Run as MCP server for Claude Desktop
288
+ python -m claude_mpm.services.mcp_gateway.main --stdio
289
+ """
290
+ )
291
+
292
+ parser.add_argument(
293
+ "--config",
294
+ type=str,
295
+ help="Path to configuration file"
296
+ )
297
+
298
+ parser.add_argument(
299
+ "--debug",
300
+ action="store_true",
301
+ help="Enable debug logging"
302
+ )
303
+
304
+ parser.add_argument(
305
+ "--stdio",
306
+ action="store_true",
307
+ default=True,
308
+ help="Use stdio for communication (default)"
309
+ )
310
+
311
+ parser.add_argument(
312
+ "--version",
313
+ action="version",
314
+ version="Claude MPM MCP Gateway 1.0.0"
315
+ )
316
+
317
+ return parser.parse_args()
318
+
319
+
320
+ if __name__ == "__main__":
321
+ # Parse arguments
322
+ args = parse_arguments()
323
+
324
+ # Run the gateway
325
+ exit_code = asyncio.run(main(args))
326
+ sys.exit(exit_code)
@@ -2,8 +2,11 @@
2
2
  MCP Gateway Registry Module
3
3
  ===========================
4
4
 
5
- Service discovery and registration for the MCP Gateway.
5
+ Tool registry components for the MCP Gateway service.
6
6
  """
7
7
 
8
- # Placeholder for future implementation
9
- # Will be implemented as part of tool and service discovery
8
+ from .tool_registry import ToolRegistry
9
+
10
+ __all__ = [
11
+ "ToolRegistry",
12
+ ]