mcp-mesh 0.7.12__tar.gz → 0.7.13__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 (155) hide show
  1. {mcp_mesh-0.7.12 → mcp_mesh-0.7.13}/PKG-INFO +1 -1
  2. {mcp_mesh-0.7.12 → mcp_mesh-0.7.13}/_mcp_mesh/__init__.py +1 -1
  3. {mcp_mesh-0.7.12 → mcp_mesh-0.7.13}/_mcp_mesh/engine/__init__.py +1 -22
  4. {mcp_mesh-0.7.12 → mcp_mesh-0.7.13}/_mcp_mesh/engine/async_mcp_client.py +88 -25
  5. {mcp_mesh-0.7.12 → mcp_mesh-0.7.13}/_mcp_mesh/engine/decorator_registry.py +10 -9
  6. {mcp_mesh-0.7.12 → mcp_mesh-0.7.13}/_mcp_mesh/engine/dependency_injector.py +64 -53
  7. {mcp_mesh-0.7.12 → mcp_mesh-0.7.13}/_mcp_mesh/engine/mesh_llm_agent.py +119 -5
  8. {mcp_mesh-0.7.12 → mcp_mesh-0.7.13}/_mcp_mesh/engine/mesh_llm_agent_injector.py +30 -0
  9. {mcp_mesh-0.7.12 → mcp_mesh-0.7.13}/_mcp_mesh/engine/session_aware_client.py +3 -3
  10. {mcp_mesh-0.7.12 → mcp_mesh-0.7.13}/_mcp_mesh/engine/unified_mcp_proxy.py +82 -90
  11. {mcp_mesh-0.7.12 → mcp_mesh-0.7.13}/_mcp_mesh/pipeline/api_heartbeat/api_dependency_resolution.py +0 -89
  12. {mcp_mesh-0.7.12 → mcp_mesh-0.7.13}/_mcp_mesh/pipeline/api_heartbeat/api_fast_heartbeat_check.py +3 -3
  13. {mcp_mesh-0.7.12 → mcp_mesh-0.7.13}/_mcp_mesh/pipeline/api_heartbeat/api_heartbeat_pipeline.py +30 -28
  14. {mcp_mesh-0.7.12 → mcp_mesh-0.7.13}/_mcp_mesh/pipeline/mcp_heartbeat/dependency_resolution.py +16 -18
  15. {mcp_mesh-0.7.12 → mcp_mesh-0.7.13}/_mcp_mesh/pipeline/mcp_heartbeat/fast_heartbeat_check.py +5 -5
  16. {mcp_mesh-0.7.12 → mcp_mesh-0.7.13}/_mcp_mesh/pipeline/mcp_heartbeat/heartbeat_orchestrator.py +3 -3
  17. {mcp_mesh-0.7.12 → mcp_mesh-0.7.13}/_mcp_mesh/pipeline/mcp_heartbeat/heartbeat_pipeline.py +6 -6
  18. {mcp_mesh-0.7.12 → mcp_mesh-0.7.13}/_mcp_mesh/pipeline/mcp_heartbeat/heartbeat_send.py +1 -1
  19. {mcp_mesh-0.7.12 → mcp_mesh-0.7.13}/_mcp_mesh/pipeline/mcp_heartbeat/llm_tools_resolution.py +15 -11
  20. {mcp_mesh-0.7.12 → mcp_mesh-0.7.13}/_mcp_mesh/pipeline/mcp_heartbeat/registry_connection.py +3 -3
  21. {mcp_mesh-0.7.12 → mcp_mesh-0.7.13}/_mcp_mesh/pipeline/mcp_startup/fastapiserver_setup.py +37 -268
  22. mcp_mesh-0.7.13/_mcp_mesh/pipeline/mcp_startup/lifespan_factory.py +142 -0
  23. {mcp_mesh-0.7.12 → mcp_mesh-0.7.13}/_mcp_mesh/pipeline/mcp_startup/startup_orchestrator.py +57 -93
  24. {mcp_mesh-0.7.12 → mcp_mesh-0.7.13}/_mcp_mesh/pipeline/shared/registry_connection.py +1 -1
  25. mcp_mesh-0.7.13/_mcp_mesh/shared/health_check_manager.py +313 -0
  26. mcp_mesh-0.7.13/_mcp_mesh/shared/logging_config.py +277 -0
  27. {mcp_mesh-0.7.12 → mcp_mesh-0.7.13}/_mcp_mesh/shared/registry_client_wrapper.py +8 -8
  28. {mcp_mesh-0.7.12 → mcp_mesh-0.7.13}/_mcp_mesh/shared/sse_parser.py +19 -17
  29. {mcp_mesh-0.7.12 → mcp_mesh-0.7.13}/_mcp_mesh/tracing/execution_tracer.py +26 -1
  30. {mcp_mesh-0.7.12 → mcp_mesh-0.7.13}/_mcp_mesh/tracing/fastapi_tracing_middleware.py +3 -4
  31. {mcp_mesh-0.7.12 → mcp_mesh-0.7.13}/_mcp_mesh/tracing/trace_context_helper.py +25 -6
  32. {mcp_mesh-0.7.12 → mcp_mesh-0.7.13}/mesh/__init__.py +3 -1
  33. {mcp_mesh-0.7.12 → mcp_mesh-0.7.13}/mesh/decorators.py +81 -43
  34. {mcp_mesh-0.7.12 → mcp_mesh-0.7.13}/mesh/helpers.py +72 -4
  35. {mcp_mesh-0.7.12 → mcp_mesh-0.7.13}/mesh/types.py +48 -4
  36. {mcp_mesh-0.7.12 → mcp_mesh-0.7.13}/pyproject.toml +4 -4
  37. mcp_mesh-0.7.12/_mcp_mesh/engine/full_mcp_proxy.py +0 -641
  38. mcp_mesh-0.7.12/_mcp_mesh/engine/mcp_client_proxy.py +0 -457
  39. mcp_mesh-0.7.12/_mcp_mesh/shared/health_check_cache.py +0 -246
  40. mcp_mesh-0.7.12/_mcp_mesh/shared/logging_config.py +0 -94
  41. {mcp_mesh-0.7.12 → mcp_mesh-0.7.13}/.gitignore +0 -0
  42. {mcp_mesh-0.7.12 → mcp_mesh-0.7.13}/LICENSE +0 -0
  43. {mcp_mesh-0.7.12 → mcp_mesh-0.7.13}/README.md +0 -0
  44. {mcp_mesh-0.7.12 → mcp_mesh-0.7.13}/_mcp_mesh/engine/base_injector.py +0 -0
  45. {mcp_mesh-0.7.12 → mcp_mesh-0.7.13}/_mcp_mesh/engine/http_wrapper.py +0 -0
  46. {mcp_mesh-0.7.12 → mcp_mesh-0.7.13}/_mcp_mesh/engine/llm_config.py +0 -0
  47. {mcp_mesh-0.7.12 → mcp_mesh-0.7.13}/_mcp_mesh/engine/llm_errors.py +0 -0
  48. {mcp_mesh-0.7.12 → mcp_mesh-0.7.13}/_mcp_mesh/engine/provider_handlers/__init__.py +0 -0
  49. {mcp_mesh-0.7.12 → mcp_mesh-0.7.13}/_mcp_mesh/engine/provider_handlers/base_provider_handler.py +0 -0
  50. {mcp_mesh-0.7.12 → mcp_mesh-0.7.13}/_mcp_mesh/engine/provider_handlers/claude_handler.py +0 -0
  51. {mcp_mesh-0.7.12 → mcp_mesh-0.7.13}/_mcp_mesh/engine/provider_handlers/generic_handler.py +0 -0
  52. {mcp_mesh-0.7.12 → mcp_mesh-0.7.13}/_mcp_mesh/engine/provider_handlers/openai_handler.py +0 -0
  53. {mcp_mesh-0.7.12 → mcp_mesh-0.7.13}/_mcp_mesh/engine/provider_handlers/provider_handler_registry.py +0 -0
  54. {mcp_mesh-0.7.12 → mcp_mesh-0.7.13}/_mcp_mesh/engine/response_parser.py +0 -0
  55. {mcp_mesh-0.7.12 → mcp_mesh-0.7.13}/_mcp_mesh/engine/self_dependency_proxy.py +0 -0
  56. {mcp_mesh-0.7.12 → mcp_mesh-0.7.13}/_mcp_mesh/engine/session_manager.py +0 -0
  57. {mcp_mesh-0.7.12 → mcp_mesh-0.7.13}/_mcp_mesh/engine/signature_analyzer.py +0 -0
  58. {mcp_mesh-0.7.12 → mcp_mesh-0.7.13}/_mcp_mesh/engine/tool_executor.py +0 -0
  59. {mcp_mesh-0.7.12 → mcp_mesh-0.7.13}/_mcp_mesh/engine/tool_schema_builder.py +0 -0
  60. {mcp_mesh-0.7.12 → mcp_mesh-0.7.13}/_mcp_mesh/generated/.openapi-generator/FILES +0 -0
  61. {mcp_mesh-0.7.12 → mcp_mesh-0.7.13}/_mcp_mesh/generated/.openapi-generator/VERSION +0 -0
  62. {mcp_mesh-0.7.12 → mcp_mesh-0.7.13}/_mcp_mesh/generated/.openapi-generator-ignore +0 -0
  63. {mcp_mesh-0.7.12 → mcp_mesh-0.7.13}/_mcp_mesh/generated/mcp_mesh_registry_client/__init__.py +0 -0
  64. {mcp_mesh-0.7.12 → mcp_mesh-0.7.13}/_mcp_mesh/generated/mcp_mesh_registry_client/api/__init__.py +0 -0
  65. {mcp_mesh-0.7.12 → mcp_mesh-0.7.13}/_mcp_mesh/generated/mcp_mesh_registry_client/api/agents_api.py +0 -0
  66. {mcp_mesh-0.7.12 → mcp_mesh-0.7.13}/_mcp_mesh/generated/mcp_mesh_registry_client/api/health_api.py +0 -0
  67. {mcp_mesh-0.7.12 → mcp_mesh-0.7.13}/_mcp_mesh/generated/mcp_mesh_registry_client/api/tracing_api.py +0 -0
  68. {mcp_mesh-0.7.12 → mcp_mesh-0.7.13}/_mcp_mesh/generated/mcp_mesh_registry_client/api_client.py +0 -0
  69. {mcp_mesh-0.7.12 → mcp_mesh-0.7.13}/_mcp_mesh/generated/mcp_mesh_registry_client/api_response.py +0 -0
  70. {mcp_mesh-0.7.12 → mcp_mesh-0.7.13}/_mcp_mesh/generated/mcp_mesh_registry_client/configuration.py +0 -0
  71. {mcp_mesh-0.7.12 → mcp_mesh-0.7.13}/_mcp_mesh/generated/mcp_mesh_registry_client/exceptions.py +0 -0
  72. {mcp_mesh-0.7.12 → mcp_mesh-0.7.13}/_mcp_mesh/generated/mcp_mesh_registry_client/models/__init__.py +0 -0
  73. {mcp_mesh-0.7.12 → mcp_mesh-0.7.13}/_mcp_mesh/generated/mcp_mesh_registry_client/models/agent_info.py +0 -0
  74. {mcp_mesh-0.7.12 → mcp_mesh-0.7.13}/_mcp_mesh/generated/mcp_mesh_registry_client/models/agent_metadata.py +0 -0
  75. {mcp_mesh-0.7.12 → mcp_mesh-0.7.13}/_mcp_mesh/generated/mcp_mesh_registry_client/models/agent_metadata_dependencies_inner.py +0 -0
  76. {mcp_mesh-0.7.12 → mcp_mesh-0.7.13}/_mcp_mesh/generated/mcp_mesh_registry_client/models/agent_metadata_dependencies_inner_one_of.py +0 -0
  77. {mcp_mesh-0.7.12 → mcp_mesh-0.7.13}/_mcp_mesh/generated/mcp_mesh_registry_client/models/agent_registration.py +0 -0
  78. {mcp_mesh-0.7.12 → mcp_mesh-0.7.13}/_mcp_mesh/generated/mcp_mesh_registry_client/models/agent_registration_metadata.py +0 -0
  79. {mcp_mesh-0.7.12 → mcp_mesh-0.7.13}/_mcp_mesh/generated/mcp_mesh_registry_client/models/agents_list_response.py +0 -0
  80. {mcp_mesh-0.7.12 → mcp_mesh-0.7.13}/_mcp_mesh/generated/mcp_mesh_registry_client/models/capability_info.py +0 -0
  81. {mcp_mesh-0.7.12 → mcp_mesh-0.7.13}/_mcp_mesh/generated/mcp_mesh_registry_client/models/decorator_agent_metadata.py +0 -0
  82. {mcp_mesh-0.7.12 → mcp_mesh-0.7.13}/_mcp_mesh/generated/mcp_mesh_registry_client/models/decorator_agent_request.py +0 -0
  83. {mcp_mesh-0.7.12 → mcp_mesh-0.7.13}/_mcp_mesh/generated/mcp_mesh_registry_client/models/decorator_info.py +0 -0
  84. {mcp_mesh-0.7.12 → mcp_mesh-0.7.13}/_mcp_mesh/generated/mcp_mesh_registry_client/models/dependency_info.py +0 -0
  85. {mcp_mesh-0.7.12 → mcp_mesh-0.7.13}/_mcp_mesh/generated/mcp_mesh_registry_client/models/dependency_resolution_info.py +0 -0
  86. {mcp_mesh-0.7.12 → mcp_mesh-0.7.13}/_mcp_mesh/generated/mcp_mesh_registry_client/models/error_response.py +0 -0
  87. {mcp_mesh-0.7.12 → mcp_mesh-0.7.13}/_mcp_mesh/generated/mcp_mesh_registry_client/models/health_response.py +0 -0
  88. {mcp_mesh-0.7.12 → mcp_mesh-0.7.13}/_mcp_mesh/generated/mcp_mesh_registry_client/models/heartbeat_request.py +0 -0
  89. {mcp_mesh-0.7.12 → mcp_mesh-0.7.13}/_mcp_mesh/generated/mcp_mesh_registry_client/models/heartbeat_request_metadata.py +0 -0
  90. {mcp_mesh-0.7.12 → mcp_mesh-0.7.13}/_mcp_mesh/generated/mcp_mesh_registry_client/models/heartbeat_response.py +0 -0
  91. {mcp_mesh-0.7.12 → mcp_mesh-0.7.13}/_mcp_mesh/generated/mcp_mesh_registry_client/models/llm_provider.py +0 -0
  92. {mcp_mesh-0.7.12 → mcp_mesh-0.7.13}/_mcp_mesh/generated/mcp_mesh_registry_client/models/llm_provider_resolution_info.py +0 -0
  93. {mcp_mesh-0.7.12 → mcp_mesh-0.7.13}/_mcp_mesh/generated/mcp_mesh_registry_client/models/llm_tool_filter.py +0 -0
  94. {mcp_mesh-0.7.12 → mcp_mesh-0.7.13}/_mcp_mesh/generated/mcp_mesh_registry_client/models/llm_tool_filter_filter_inner.py +0 -0
  95. {mcp_mesh-0.7.12 → mcp_mesh-0.7.13}/_mcp_mesh/generated/mcp_mesh_registry_client/models/llm_tool_filter_filter_inner_one_of.py +0 -0
  96. {mcp_mesh-0.7.12 → mcp_mesh-0.7.13}/_mcp_mesh/generated/mcp_mesh_registry_client/models/llm_tool_info.py +0 -0
  97. {mcp_mesh-0.7.12 → mcp_mesh-0.7.13}/_mcp_mesh/generated/mcp_mesh_registry_client/models/llm_tool_resolution_info.py +0 -0
  98. {mcp_mesh-0.7.12 → mcp_mesh-0.7.13}/_mcp_mesh/generated/mcp_mesh_registry_client/models/mesh_agent_register_metadata.py +0 -0
  99. {mcp_mesh-0.7.12 → mcp_mesh-0.7.13}/_mcp_mesh/generated/mcp_mesh_registry_client/models/mesh_agent_registration.py +0 -0
  100. {mcp_mesh-0.7.12 → mcp_mesh-0.7.13}/_mcp_mesh/generated/mcp_mesh_registry_client/models/mesh_registration_response.py +0 -0
  101. {mcp_mesh-0.7.12 → mcp_mesh-0.7.13}/_mcp_mesh/generated/mcp_mesh_registry_client/models/mesh_registration_response_dependencies_resolved_value_inner.py +0 -0
  102. {mcp_mesh-0.7.12 → mcp_mesh-0.7.13}/_mcp_mesh/generated/mcp_mesh_registry_client/models/mesh_tool_dependency_registration.py +0 -0
  103. {mcp_mesh-0.7.12 → mcp_mesh-0.7.13}/_mcp_mesh/generated/mcp_mesh_registry_client/models/mesh_tool_register_metadata.py +0 -0
  104. {mcp_mesh-0.7.12 → mcp_mesh-0.7.13}/_mcp_mesh/generated/mcp_mesh_registry_client/models/mesh_tool_registration.py +0 -0
  105. {mcp_mesh-0.7.12 → mcp_mesh-0.7.13}/_mcp_mesh/generated/mcp_mesh_registry_client/models/registration_response.py +0 -0
  106. {mcp_mesh-0.7.12 → mcp_mesh-0.7.13}/_mcp_mesh/generated/mcp_mesh_registry_client/models/resolved_llm_provider.py +0 -0
  107. {mcp_mesh-0.7.12 → mcp_mesh-0.7.13}/_mcp_mesh/generated/mcp_mesh_registry_client/models/rich_dependency.py +0 -0
  108. {mcp_mesh-0.7.12 → mcp_mesh-0.7.13}/_mcp_mesh/generated/mcp_mesh_registry_client/models/root_response.py +0 -0
  109. {mcp_mesh-0.7.12 → mcp_mesh-0.7.13}/_mcp_mesh/generated/mcp_mesh_registry_client/models/standardized_dependency.py +0 -0
  110. {mcp_mesh-0.7.12 → mcp_mesh-0.7.13}/_mcp_mesh/generated/mcp_mesh_registry_client/models/trace_event.py +0 -0
  111. {mcp_mesh-0.7.12 → mcp_mesh-0.7.13}/_mcp_mesh/generated/mcp_mesh_registry_client/py.typed +0 -0
  112. {mcp_mesh-0.7.12 → mcp_mesh-0.7.13}/_mcp_mesh/generated/mcp_mesh_registry_client/rest.py +0 -0
  113. {mcp_mesh-0.7.12 → mcp_mesh-0.7.13}/_mcp_mesh/pipeline/__init__.py +0 -0
  114. {mcp_mesh-0.7.12 → mcp_mesh-0.7.13}/_mcp_mesh/pipeline/api_heartbeat/__init__.py +0 -0
  115. {mcp_mesh-0.7.12 → mcp_mesh-0.7.13}/_mcp_mesh/pipeline/api_heartbeat/api_health_check.py +0 -0
  116. {mcp_mesh-0.7.12 → mcp_mesh-0.7.13}/_mcp_mesh/pipeline/api_heartbeat/api_heartbeat_orchestrator.py +0 -0
  117. {mcp_mesh-0.7.12 → mcp_mesh-0.7.13}/_mcp_mesh/pipeline/api_heartbeat/api_heartbeat_send.py +0 -0
  118. {mcp_mesh-0.7.12 → mcp_mesh-0.7.13}/_mcp_mesh/pipeline/api_heartbeat/api_lifespan_integration.py +0 -0
  119. {mcp_mesh-0.7.12 → mcp_mesh-0.7.13}/_mcp_mesh/pipeline/api_heartbeat/api_registry_connection.py +0 -0
  120. {mcp_mesh-0.7.12 → mcp_mesh-0.7.13}/_mcp_mesh/pipeline/api_startup/__init__.py +0 -0
  121. {mcp_mesh-0.7.12 → mcp_mesh-0.7.13}/_mcp_mesh/pipeline/api_startup/api_pipeline.py +0 -0
  122. {mcp_mesh-0.7.12 → mcp_mesh-0.7.13}/_mcp_mesh/pipeline/api_startup/api_server_setup.py +0 -0
  123. {mcp_mesh-0.7.12 → mcp_mesh-0.7.13}/_mcp_mesh/pipeline/api_startup/fastapi_discovery.py +0 -0
  124. {mcp_mesh-0.7.12 → mcp_mesh-0.7.13}/_mcp_mesh/pipeline/api_startup/middleware_integration.py +0 -0
  125. {mcp_mesh-0.7.12 → mcp_mesh-0.7.13}/_mcp_mesh/pipeline/api_startup/route_collection.py +0 -0
  126. {mcp_mesh-0.7.12 → mcp_mesh-0.7.13}/_mcp_mesh/pipeline/api_startup/route_integration.py +0 -0
  127. {mcp_mesh-0.7.12 → mcp_mesh-0.7.13}/_mcp_mesh/pipeline/mcp_heartbeat/__init__.py +0 -0
  128. {mcp_mesh-0.7.12 → mcp_mesh-0.7.13}/_mcp_mesh/pipeline/mcp_heartbeat/lifespan_integration.py +0 -0
  129. {mcp_mesh-0.7.12 → mcp_mesh-0.7.13}/_mcp_mesh/pipeline/mcp_startup/__init__.py +0 -0
  130. {mcp_mesh-0.7.12 → mcp_mesh-0.7.13}/_mcp_mesh/pipeline/mcp_startup/configuration.py +0 -0
  131. {mcp_mesh-0.7.12 → mcp_mesh-0.7.13}/_mcp_mesh/pipeline/mcp_startup/decorator_collection.py +0 -0
  132. {mcp_mesh-0.7.12 → mcp_mesh-0.7.13}/_mcp_mesh/pipeline/mcp_startup/fastmcpserver_discovery.py +0 -0
  133. {mcp_mesh-0.7.12 → mcp_mesh-0.7.13}/_mcp_mesh/pipeline/mcp_startup/heartbeat_loop.py +0 -0
  134. {mcp_mesh-0.7.12 → mcp_mesh-0.7.13}/_mcp_mesh/pipeline/mcp_startup/heartbeat_preparation.py +0 -0
  135. {mcp_mesh-0.7.12 → mcp_mesh-0.7.13}/_mcp_mesh/pipeline/mcp_startup/server_discovery.py +0 -0
  136. {mcp_mesh-0.7.12 → mcp_mesh-0.7.13}/_mcp_mesh/pipeline/mcp_startup/startup_pipeline.py +0 -0
  137. {mcp_mesh-0.7.12 → mcp_mesh-0.7.13}/_mcp_mesh/pipeline/shared/__init__.py +0 -0
  138. {mcp_mesh-0.7.12 → mcp_mesh-0.7.13}/_mcp_mesh/pipeline/shared/base_step.py +0 -0
  139. {mcp_mesh-0.7.12 → mcp_mesh-0.7.13}/_mcp_mesh/pipeline/shared/mesh_pipeline.py +0 -0
  140. {mcp_mesh-0.7.12 → mcp_mesh-0.7.13}/_mcp_mesh/pipeline/shared/pipeline_types.py +0 -0
  141. {mcp_mesh-0.7.12 → mcp_mesh-0.7.13}/_mcp_mesh/shared/__init__.py +0 -0
  142. {mcp_mesh-0.7.12 → mcp_mesh-0.7.13}/_mcp_mesh/shared/config_resolver.py +0 -0
  143. {mcp_mesh-0.7.12 → mcp_mesh-0.7.13}/_mcp_mesh/shared/content_extractor.py +0 -0
  144. {mcp_mesh-0.7.12 → mcp_mesh-0.7.13}/_mcp_mesh/shared/defaults.py +0 -0
  145. {mcp_mesh-0.7.12 → mcp_mesh-0.7.13}/_mcp_mesh/shared/fast_heartbeat_status.py +0 -0
  146. {mcp_mesh-0.7.12 → mcp_mesh-0.7.13}/_mcp_mesh/shared/fastapi_middleware_manager.py +0 -0
  147. {mcp_mesh-0.7.12 → mcp_mesh-0.7.13}/_mcp_mesh/shared/host_resolver.py +0 -0
  148. {mcp_mesh-0.7.12 → mcp_mesh-0.7.13}/_mcp_mesh/shared/server_discovery.py +0 -0
  149. {mcp_mesh-0.7.12 → mcp_mesh-0.7.13}/_mcp_mesh/shared/simple_shutdown.py +0 -0
  150. {mcp_mesh-0.7.12 → mcp_mesh-0.7.13}/_mcp_mesh/shared/support_types.py +0 -0
  151. {mcp_mesh-0.7.12 → mcp_mesh-0.7.13}/_mcp_mesh/tracing/agent_context_helper.py +0 -0
  152. {mcp_mesh-0.7.12 → mcp_mesh-0.7.13}/_mcp_mesh/tracing/context.py +0 -0
  153. {mcp_mesh-0.7.12 → mcp_mesh-0.7.13}/_mcp_mesh/tracing/redis_metadata_publisher.py +0 -0
  154. {mcp_mesh-0.7.12 → mcp_mesh-0.7.13}/_mcp_mesh/tracing/utils.py +0 -0
  155. {mcp_mesh-0.7.12 → mcp_mesh-0.7.13}/_mcp_mesh/utils/fastmcp_schema_extractor.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mcp-mesh
3
- Version: 0.7.12
3
+ Version: 0.7.13
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
@@ -31,7 +31,7 @@ from .engine.decorator_registry import (
31
31
  get_decorator_stats,
32
32
  )
33
33
 
34
- __version__ = "0.7.12"
34
+ __version__ = "0.7.13"
35
35
 
36
36
  # Store reference to runtime processor if initialized
37
37
  _runtime_processor = None
@@ -17,13 +17,8 @@ __all__ = [
17
17
  # Dependency injection
18
18
  "DependencyInjector",
19
19
  "get_global_injector",
20
- # MCP client proxies (legacy)
21
- "MCPClientProxy",
22
- "EnhancedMCPClientProxy",
23
- "FullMCPProxy",
24
- "EnhancedFullMCPProxy",
20
+ # MCP client proxies
25
21
  "AsyncMCPClient",
26
- # Unified MCP proxy (recommended)
27
22
  "UnifiedMCPProxy",
28
23
  "EnhancedUnifiedMCPProxy",
29
24
  # Self-dependency proxy
@@ -59,22 +54,6 @@ def __getattr__(name):
59
54
 
60
55
  return get_global_injector
61
56
  # MCP client proxies
62
- elif name == "MCPClientProxy":
63
- from .mcp_client_proxy import MCPClientProxy
64
-
65
- return MCPClientProxy
66
- elif name == "EnhancedMCPClientProxy":
67
- from .mcp_client_proxy import EnhancedMCPClientProxy
68
-
69
- return EnhancedMCPClientProxy
70
- elif name == "FullMCPProxy":
71
- from .full_mcp_proxy import FullMCPProxy
72
-
73
- return FullMCPProxy
74
- elif name == "EnhancedFullMCPProxy":
75
- from .full_mcp_proxy import EnhancedFullMCPProxy
76
-
77
- return EnhancedFullMCPProxy
78
57
  elif name == "AsyncMCPClient":
79
58
  from .async_mcp_client import AsyncMCPClient
80
59
 
@@ -1,10 +1,12 @@
1
1
  """Async HTTP client for MCP JSON-RPC protocol."""
2
2
 
3
+ import asyncio
4
+ import atexit
3
5
  import json
4
6
  import logging
5
7
  import urllib.error
6
8
  import urllib.request
7
- from typing import Any
9
+ from typing import Any, ClassVar, Optional
8
10
 
9
11
  from ..shared.sse_parser import SSEParser
10
12
 
@@ -12,13 +14,67 @@ logger = logging.getLogger(__name__)
12
14
 
13
15
 
14
16
  class AsyncMCPClient:
15
- """Async HTTP client for MCP JSON-RPC protocol."""
17
+ """Async HTTP client for MCP JSON-RPC protocol.
18
+
19
+ Uses connection pooling to reuse HTTP connections across requests,
20
+ reducing TCP/SSL handshake overhead and preventing port exhaustion.
21
+ """
22
+
23
+ # Class-level connection pool (shared across instances for same endpoint)
24
+ _client_pool: ClassVar[dict[str, "httpx.AsyncClient"]] = {}
25
+ _pool_lock: ClassVar[Optional[asyncio.Lock]] = None
26
+
27
+ # Default connection limits for pooling
28
+ DEFAULT_MAX_CONNECTIONS = 100
29
+ DEFAULT_MAX_KEEPALIVE_CONNECTIONS = 20
16
30
 
17
31
  def __init__(self, endpoint: str, timeout: float = 30.0):
18
32
  self.endpoint = endpoint
19
33
  self.timeout = timeout
20
34
  self.logger = logger.getChild(f"client.{endpoint}")
21
35
 
36
+ @classmethod
37
+ def _get_lock(cls) -> asyncio.Lock:
38
+ """Get or create the class-level lock (handles event loop creation)."""
39
+ if cls._pool_lock is None:
40
+ cls._pool_lock = asyncio.Lock()
41
+ return cls._pool_lock
42
+
43
+ @classmethod
44
+ async def _get_pooled_client(
45
+ cls, endpoint: str, timeout: float
46
+ ) -> "httpx.AsyncClient":
47
+ """Get or create a pooled httpx client for the endpoint.
48
+
49
+ This enables connection reuse across multiple requests to the same endpoint,
50
+ significantly reducing overhead from TCP connection establishment and SSL handshakes.
51
+ """
52
+ import httpx
53
+
54
+ async with cls._get_lock():
55
+ if endpoint not in cls._client_pool:
56
+ cls._client_pool[endpoint] = httpx.AsyncClient(
57
+ timeout=timeout,
58
+ limits=httpx.Limits(
59
+ max_connections=cls.DEFAULT_MAX_CONNECTIONS,
60
+ max_keepalive_connections=cls.DEFAULT_MAX_KEEPALIVE_CONNECTIONS,
61
+ ),
62
+ )
63
+ logger.debug(f"Created pooled client for endpoint: {endpoint}")
64
+ return cls._client_pool[endpoint]
65
+
66
+ @classmethod
67
+ async def close_all_clients(cls) -> None:
68
+ """Close all pooled clients. Call during application shutdown."""
69
+ async with cls._get_lock():
70
+ for endpoint, client in list(cls._client_pool.items()):
71
+ try:
72
+ await client.aclose()
73
+ logger.debug(f"Closed pooled client for: {endpoint}")
74
+ except Exception as e:
75
+ logger.warning(f"Error closing client for {endpoint}: {e}")
76
+ cls._client_pool.clear()
77
+
22
78
  async def call_tool(self, tool_name: str, arguments: dict) -> Any:
23
79
  """Call remote tool using MCP JSON-RPC protocol."""
24
80
  payload = {
@@ -38,37 +94,39 @@ class AsyncMCPClient:
38
94
  raise
39
95
 
40
96
  async def _make_request(self, payload: dict) -> dict:
41
- """Make async HTTP request to MCP endpoint."""
97
+ """Make async HTTP request to MCP endpoint using pooled connections."""
42
98
  url = f"{self.endpoint}/mcp"
43
99
 
44
100
  try:
45
- # Use httpx for proper async HTTP requests (better threading support than aiohttp)
101
+ # Use httpx with connection pooling for better resource management
46
102
  import httpx
47
103
 
48
- async with httpx.AsyncClient(timeout=self.timeout) as client:
49
- response = await client.post(
50
- url,
51
- json=payload,
52
- headers={
53
- "Content-Type": "application/json",
54
- "Accept": "application/json, text/event-stream",
55
- },
56
- )
104
+ # Get pooled client (reuses connections across requests)
105
+ client = await self._get_pooled_client(self.endpoint, self.timeout)
57
106
 
58
- if response.status_code == 404:
59
- raise RuntimeError(f"MCP endpoint not found at {url}")
60
- elif response.status_code >= 400:
61
- raise RuntimeError(
62
- f"HTTP error {response.status_code}: {response.reason_phrase}"
63
- )
107
+ response = await client.post(
108
+ url,
109
+ json=payload,
110
+ headers={
111
+ "Content-Type": "application/json",
112
+ "Accept": "application/json, text/event-stream",
113
+ },
114
+ )
64
115
 
65
- response_text = response.text
66
-
67
- # Use shared SSE parser
68
- data = SSEParser.parse_sse_response(
69
- response_text, f"AsyncMCPClient.{self.endpoint}"
116
+ if response.status_code == 404:
117
+ raise RuntimeError(f"MCP endpoint not found at {url}")
118
+ elif response.status_code >= 400:
119
+ raise RuntimeError(
120
+ f"HTTP error {response.status_code}: {response.reason_phrase}"
70
121
  )
71
122
 
123
+ response_text = response.text
124
+
125
+ # Use shared SSE parser
126
+ data = SSEParser.parse_sse_response(
127
+ response_text, f"AsyncMCPClient.{self.endpoint}"
128
+ )
129
+
72
130
  # Check for JSON-RPC error
73
131
  if "error" in data:
74
132
  error = data["error"]
@@ -169,5 +227,10 @@ class AsyncMCPClient:
169
227
  return result
170
228
 
171
229
  async def close(self):
172
- """Close client (no persistent connection to close)."""
230
+ """Close client instance (no-op as connections are pooled at class level).
231
+
232
+ Connection pooling is managed at the class level for efficiency.
233
+ To close all pooled connections during shutdown, use:
234
+ await AsyncMCPClient.close_all_clients()
235
+ """
173
236
  pass
@@ -664,27 +664,28 @@ class DecoratorRegistry:
664
664
  cls._immediate_uvicorn_server = None
665
665
  logger.debug("🔄 REGISTRY: Cleared immediate uvicorn server reference")
666
666
 
667
- # Health check result storage
668
- _health_check_result: dict | None = None
667
+ # Health check result storage (delegated to health_check_manager)
669
668
 
670
669
  @classmethod
671
670
  def store_health_check_result(cls, result: dict) -> None:
672
671
  """Store health check result for /health endpoint."""
673
- cls._health_check_result = result
674
- logger.debug(
675
- f"💾 REGISTRY: Stored health check result: {result.get('status', 'unknown')}"
676
- )
672
+ from ..shared.health_check_manager import store_health_check_result
673
+
674
+ store_health_check_result(result)
677
675
 
678
676
  @classmethod
679
677
  def get_health_check_result(cls) -> dict | None:
680
678
  """Get stored health check result."""
681
- return cls._health_check_result
679
+ from ..shared.health_check_manager import get_health_check_result
680
+
681
+ return get_health_check_result()
682
682
 
683
683
  @classmethod
684
684
  def clear_health_check_result(cls) -> None:
685
685
  """Clear stored health check result."""
686
- cls._health_check_result = None
687
- logger.debug("🗑️ REGISTRY: Cleared health check result")
686
+ from ..shared.health_check_manager import clear_health_check_result
687
+
688
+ clear_health_check_result()
688
689
 
689
690
  @classmethod
690
691
  def store_fastmcp_lifespan(cls, lifespan: Any) -> None:
@@ -14,6 +14,11 @@ import weakref
14
14
  from collections.abc import Callable
15
15
  from typing import Any
16
16
 
17
+ from ..shared.logging_config import (
18
+ format_log_value,
19
+ format_result_summary,
20
+ get_trace_prefix,
21
+ )
17
22
  from .signature_analyzer import get_mesh_agent_positions, has_llm_agent_parameter
18
23
 
19
24
  logger = logging.getLogger(__name__)
@@ -448,17 +453,17 @@ class DependencyInjector:
448
453
 
449
454
  @functools.wraps(func)
450
455
  async def dependency_wrapper(*args, **kwargs):
456
+ # Get trace prefix if available
457
+ tp = get_trace_prefix()
458
+
459
+ # Log tool invocation - summary line
460
+ arg_keys = list(kwargs.keys()) if kwargs else []
451
461
  wrapper_logger.debug(
452
- f"🔧 DEPENDENCY_WRAPPER: Function {func.__name__} called"
453
- )
454
- wrapper_logger.debug(
455
- f"🔧 DEPENDENCY_WRAPPER: args={args}, kwargs={kwargs}"
456
- )
457
- wrapper_logger.debug(
458
- f"🔧 DEPENDENCY_WRAPPER: mesh_positions={mesh_positions}"
462
+ f"{tp}🔧 Tool '{func.__name__}' called with kwargs={arg_keys}"
459
463
  )
464
+ # Log full args (will be TRACE later)
460
465
  wrapper_logger.debug(
461
- f"🔧 DEPENDENCY_WRAPPER: dependencies={dependencies}"
466
+ f"{tp}🔧 Tool '{func.__name__}' args: {format_log_value(kwargs)}"
462
467
  )
463
468
 
464
469
  # We know mesh_positions is not empty since we checked above
@@ -468,20 +473,14 @@ class DependencyInjector:
468
473
  params = list(sig.parameters.keys())
469
474
  final_kwargs = kwargs.copy()
470
475
 
471
- wrapper_logger.debug(f"🔧 DEPENDENCY_WRAPPER: params={params}")
472
- wrapper_logger.debug(f"🔧 DEPENDENCY_WRAPPER: original kwargs={kwargs}")
473
-
474
476
  # Inject dependencies as kwargs (using array-based lookup)
475
477
  injected_count = 0
478
+ injected_deps = [] # Track what was injected for logging
476
479
  for dep_index, param_position in enumerate(mesh_positions):
477
480
  if dep_index < len(dependencies):
478
481
  dep_name = dependencies[dep_index]
479
482
  param_name = params[param_position]
480
483
 
481
- wrapper_logger.debug(
482
- f"🔧 DEPENDENCY_WRAPPER: Processing dep {dep_index}: {dep_name} -> {param_name}"
483
- )
484
-
485
484
  # Only inject if the parameter wasn't explicitly provided
486
485
  if (
487
486
  param_name not in final_kwargs
@@ -493,34 +492,25 @@ class DependencyInjector:
493
492
  dependency = dependency_wrapper._mesh_injected_deps[
494
493
  dep_index
495
494
  ]
496
- wrapper_logger.debug(
497
- f"🔧 DEPENDENCY_WRAPPER: From wrapper storage[{dep_index}]: {dependency}"
498
- )
499
495
 
500
496
  if dependency is None:
501
497
  # Fallback to global storage with composite key
502
498
  dep_key = f"{func.__module__}.{func.__qualname__}:dep_{dep_index}"
503
499
  dependency = self.get_dependency(dep_key)
504
- wrapper_logger.debug(
505
- f"🔧 DEPENDENCY_WRAPPER: From global storage[{dep_key}]: {dependency}"
506
- )
507
500
 
508
501
  final_kwargs[param_name] = dependency
509
502
  injected_count += 1
510
- wrapper_logger.debug(
511
- f"🔧 DEPENDENCY_WRAPPER: Injected {dep_name} from index {dep_index} as {param_name}"
512
- )
513
- else:
514
- wrapper_logger.debug(
515
- f"🔧 DEPENDENCY_WRAPPER: Skipping {param_name} - already provided"
503
+ # Track for consolidated logging
504
+ proxy_type = (
505
+ type(dependency).__name__ if dependency else "None"
516
506
  )
507
+ injected_deps.append(f"{dep_name} → {proxy_type}")
517
508
 
518
- wrapper_logger.debug(
519
- f"🔧 DEPENDENCY_WRAPPER: Injected {injected_count} dependencies"
520
- )
521
- wrapper_logger.debug(
522
- f"🔧 DEPENDENCY_WRAPPER: final_kwargs={final_kwargs}"
523
- )
509
+ # Log consolidated dependency injection summary
510
+ if injected_count > 0:
511
+ wrapper_logger.debug(
512
+ f"{tp}🔧 Injected {injected_count} dependencies: {', '.join(injected_deps)}"
513
+ )
524
514
 
525
515
  # ===== INJECT LLM AGENT IF PRESENT (Option A) =====
526
516
  # Check if this function has @mesh.llm metadata attached (on the original function)
@@ -534,7 +524,7 @@ class DependencyInjector:
534
524
  llm_agent = getattr(func, "_mesh_llm_agent", None)
535
525
  final_kwargs[llm_param] = llm_agent
536
526
  wrapper_logger.debug(
537
- f"🤖 LLM_INJECTION: Injected {llm_param}={llm_agent}"
527
+ f"{tp}🤖 LLM_INJECTION: Injected {llm_param}={llm_agent}"
538
528
  )
539
529
 
540
530
  # ===== EXECUTE WITH DEPENDENCY INJECTION AND TRACING =====
@@ -543,10 +533,6 @@ class DependencyInjector:
543
533
 
544
534
  original_func = func._mesh_original_func
545
535
 
546
- wrapper_logger.debug(
547
- f"🔧 DI: Executing async function {original_func.__name__} with {injected_count} injected dependencies"
548
- )
549
-
550
536
  # Use ExecutionTracer's async method for clean tracing
551
537
  result = await ExecutionTracer.trace_function_execution_async(
552
538
  original_func,
@@ -558,26 +544,32 @@ class DependencyInjector:
558
544
  wrapper_logger,
559
545
  )
560
546
 
547
+ # Log result - summary line
561
548
  wrapper_logger.debug(
562
- f"🔧 DI: Function {original_func.__name__} returned: {type(result)}"
549
+ f"{tp}🔧 Tool '{func.__name__}' returned: {format_result_summary(result)}"
563
550
  )
551
+ # Log full result (will be TRACE later)
552
+ wrapper_logger.debug(
553
+ f"{tp}🔧 Tool '{func.__name__}' result: {format_log_value(result)}"
554
+ )
555
+
564
556
  return result
565
557
 
566
558
  else:
567
559
  # Create sync wrapper for sync functions without dependencies
568
560
  @functools.wraps(func)
569
561
  def dependency_wrapper(*args, **kwargs):
562
+ # Get trace prefix if available
563
+ tp = get_trace_prefix()
564
+
565
+ # Log tool invocation - summary line
566
+ arg_keys = list(kwargs.keys()) if kwargs else []
570
567
  wrapper_logger.debug(
571
- f"🔧 DEPENDENCY_WRAPPER: Function {func.__name__} called"
572
- )
573
- wrapper_logger.debug(
574
- f"🔧 DEPENDENCY_WRAPPER: args={args}, kwargs={kwargs}"
575
- )
576
- wrapper_logger.debug(
577
- f"🔧 DEPENDENCY_WRAPPER: mesh_positions={mesh_positions}"
568
+ f"{tp}🔧 Tool '{func.__name__}' called with kwargs={arg_keys}"
578
569
  )
570
+ # Log full args (will be TRACE later)
579
571
  wrapper_logger.debug(
580
- f"🔧 DEPENDENCY_WRAPPER: dependencies={dependencies}"
572
+ f"{tp}🔧 Tool '{func.__name__}' args: {format_log_value(kwargs)}"
581
573
  )
582
574
 
583
575
  # We know mesh_positions is not empty since we checked above
@@ -589,6 +581,7 @@ class DependencyInjector:
589
581
 
590
582
  # Inject dependencies as kwargs (using array-based lookup)
591
583
  injected_count = 0
584
+ injected_deps = [] # Track what was injected for logging
592
585
  for dep_index, param_position in enumerate(mesh_positions):
593
586
  if dep_index < len(dependencies):
594
587
  dep_name = dependencies[dep_index]
@@ -613,6 +606,17 @@ class DependencyInjector:
613
606
 
614
607
  final_kwargs[param_name] = dependency
615
608
  injected_count += 1
609
+ # Track for consolidated logging
610
+ proxy_type = (
611
+ type(dependency).__name__ if dependency else "None"
612
+ )
613
+ injected_deps.append(f"{dep_name} → {proxy_type}")
614
+
615
+ # Log consolidated dependency injection summary
616
+ if injected_count > 0:
617
+ wrapper_logger.debug(
618
+ f"{tp}🔧 Injected {injected_count} dependencies: {', '.join(injected_deps)}"
619
+ )
616
620
 
617
621
  # ===== INJECT LLM AGENT IF PRESENT (Option A) =====
618
622
  # Check if this function has @mesh.llm metadata attached (on the original function)
@@ -626,19 +630,15 @@ class DependencyInjector:
626
630
  llm_agent = getattr(func, "_mesh_llm_agent", None)
627
631
  final_kwargs[llm_param] = llm_agent
628
632
  wrapper_logger.debug(
629
- f"🤖 LLM_INJECTION: Injected {llm_param}={llm_agent}"
633
+ f"{tp}🤖 LLM_INJECTION: Injected {llm_param}={llm_agent}"
630
634
  )
631
635
 
632
636
  # ===== EXECUTE WITH DEPENDENCY INJECTION AND TRACING =====
633
637
  # Use ExecutionTracer for comprehensive execution logging (v0.4.0 style)
634
638
  from ..tracing.execution_tracer import ExecutionTracer
635
639
 
636
- wrapper_logger.debug(
637
- f"🔧 DI: Executing sync function {func._mesh_original_func.__name__} with {injected_count} injected dependencies"
638
- )
639
-
640
640
  # Use ExecutionTracer for clean execution tracing
641
- return ExecutionTracer.trace_function_execution(
641
+ result = ExecutionTracer.trace_function_execution(
642
642
  func._mesh_original_func,
643
643
  args,
644
644
  final_kwargs,
@@ -648,6 +648,17 @@ class DependencyInjector:
648
648
  wrapper_logger,
649
649
  )
650
650
 
651
+ # Log result - summary line
652
+ wrapper_logger.debug(
653
+ f"{tp}🔧 Tool '{func.__name__}' returned: {format_result_summary(result)}"
654
+ )
655
+ # Log full result (will be TRACE later)
656
+ wrapper_logger.debug(
657
+ f"{tp}🔧 Tool '{func.__name__}' result: {format_log_value(result)}"
658
+ )
659
+
660
+ return result
661
+
651
662
  # Store dependency state on wrapper as array (indexed by position)
652
663
  dependency_wrapper._mesh_injected_deps = [None] * len(dependencies)
653
664