claude-mpm 4.3.12__py3-none-any.whl → 4.3.14__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 (206) hide show
  1. claude_mpm/VERSION +1 -1
  2. claude_mpm/agents/PM_INSTRUCTIONS.md +414 -28
  3. claude_mpm/agents/templates/data_engineer.json +39 -14
  4. claude_mpm/agents/templates/engineer.json +11 -3
  5. claude_mpm/cli/commands/agent_manager.py +3 -3
  6. claude_mpm/cli/commands/agents.py +2 -2
  7. claude_mpm/cli/commands/aggregate.py +1 -1
  8. claude_mpm/cli/commands/config.py +2 -2
  9. claude_mpm/cli/commands/configure.py +5 -5
  10. claude_mpm/cli/commands/configure_tui.py +7 -7
  11. claude_mpm/cli/commands/dashboard.py +1 -1
  12. claude_mpm/cli/commands/debug.py +5 -5
  13. claude_mpm/cli/commands/mcp.py +1 -1
  14. claude_mpm/cli/commands/mcp_command_router.py +1 -1
  15. claude_mpm/cli/commands/mcp_config.py +7 -10
  16. claude_mpm/cli/commands/mcp_external_commands.py +40 -32
  17. claude_mpm/cli/commands/mcp_install_commands.py +38 -10
  18. claude_mpm/cli/commands/mcp_setup_external.py +143 -102
  19. claude_mpm/cli/commands/monitor.py +2 -2
  20. claude_mpm/cli/commands/mpm_init_handler.py +1 -1
  21. claude_mpm/cli/commands/run.py +54 -2
  22. claude_mpm/cli/commands/search.py +41 -34
  23. claude_mpm/cli/interactive/agent_wizard.py +6 -2
  24. claude_mpm/cli/parsers/mcp_parser.py +1 -3
  25. claude_mpm/cli/parsers/search_parser.py +10 -4
  26. claude_mpm/cli/startup_logging.py +158 -5
  27. claude_mpm/cli/utils.py +1 -1
  28. claude_mpm/core/agent_registry.py +2 -2
  29. claude_mpm/core/agent_session_manager.py +8 -8
  30. claude_mpm/core/api_validator.py +6 -4
  31. claude_mpm/core/base_service.py +10 -10
  32. claude_mpm/core/cache.py +5 -5
  33. claude_mpm/core/config_constants.py +1 -1
  34. claude_mpm/core/container.py +1 -1
  35. claude_mpm/core/error_handler.py +2 -2
  36. claude_mpm/core/file_utils.py +1 -1
  37. claude_mpm/core/framework_loader.py +3 -3
  38. claude_mpm/core/hook_manager.py +8 -6
  39. claude_mpm/core/instruction_reinforcement_hook.py +2 -2
  40. claude_mpm/core/interactive_session.py +3 -1
  41. claude_mpm/core/lazy.py +3 -3
  42. claude_mpm/core/log_manager.py +16 -12
  43. claude_mpm/core/logger.py +16 -11
  44. claude_mpm/core/optimized_agent_loader.py +6 -6
  45. claude_mpm/core/output_style_manager.py +1 -1
  46. claude_mpm/core/pm_hook_interceptor.py +3 -3
  47. claude_mpm/core/service_registry.py +1 -1
  48. claude_mpm/core/session_manager.py +11 -9
  49. claude_mpm/core/socketio_pool.py +13 -13
  50. claude_mpm/core/types.py +2 -2
  51. claude_mpm/core/unified_agent_registry.py +2 -2
  52. claude_mpm/core/unified_paths.py +1 -1
  53. claude_mpm/dashboard/analysis_runner.py +4 -4
  54. claude_mpm/dashboard/api/simple_directory.py +1 -1
  55. claude_mpm/generators/agent_profile_generator.py +4 -2
  56. claude_mpm/hooks/base_hook.py +2 -2
  57. claude_mpm/hooks/claude_hooks/__pycache__/__init__.cpython-313.pyc +0 -0
  58. claude_mpm/hooks/claude_hooks/__pycache__/event_handlers.cpython-313.pyc +0 -0
  59. claude_mpm/hooks/claude_hooks/__pycache__/hook_handler.cpython-313.pyc +0 -0
  60. claude_mpm/hooks/claude_hooks/__pycache__/installer.cpython-313.pyc +0 -0
  61. claude_mpm/hooks/claude_hooks/__pycache__/memory_integration.cpython-313.pyc +0 -0
  62. claude_mpm/hooks/claude_hooks/__pycache__/response_tracking.cpython-313.pyc +0 -0
  63. claude_mpm/hooks/claude_hooks/__pycache__/tool_analysis.cpython-313.pyc +0 -0
  64. claude_mpm/hooks/claude_hooks/connection_pool.py +4 -4
  65. claude_mpm/hooks/claude_hooks/event_handlers.py +12 -12
  66. claude_mpm/hooks/claude_hooks/hook_handler.py +4 -4
  67. claude_mpm/hooks/claude_hooks/hook_handler_eventbus.py +3 -3
  68. claude_mpm/hooks/claude_hooks/hook_handler_original.py +15 -14
  69. claude_mpm/hooks/claude_hooks/hook_handler_refactored.py +4 -4
  70. claude_mpm/hooks/claude_hooks/installer.py +3 -3
  71. claude_mpm/hooks/claude_hooks/memory_integration.py +3 -3
  72. claude_mpm/hooks/claude_hooks/response_tracking.py +3 -3
  73. claude_mpm/hooks/claude_hooks/services/__pycache__/__init__.cpython-313.pyc +0 -0
  74. claude_mpm/hooks/claude_hooks/services/__pycache__/connection_manager.cpython-313.pyc +0 -0
  75. claude_mpm/hooks/claude_hooks/services/__pycache__/connection_manager_http.cpython-313.pyc +0 -0
  76. claude_mpm/hooks/claude_hooks/services/__pycache__/duplicate_detector.cpython-313.pyc +0 -0
  77. claude_mpm/hooks/claude_hooks/services/__pycache__/state_manager.cpython-313.pyc +0 -0
  78. claude_mpm/hooks/claude_hooks/services/__pycache__/subagent_processor.cpython-313.pyc +0 -0
  79. claude_mpm/hooks/claude_hooks/services/connection_manager.py +8 -5
  80. claude_mpm/hooks/claude_hooks/services/connection_manager_http.py +3 -3
  81. claude_mpm/hooks/claude_hooks/services/state_manager.py +8 -7
  82. claude_mpm/hooks/claude_hooks/services/subagent_processor.py +3 -3
  83. claude_mpm/hooks/claude_hooks/tool_analysis.py +2 -2
  84. claude_mpm/hooks/memory_integration_hook.py +1 -1
  85. claude_mpm/hooks/tool_call_interceptor.py +2 -2
  86. claude_mpm/models/agent_session.py +7 -5
  87. claude_mpm/scripts/mcp_server.py +0 -0
  88. claude_mpm/scripts/start_activity_logging.py +0 -0
  89. claude_mpm/services/__init__.py +1 -1
  90. claude_mpm/services/agent_capabilities_service.py +1 -1
  91. claude_mpm/services/agents/agent_builder.py +3 -3
  92. claude_mpm/services/agents/deployment/agent_deployment.py +2 -1
  93. claude_mpm/services/agents/deployment/agent_discovery_service.py +9 -3
  94. claude_mpm/services/agents/deployment/agent_filesystem_manager.py +5 -5
  95. claude_mpm/services/agents/deployment/agent_lifecycle_manager.py +3 -1
  96. claude_mpm/services/agents/deployment/agent_metrics_collector.py +1 -1
  97. claude_mpm/services/agents/deployment/agent_operation_service.py +2 -2
  98. claude_mpm/services/agents/deployment/agent_state_service.py +2 -2
  99. claude_mpm/services/agents/deployment/agent_template_builder.py +1 -1
  100. claude_mpm/services/agents/deployment/agent_versioning.py +1 -1
  101. claude_mpm/services/agents/deployment/deployment_wrapper.py +2 -3
  102. claude_mpm/services/agents/deployment/pipeline/steps/agent_processing_step.py +1 -1
  103. claude_mpm/services/agents/loading/agent_profile_loader.py +5 -3
  104. claude_mpm/services/agents/loading/base_agent_manager.py +2 -2
  105. claude_mpm/services/agents/local_template_manager.py +6 -6
  106. claude_mpm/services/agents/management/agent_management_service.py +3 -3
  107. claude_mpm/services/agents/memory/content_manager.py +3 -3
  108. claude_mpm/services/agents/memory/memory_format_service.py +2 -2
  109. claude_mpm/services/agents/memory/template_generator.py +3 -3
  110. claude_mpm/services/agents/registry/modification_tracker.py +2 -2
  111. claude_mpm/services/async_session_logger.py +3 -3
  112. claude_mpm/services/claude_session_logger.py +4 -4
  113. claude_mpm/services/cli/agent_listing_service.py +3 -1
  114. claude_mpm/services/cli/agent_validation_service.py +2 -0
  115. claude_mpm/services/cli/memory_crud_service.py +11 -6
  116. claude_mpm/services/cli/memory_output_formatter.py +1 -1
  117. claude_mpm/services/cli/session_manager.py +15 -11
  118. claude_mpm/services/core/memory_manager.py +81 -23
  119. claude_mpm/services/core/path_resolver.py +1 -1
  120. claude_mpm/services/diagnostics/checks/installation_check.py +1 -1
  121. claude_mpm/services/event_aggregator.py +4 -2
  122. claude_mpm/services/event_bus/direct_relay.py +5 -3
  123. claude_mpm/services/event_bus/event_bus.py +3 -3
  124. claude_mpm/services/event_bus/relay.py +6 -4
  125. claude_mpm/services/events/consumers/dead_letter.py +5 -3
  126. claude_mpm/services/events/core.py +3 -3
  127. claude_mpm/services/events/producers/hook.py +6 -6
  128. claude_mpm/services/events/producers/system.py +8 -8
  129. claude_mpm/services/exceptions.py +5 -5
  130. claude_mpm/services/framework_claude_md_generator/content_assembler.py +3 -3
  131. claude_mpm/services/framework_claude_md_generator/section_generators/__init__.py +2 -2
  132. claude_mpm/services/hook_installer_service.py +1 -1
  133. claude_mpm/services/infrastructure/context_preservation.py +6 -4
  134. claude_mpm/services/infrastructure/daemon_manager.py +2 -2
  135. claude_mpm/services/infrastructure/logging.py +2 -2
  136. claude_mpm/services/mcp_config_manager.py +175 -30
  137. claude_mpm/services/mcp_gateway/__init__.py +1 -1
  138. claude_mpm/services/mcp_gateway/auto_configure.py +3 -3
  139. claude_mpm/services/mcp_gateway/config/config_loader.py +1 -1
  140. claude_mpm/services/mcp_gateway/config/configuration.py +1 -1
  141. claude_mpm/services/mcp_gateway/core/base.py +2 -2
  142. claude_mpm/services/mcp_gateway/main.py +21 -7
  143. claude_mpm/services/mcp_gateway/registry/tool_registry.py +10 -8
  144. claude_mpm/services/mcp_gateway/server/mcp_gateway.py +4 -4
  145. claude_mpm/services/mcp_gateway/server/stdio_handler.py +1 -1
  146. claude_mpm/services/mcp_gateway/server/stdio_server.py +5 -2
  147. claude_mpm/services/mcp_gateway/tools/base_adapter.py +15 -15
  148. claude_mpm/services/mcp_gateway/tools/document_summarizer.py +7 -5
  149. claude_mpm/services/mcp_gateway/tools/external_mcp_services.py +190 -137
  150. claude_mpm/services/mcp_gateway/tools/health_check_tool.py +5 -5
  151. claude_mpm/services/mcp_gateway/tools/hello_world.py +9 -9
  152. claude_mpm/services/mcp_gateway/tools/ticket_tools.py +16 -16
  153. claude_mpm/services/mcp_gateway/tools/unified_ticket_tool.py +16 -16
  154. claude_mpm/services/memory/builder.py +7 -5
  155. claude_mpm/services/memory/indexed_memory.py +4 -4
  156. claude_mpm/services/memory/optimizer.py +6 -6
  157. claude_mpm/services/memory/router.py +3 -3
  158. claude_mpm/services/monitor/daemon.py +1 -1
  159. claude_mpm/services/monitor/daemon_manager.py +6 -6
  160. claude_mpm/services/monitor/event_emitter.py +2 -2
  161. claude_mpm/services/monitor/management/lifecycle.py +3 -1
  162. claude_mpm/services/monitor/server.py +4 -4
  163. claude_mpm/services/monitor_build_service.py +2 -2
  164. claude_mpm/services/port_manager.py +3 -1
  165. claude_mpm/services/response_tracker.py +2 -2
  166. claude_mpm/services/session_management_service.py +3 -2
  167. claude_mpm/services/socketio/client_proxy.py +2 -2
  168. claude_mpm/services/socketio/dashboard_server.py +4 -3
  169. claude_mpm/services/socketio/event_normalizer.py +11 -7
  170. claude_mpm/services/socketio/handlers/base.py +2 -2
  171. claude_mpm/services/socketio/handlers/connection.py +10 -10
  172. claude_mpm/services/socketio/handlers/connection_handler.py +13 -10
  173. claude_mpm/services/socketio/handlers/hook.py +16 -15
  174. claude_mpm/services/socketio/migration_utils.py +1 -1
  175. claude_mpm/services/socketio/monitor_client.py +5 -5
  176. claude_mpm/services/socketio/server/broadcaster.py +9 -7
  177. claude_mpm/services/socketio/server/connection_manager.py +2 -2
  178. claude_mpm/services/socketio/server/core.py +7 -5
  179. claude_mpm/services/socketio/server/eventbus_integration.py +18 -12
  180. claude_mpm/services/socketio/server/main.py +13 -13
  181. claude_mpm/services/socketio_client_manager.py +4 -4
  182. claude_mpm/services/system_instructions_service.py +2 -2
  183. claude_mpm/services/utility_service.py +5 -2
  184. claude_mpm/services/version_control/branch_strategy.py +2 -2
  185. claude_mpm/services/version_control/git_operations.py +22 -20
  186. claude_mpm/services/version_control/semantic_versioning.py +3 -3
  187. claude_mpm/services/version_control/version_parser.py +7 -5
  188. claude_mpm/services/visualization/mermaid_generator.py +3 -1
  189. claude_mpm/storage/state_storage.py +1 -1
  190. claude_mpm/tools/code_tree_analyzer.py +23 -18
  191. claude_mpm/tools/code_tree_builder.py +2 -2
  192. claude_mpm/tools/code_tree_events.py +10 -8
  193. claude_mpm/tools/socketio_debug.py +3 -3
  194. claude_mpm/utils/agent_dependency_loader.py +6 -2
  195. claude_mpm/utils/dependency_strategies.py +8 -3
  196. claude_mpm/utils/environment_context.py +1 -1
  197. claude_mpm/utils/error_handler.py +2 -2
  198. claude_mpm/utils/file_utils.py +1 -1
  199. claude_mpm/utils/log_cleanup.py +21 -7
  200. claude_mpm/validation/agent_validator.py +2 -2
  201. {claude_mpm-4.3.12.dist-info → claude_mpm-4.3.14.dist-info}/METADATA +1 -1
  202. {claude_mpm-4.3.12.dist-info → claude_mpm-4.3.14.dist-info}/RECORD +204 -191
  203. {claude_mpm-4.3.12.dist-info → claude_mpm-4.3.14.dist-info}/WHEEL +0 -0
  204. {claude_mpm-4.3.12.dist-info → claude_mpm-4.3.14.dist-info}/entry_points.txt +0 -0
  205. {claude_mpm-4.3.12.dist-info → claude_mpm-4.3.14.dist-info}/licenses/LICENSE +0 -0
  206. {claude_mpm-4.3.12.dist-info → claude_mpm-4.3.14.dist-info}/top_level.txt +0 -0
@@ -26,7 +26,7 @@ __version__ = "0.1.0"
26
26
 
27
27
 
28
28
  # Lazy imports to prevent circular dependencies and improve startup performance
29
- def __getattr__(name):
29
+ def __getattr__(name): # noqa: PLR0911
30
30
  """Lazy import mechanism for MCP Gateway components."""
31
31
 
32
32
  # Core interfaces and base classes
@@ -20,7 +20,7 @@ DESIGN DECISIONS:
20
20
  import json
21
21
  import os
22
22
  import sys
23
- from datetime import datetime
23
+ from datetime import datetime, timezone
24
24
  from pathlib import Path
25
25
  from typing import Any, Dict, Optional
26
26
 
@@ -144,7 +144,7 @@ class MCPAutoConfigurator:
144
144
  prefs = {
145
145
  "asked": True,
146
146
  "choice": choice,
147
- "timestamp": datetime.now().isoformat(),
147
+ "timestamp": datetime.now(timezone.utc).isoformat(),
148
148
  }
149
149
 
150
150
  try:
@@ -266,7 +266,7 @@ class MCPAutoConfigurator:
266
266
  def _create_backup(self) -> Optional[Path]:
267
267
  """Create backup of existing configuration."""
268
268
  try:
269
- timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
269
+ timestamp = datetime.now(timezone.utc).strftime("%Y%m%d_%H%M%S")
270
270
  backup_path = self.claude_config_path.with_suffix(
271
271
  f".backup.{timestamp}.json"
272
272
  )
@@ -143,7 +143,7 @@ class MCPConfigLoader:
143
143
  import json
144
144
 
145
145
  current[key] = json.loads(env_value)
146
- except:
146
+ except Exception:
147
147
  # Fall back to string value
148
148
  current[key] = env_value
149
149
 
@@ -225,7 +225,7 @@ class MCPConfiguration(BaseMCPService, IMCPConfiguration):
225
225
  import json
226
226
 
227
227
  current[key] = json.loads(env_value)
228
- except:
228
+ except Exception:
229
229
  # Fall back to string value
230
230
  current[key] = env_value
231
231
 
@@ -279,10 +279,10 @@ class BaseMCPService(BaseService):
279
279
  healthy: Whether service is healthy
280
280
  details: Additional health details
281
281
  """
282
- from datetime import datetime
282
+ from datetime import datetime, timezone
283
283
 
284
284
  self._health_status["healthy"] = healthy
285
- self._health_status["last_check"] = datetime.now().isoformat()
285
+ self._health_status["last_check"] = datetime.now(timezone.utc).isoformat()
286
286
 
287
287
  if details:
288
288
  self._health_status["details"].update(details)
@@ -213,21 +213,35 @@ class MCPGatewayOrchestrator:
213
213
  try:
214
214
  self.logger.info("Initializing external MCP services...")
215
215
  self.external_services = ExternalMCPServiceManager()
216
- external_services = await self.external_services.initialize_services()
216
+ external_services = (
217
+ await self.external_services.initialize_services()
218
+ )
217
219
 
218
220
  if external_services and self.registry:
219
221
  for service in external_services:
220
222
  try:
221
- if self.registry.register_tool(service, category="external"):
222
- self.logger.info(f"Registered external service: {service.service_name}")
223
+ if self.registry.register_tool(
224
+ service, category="external"
225
+ ):
226
+ self.logger.info(
227
+ f"Registered external service: {service.service_name}"
228
+ )
223
229
  else:
224
- self.logger.warning(f"Failed to register external service: {service.service_name}")
230
+ self.logger.warning(
231
+ f"Failed to register external service: {service.service_name}"
232
+ )
225
233
  except Exception as e:
226
- self.logger.warning(f"Error registering {service.service_name}: {e}")
234
+ self.logger.warning(
235
+ f"Error registering {service.service_name}: {e}"
236
+ )
227
237
 
228
- self.logger.info(f"Initialized {len(external_services)} external MCP services")
238
+ self.logger.info(
239
+ f"Initialized {len(external_services)} external MCP services"
240
+ )
229
241
  except Exception as e:
230
- self.logger.warning(f"Failed to initialize external MCP services: {e}")
242
+ self.logger.warning(
243
+ f"Failed to initialize external MCP services: {e}"
244
+ )
231
245
  self.external_services = None
232
246
 
233
247
  # Initialize communication handler with fallback
@@ -11,7 +11,7 @@ Part of ISS-0035: MCP Server Implementation - Core Server and Tool Registry
11
11
  import asyncio
12
12
  import re
13
13
  import traceback
14
- from datetime import datetime
14
+ from datetime import datetime, timezone
15
15
  from threading import RLock
16
16
  from typing import Any, Dict, List, Optional, Set
17
17
 
@@ -159,9 +159,9 @@ class ToolRegistry(BaseMCPService, IMCPToolRegistry):
159
159
 
160
160
  # Update metrics
161
161
  self._metrics["total_tools"] = len(self._adapters)
162
- self._metrics["registration_time"][
163
- tool_name
164
- ] = datetime.now().isoformat()
162
+ self._metrics["registration_time"][tool_name] = datetime.now(
163
+ timezone.utc
164
+ ).isoformat()
165
165
  self._metrics["invocations"][tool_name] = 0
166
166
  self._metrics["errors"][tool_name] = 0
167
167
 
@@ -272,7 +272,7 @@ class ToolRegistry(BaseMCPService, IMCPToolRegistry):
272
272
  error handling, metrics tracking, and validation.
273
273
  """
274
274
  tool_name = invocation.tool_name
275
- start_time = datetime.now()
275
+ start_time = datetime.now(timezone.utc)
276
276
 
277
277
  try:
278
278
  self.log_info(f"Invoking tool: {tool_name}")
@@ -300,7 +300,7 @@ class ToolRegistry(BaseMCPService, IMCPToolRegistry):
300
300
  result = await adapter.invoke(invocation)
301
301
 
302
302
  # Calculate execution time
303
- execution_time = (datetime.now() - start_time).total_seconds()
303
+ execution_time = (datetime.now(timezone.utc) - start_time).total_seconds()
304
304
  result.execution_time = execution_time
305
305
 
306
306
  # Update metrics
@@ -308,7 +308,9 @@ class ToolRegistry(BaseMCPService, IMCPToolRegistry):
308
308
  self._metrics["invocations"][tool_name] = (
309
309
  self._metrics["invocations"].get(tool_name, 0) + 1
310
310
  )
311
- self._metrics["last_invocation"][tool_name] = datetime.now().isoformat()
311
+ self._metrics["last_invocation"][tool_name] = datetime.now(
312
+ timezone.utc
313
+ ).isoformat()
312
314
 
313
315
  if not result.success:
314
316
  self._metrics["errors"][tool_name] = (
@@ -331,7 +333,7 @@ class ToolRegistry(BaseMCPService, IMCPToolRegistry):
331
333
  self._metrics["errors"].get(tool_name, 0) + 1
332
334
  )
333
335
 
334
- execution_time = (datetime.now() - start_time).total_seconds()
336
+ execution_time = (datetime.now(timezone.utc) - start_time).total_seconds()
335
337
 
336
338
  return MCPToolResult(
337
339
  success=False, error=error_msg, execution_time=execution_time
@@ -16,7 +16,7 @@ import asyncio
16
16
  import contextlib
17
17
  import json
18
18
  import traceback
19
- from datetime import datetime
19
+ from datetime import datetime, timezone
20
20
  from typing import Any, Callable, Dict, List, Optional, Union
21
21
 
22
22
  # Import from the official MCP package
@@ -148,7 +148,7 @@ class MCPGateway(BaseMCPService, IMCPGateway):
148
148
  invocation = MCPToolInvocation(
149
149
  tool_name=name,
150
150
  parameters=arguments,
151
- request_id=f"req_{datetime.now().timestamp()}",
151
+ request_id=f"req_{datetime.now(timezone.utc).timestamp()}",
152
152
  )
153
153
 
154
154
  try:
@@ -212,7 +212,7 @@ class MCPGateway(BaseMCPService, IMCPGateway):
212
212
  self.log_warning("No tool registry set - server will have no tools")
213
213
 
214
214
  # Initialize metrics
215
- self._metrics["start_time"] = datetime.now().isoformat()
215
+ self._metrics["start_time"] = datetime.now(timezone.utc).isoformat()
216
216
 
217
217
  # Update capabilities based on registry
218
218
  if self._tool_registry:
@@ -287,7 +287,7 @@ class MCPGateway(BaseMCPService, IMCPGateway):
287
287
  try:
288
288
  # Update metrics
289
289
  self._metrics["requests_handled"] += 1
290
- self._metrics["last_request_time"] = datetime.now().isoformat()
290
+ self._metrics["last_request_time"] = datetime.now(timezone.utc).isoformat()
291
291
 
292
292
  # Extract request details
293
293
  method = request.get("method", "")
@@ -139,7 +139,7 @@ class StdioHandler(BaseMCPService, IMCPCommunication):
139
139
  self._metrics["errors"] += 1
140
140
  raise
141
141
 
142
- async def receive_message(self) -> Optional[Dict[str, Any]]:
142
+ async def receive_message(self) -> Optional[Dict[str, Any]]: # noqa: PLR0911
143
143
  """
144
144
  Receive a message from the MCP client via stdin.
145
145
 
@@ -17,6 +17,7 @@ import logging
17
17
  import os
18
18
  import sys
19
19
  import time
20
+ from datetime import timezone
20
21
  from typing import Any, Dict
21
22
 
22
23
  # Import MCP SDK components
@@ -214,7 +215,9 @@ class SimpleMCPServer:
214
215
  # Default to brief
215
216
  return self._create_brief_summary(sentences, max_length)
216
217
 
217
- def _create_brief_summary(self, sentences: list[str], max_length: int) -> str:
218
+ def _create_brief_summary(
219
+ self, sentences: list[str], max_length: int
220
+ ) -> str:
218
221
  """Create a brief summary by selecting most important sentences."""
219
222
  if not sentences:
220
223
  return ""
@@ -562,7 +565,7 @@ class SimpleMCPServer:
562
565
  f"Python: {sys.version.split()[0]}\n"
563
566
  f"Working Directory: {os.getcwd()}\n"
564
567
  f"Server: {self.name} v{self.version}\n"
565
- f"Timestamp: {datetime.datetime.now().isoformat()}\n"
568
+ f"Timestamp: {datetime.datetime.now(timezone.utc).isoformat()}\n"
566
569
  f"Tools Available: status, document_summarizer{', ticket' if self.unified_ticket_tool else ''}"
567
570
  )
568
571
  else:
@@ -8,7 +8,7 @@ Part of ISS-0035: MCP Server Implementation - Core Server and Tool Registry
8
8
  """
9
9
 
10
10
  from abc import ABC
11
- from datetime import datetime
11
+ from datetime import datetime, timezone
12
12
  from typing import Any, Dict
13
13
 
14
14
  from claude_mpm.services.mcp_gateway.core.base import BaseMCPService
@@ -195,7 +195,7 @@ class BaseToolAdapter(BaseMCPService, IMCPToolAdapter, ABC):
195
195
  self._metrics["average_execution_time"] = (
196
196
  self._metrics["total_execution_time"] / self._metrics["invocations"]
197
197
  )
198
- self._metrics["last_invocation"] = datetime.now().isoformat()
198
+ self._metrics["last_invocation"] = datetime.now(timezone.utc).isoformat()
199
199
 
200
200
 
201
201
  class EchoToolAdapter(BaseToolAdapter):
@@ -235,7 +235,7 @@ class EchoToolAdapter(BaseToolAdapter):
235
235
  Returns:
236
236
  Tool execution result with echoed message
237
237
  """
238
- start_time = datetime.now()
238
+ start_time = datetime.now(timezone.utc)
239
239
 
240
240
  try:
241
241
  # Get parameters
@@ -246,7 +246,7 @@ class EchoToolAdapter(BaseToolAdapter):
246
246
  result = message.upper() if uppercase else message
247
247
 
248
248
  # Calculate execution time
249
- execution_time = (datetime.now() - start_time).total_seconds()
249
+ execution_time = (datetime.now(timezone.utc) - start_time).total_seconds()
250
250
 
251
251
  # Update metrics
252
252
  self._update_metrics(True, execution_time)
@@ -259,7 +259,7 @@ class EchoToolAdapter(BaseToolAdapter):
259
259
  )
260
260
 
261
261
  except Exception as e:
262
- execution_time = (datetime.now() - start_time).total_seconds()
262
+ execution_time = (datetime.now(timezone.utc) - start_time).total_seconds()
263
263
  self._update_metrics(False, execution_time)
264
264
  self._metrics["last_error"] = str(e)
265
265
 
@@ -321,7 +321,7 @@ class CalculatorToolAdapter(BaseToolAdapter):
321
321
  Returns:
322
322
  Tool execution result with calculation
323
323
  """
324
- start_time = datetime.now()
324
+ start_time = datetime.now(timezone.utc)
325
325
 
326
326
  try:
327
327
  # Get parameters
@@ -348,7 +348,7 @@ class CalculatorToolAdapter(BaseToolAdapter):
348
348
  raise ValueError(f"Unknown operation: {operation}")
349
349
 
350
350
  # Calculate execution time
351
- execution_time = (datetime.now() - start_time).total_seconds()
351
+ execution_time = (datetime.now(timezone.utc) - start_time).total_seconds()
352
352
 
353
353
  # Update metrics
354
354
  self._update_metrics(True, execution_time)
@@ -361,7 +361,7 @@ class CalculatorToolAdapter(BaseToolAdapter):
361
361
  )
362
362
 
363
363
  except Exception as e:
364
- execution_time = (datetime.now() - start_time).total_seconds()
364
+ execution_time = (datetime.now(timezone.utc) - start_time).total_seconds()
365
365
  self._update_metrics(False, execution_time)
366
366
  self._metrics["last_error"] = str(e)
367
367
 
@@ -408,7 +408,7 @@ class SystemInfoToolAdapter(BaseToolAdapter):
408
408
  Returns:
409
409
  Tool execution result with system information
410
410
  """
411
- start_time = datetime.now()
411
+ start_time = datetime.now(timezone.utc)
412
412
 
413
413
  try:
414
414
  import platform
@@ -443,15 +443,15 @@ class SystemInfoToolAdapter(BaseToolAdapter):
443
443
  }
444
444
  elif info_type == "time":
445
445
  result = {
446
- "current": datetime.now().isoformat(),
447
- "timestamp": datetime.now().timestamp(),
448
- "timezone": str(datetime.now().astimezone().tzinfo),
446
+ "current": datetime.now(timezone.utc).isoformat(),
447
+ "timestamp": datetime.now(timezone.utc).timestamp(),
448
+ "timezone": str(datetime.now(timezone.utc).astimezone().tzinfo),
449
449
  }
450
450
  else:
451
451
  raise ValueError(f"Unknown info type: {info_type}")
452
452
 
453
453
  # Calculate execution time
454
- execution_time = (datetime.now() - start_time).total_seconds()
454
+ execution_time = (datetime.now(timezone.utc) - start_time).total_seconds()
455
455
 
456
456
  # Update metrics
457
457
  self._update_metrics(True, execution_time)
@@ -465,7 +465,7 @@ class SystemInfoToolAdapter(BaseToolAdapter):
465
465
 
466
466
  except ImportError as e:
467
467
  # Handle missing psutil dependency gracefully
468
- execution_time = (datetime.now() - start_time).total_seconds()
468
+ execution_time = (datetime.now(timezone.utc) - start_time).total_seconds()
469
469
  self._update_metrics(False, execution_time)
470
470
 
471
471
  return MCPToolResult(
@@ -474,7 +474,7 @@ class SystemInfoToolAdapter(BaseToolAdapter):
474
474
  execution_time=execution_time,
475
475
  )
476
476
  except Exception as e:
477
- execution_time = (datetime.now() - start_time).total_seconds()
477
+ execution_time = (datetime.now(timezone.utc) - start_time).total_seconds()
478
478
  self._update_metrics(False, execution_time)
479
479
  self._metrics["last_error"] = str(e)
480
480
 
@@ -13,7 +13,7 @@ import mimetypes
13
13
  import os
14
14
  import re
15
15
  from collections import OrderedDict
16
- from datetime import datetime
16
+ from datetime import datetime, timezone
17
17
  from pathlib import Path
18
18
  from typing import Any, Dict, List, Optional, Tuple
19
19
 
@@ -605,7 +605,7 @@ class DocumentSummarizerTool(BaseToolAdapter):
605
605
  Returns:
606
606
  Tool execution result with summary
607
607
  """
608
- start_time = datetime.now()
608
+ start_time = datetime.now(timezone.utc)
609
609
 
610
610
  try:
611
611
  # Get parameters
@@ -628,7 +628,9 @@ class DocumentSummarizerTool(BaseToolAdapter):
628
628
  cached_result = self._cache.get(cache_key)
629
629
  if cached_result:
630
630
  cache_hit = True
631
- execution_time = (datetime.now() - start_time).total_seconds()
631
+ execution_time = (
632
+ datetime.now(timezone.utc) - start_time
633
+ ).total_seconds()
632
634
  self._update_metrics(True, execution_time)
633
635
 
634
636
  return MCPToolResult(
@@ -709,7 +711,7 @@ class DocumentSummarizerTool(BaseToolAdapter):
709
711
  self._cache.put(cache_key, result.copy(), summary_size)
710
712
 
711
713
  # Calculate execution time
712
- execution_time = (datetime.now() - start_time).total_seconds()
714
+ execution_time = (datetime.now(timezone.utc) - start_time).total_seconds()
713
715
 
714
716
  # Update metrics
715
717
  self._update_metrics(True, execution_time)
@@ -730,7 +732,7 @@ class DocumentSummarizerTool(BaseToolAdapter):
730
732
  )
731
733
 
732
734
  except Exception as e:
733
- execution_time = (datetime.now() - start_time).total_seconds()
735
+ execution_time = (datetime.now(timezone.utc) - start_time).total_seconds()
734
736
  self._update_metrics(False, execution_time)
735
737
  self._metrics["last_error"] = str(e)
736
738