claude-mpm 5.0.9__py3-none-any.whl → 5.4.41__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 (263) 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/{PM_INSTRUCTIONS_TEACH.md → CLAUDE_MPM_TEACHER_OUTPUT_STYLE.md} +721 -41
  5. claude_mpm/agents/MEMORY.md +1 -1
  6. claude_mpm/agents/PM_INSTRUCTIONS.md +468 -468
  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 +70 -2
  11. claude_mpm/agents/templates/circuit-breakers.md +431 -45
  12. claude_mpm/cli/__init__.py +0 -1
  13. claude_mpm/cli/__main__.py +4 -0
  14. claude_mpm/cli/chrome_devtools_installer.py +175 -0
  15. claude_mpm/cli/commands/agent_state_manager.py +18 -27
  16. claude_mpm/cli/commands/agents.py +175 -37
  17. claude_mpm/cli/commands/auto_configure.py +723 -236
  18. claude_mpm/cli/commands/config.py +88 -2
  19. claude_mpm/cli/commands/configure.py +1262 -157
  20. claude_mpm/cli/commands/configure_agent_display.py +25 -6
  21. claude_mpm/cli/commands/mpm_init/core.py +225 -46
  22. claude_mpm/cli/commands/mpm_init/knowledge_extractor.py +481 -0
  23. claude_mpm/cli/commands/mpm_init/prompts.py +280 -0
  24. claude_mpm/cli/commands/postmortem.py +1 -1
  25. claude_mpm/cli/commands/profile.py +277 -0
  26. claude_mpm/cli/commands/skills.py +214 -189
  27. claude_mpm/cli/commands/summarize.py +413 -0
  28. claude_mpm/cli/executor.py +21 -3
  29. claude_mpm/cli/interactive/agent_wizard.py +85 -10
  30. claude_mpm/cli/parsers/agents_parser.py +54 -9
  31. claude_mpm/cli/parsers/auto_configure_parser.py +13 -138
  32. claude_mpm/cli/parsers/base_parser.py +12 -0
  33. claude_mpm/cli/parsers/config_parser.py +153 -83
  34. claude_mpm/cli/parsers/profile_parser.py +148 -0
  35. claude_mpm/cli/parsers/skills_parser.py +3 -2
  36. claude_mpm/cli/startup.py +879 -149
  37. claude_mpm/commands/mpm-config.md +28 -0
  38. claude_mpm/commands/mpm-doctor.md +9 -22
  39. claude_mpm/commands/mpm-help.md +5 -287
  40. claude_mpm/commands/mpm-init.md +81 -507
  41. claude_mpm/commands/mpm-monitor.md +15 -402
  42. claude_mpm/commands/mpm-organize.md +120 -0
  43. claude_mpm/commands/mpm-postmortem.md +6 -108
  44. claude_mpm/commands/mpm-session-resume.md +12 -363
  45. claude_mpm/commands/mpm-status.md +5 -69
  46. claude_mpm/commands/mpm-ticket-view.md +52 -495
  47. claude_mpm/commands/mpm-version.md +5 -107
  48. claude_mpm/config/agent_sources.py +27 -0
  49. claude_mpm/core/config.py +2 -4
  50. claude_mpm/core/framework/formatters/content_formatter.py +3 -13
  51. claude_mpm/core/framework/loaders/agent_loader.py +8 -5
  52. claude_mpm/core/framework/loaders/instruction_loader.py +52 -11
  53. claude_mpm/core/framework_loader.py +4 -2
  54. claude_mpm/core/logger.py +13 -0
  55. claude_mpm/core/optimized_startup.py +59 -0
  56. claude_mpm/core/output_style_manager.py +173 -43
  57. claude_mpm/core/shared/config_loader.py +1 -1
  58. claude_mpm/core/socketio_pool.py +3 -3
  59. claude_mpm/core/unified_agent_registry.py +134 -16
  60. claude_mpm/core/unified_config.py +22 -0
  61. claude_mpm/dashboard/static/svelte-build/_app/env.js +1 -0
  62. claude_mpm/dashboard/static/svelte-build/_app/immutable/assets/0.B_FtCwCQ.css +1 -0
  63. claude_mpm/dashboard/static/svelte-build/_app/immutable/assets/2.Cl_eSA4x.css +1 -0
  64. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BgChzWQ1.js +1 -0
  65. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CIXEwuWe.js +1 -0
  66. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CWc5urbQ.js +1 -0
  67. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DMkZpdF2.js +2 -0
  68. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DjhvlsAc.js +1 -0
  69. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/N4qtv3Hx.js +2 -0
  70. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/uj46x2Wr.js +1 -0
  71. claude_mpm/dashboard/static/svelte-build/_app/immutable/entry/app.DTL5mJO-.js +2 -0
  72. claude_mpm/dashboard/static/svelte-build/_app/immutable/entry/start.DzuEhzqh.js +1 -0
  73. claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/0.CAGBuiOw.js +1 -0
  74. claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/1.DFLC8jdE.js +1 -0
  75. claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/2.DPvEihJJ.js +10 -0
  76. claude_mpm/dashboard/static/svelte-build/_app/version.json +1 -0
  77. claude_mpm/dashboard/static/svelte-build/favicon.svg +7 -0
  78. claude_mpm/dashboard/static/svelte-build/index.html +36 -0
  79. claude_mpm/hooks/claude_hooks/__pycache__/__init__.cpython-311.pyc +0 -0
  80. claude_mpm/hooks/claude_hooks/__pycache__/correlation_manager.cpython-311.pyc +0 -0
  81. claude_mpm/hooks/claude_hooks/__pycache__/event_handlers.cpython-311.pyc +0 -0
  82. claude_mpm/hooks/claude_hooks/__pycache__/hook_handler.cpython-311.pyc +0 -0
  83. claude_mpm/hooks/claude_hooks/__pycache__/installer.cpython-311.pyc +0 -0
  84. claude_mpm/hooks/claude_hooks/__pycache__/memory_integration.cpython-311.pyc +0 -0
  85. claude_mpm/hooks/claude_hooks/__pycache__/response_tracking.cpython-311.pyc +0 -0
  86. claude_mpm/hooks/claude_hooks/__pycache__/tool_analysis.cpython-311.pyc +0 -0
  87. claude_mpm/hooks/claude_hooks/correlation_manager.py +60 -0
  88. claude_mpm/hooks/claude_hooks/event_handlers.py +211 -78
  89. claude_mpm/hooks/claude_hooks/hook_handler.py +155 -1
  90. claude_mpm/hooks/claude_hooks/installer.py +33 -10
  91. claude_mpm/hooks/claude_hooks/memory_integration.py +28 -0
  92. claude_mpm/hooks/claude_hooks/response_tracking.py +2 -3
  93. claude_mpm/hooks/claude_hooks/services/__pycache__/__init__.cpython-311.pyc +0 -0
  94. claude_mpm/hooks/claude_hooks/services/__pycache__/connection_manager.cpython-311.pyc +0 -0
  95. claude_mpm/hooks/claude_hooks/services/__pycache__/connection_manager_http.cpython-311.pyc +0 -0
  96. claude_mpm/hooks/claude_hooks/services/__pycache__/duplicate_detector.cpython-311.pyc +0 -0
  97. claude_mpm/hooks/claude_hooks/services/__pycache__/state_manager.cpython-311.pyc +0 -0
  98. claude_mpm/hooks/claude_hooks/services/__pycache__/subagent_processor.cpython-311.pyc +0 -0
  99. claude_mpm/hooks/claude_hooks/services/connection_manager.py +30 -6
  100. claude_mpm/hooks/memory_integration_hook.py +46 -1
  101. claude_mpm/init.py +63 -19
  102. claude_mpm/models/agent_definition.py +7 -0
  103. claude_mpm/models/git_repository.py +3 -3
  104. claude_mpm/scripts/claude-hook-handler.sh +58 -18
  105. claude_mpm/scripts/launch_monitor.py +93 -13
  106. claude_mpm/scripts/start_activity_logging.py +0 -0
  107. claude_mpm/services/agents/agent_builder.py +3 -3
  108. claude_mpm/services/agents/agent_recommendation_service.py +278 -0
  109. claude_mpm/services/agents/agent_review_service.py +280 -0
  110. claude_mpm/services/agents/cache_git_manager.py +6 -6
  111. claude_mpm/services/agents/deployment/agent_deployment.py +29 -7
  112. claude_mpm/services/agents/deployment/agent_discovery_service.py +4 -5
  113. claude_mpm/services/agents/deployment/agent_template_builder.py +5 -3
  114. claude_mpm/services/agents/deployment/agents_directory_resolver.py +2 -2
  115. claude_mpm/services/agents/deployment/multi_source_deployment_service.py +320 -29
  116. claude_mpm/services/agents/deployment/remote_agent_discovery_service.py +546 -68
  117. claude_mpm/services/agents/git_source_manager.py +36 -2
  118. claude_mpm/services/agents/loading/base_agent_manager.py +1 -13
  119. claude_mpm/services/agents/recommender.py +5 -3
  120. claude_mpm/services/agents/single_tier_deployment_service.py +2 -2
  121. claude_mpm/services/agents/sources/git_source_sync_service.py +13 -6
  122. claude_mpm/services/agents/startup_sync.py +22 -2
  123. claude_mpm/services/agents/toolchain_detector.py +10 -6
  124. claude_mpm/services/analysis/__init__.py +11 -1
  125. claude_mpm/services/analysis/clone_detector.py +1030 -0
  126. claude_mpm/services/command_deployment_service.py +81 -10
  127. claude_mpm/services/diagnostics/checks/agent_check.py +2 -2
  128. claude_mpm/services/diagnostics/checks/agent_sources_check.py +1 -1
  129. claude_mpm/services/event_bus/config.py +3 -1
  130. claude_mpm/services/git/git_operations_service.py +101 -16
  131. claude_mpm/services/monitor/daemon.py +9 -2
  132. claude_mpm/services/monitor/daemon_manager.py +39 -3
  133. claude_mpm/services/monitor/management/lifecycle.py +8 -1
  134. claude_mpm/services/monitor/server.py +698 -22
  135. claude_mpm/services/pm_skills_deployer.py +676 -0
  136. claude_mpm/services/profile_manager.py +331 -0
  137. claude_mpm/services/project/project_organizer.py +4 -0
  138. claude_mpm/services/self_upgrade_service.py +120 -12
  139. claude_mpm/services/skills/__init__.py +3 -0
  140. claude_mpm/services/skills/git_skill_source_manager.py +130 -2
  141. claude_mpm/services/skills/selective_skill_deployer.py +704 -0
  142. claude_mpm/services/skills/skill_to_agent_mapper.py +406 -0
  143. claude_mpm/services/skills_deployer.py +126 -9
  144. claude_mpm/services/socketio/dashboard_server.py +1 -0
  145. claude_mpm/services/socketio/event_normalizer.py +51 -6
  146. claude_mpm/services/socketio/server/core.py +386 -108
  147. claude_mpm/services/version_control/git_operations.py +103 -0
  148. claude_mpm/skills/skill_manager.py +92 -3
  149. claude_mpm/utils/agent_dependency_loader.py +14 -2
  150. claude_mpm/utils/agent_filters.py +17 -44
  151. claude_mpm/utils/gitignore.py +3 -0
  152. claude_mpm/utils/migration.py +4 -4
  153. claude_mpm/utils/robust_installer.py +47 -3
  154. {claude_mpm-5.0.9.dist-info → claude_mpm-5.4.41.dist-info}/METADATA +57 -87
  155. {claude_mpm-5.0.9.dist-info → claude_mpm-5.4.41.dist-info}/RECORD +160 -211
  156. claude_mpm-5.4.41.dist-info/entry_points.txt +5 -0
  157. claude_mpm-5.4.41.dist-info/licenses/LICENSE +94 -0
  158. claude_mpm-5.4.41.dist-info/licenses/LICENSE-FAQ.md +153 -0
  159. claude_mpm/agents/BASE_AGENT_TEMPLATE.md +0 -292
  160. claude_mpm/agents/BASE_DOCUMENTATION.md +0 -53
  161. claude_mpm/agents/BASE_OPS.md +0 -219
  162. claude_mpm/agents/BASE_PM.md +0 -480
  163. claude_mpm/agents/BASE_PROMPT_ENGINEER.md +0 -787
  164. claude_mpm/agents/BASE_QA.md +0 -167
  165. claude_mpm/agents/BASE_RESEARCH.md +0 -53
  166. claude_mpm/agents/base_agent_loader.py +0 -601
  167. claude_mpm/cli/commands/agents_detect.py +0 -380
  168. claude_mpm/cli/commands/agents_recommend.py +0 -309
  169. claude_mpm/cli/ticket_cli.py +0 -35
  170. claude_mpm/commands/mpm-agents-auto-configure.md +0 -278
  171. claude_mpm/commands/mpm-agents-detect.md +0 -177
  172. claude_mpm/commands/mpm-agents-list.md +0 -131
  173. claude_mpm/commands/mpm-agents-recommend.md +0 -223
  174. claude_mpm/commands/mpm-config-view.md +0 -150
  175. claude_mpm/commands/mpm-ticket-organize.md +0 -304
  176. claude_mpm/dashboard/analysis_runner.py +0 -455
  177. claude_mpm/dashboard/index.html +0 -13
  178. claude_mpm/dashboard/open_dashboard.py +0 -66
  179. claude_mpm/dashboard/static/css/activity.css +0 -1958
  180. claude_mpm/dashboard/static/css/connection-status.css +0 -370
  181. claude_mpm/dashboard/static/css/dashboard.css +0 -4701
  182. claude_mpm/dashboard/static/js/components/activity-tree.js +0 -1871
  183. claude_mpm/dashboard/static/js/components/agent-hierarchy.js +0 -777
  184. claude_mpm/dashboard/static/js/components/agent-inference.js +0 -956
  185. claude_mpm/dashboard/static/js/components/build-tracker.js +0 -333
  186. claude_mpm/dashboard/static/js/components/code-simple.js +0 -857
  187. claude_mpm/dashboard/static/js/components/connection-debug.js +0 -654
  188. claude_mpm/dashboard/static/js/components/diff-viewer.js +0 -891
  189. claude_mpm/dashboard/static/js/components/event-processor.js +0 -542
  190. claude_mpm/dashboard/static/js/components/event-viewer.js +0 -1155
  191. claude_mpm/dashboard/static/js/components/export-manager.js +0 -368
  192. claude_mpm/dashboard/static/js/components/file-change-tracker.js +0 -443
  193. claude_mpm/dashboard/static/js/components/file-change-viewer.js +0 -690
  194. claude_mpm/dashboard/static/js/components/file-tool-tracker.js +0 -724
  195. claude_mpm/dashboard/static/js/components/file-viewer.js +0 -580
  196. claude_mpm/dashboard/static/js/components/hud-library-loader.js +0 -211
  197. claude_mpm/dashboard/static/js/components/hud-manager.js +0 -671
  198. claude_mpm/dashboard/static/js/components/hud-visualizer.js +0 -1718
  199. claude_mpm/dashboard/static/js/components/module-viewer.js +0 -2764
  200. claude_mpm/dashboard/static/js/components/session-manager.js +0 -579
  201. claude_mpm/dashboard/static/js/components/socket-manager.js +0 -368
  202. claude_mpm/dashboard/static/js/components/ui-state-manager.js +0 -749
  203. claude_mpm/dashboard/static/js/components/unified-data-viewer.js +0 -1824
  204. claude_mpm/dashboard/static/js/components/working-directory.js +0 -920
  205. claude_mpm/dashboard/static/js/connection-manager.js +0 -536
  206. claude_mpm/dashboard/static/js/dashboard.js +0 -1914
  207. claude_mpm/dashboard/static/js/extension-error-handler.js +0 -164
  208. claude_mpm/dashboard/static/js/socket-client.js +0 -1474
  209. claude_mpm/dashboard/static/js/tab-isolation-fix.js +0 -185
  210. claude_mpm/dashboard/static/socket.io.min.js +0 -7
  211. claude_mpm/dashboard/static/socket.io.v4.8.1.backup.js +0 -7
  212. claude_mpm/dashboard/templates/code_simple.html +0 -153
  213. claude_mpm/dashboard/templates/index.html +0 -606
  214. claude_mpm/dashboard/test_dashboard.html +0 -372
  215. claude_mpm/hooks/claude_hooks/__pycache__/__init__.cpython-313.pyc +0 -0
  216. claude_mpm/hooks/claude_hooks/__pycache__/event_handlers.cpython-313.pyc +0 -0
  217. claude_mpm/hooks/claude_hooks/__pycache__/hook_handler.cpython-313.pyc +0 -0
  218. claude_mpm/hooks/claude_hooks/__pycache__/memory_integration.cpython-313.pyc +0 -0
  219. claude_mpm/hooks/claude_hooks/__pycache__/response_tracking.cpython-313.pyc +0 -0
  220. claude_mpm/hooks/claude_hooks/__pycache__/tool_analysis.cpython-313.pyc +0 -0
  221. claude_mpm/hooks/claude_hooks/services/__pycache__/__init__.cpython-313.pyc +0 -0
  222. claude_mpm/hooks/claude_hooks/services/__pycache__/connection_manager_http.cpython-313.pyc +0 -0
  223. claude_mpm/hooks/claude_hooks/services/__pycache__/duplicate_detector.cpython-313.pyc +0 -0
  224. claude_mpm/hooks/claude_hooks/services/__pycache__/state_manager.cpython-313.pyc +0 -0
  225. claude_mpm/hooks/claude_hooks/services/__pycache__/subagent_processor.cpython-313.pyc +0 -0
  226. claude_mpm/scripts/mcp_server.py +0 -75
  227. claude_mpm/scripts/mcp_wrapper.py +0 -39
  228. claude_mpm/services/mcp_gateway/__init__.py +0 -159
  229. claude_mpm/services/mcp_gateway/auto_configure.py +0 -369
  230. claude_mpm/services/mcp_gateway/config/__init__.py +0 -17
  231. claude_mpm/services/mcp_gateway/config/config_loader.py +0 -296
  232. claude_mpm/services/mcp_gateway/config/config_schema.py +0 -243
  233. claude_mpm/services/mcp_gateway/config/configuration.py +0 -429
  234. claude_mpm/services/mcp_gateway/core/__init__.py +0 -43
  235. claude_mpm/services/mcp_gateway/core/base.py +0 -312
  236. claude_mpm/services/mcp_gateway/core/exceptions.py +0 -253
  237. claude_mpm/services/mcp_gateway/core/interfaces.py +0 -443
  238. claude_mpm/services/mcp_gateway/core/process_pool.py +0 -977
  239. claude_mpm/services/mcp_gateway/core/singleton_manager.py +0 -315
  240. claude_mpm/services/mcp_gateway/core/startup_verification.py +0 -316
  241. claude_mpm/services/mcp_gateway/main.py +0 -589
  242. claude_mpm/services/mcp_gateway/registry/__init__.py +0 -12
  243. claude_mpm/services/mcp_gateway/registry/service_registry.py +0 -412
  244. claude_mpm/services/mcp_gateway/registry/tool_registry.py +0 -489
  245. claude_mpm/services/mcp_gateway/server/__init__.py +0 -15
  246. claude_mpm/services/mcp_gateway/server/mcp_gateway.py +0 -414
  247. claude_mpm/services/mcp_gateway/server/stdio_handler.py +0 -372
  248. claude_mpm/services/mcp_gateway/server/stdio_server.py +0 -712
  249. claude_mpm/services/mcp_gateway/tools/__init__.py +0 -36
  250. claude_mpm/services/mcp_gateway/tools/base_adapter.py +0 -485
  251. claude_mpm/services/mcp_gateway/tools/document_summarizer.py +0 -789
  252. claude_mpm/services/mcp_gateway/tools/external_mcp_services.py +0 -654
  253. claude_mpm/services/mcp_gateway/tools/health_check_tool.py +0 -456
  254. claude_mpm/services/mcp_gateway/tools/hello_world.py +0 -551
  255. claude_mpm/services/mcp_gateway/tools/kuzu_memory_service.py +0 -555
  256. claude_mpm/services/mcp_gateway/utils/__init__.py +0 -14
  257. claude_mpm/services/mcp_gateway/utils/package_version_checker.py +0 -160
  258. claude_mpm/services/mcp_gateway/utils/update_preferences.py +0 -170
  259. claude_mpm-5.0.9.dist-info/entry_points.txt +0 -10
  260. claude_mpm-5.0.9.dist-info/licenses/LICENSE +0 -21
  261. /claude_mpm/agents/{OUTPUT_STYLE.md → CLAUDE_MPM_OUTPUT_STYLE.md} +0 -0
  262. {claude_mpm-5.0.9.dist-info → claude_mpm-5.4.41.dist-info}/WHEEL +0 -0
  263. {claude_mpm-5.0.9.dist-info → claude_mpm-5.4.41.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
- )