mcp-mesh 0.3.0__tar.gz → 0.6.4__tar.gz

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 (156) hide show
  1. {mcp_mesh-0.3.0 → mcp_mesh-0.6.4}/.gitignore +8 -1
  2. {mcp_mesh-0.3.0 → mcp_mesh-0.6.4}/PKG-INFO +4 -1
  3. {mcp_mesh-0.3.0 → mcp_mesh-0.6.4}/_mcp_mesh/__init__.py +18 -4
  4. {mcp_mesh-0.3.0 → mcp_mesh-0.6.4}/_mcp_mesh/engine/__init__.py +12 -1
  5. {mcp_mesh-0.3.0 → mcp_mesh-0.6.4}/_mcp_mesh/engine/async_mcp_client.py +8 -21
  6. mcp_mesh-0.6.4/_mcp_mesh/engine/base_injector.py +171 -0
  7. {mcp_mesh-0.3.0 → mcp_mesh-0.6.4}/_mcp_mesh/engine/decorator_registry.py +322 -10
  8. mcp_mesh-0.6.4/_mcp_mesh/engine/dependency_injector.py +697 -0
  9. {mcp_mesh-0.3.0 → mcp_mesh-0.6.4}/_mcp_mesh/engine/full_mcp_proxy.py +53 -28
  10. {mcp_mesh-0.3.0 → mcp_mesh-0.6.4}/_mcp_mesh/engine/http_wrapper.py +27 -22
  11. mcp_mesh-0.6.4/_mcp_mesh/engine/llm_config.py +54 -0
  12. mcp_mesh-0.6.4/_mcp_mesh/engine/llm_errors.py +115 -0
  13. {mcp_mesh-0.3.0 → mcp_mesh-0.6.4}/_mcp_mesh/engine/mcp_client_proxy.py +33 -27
  14. mcp_mesh-0.6.4/_mcp_mesh/engine/mesh_llm_agent.py +644 -0
  15. mcp_mesh-0.6.4/_mcp_mesh/engine/mesh_llm_agent_injector.py +680 -0
  16. mcp_mesh-0.6.4/_mcp_mesh/engine/provider_handlers/__init__.py +20 -0
  17. mcp_mesh-0.6.4/_mcp_mesh/engine/provider_handlers/base_provider_handler.py +122 -0
  18. mcp_mesh-0.6.4/_mcp_mesh/engine/provider_handlers/claude_handler.py +418 -0
  19. mcp_mesh-0.6.4/_mcp_mesh/engine/provider_handlers/generic_handler.py +156 -0
  20. mcp_mesh-0.6.4/_mcp_mesh/engine/provider_handlers/openai_handler.py +219 -0
  21. mcp_mesh-0.6.4/_mcp_mesh/engine/provider_handlers/provider_handler_registry.py +167 -0
  22. mcp_mesh-0.6.4/_mcp_mesh/engine/response_parser.py +244 -0
  23. {mcp_mesh-0.3.0 → mcp_mesh-0.6.4}/_mcp_mesh/engine/self_dependency_proxy.py +16 -0
  24. mcp_mesh-0.6.4/_mcp_mesh/engine/signature_analyzer.py +359 -0
  25. mcp_mesh-0.6.4/_mcp_mesh/engine/tool_executor.py +169 -0
  26. mcp_mesh-0.6.4/_mcp_mesh/engine/tool_schema_builder.py +126 -0
  27. mcp_mesh-0.6.4/_mcp_mesh/engine/unified_mcp_proxy.py +892 -0
  28. {mcp_mesh-0.3.0 → mcp_mesh-0.6.4}/_mcp_mesh/generated/.openapi-generator/FILES +9 -0
  29. {mcp_mesh-0.3.0 → mcp_mesh-0.6.4}/_mcp_mesh/generated/.openapi-generator-ignore +0 -1
  30. {mcp_mesh-0.3.0 → mcp_mesh-0.6.4}/_mcp_mesh/generated/mcp_mesh_registry_client/__init__.py +9 -16
  31. {mcp_mesh-0.3.0 → mcp_mesh-0.6.4}/_mcp_mesh/generated/mcp_mesh_registry_client/api/__init__.py +1 -0
  32. mcp_mesh-0.6.4/_mcp_mesh/generated/mcp_mesh_registry_client/api/tracing_api.py +305 -0
  33. {mcp_mesh-0.3.0 → mcp_mesh-0.6.4}/_mcp_mesh/generated/mcp_mesh_registry_client/models/__init__.py +8 -0
  34. {mcp_mesh-0.3.0 → mcp_mesh-0.6.4}/_mcp_mesh/generated/mcp_mesh_registry_client/models/agent_info.py +20 -1
  35. mcp_mesh-0.6.4/_mcp_mesh/generated/mcp_mesh_registry_client/models/dependency_resolution_info.py +108 -0
  36. mcp_mesh-0.6.4/_mcp_mesh/generated/mcp_mesh_registry_client/models/llm_provider.py +95 -0
  37. mcp_mesh-0.6.4/_mcp_mesh/generated/mcp_mesh_registry_client/models/llm_tool_filter.py +111 -0
  38. mcp_mesh-0.6.4/_mcp_mesh/generated/mcp_mesh_registry_client/models/llm_tool_filter_filter_inner.py +141 -0
  39. mcp_mesh-0.6.4/_mcp_mesh/generated/mcp_mesh_registry_client/models/llm_tool_filter_filter_inner_one_of.py +93 -0
  40. mcp_mesh-0.6.4/_mcp_mesh/generated/mcp_mesh_registry_client/models/llm_tool_info.py +103 -0
  41. {mcp_mesh-0.3.0 → mcp_mesh-0.6.4}/_mcp_mesh/generated/mcp_mesh_registry_client/models/mesh_agent_registration.py +5 -5
  42. {mcp_mesh-0.3.0 → mcp_mesh-0.6.4}/_mcp_mesh/generated/mcp_mesh_registry_client/models/mesh_registration_response.py +35 -1
  43. {mcp_mesh-0.3.0 → mcp_mesh-0.6.4}/_mcp_mesh/generated/mcp_mesh_registry_client/models/mesh_tool_registration.py +11 -1
  44. mcp_mesh-0.6.4/_mcp_mesh/generated/mcp_mesh_registry_client/models/resolved_llm_provider.py +112 -0
  45. mcp_mesh-0.6.4/_mcp_mesh/generated/mcp_mesh_registry_client/models/trace_event.py +108 -0
  46. {mcp_mesh-0.3.0 → mcp_mesh-0.6.4}/_mcp_mesh/pipeline/__init__.py +2 -2
  47. mcp_mesh-0.6.4/_mcp_mesh/pipeline/api_heartbeat/__init__.py +16 -0
  48. mcp_mesh-0.6.4/_mcp_mesh/pipeline/api_heartbeat/api_dependency_resolution.py +525 -0
  49. mcp_mesh-0.6.4/_mcp_mesh/pipeline/api_heartbeat/api_fast_heartbeat_check.py +117 -0
  50. mcp_mesh-0.6.4/_mcp_mesh/pipeline/api_heartbeat/api_health_check.py +140 -0
  51. mcp_mesh-0.6.4/_mcp_mesh/pipeline/api_heartbeat/api_heartbeat_orchestrator.py +247 -0
  52. mcp_mesh-0.6.4/_mcp_mesh/pipeline/api_heartbeat/api_heartbeat_pipeline.py +309 -0
  53. mcp_mesh-0.6.4/_mcp_mesh/pipeline/api_heartbeat/api_heartbeat_send.py +332 -0
  54. mcp_mesh-0.6.4/_mcp_mesh/pipeline/api_heartbeat/api_lifespan_integration.py +147 -0
  55. mcp_mesh-0.6.4/_mcp_mesh/pipeline/api_heartbeat/api_registry_connection.py +104 -0
  56. mcp_mesh-0.6.4/_mcp_mesh/pipeline/api_startup/__init__.py +20 -0
  57. mcp_mesh-0.6.4/_mcp_mesh/pipeline/api_startup/api_pipeline.py +64 -0
  58. mcp_mesh-0.6.4/_mcp_mesh/pipeline/api_startup/api_server_setup.py +367 -0
  59. mcp_mesh-0.6.4/_mcp_mesh/pipeline/api_startup/fastapi_discovery.py +139 -0
  60. mcp_mesh-0.6.4/_mcp_mesh/pipeline/api_startup/middleware_integration.py +153 -0
  61. mcp_mesh-0.6.4/_mcp_mesh/pipeline/api_startup/route_collection.py +56 -0
  62. mcp_mesh-0.6.4/_mcp_mesh/pipeline/api_startup/route_integration.py +318 -0
  63. mcp_mesh-0.6.4/_mcp_mesh/pipeline/mcp_heartbeat/dependency_resolution.py +398 -0
  64. {mcp_mesh-0.3.0/_mcp_mesh/pipeline/heartbeat → mcp_mesh-0.6.4/_mcp_mesh/pipeline/mcp_heartbeat}/fast_heartbeat_check.py +3 -3
  65. {mcp_mesh-0.3.0/_mcp_mesh/pipeline/heartbeat → mcp_mesh-0.6.4/_mcp_mesh/pipeline/mcp_heartbeat}/heartbeat_orchestrator.py +38 -9
  66. {mcp_mesh-0.3.0/_mcp_mesh/pipeline/heartbeat → mcp_mesh-0.6.4/_mcp_mesh/pipeline/mcp_heartbeat}/heartbeat_pipeline.py +7 -4
  67. {mcp_mesh-0.3.0/_mcp_mesh/pipeline/heartbeat → mcp_mesh-0.6.4/_mcp_mesh/pipeline/mcp_heartbeat}/lifespan_integration.py +13 -0
  68. mcp_mesh-0.6.4/_mcp_mesh/pipeline/mcp_heartbeat/llm_tools_resolution.py +260 -0
  69. {mcp_mesh-0.3.0/_mcp_mesh/pipeline/startup → mcp_mesh-0.6.4/_mcp_mesh/pipeline/mcp_startup}/__init__.py +2 -0
  70. {mcp_mesh-0.3.0/_mcp_mesh/pipeline/startup → mcp_mesh-0.6.4/_mcp_mesh/pipeline/mcp_startup}/configuration.py +9 -0
  71. {mcp_mesh-0.3.0/_mcp_mesh/pipeline/startup → mcp_mesh-0.6.4/_mcp_mesh/pipeline/mcp_startup}/fastapiserver_setup.py +413 -187
  72. {mcp_mesh-0.3.0/_mcp_mesh/pipeline/startup → mcp_mesh-0.6.4/_mcp_mesh/pipeline/mcp_startup}/fastmcpserver_discovery.py +12 -5
  73. {mcp_mesh-0.3.0/_mcp_mesh/pipeline/startup → mcp_mesh-0.6.4/_mcp_mesh/pipeline/mcp_startup}/heartbeat_loop.py +1 -1
  74. {mcp_mesh-0.3.0/_mcp_mesh/pipeline/startup → mcp_mesh-0.6.4/_mcp_mesh/pipeline/mcp_startup}/heartbeat_preparation.py +111 -5
  75. mcp_mesh-0.6.4/_mcp_mesh/pipeline/mcp_startup/server_discovery.py +193 -0
  76. mcp_mesh-0.6.4/_mcp_mesh/pipeline/mcp_startup/startup_orchestrator.py +668 -0
  77. {mcp_mesh-0.3.0/_mcp_mesh/pipeline/startup → mcp_mesh-0.6.4/_mcp_mesh/pipeline/mcp_startup}/startup_pipeline.py +9 -6
  78. {mcp_mesh-0.3.0 → mcp_mesh-0.6.4}/_mcp_mesh/pipeline/shared/mesh_pipeline.py +4 -0
  79. {mcp_mesh-0.3.0 → mcp_mesh-0.6.4}/_mcp_mesh/shared/config_resolver.py +0 -3
  80. mcp_mesh-0.6.4/_mcp_mesh/shared/fastapi_middleware_manager.py +371 -0
  81. mcp_mesh-0.6.4/_mcp_mesh/shared/health_check_cache.py +246 -0
  82. {mcp_mesh-0.3.0 → mcp_mesh-0.6.4}/_mcp_mesh/shared/logging_config.py +2 -1
  83. {mcp_mesh-0.3.0 → mcp_mesh-0.6.4}/_mcp_mesh/shared/registry_client_wrapper.py +87 -4
  84. mcp_mesh-0.6.4/_mcp_mesh/shared/server_discovery.py +312 -0
  85. mcp_mesh-0.6.4/_mcp_mesh/shared/simple_shutdown.py +217 -0
  86. mcp_mesh-0.6.4/_mcp_mesh/shared/sse_parser.py +217 -0
  87. mcp_mesh-0.6.4/_mcp_mesh/tracing/agent_context_helper.py +128 -0
  88. mcp_mesh-0.6.4/_mcp_mesh/tracing/context.py +85 -0
  89. mcp_mesh-0.6.4/_mcp_mesh/tracing/execution_tracer.py +217 -0
  90. mcp_mesh-0.6.4/_mcp_mesh/tracing/fastapi_tracing_middleware.py +204 -0
  91. mcp_mesh-0.6.4/_mcp_mesh/tracing/redis_metadata_publisher.py +139 -0
  92. mcp_mesh-0.6.4/_mcp_mesh/tracing/trace_context_helper.py +166 -0
  93. mcp_mesh-0.6.4/_mcp_mesh/tracing/utils.py +137 -0
  94. mcp_mesh-0.6.4/_mcp_mesh/utils/fastmcp_schema_extractor.py +476 -0
  95. {mcp_mesh-0.3.0 → mcp_mesh-0.6.4}/mesh/__init__.py +20 -2
  96. mcp_mesh-0.6.4/mesh/decorators.py +1376 -0
  97. mcp_mesh-0.6.4/mesh/helpers.py +259 -0
  98. mcp_mesh-0.6.4/mesh/types.py +422 -0
  99. {mcp_mesh-0.3.0 → mcp_mesh-0.6.4}/pyproject.toml +8 -5
  100. mcp_mesh-0.3.0/_mcp_mesh/engine/dependency_injector.py +0 -397
  101. mcp_mesh-0.3.0/_mcp_mesh/engine/signature_analyzer.py +0 -220
  102. mcp_mesh-0.3.0/_mcp_mesh/pipeline/heartbeat/dependency_resolution.py +0 -517
  103. mcp_mesh-0.3.0/_mcp_mesh/pipeline/startup/startup_orchestrator.py +0 -465
  104. mcp_mesh-0.3.0/mesh/decorators.py +0 -485
  105. mcp_mesh-0.3.0/mesh/types.py +0 -261
  106. {mcp_mesh-0.3.0 → mcp_mesh-0.6.4}/LICENSE +0 -0
  107. {mcp_mesh-0.3.0 → mcp_mesh-0.6.4}/README.md +0 -0
  108. {mcp_mesh-0.3.0 → mcp_mesh-0.6.4}/_mcp_mesh/engine/session_aware_client.py +0 -0
  109. {mcp_mesh-0.3.0 → mcp_mesh-0.6.4}/_mcp_mesh/engine/session_manager.py +0 -0
  110. {mcp_mesh-0.3.0 → mcp_mesh-0.6.4}/_mcp_mesh/generated/.openapi-generator/VERSION +0 -0
  111. {mcp_mesh-0.3.0 → mcp_mesh-0.6.4}/_mcp_mesh/generated/mcp_mesh_registry_client/api/agents_api.py +0 -0
  112. {mcp_mesh-0.3.0 → mcp_mesh-0.6.4}/_mcp_mesh/generated/mcp_mesh_registry_client/api/health_api.py +0 -0
  113. {mcp_mesh-0.3.0 → mcp_mesh-0.6.4}/_mcp_mesh/generated/mcp_mesh_registry_client/api_client.py +0 -0
  114. {mcp_mesh-0.3.0 → mcp_mesh-0.6.4}/_mcp_mesh/generated/mcp_mesh_registry_client/api_response.py +0 -0
  115. {mcp_mesh-0.3.0 → mcp_mesh-0.6.4}/_mcp_mesh/generated/mcp_mesh_registry_client/configuration.py +0 -0
  116. {mcp_mesh-0.3.0 → mcp_mesh-0.6.4}/_mcp_mesh/generated/mcp_mesh_registry_client/exceptions.py +0 -0
  117. {mcp_mesh-0.3.0 → mcp_mesh-0.6.4}/_mcp_mesh/generated/mcp_mesh_registry_client/models/agent_metadata.py +0 -0
  118. {mcp_mesh-0.3.0 → mcp_mesh-0.6.4}/_mcp_mesh/generated/mcp_mesh_registry_client/models/agent_metadata_dependencies_inner.py +0 -0
  119. {mcp_mesh-0.3.0 → mcp_mesh-0.6.4}/_mcp_mesh/generated/mcp_mesh_registry_client/models/agent_metadata_dependencies_inner_one_of.py +0 -0
  120. {mcp_mesh-0.3.0 → mcp_mesh-0.6.4}/_mcp_mesh/generated/mcp_mesh_registry_client/models/agent_registration.py +0 -0
  121. {mcp_mesh-0.3.0 → mcp_mesh-0.6.4}/_mcp_mesh/generated/mcp_mesh_registry_client/models/agent_registration_metadata.py +0 -0
  122. {mcp_mesh-0.3.0 → mcp_mesh-0.6.4}/_mcp_mesh/generated/mcp_mesh_registry_client/models/agents_list_response.py +0 -0
  123. {mcp_mesh-0.3.0 → mcp_mesh-0.6.4}/_mcp_mesh/generated/mcp_mesh_registry_client/models/capability_info.py +0 -0
  124. {mcp_mesh-0.3.0 → mcp_mesh-0.6.4}/_mcp_mesh/generated/mcp_mesh_registry_client/models/decorator_agent_metadata.py +0 -0
  125. {mcp_mesh-0.3.0 → mcp_mesh-0.6.4}/_mcp_mesh/generated/mcp_mesh_registry_client/models/decorator_agent_request.py +0 -0
  126. {mcp_mesh-0.3.0 → mcp_mesh-0.6.4}/_mcp_mesh/generated/mcp_mesh_registry_client/models/decorator_info.py +0 -0
  127. {mcp_mesh-0.3.0 → mcp_mesh-0.6.4}/_mcp_mesh/generated/mcp_mesh_registry_client/models/dependency_info.py +0 -0
  128. {mcp_mesh-0.3.0 → mcp_mesh-0.6.4}/_mcp_mesh/generated/mcp_mesh_registry_client/models/error_response.py +0 -0
  129. {mcp_mesh-0.3.0 → mcp_mesh-0.6.4}/_mcp_mesh/generated/mcp_mesh_registry_client/models/health_response.py +0 -0
  130. {mcp_mesh-0.3.0 → mcp_mesh-0.6.4}/_mcp_mesh/generated/mcp_mesh_registry_client/models/heartbeat_request.py +0 -0
  131. {mcp_mesh-0.3.0 → mcp_mesh-0.6.4}/_mcp_mesh/generated/mcp_mesh_registry_client/models/heartbeat_request_metadata.py +0 -0
  132. {mcp_mesh-0.3.0 → mcp_mesh-0.6.4}/_mcp_mesh/generated/mcp_mesh_registry_client/models/heartbeat_response.py +0 -0
  133. {mcp_mesh-0.3.0 → mcp_mesh-0.6.4}/_mcp_mesh/generated/mcp_mesh_registry_client/models/mesh_agent_register_metadata.py +0 -0
  134. {mcp_mesh-0.3.0 → mcp_mesh-0.6.4}/_mcp_mesh/generated/mcp_mesh_registry_client/models/mesh_registration_response_dependencies_resolved_value_inner.py +0 -0
  135. {mcp_mesh-0.3.0 → mcp_mesh-0.6.4}/_mcp_mesh/generated/mcp_mesh_registry_client/models/mesh_tool_dependency_registration.py +0 -0
  136. {mcp_mesh-0.3.0 → mcp_mesh-0.6.4}/_mcp_mesh/generated/mcp_mesh_registry_client/models/mesh_tool_register_metadata.py +0 -0
  137. {mcp_mesh-0.3.0 → mcp_mesh-0.6.4}/_mcp_mesh/generated/mcp_mesh_registry_client/models/registration_response.py +0 -0
  138. {mcp_mesh-0.3.0 → mcp_mesh-0.6.4}/_mcp_mesh/generated/mcp_mesh_registry_client/models/rich_dependency.py +0 -0
  139. {mcp_mesh-0.3.0 → mcp_mesh-0.6.4}/_mcp_mesh/generated/mcp_mesh_registry_client/models/root_response.py +0 -0
  140. {mcp_mesh-0.3.0 → mcp_mesh-0.6.4}/_mcp_mesh/generated/mcp_mesh_registry_client/models/standardized_dependency.py +0 -0
  141. {mcp_mesh-0.3.0 → mcp_mesh-0.6.4}/_mcp_mesh/generated/mcp_mesh_registry_client/py.typed +0 -0
  142. {mcp_mesh-0.3.0 → mcp_mesh-0.6.4}/_mcp_mesh/generated/mcp_mesh_registry_client/rest.py +0 -0
  143. {mcp_mesh-0.3.0/_mcp_mesh/pipeline/heartbeat → mcp_mesh-0.6.4/_mcp_mesh/pipeline/mcp_heartbeat}/__init__.py +0 -0
  144. {mcp_mesh-0.3.0/_mcp_mesh/pipeline/heartbeat → mcp_mesh-0.6.4/_mcp_mesh/pipeline/mcp_heartbeat}/heartbeat_send.py +0 -0
  145. {mcp_mesh-0.3.0/_mcp_mesh/pipeline/heartbeat → mcp_mesh-0.6.4/_mcp_mesh/pipeline/mcp_heartbeat}/registry_connection.py +0 -0
  146. {mcp_mesh-0.3.0/_mcp_mesh/pipeline/startup → mcp_mesh-0.6.4/_mcp_mesh/pipeline/mcp_startup}/decorator_collection.py +0 -0
  147. {mcp_mesh-0.3.0 → mcp_mesh-0.6.4}/_mcp_mesh/pipeline/shared/__init__.py +0 -0
  148. {mcp_mesh-0.3.0 → mcp_mesh-0.6.4}/_mcp_mesh/pipeline/shared/base_step.py +0 -0
  149. {mcp_mesh-0.3.0 → mcp_mesh-0.6.4}/_mcp_mesh/pipeline/shared/pipeline_types.py +0 -0
  150. {mcp_mesh-0.3.0 → mcp_mesh-0.6.4}/_mcp_mesh/pipeline/shared/registry_connection.py +0 -0
  151. {mcp_mesh-0.3.0 → mcp_mesh-0.6.4}/_mcp_mesh/shared/__init__.py +0 -0
  152. {mcp_mesh-0.3.0 → mcp_mesh-0.6.4}/_mcp_mesh/shared/content_extractor.py +0 -0
  153. {mcp_mesh-0.3.0 → mcp_mesh-0.6.4}/_mcp_mesh/shared/defaults.py +0 -0
  154. {mcp_mesh-0.3.0 → mcp_mesh-0.6.4}/_mcp_mesh/shared/fast_heartbeat_status.py +0 -0
  155. {mcp_mesh-0.3.0 → mcp_mesh-0.6.4}/_mcp_mesh/shared/host_resolver.py +0 -0
  156. {mcp_mesh-0.3.0 → mcp_mesh-0.6.4}/_mcp_mesh/shared/support_types.py +0 -0
@@ -163,6 +163,11 @@ cython_debug/
163
163
  # VS Code
164
164
  .vscode/
165
165
 
166
+ # Other IDEs/Tools
167
+ .emigo_repomap/
168
+ .windsurf/
169
+ .windsurfrules
170
+
166
171
  # MCP Mesh specific
167
172
  *.mcpconfig
168
173
  .mcpconfig/
@@ -170,10 +175,11 @@ logs/
170
175
  .logs/
171
176
  capability_store/
172
177
  *.db
178
+ *.pid
173
179
 
174
180
  # Go binaries
175
181
  mcp-mesh-dev
176
- mcp-mesh-registry
182
+ /mcp-mesh-registry
177
183
  meshctl
178
184
  bin/meshctl
179
185
  *.exe
@@ -229,3 +235,4 @@ packaging/pypi/src/
229
235
  packaging/pypi/README.md
230
236
  packaging/pypi/LICENSE
231
237
  packaging/pypi/dist/
238
+ MEDIUM-POST-MULTI-AGENT-POC.md
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mcp-mesh
3
- Version: 0.3.0
3
+ Version: 0.6.4
4
4
  Summary: Kubernetes-native platform for distributed MCP applications
5
5
  Project-URL: Homepage, https://github.com/dhyansraj/mcp-mesh
6
6
  Project-URL: Documentation, https://github.com/dhyansraj/mcp-mesh/tree/main/docs
@@ -23,10 +23,13 @@ Classifier: Topic :: Software Development :: Libraries :: Python Modules
23
23
  Classifier: Topic :: System :: Distributed Computing
24
24
  Requires-Python: >=3.11
25
25
  Requires-Dist: aiohttp<4.0.0,>=3.8.0
26
+ Requires-Dist: cachetools>=5.3.0
26
27
  Requires-Dist: click<9.0.0,>=8.1.0
27
28
  Requires-Dist: fastapi<1.0.0,>=0.104.0
28
29
  Requires-Dist: fastmcp<3.0.0,>=2.8.0
29
30
  Requires-Dist: httpx<1.0.0,>=0.25.0
31
+ Requires-Dist: jinja2>=3.1.0
32
+ Requires-Dist: litellm>=1.30.0
30
33
  Requires-Dist: mcp<2.0.0,>=1.9.0
31
34
  Requires-Dist: prometheus-client<1.0.0,>=0.19.0
32
35
  Requires-Dist: pydantic<3.0.0,>=2.4.0
@@ -31,7 +31,7 @@ from .engine.decorator_registry import (
31
31
  get_decorator_stats,
32
32
  )
33
33
 
34
- __version__ = "0.3.0"
34
+ __version__ = "0.6.4"
35
35
 
36
36
  # Store reference to runtime processor if initialized
37
37
  _runtime_processor = None
@@ -48,7 +48,7 @@ def initialize_runtime():
48
48
  # Legacy processor system has been replaced by pipeline architecture
49
49
 
50
50
  # Use pipeline-based runtime
51
- from .pipeline.startup import start_runtime
51
+ from .pipeline.mcp_startup import start_runtime
52
52
 
53
53
  start_runtime()
54
54
 
@@ -59,8 +59,22 @@ def initialize_runtime():
59
59
 
60
60
 
61
61
  # Auto-initialize runtime if enabled
62
- if os.getenv("MCP_MESH_ENABLED", "true").lower() == "true":
63
- initialize_runtime()
62
+ if (
63
+ os.getenv("MCP_MESH_ENABLED", "true").lower() == "true"
64
+ and os.getenv("MCP_MESH_AUTO_RUN", "true").lower() == "true"
65
+ ):
66
+ # Use debounced initialization instead of immediate MCP startup
67
+ # This allows the system to determine MCP vs API pipeline based on decorators
68
+ try:
69
+ from .pipeline.mcp_startup import start_runtime
70
+
71
+ # Start the debounced runtime (sets up coordinator, no immediate pipeline execution)
72
+ start_runtime()
73
+
74
+ sys.stderr.write("MCP Mesh debounced runtime initialized\n")
75
+ except Exception as e:
76
+ # Log but don't fail - allows graceful degradation
77
+ sys.stderr.write(f"MCP Mesh runtime initialization failed: {e}\n")
64
78
 
65
79
 
66
80
  __all__ = [
@@ -17,12 +17,15 @@ __all__ = [
17
17
  # Dependency injection
18
18
  "DependencyInjector",
19
19
  "get_global_injector",
20
- # MCP client proxies
20
+ # MCP client proxies (legacy)
21
21
  "MCPClientProxy",
22
22
  "EnhancedMCPClientProxy",
23
23
  "FullMCPProxy",
24
24
  "EnhancedFullMCPProxy",
25
25
  "AsyncMCPClient",
26
+ # Unified MCP proxy (recommended)
27
+ "UnifiedMCPProxy",
28
+ "EnhancedUnifiedMCPProxy",
26
29
  # Self-dependency proxy
27
30
  "SelfDependencyProxy",
28
31
  # Decorator registry
@@ -76,6 +79,14 @@ def __getattr__(name):
76
79
  from .async_mcp_client import AsyncMCPClient
77
80
 
78
81
  return AsyncMCPClient
82
+ elif name == "UnifiedMCPProxy":
83
+ from .unified_mcp_proxy import UnifiedMCPProxy
84
+
85
+ return UnifiedMCPProxy
86
+ elif name == "EnhancedUnifiedMCPProxy":
87
+ from .unified_mcp_proxy import EnhancedUnifiedMCPProxy
88
+
89
+ return EnhancedUnifiedMCPProxy
79
90
  # Self-dependency proxy
80
91
  elif name == "SelfDependencyProxy":
81
92
  from .self_dependency_proxy import SelfDependencyProxy
@@ -6,6 +6,8 @@ import urllib.error
6
6
  import urllib.request
7
7
  from typing import Any
8
8
 
9
+ from ..shared.sse_parser import SSEParser
10
+
9
11
  logger = logging.getLogger(__name__)
10
12
 
11
13
 
@@ -37,7 +39,7 @@ class AsyncMCPClient:
37
39
 
38
40
  async def _make_request(self, payload: dict) -> dict:
39
41
  """Make async HTTP request to MCP endpoint."""
40
- url = f"{self.endpoint}/mcp/"
42
+ url = f"{self.endpoint}/mcp"
41
43
 
42
44
  try:
43
45
  # Use httpx for proper async HTTP requests (better threading support than aiohttp)
@@ -62,25 +64,10 @@ class AsyncMCPClient:
62
64
 
63
65
  response_text = response.text
64
66
 
65
- # Handle Server-Sent Events format from FastMCP
66
- if response_text.startswith("event:"):
67
- # Parse SSE format: extract JSON from "data:" lines
68
- json_data = None
69
- for line in response_text.split("\n"):
70
- if line.startswith("data:"):
71
- json_str = line[5:].strip() # Remove 'data:' prefix
72
- try:
73
- json_data = json.loads(json_str)
74
- break
75
- except json.JSONDecodeError:
76
- continue
77
-
78
- if json_data is None:
79
- raise RuntimeError("Could not parse SSE response from FastMCP")
80
- data = json_data
81
- else:
82
- # Plain JSON response
83
- data = response.json()
67
+ # Use shared SSE parser
68
+ data = SSEParser.parse_sse_response(
69
+ response_text, f"AsyncMCPClient.{self.endpoint}"
70
+ )
84
71
 
85
72
  # Check for JSON-RPC error
86
73
  if "error" in data:
@@ -104,7 +91,7 @@ class AsyncMCPClient:
104
91
 
105
92
  async def _make_request_sync(self, payload: dict) -> dict:
106
93
  """Fallback sync HTTP request using urllib."""
107
- url = f"{self.endpoint}/mcp/"
94
+ url = f"{self.endpoint}/mcp"
108
95
  data = json.dumps(payload).encode("utf-8")
109
96
 
110
97
  # Create request
@@ -0,0 +1,171 @@
1
+ """
2
+ Base injector class with shared wrapper creation logic.
3
+
4
+ Provides common functionality for DependencyInjector and MeshLlmAgentInjector.
5
+ """
6
+
7
+ import functools
8
+ import inspect
9
+ import logging
10
+ import weakref
11
+ from collections.abc import Callable
12
+ from typing import Any
13
+
14
+ logger = logging.getLogger(__name__)
15
+
16
+
17
+ class BaseInjector:
18
+ """
19
+ Base class for injection systems.
20
+
21
+ Provides shared functionality for creating and managing function wrappers
22
+ that support dynamic injection with two-phase updates.
23
+
24
+ Two-Phase Injection Pattern:
25
+ 1. Phase 1 (decorator time): Create wrapper with initial state (None)
26
+ 2. Phase 2 (runtime): Update wrapper with actual instances via update method
27
+
28
+ Subclasses must implement:
29
+ - Wrapper logic (what to inject and how)
30
+ - Update method signature
31
+ """
32
+
33
+ def __init__(self):
34
+ """Initialize base injector with function registry."""
35
+ self._function_registry: weakref.WeakValueDictionary = (
36
+ weakref.WeakValueDictionary()
37
+ )
38
+ logger.debug(f"🔧 {self.__class__.__name__} initialized")
39
+
40
+ def _register_wrapper(self, function_id: str, wrapper: Callable) -> None:
41
+ """
42
+ Register a wrapper in the function registry.
43
+
44
+ Args:
45
+ function_id: Unique function identifier
46
+ wrapper: Wrapper function to register
47
+ """
48
+ self._function_registry[function_id] = wrapper
49
+ logger.debug(f"🔧 Registered wrapper for {function_id} at {hex(id(wrapper))}")
50
+
51
+ def _create_async_wrapper(
52
+ self,
53
+ func: Callable,
54
+ function_id: str,
55
+ injection_logic: Callable[[Callable, tuple, dict], tuple],
56
+ metadata: dict[str, Any],
57
+ ) -> Callable:
58
+ """
59
+ Create async wrapper with injection logic.
60
+
61
+ Args:
62
+ func: Original async function to wrap
63
+ function_id: Unique function identifier
64
+ injection_logic: Callable that takes (func, args, kwargs) and returns (args, kwargs)
65
+ This function should modify kwargs to inject dependencies
66
+ metadata: Additional metadata to store on wrapper
67
+
68
+ Returns:
69
+ Async wrapper function
70
+ """
71
+
72
+ @functools.wraps(func)
73
+ async def async_wrapper(*args, **kwargs):
74
+ # Apply injection logic to modify kwargs
75
+ args, kwargs = injection_logic(func, args, kwargs)
76
+
77
+ # Execute original function
78
+ return await func(*args, **kwargs)
79
+
80
+ # Store metadata on wrapper
81
+ async_wrapper._mesh_original_func = func
82
+ async_wrapper._mesh_function_id = function_id
83
+
84
+ # Store additional metadata
85
+ for key, value in metadata.items():
86
+ setattr(async_wrapper, key, value)
87
+
88
+ return async_wrapper
89
+
90
+ def _create_sync_wrapper(
91
+ self,
92
+ func: Callable,
93
+ function_id: str,
94
+ injection_logic: Callable[[Callable, tuple, dict], tuple],
95
+ metadata: dict[str, Any],
96
+ ) -> Callable:
97
+ """
98
+ Create sync wrapper with injection logic.
99
+
100
+ Args:
101
+ func: Original sync function to wrap
102
+ function_id: Unique function identifier
103
+ injection_logic: Callable that takes (func, args, kwargs) and returns (args, kwargs)
104
+ This function should modify kwargs to inject dependencies
105
+ metadata: Additional metadata to store on wrapper
106
+
107
+ Returns:
108
+ Sync wrapper function
109
+ """
110
+
111
+ @functools.wraps(func)
112
+ def sync_wrapper(*args, **kwargs):
113
+ # Apply injection logic to modify kwargs
114
+ args, kwargs = injection_logic(func, args, kwargs)
115
+
116
+ # Execute original function
117
+ return func(*args, **kwargs)
118
+
119
+ # Store metadata on wrapper
120
+ sync_wrapper._mesh_original_func = func
121
+ sync_wrapper._mesh_function_id = function_id
122
+
123
+ # Store additional metadata
124
+ for key, value in metadata.items():
125
+ setattr(sync_wrapper, key, value)
126
+
127
+ return sync_wrapper
128
+
129
+ def create_wrapper_with_injection(
130
+ self,
131
+ func: Callable,
132
+ function_id: str,
133
+ injection_logic: Callable[[Callable, tuple, dict], tuple],
134
+ metadata: dict[str, Any],
135
+ register: bool = True,
136
+ ) -> Callable:
137
+ """
138
+ Create wrapper (async or sync) based on function type.
139
+
140
+ This is the main entry point for creating wrappers. It automatically
141
+ detects if the function is async or sync and creates the appropriate wrapper.
142
+
143
+ Args:
144
+ func: Function to wrap
145
+ function_id: Unique function identifier
146
+ injection_logic: Callable that takes (func, args, kwargs) and returns (args, kwargs)
147
+ metadata: Additional metadata to store on wrapper
148
+ register: Whether to register wrapper in function_registry (default: True)
149
+
150
+ Returns:
151
+ Wrapped function with injection capability
152
+ """
153
+ # Detect async vs sync
154
+ is_async = inspect.iscoroutinefunction(func)
155
+
156
+ if is_async:
157
+ wrapper = self._create_async_wrapper(
158
+ func, function_id, injection_logic, metadata
159
+ )
160
+ logger.debug(f"✅ Created async wrapper for {function_id}")
161
+ else:
162
+ wrapper = self._create_sync_wrapper(
163
+ func, function_id, injection_logic, metadata
164
+ )
165
+ logger.debug(f"✅ Created sync wrapper for {function_id}")
166
+
167
+ # Register wrapper if requested
168
+ if register:
169
+ self._register_wrapper(function_id, wrapper)
170
+
171
+ return wrapper