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,36 +0,0 @@
1
- """
2
- MCP Gateway Tools Module
3
- ========================
4
-
5
- Tool adapters and implementations for the MCP Gateway service.
6
- """
7
-
8
- from .base_adapter import (
9
- BaseToolAdapter,
10
- CalculatorToolAdapter,
11
- EchoToolAdapter,
12
- SystemInfoToolAdapter,
13
- )
14
- from .document_summarizer import DocumentSummarizerTool
15
- from .kuzu_memory_service import (
16
- KuzuMemoryService,
17
- get_context,
18
- recall_memories,
19
- search_memories,
20
- store_memory,
21
- )
22
-
23
- # Ticket tools removed - using mcp-ticketer instead
24
-
25
- __all__ = [
26
- "BaseToolAdapter",
27
- "CalculatorToolAdapter",
28
- "DocumentSummarizerTool",
29
- "EchoToolAdapter",
30
- "KuzuMemoryService",
31
- "SystemInfoToolAdapter",
32
- "get_context",
33
- "recall_memories",
34
- "search_memories",
35
- "store_memory",
36
- ]
@@ -1,485 +0,0 @@
1
- """
2
- Base Tool Adapter and Example Implementations
3
- ==============================================
4
-
5
- Base class for MCP tool adapters and example implementations.
6
-
7
- Part of ISS-0035: MCP Server Implementation - Core Server and Tool Registry
8
- """
9
-
10
- from abc import ABC
11
- from datetime import datetime, timezone
12
- from typing import Any, Dict
13
-
14
- from claude_mpm.services.mcp_gateway.core.base import BaseMCPService
15
- from claude_mpm.services.mcp_gateway.core.interfaces import (
16
- IMCPToolAdapter,
17
- MCPToolDefinition,
18
- MCPToolInvocation,
19
- MCPToolResult,
20
- )
21
-
22
-
23
- class BaseToolAdapter(BaseMCPService, IMCPToolAdapter, ABC):
24
- """
25
- Base class for MCP tool adapters.
26
-
27
- WHY: This base class provides common functionality for all tool adapters,
28
- including parameter validation, error handling, and metrics tracking.
29
- Concrete tool implementations should extend this class.
30
-
31
- DESIGN DECISIONS:
32
- - Provide default parameter validation using JSON Schema
33
- - Include standard error handling and logging
34
- - Track execution metrics for monitoring
35
- - Support both sync and async tool implementations
36
- """
37
-
38
- def __init__(self, tool_definition: MCPToolDefinition):
39
- """
40
- Initialize the base tool adapter.
41
-
42
- Args:
43
- tool_definition: Tool definition with schema and metadata
44
- """
45
- super().__init__(f"Tool-{tool_definition.name}")
46
- self._definition = tool_definition
47
- self._initialized = False
48
-
49
- # Metrics
50
- self._metrics = {
51
- "invocations": 0,
52
- "successes": 0,
53
- "failures": 0,
54
- "total_execution_time": 0.0,
55
- "average_execution_time": 0.0,
56
- "last_invocation": None,
57
- "last_error": None,
58
- }
59
-
60
- def get_definition(self) -> MCPToolDefinition:
61
- """
62
- Get the tool definition.
63
-
64
- Returns:
65
- Tool definition with schema and metadata
66
- """
67
- return self._definition
68
-
69
- def validate_parameters(self, parameters: Dict[str, Any]) -> bool:
70
- """
71
- Validate tool parameters against schema.
72
-
73
- Default implementation performs basic JSON Schema validation.
74
- Override for custom validation logic.
75
-
76
- Args:
77
- parameters: Parameters to validate
78
-
79
- Returns:
80
- True if parameters are valid
81
- """
82
- try:
83
- # Get required parameters from schema
84
- schema = self._definition.input_schema
85
- required = schema.get("required", [])
86
- properties = schema.get("properties", {})
87
-
88
- # Check required parameters
89
- for param in required:
90
- if param not in parameters:
91
- self.log_error(f"Missing required parameter: {param}")
92
- return False
93
-
94
- # Check parameter types (basic validation)
95
- for param_name, param_value in parameters.items():
96
- if param_name in properties:
97
- expected_type = properties[param_name].get("type")
98
- if expected_type:
99
- if not self._validate_type(param_value, expected_type):
100
- self.log_error(
101
- f"Invalid type for parameter {param_name}: expected {expected_type}"
102
- )
103
- return False
104
-
105
- return True
106
-
107
- except Exception as e:
108
- self.log_error(f"Error validating parameters: {e}")
109
- return False
110
-
111
- def _validate_type(self, value: Any, expected_type: str) -> bool:
112
- """
113
- Validate a value against an expected JSON Schema type.
114
-
115
- Args:
116
- value: Value to validate
117
- expected_type: Expected type (string, number, boolean, array, object)
118
-
119
- Returns:
120
- True if type matches
121
- """
122
- type_map = {
123
- "string": str,
124
- "number": (int, float),
125
- "boolean": bool,
126
- "array": list,
127
- "object": dict,
128
- "null": type(None),
129
- }
130
-
131
- expected_python_type = type_map.get(expected_type)
132
- if expected_python_type:
133
- return isinstance(value, expected_python_type)
134
-
135
- return True # Unknown type, allow it
136
-
137
- async def initialize(self) -> bool:
138
- """
139
- Initialize the tool adapter.
140
-
141
- Default implementation marks as initialized.
142
- Override for custom initialization logic.
143
-
144
- Returns:
145
- True if initialization successful
146
- """
147
- try:
148
- self.log_info(f"Initializing tool: {self._definition.name}")
149
- self._initialized = True
150
- return True
151
-
152
- except Exception as e:
153
- self.log_error(f"Failed to initialize tool: {e}")
154
- return False
155
-
156
- async def shutdown(self) -> None:
157
- """
158
- Shutdown the tool adapter and clean up resources.
159
-
160
- Default implementation marks as not initialized.
161
- Override for custom cleanup logic.
162
- """
163
- try:
164
- self.log_info(f"Shutting down tool: {self._definition.name}")
165
- self._initialized = False
166
-
167
- except Exception as e:
168
- self.log_error(f"Error during tool shutdown: {e}")
169
-
170
- def get_metrics(self) -> Dict[str, Any]:
171
- """
172
- Get tool metrics.
173
-
174
- Returns:
175
- Metrics dictionary
176
- """
177
- return self._metrics.copy()
178
-
179
- def _update_metrics(self, success: bool, execution_time: float) -> None:
180
- """
181
- Update tool metrics after invocation.
182
-
183
- Args:
184
- success: Whether invocation was successful
185
- execution_time: Execution time in seconds
186
- """
187
- self._metrics["invocations"] += 1
188
-
189
- if success:
190
- self._metrics["successes"] += 1
191
- else:
192
- self._metrics["failures"] += 1
193
-
194
- self._metrics["total_execution_time"] += execution_time
195
- self._metrics["average_execution_time"] = (
196
- self._metrics["total_execution_time"] / self._metrics["invocations"]
197
- )
198
- self._metrics["last_invocation"] = datetime.now(timezone.utc).isoformat()
199
-
200
-
201
- class EchoToolAdapter(BaseToolAdapter):
202
- """
203
- Example tool adapter that echoes input back.
204
-
205
- This is a simple example showing how to implement a concrete tool adapter.
206
- """
207
-
208
- def __init__(self):
209
- """Initialize the echo tool."""
210
- definition = MCPToolDefinition(
211
- name="echo",
212
- description="Echoes the input message back to the user",
213
- input_schema={
214
- "type": "object",
215
- "properties": {
216
- "message": {"type": "string", "description": "The message to echo"},
217
- "uppercase": {
218
- "type": "boolean",
219
- "description": "Whether to convert to uppercase",
220
- "default": False,
221
- },
222
- },
223
- "required": ["message"],
224
- },
225
- )
226
- super().__init__(definition)
227
-
228
- async def invoke(self, invocation: MCPToolInvocation) -> MCPToolResult:
229
- """
230
- Invoke the echo tool.
231
-
232
- Args:
233
- invocation: Tool invocation request
234
-
235
- Returns:
236
- Tool execution result with echoed message
237
- """
238
- start_time = datetime.now(timezone.utc)
239
-
240
- try:
241
- # Get parameters
242
- message = invocation.parameters.get("message", "")
243
- uppercase = invocation.parameters.get("uppercase", False)
244
-
245
- # Process message
246
- result = message.upper() if uppercase else message
247
-
248
- # Calculate execution time
249
- execution_time = (datetime.now(timezone.utc) - start_time).total_seconds()
250
-
251
- # Update metrics
252
- self._update_metrics(True, execution_time)
253
-
254
- return MCPToolResult(
255
- success=True,
256
- data=result,
257
- execution_time=execution_time,
258
- metadata={"tool": "echo", "length": len(result)},
259
- )
260
-
261
- except Exception as e:
262
- execution_time = (datetime.now(timezone.utc) - start_time).total_seconds()
263
- self._update_metrics(False, execution_time)
264
- self._metrics["last_error"] = str(e)
265
-
266
- return MCPToolResult(
267
- success=False,
268
- error=f"Echo tool failed: {e!s}",
269
- execution_time=execution_time,
270
- )
271
-
272
-
273
- class CalculatorToolAdapter(BaseToolAdapter):
274
- """
275
- Example calculator tool adapter.
276
-
277
- Demonstrates a more complex tool with multiple operations.
278
- """
279
-
280
- def __init__(self):
281
- """Initialize the calculator tool."""
282
- definition = MCPToolDefinition(
283
- name="calculator",
284
- description="Performs basic mathematical calculations",
285
- input_schema={
286
- "type": "object",
287
- "properties": {
288
- "operation": {
289
- "type": "string",
290
- "enum": ["add", "subtract", "multiply", "divide"],
291
- "description": "The mathematical operation to perform",
292
- },
293
- "a": {"type": "number", "description": "First operand"},
294
- "b": {"type": "number", "description": "Second operand"},
295
- },
296
- "required": ["operation", "a", "b"],
297
- },
298
- output_schema={
299
- "type": "object",
300
- "properties": {
301
- "result": {
302
- "type": "number",
303
- "description": "The calculation result",
304
- },
305
- "expression": {
306
- "type": "string",
307
- "description": "The mathematical expression",
308
- },
309
- },
310
- },
311
- )
312
- super().__init__(definition)
313
-
314
- async def invoke(self, invocation: MCPToolInvocation) -> MCPToolResult:
315
- """
316
- Invoke the calculator tool.
317
-
318
- Args:
319
- invocation: Tool invocation request
320
-
321
- Returns:
322
- Tool execution result with calculation
323
- """
324
- start_time = datetime.now(timezone.utc)
325
-
326
- try:
327
- # Get parameters
328
- operation = invocation.parameters["operation"]
329
- a = invocation.parameters["a"]
330
- b = invocation.parameters["b"]
331
-
332
- # Perform calculation
333
- if operation == "add":
334
- result = a + b
335
- expression = f"{a} + {b} = {result}"
336
- elif operation == "subtract":
337
- result = a - b
338
- expression = f"{a} - {b} = {result}"
339
- elif operation == "multiply":
340
- result = a * b
341
- expression = f"{a} * {b} = {result}"
342
- elif operation == "divide":
343
- if b == 0:
344
- raise ValueError("Division by zero")
345
- result = a / b
346
- expression = f"{a} / {b} = {result}"
347
- else:
348
- raise ValueError(f"Unknown operation: {operation}")
349
-
350
- # Calculate execution time
351
- execution_time = (datetime.now(timezone.utc) - start_time).total_seconds()
352
-
353
- # Update metrics
354
- self._update_metrics(True, execution_time)
355
-
356
- return MCPToolResult(
357
- success=True,
358
- data={"result": result, "expression": expression},
359
- execution_time=execution_time,
360
- metadata={"tool": "calculator", "operation": operation},
361
- )
362
-
363
- except Exception as e:
364
- execution_time = (datetime.now(timezone.utc) - start_time).total_seconds()
365
- self._update_metrics(False, execution_time)
366
- self._metrics["last_error"] = str(e)
367
-
368
- return MCPToolResult(
369
- success=False,
370
- error=f"Calculator tool failed: {e!s}",
371
- execution_time=execution_time,
372
- )
373
-
374
-
375
- class SystemInfoToolAdapter(BaseToolAdapter):
376
- """
377
- Example system information tool adapter.
378
-
379
- Demonstrates async operations and system interaction.
380
- """
381
-
382
- def __init__(self):
383
- """Initialize the system info tool."""
384
- definition = MCPToolDefinition(
385
- name="system_info",
386
- description="Provides system information",
387
- input_schema={
388
- "type": "object",
389
- "properties": {
390
- "info_type": {
391
- "type": "string",
392
- "enum": ["platform", "memory", "cpu", "time"],
393
- "description": "Type of system information to retrieve",
394
- }
395
- },
396
- "required": ["info_type"],
397
- },
398
- )
399
- super().__init__(definition)
400
-
401
- async def invoke(self, invocation: MCPToolInvocation) -> MCPToolResult:
402
- """
403
- Invoke the system info tool.
404
-
405
- Args:
406
- invocation: Tool invocation request
407
-
408
- Returns:
409
- Tool execution result with system information
410
- """
411
- start_time = datetime.now(timezone.utc)
412
-
413
- try:
414
- import platform
415
-
416
- import psutil
417
-
418
- info_type = invocation.parameters["info_type"]
419
-
420
- if info_type == "platform":
421
- result = {
422
- "system": platform.system(),
423
- "release": platform.release(),
424
- "version": platform.version(),
425
- "machine": platform.machine(),
426
- "processor": platform.processor(),
427
- "python_version": platform.python_version(),
428
- }
429
- elif info_type == "memory":
430
- mem = psutil.virtual_memory()
431
- result = {
432
- "total": mem.total,
433
- "available": mem.available,
434
- "percent": mem.percent,
435
- "used": mem.used,
436
- "free": mem.free,
437
- }
438
- elif info_type == "cpu":
439
- result = {
440
- "count": psutil.cpu_count(),
441
- "percent": psutil.cpu_percent(interval=0.1),
442
- "freq": psutil.cpu_freq()._asdict() if psutil.cpu_freq() else None,
443
- }
444
- elif info_type == "time":
445
- result = {
446
- "current": datetime.now(timezone.utc).isoformat(),
447
- "timestamp": datetime.now(timezone.utc).timestamp(),
448
- "timezone": str(datetime.now(timezone.utc).astimezone().tzinfo),
449
- }
450
- else:
451
- raise ValueError(f"Unknown info type: {info_type}")
452
-
453
- # Calculate execution time
454
- execution_time = (datetime.now(timezone.utc) - start_time).total_seconds()
455
-
456
- # Update metrics
457
- self._update_metrics(True, execution_time)
458
-
459
- return MCPToolResult(
460
- success=True,
461
- data=result,
462
- execution_time=execution_time,
463
- metadata={"tool": "system_info", "info_type": info_type},
464
- )
465
-
466
- except ImportError as e:
467
- # Handle missing psutil dependency gracefully
468
- execution_time = (datetime.now(timezone.utc) - start_time).total_seconds()
469
- self._update_metrics(False, execution_time)
470
-
471
- return MCPToolResult(
472
- success=False,
473
- error=f"System info tool requires psutil: {e!s}",
474
- execution_time=execution_time,
475
- )
476
- except Exception as e:
477
- execution_time = (datetime.now(timezone.utc) - start_time).total_seconds()
478
- self._update_metrics(False, execution_time)
479
- self._metrics["last_error"] = str(e)
480
-
481
- return MCPToolResult(
482
- success=False,
483
- error=f"System info tool failed: {e!s}",
484
- execution_time=execution_time,
485
- )