mcp-mesh 0.7.21__py3-none-any.whl → 0.8.0b1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (121) hide show
  1. _mcp_mesh/__init__.py +1 -1
  2. _mcp_mesh/engine/dependency_injector.py +4 -6
  3. _mcp_mesh/engine/http_wrapper.py +69 -10
  4. _mcp_mesh/engine/mesh_llm_agent.py +4 -7
  5. _mcp_mesh/engine/mesh_llm_agent_injector.py +2 -1
  6. _mcp_mesh/engine/provider_handlers/__init__.py +14 -1
  7. _mcp_mesh/engine/provider_handlers/base_provider_handler.py +114 -8
  8. _mcp_mesh/engine/provider_handlers/claude_handler.py +15 -57
  9. _mcp_mesh/engine/provider_handlers/gemini_handler.py +181 -0
  10. _mcp_mesh/engine/provider_handlers/openai_handler.py +8 -63
  11. _mcp_mesh/engine/provider_handlers/provider_handler_registry.py +16 -10
  12. _mcp_mesh/engine/response_parser.py +61 -15
  13. _mcp_mesh/engine/unified_mcp_proxy.py +18 -34
  14. _mcp_mesh/pipeline/__init__.py +9 -20
  15. _mcp_mesh/pipeline/api_heartbeat/__init__.py +12 -7
  16. _mcp_mesh/pipeline/api_heartbeat/api_lifespan_integration.py +23 -49
  17. _mcp_mesh/pipeline/api_heartbeat/rust_api_heartbeat.py +425 -0
  18. _mcp_mesh/pipeline/api_startup/api_pipeline.py +7 -9
  19. _mcp_mesh/pipeline/api_startup/api_server_setup.py +91 -70
  20. _mcp_mesh/pipeline/api_startup/fastapi_discovery.py +22 -23
  21. _mcp_mesh/pipeline/api_startup/middleware_integration.py +32 -24
  22. _mcp_mesh/pipeline/api_startup/route_collection.py +2 -4
  23. _mcp_mesh/pipeline/mcp_heartbeat/__init__.py +5 -17
  24. _mcp_mesh/pipeline/mcp_heartbeat/rust_heartbeat.py +695 -0
  25. _mcp_mesh/pipeline/mcp_startup/__init__.py +2 -5
  26. _mcp_mesh/pipeline/mcp_startup/configuration.py +1 -1
  27. _mcp_mesh/pipeline/mcp_startup/fastapiserver_setup.py +5 -6
  28. _mcp_mesh/pipeline/mcp_startup/heartbeat_loop.py +6 -7
  29. _mcp_mesh/pipeline/mcp_startup/startup_orchestrator.py +21 -9
  30. _mcp_mesh/pipeline/mcp_startup/startup_pipeline.py +3 -8
  31. _mcp_mesh/pipeline/shared/mesh_pipeline.py +0 -2
  32. _mcp_mesh/reload.py +1 -3
  33. _mcp_mesh/shared/__init__.py +2 -8
  34. _mcp_mesh/shared/config_resolver.py +124 -80
  35. _mcp_mesh/shared/defaults.py +89 -14
  36. _mcp_mesh/shared/fastapi_middleware_manager.py +149 -91
  37. _mcp_mesh/shared/host_resolver.py +8 -46
  38. _mcp_mesh/shared/server_discovery.py +115 -86
  39. _mcp_mesh/shared/simple_shutdown.py +44 -86
  40. _mcp_mesh/tracing/execution_tracer.py +2 -6
  41. _mcp_mesh/tracing/redis_metadata_publisher.py +24 -79
  42. _mcp_mesh/tracing/trace_context_helper.py +3 -13
  43. _mcp_mesh/tracing/utils.py +29 -15
  44. _mcp_mesh/utils/fastmcp_schema_extractor.py +2 -1
  45. {mcp_mesh-0.7.21.dist-info → mcp_mesh-0.8.0b1.dist-info}/METADATA +2 -1
  46. mcp_mesh-0.8.0b1.dist-info/RECORD +85 -0
  47. mesh/__init__.py +2 -1
  48. mesh/decorators.py +89 -5
  49. _mcp_mesh/generated/.openapi-generator/FILES +0 -50
  50. _mcp_mesh/generated/.openapi-generator/VERSION +0 -1
  51. _mcp_mesh/generated/.openapi-generator-ignore +0 -15
  52. _mcp_mesh/generated/mcp_mesh_registry_client/__init__.py +0 -90
  53. _mcp_mesh/generated/mcp_mesh_registry_client/api/__init__.py +0 -6
  54. _mcp_mesh/generated/mcp_mesh_registry_client/api/agents_api.py +0 -1088
  55. _mcp_mesh/generated/mcp_mesh_registry_client/api/health_api.py +0 -764
  56. _mcp_mesh/generated/mcp_mesh_registry_client/api/tracing_api.py +0 -303
  57. _mcp_mesh/generated/mcp_mesh_registry_client/api_client.py +0 -798
  58. _mcp_mesh/generated/mcp_mesh_registry_client/api_response.py +0 -21
  59. _mcp_mesh/generated/mcp_mesh_registry_client/configuration.py +0 -577
  60. _mcp_mesh/generated/mcp_mesh_registry_client/exceptions.py +0 -217
  61. _mcp_mesh/generated/mcp_mesh_registry_client/models/__init__.py +0 -55
  62. _mcp_mesh/generated/mcp_mesh_registry_client/models/agent_info.py +0 -158
  63. _mcp_mesh/generated/mcp_mesh_registry_client/models/agent_metadata.py +0 -126
  64. _mcp_mesh/generated/mcp_mesh_registry_client/models/agent_metadata_dependencies_inner.py +0 -139
  65. _mcp_mesh/generated/mcp_mesh_registry_client/models/agent_metadata_dependencies_inner_one_of.py +0 -92
  66. _mcp_mesh/generated/mcp_mesh_registry_client/models/agent_registration.py +0 -103
  67. _mcp_mesh/generated/mcp_mesh_registry_client/models/agent_registration_metadata.py +0 -136
  68. _mcp_mesh/generated/mcp_mesh_registry_client/models/agents_list_response.py +0 -100
  69. _mcp_mesh/generated/mcp_mesh_registry_client/models/capability_info.py +0 -107
  70. _mcp_mesh/generated/mcp_mesh_registry_client/models/decorator_agent_metadata.py +0 -112
  71. _mcp_mesh/generated/mcp_mesh_registry_client/models/decorator_agent_request.py +0 -103
  72. _mcp_mesh/generated/mcp_mesh_registry_client/models/decorator_info.py +0 -105
  73. _mcp_mesh/generated/mcp_mesh_registry_client/models/dependency_info.py +0 -103
  74. _mcp_mesh/generated/mcp_mesh_registry_client/models/dependency_resolution_info.py +0 -106
  75. _mcp_mesh/generated/mcp_mesh_registry_client/models/error_response.py +0 -91
  76. _mcp_mesh/generated/mcp_mesh_registry_client/models/health_response.py +0 -103
  77. _mcp_mesh/generated/mcp_mesh_registry_client/models/heartbeat_request.py +0 -101
  78. _mcp_mesh/generated/mcp_mesh_registry_client/models/heartbeat_request_metadata.py +0 -111
  79. _mcp_mesh/generated/mcp_mesh_registry_client/models/heartbeat_response.py +0 -117
  80. _mcp_mesh/generated/mcp_mesh_registry_client/models/llm_provider.py +0 -93
  81. _mcp_mesh/generated/mcp_mesh_registry_client/models/llm_provider_resolution_info.py +0 -106
  82. _mcp_mesh/generated/mcp_mesh_registry_client/models/llm_tool_filter.py +0 -109
  83. _mcp_mesh/generated/mcp_mesh_registry_client/models/llm_tool_filter_filter_inner.py +0 -139
  84. _mcp_mesh/generated/mcp_mesh_registry_client/models/llm_tool_filter_filter_inner_one_of.py +0 -91
  85. _mcp_mesh/generated/mcp_mesh_registry_client/models/llm_tool_info.py +0 -101
  86. _mcp_mesh/generated/mcp_mesh_registry_client/models/llm_tool_resolution_info.py +0 -120
  87. _mcp_mesh/generated/mcp_mesh_registry_client/models/mesh_agent_register_metadata.py +0 -112
  88. _mcp_mesh/generated/mcp_mesh_registry_client/models/mesh_agent_registration.py +0 -129
  89. _mcp_mesh/generated/mcp_mesh_registry_client/models/mesh_registration_response.py +0 -153
  90. _mcp_mesh/generated/mcp_mesh_registry_client/models/mesh_registration_response_dependencies_resolved_value_inner.py +0 -101
  91. _mcp_mesh/generated/mcp_mesh_registry_client/models/mesh_tool_dependency_registration.py +0 -93
  92. _mcp_mesh/generated/mcp_mesh_registry_client/models/mesh_tool_register_metadata.py +0 -107
  93. _mcp_mesh/generated/mcp_mesh_registry_client/models/mesh_tool_registration.py +0 -117
  94. _mcp_mesh/generated/mcp_mesh_registry_client/models/registration_response.py +0 -119
  95. _mcp_mesh/generated/mcp_mesh_registry_client/models/resolved_llm_provider.py +0 -110
  96. _mcp_mesh/generated/mcp_mesh_registry_client/models/rich_dependency.py +0 -93
  97. _mcp_mesh/generated/mcp_mesh_registry_client/models/root_response.py +0 -92
  98. _mcp_mesh/generated/mcp_mesh_registry_client/models/standardized_dependency.py +0 -93
  99. _mcp_mesh/generated/mcp_mesh_registry_client/models/trace_event.py +0 -106
  100. _mcp_mesh/generated/mcp_mesh_registry_client/py.typed +0 -0
  101. _mcp_mesh/generated/mcp_mesh_registry_client/rest.py +0 -259
  102. _mcp_mesh/pipeline/api_heartbeat/api_dependency_resolution.py +0 -418
  103. _mcp_mesh/pipeline/api_heartbeat/api_fast_heartbeat_check.py +0 -117
  104. _mcp_mesh/pipeline/api_heartbeat/api_health_check.py +0 -140
  105. _mcp_mesh/pipeline/api_heartbeat/api_heartbeat_orchestrator.py +0 -243
  106. _mcp_mesh/pipeline/api_heartbeat/api_heartbeat_pipeline.py +0 -311
  107. _mcp_mesh/pipeline/api_heartbeat/api_heartbeat_send.py +0 -386
  108. _mcp_mesh/pipeline/api_heartbeat/api_registry_connection.py +0 -104
  109. _mcp_mesh/pipeline/mcp_heartbeat/dependency_resolution.py +0 -396
  110. _mcp_mesh/pipeline/mcp_heartbeat/fast_heartbeat_check.py +0 -116
  111. _mcp_mesh/pipeline/mcp_heartbeat/heartbeat_orchestrator.py +0 -311
  112. _mcp_mesh/pipeline/mcp_heartbeat/heartbeat_pipeline.py +0 -282
  113. _mcp_mesh/pipeline/mcp_heartbeat/heartbeat_send.py +0 -98
  114. _mcp_mesh/pipeline/mcp_heartbeat/lifespan_integration.py +0 -84
  115. _mcp_mesh/pipeline/mcp_heartbeat/llm_tools_resolution.py +0 -264
  116. _mcp_mesh/pipeline/mcp_heartbeat/registry_connection.py +0 -79
  117. _mcp_mesh/pipeline/shared/registry_connection.py +0 -80
  118. _mcp_mesh/shared/registry_client_wrapper.py +0 -515
  119. mcp_mesh-0.7.21.dist-info/RECORD +0 -152
  120. {mcp_mesh-0.7.21.dist-info → mcp_mesh-0.8.0b1.dist-info}/WHEEL +0 -0
  121. {mcp_mesh-0.7.21.dist-info → mcp_mesh-0.8.0b1.dist-info}/licenses/LICENSE +0 -0
@@ -2,93 +2,55 @@
2
2
  Redis Trace Publisher
3
3
 
4
4
  Publishes execution trace data to Redis streams for distributed tracing storage and analysis.
5
- Based on the session storage pattern from http_wrapper.py.
5
+ Uses Rust core for Redis publishing to share implementation across all language SDKs.
6
6
  """
7
7
 
8
8
  import logging
9
- import os
10
9
  from typing import Any, Optional
11
10
 
12
- logger = logging.getLogger(__name__)
13
-
14
- try:
15
- import redis
11
+ import mcp_mesh_core
16
12
 
17
- REDIS_AVAILABLE = True
18
- except ImportError:
19
- REDIS_AVAILABLE = False
20
- redis = None
13
+ logger = logging.getLogger(__name__)
21
14
 
22
15
 
23
16
  class RedisTracePublisher:
24
- """Non-blocking execution trace publisher to Redis."""
17
+ """Non-blocking execution trace publisher to Redis via Rust core."""
25
18
 
26
- def __init__(self, redis_url: Optional[str] = None):
27
- # Use existing REDIS_URL pattern from MCP Mesh
28
- self.redis_url = redis_url or os.getenv("REDIS_URL", "redis://localhost:6379")
19
+ def __init__(self):
29
20
  self.stream_name = "mesh:trace"
30
- self._redis_client = None
31
21
  self._available = False
32
- self._tracing_enabled = self._is_tracing_enabled()
33
-
34
- if not REDIS_AVAILABLE:
35
- logger.warning("redis not available. Execution metadata storage disabled.")
36
- self._available = False
22
+ self._tracing_enabled = mcp_mesh_core.is_tracing_enabled_py()
23
+
24
+ if self._tracing_enabled:
25
+ logger.info("Distributed tracing: enabled")
26
+ # Initialize Rust core trace publisher (handles Redis connection)
27
+ self._available = mcp_mesh_core.init_trace_publisher_py()
28
+ if not self._available:
29
+ logger.warning("Rust core trace publisher initialization failed")
37
30
  else:
38
- self._init_redis()
39
-
40
- def _is_tracing_enabled(self) -> bool:
41
- """Check if distributed tracing is enabled via environment variable."""
42
- from .utils import is_tracing_enabled
43
-
44
- return is_tracing_enabled()
45
-
46
- def _init_redis(self):
47
- """Initialize Redis connection with graceful fallback (following session storage pattern)."""
48
- if not self._tracing_enabled:
49
- self._available = False
50
- return
51
-
52
- logger.info("Distributed tracing: enabled")
53
-
54
- if not REDIS_AVAILABLE:
55
- self._available = False
56
- return
57
-
58
- try:
59
- # Use sync Redis client like session storage (no atexit issues)
60
- self._redis_client = redis.from_url(self.redis_url, decode_responses=True)
61
-
62
- # Test connection
63
- self._redis_client.ping()
64
- self._available = True
65
- except Exception as e:
66
- # Graceful fallback - metadata storage disabled if Redis unavailable
67
- self._available = False
31
+ logger.debug("Distributed tracing: disabled")
68
32
 
69
33
  def publish_execution_trace(self, trace_data: dict[str, Any]) -> None:
70
- """Publish execution trace data to Redis Stream (non-blocking)."""
34
+ """Publish execution trace data to Redis Stream via Rust core (non-blocking)."""
71
35
  if not self._available:
72
36
  return # Silent no-op when Redis unavailable
73
37
 
74
38
  try:
75
- function_name = trace_data.get("function_name", "unknown")
76
- trace_id = trace_data.get("trace_id", "no-trace-id")
77
-
78
- # Add timestamp and convert for Redis storage
39
+ # Convert trace data to strings for Redis storage
79
40
  from .utils import add_timestamp_if_missing, convert_for_redis_storage
80
41
 
81
42
  add_timestamp_if_missing(trace_data)
82
43
  redis_trace_data = convert_for_redis_storage(trace_data)
83
44
 
84
- # Publish to Redis Stream
85
- if self._redis_client:
86
- message_id = self._redis_client.xadd(self.stream_name, redis_trace_data)
87
- logger.debug(f"Published trace for '{function_name}' to Redis stream")
45
+ # Publish via Rust core
46
+ mcp_mesh_core.publish_span_py(redis_trace_data)
47
+ logger.debug(
48
+ f"Published trace for '{trace_data.get('function_name', 'unknown')}' via Rust core"
49
+ )
88
50
 
89
51
  except Exception as e:
90
52
  # Non-blocking - never fail agent operations due to trace publishing
91
- pass
53
+ logger.debug(f"Failed to publish trace: {e}")
92
54
 
93
55
  @property
94
56
  def is_available(self) -> bool:
@@ -102,30 +64,13 @@ class RedisTracePublisher:
102
64
 
103
65
  def get_stats(self) -> dict[str, Any]:
104
66
  """Get Redis trace publisher statistics."""
105
- stats = {
67
+ return {
106
68
  "redis_available": self._available,
107
69
  "tracing_enabled": self._tracing_enabled,
108
70
  "stream_name": self.stream_name,
109
- "redis_url": (
110
- self.redis_url.replace("redis:/", "redis://***")
111
- if self.redis_url
112
- else None
113
- ),
71
+ "backend": "rust_core",
114
72
  }
115
73
 
116
- if self._available and self._redis_client:
117
- try:
118
- # Get approximate stream length
119
- stream_info = self._redis_client.xinfo_stream(self.stream_name)
120
- stats["stream_length"] = stream_info.get("length", 0)
121
- stats["stream_last_generated_id"] = stream_info.get(
122
- "last-generated-id", "N/A"
123
- )
124
- except Exception as e:
125
- stats["stream_error"] = str(e)
126
-
127
- return stats
128
-
129
74
 
130
75
  # Global instance for reuse
131
76
  _trace_publisher: Optional[RedisTracePublisher] = None
@@ -67,19 +67,9 @@ class TraceContextHelper:
67
67
  or "", # Use parent as current (will be overwritten by ExecutionTracer)
68
68
  parent_span=None, # No grandparent needed at this level
69
69
  )
70
- else:
71
- # NEW ROOT TRACE: This service is the entry point (no incoming trace headers)
72
- from .utils import generate_span_id, generate_trace_id
73
-
74
- root_trace_id = generate_trace_id()
75
- root_span_id = generate_span_id()
76
-
77
- # Set context for root trace (no parent_span)
78
- TraceContext.set_current(
79
- trace_id=root_trace_id,
80
- span_id=root_span_id,
81
- parent_span=None, # Root trace has no parent
82
- )
70
+ # else: Don't generate root trace here - let ExecutionTracer do it
71
+ # This prevents orphan parent_span values when middleware context doesn't
72
+ # propagate to FastMCP's async context
83
73
 
84
74
  except Exception as e:
85
75
  logger_instance.warning(f"Failed to setup trace context: {e}")
@@ -7,44 +7,58 @@ and maintain consistency.
7
7
 
8
8
  import json
9
9
  import logging
10
- import os
11
10
  import time
12
11
  import uuid
13
- from typing import Any, Optional
12
+ from typing import Any
14
13
 
15
14
  logger = logging.getLogger(__name__)
16
15
 
16
+ # Try to import the Rust core module for tracing
17
+ # Falls back gracefully if not available
18
+ try:
19
+ import mcp_mesh_core
20
+
21
+ _RUST_CORE_AVAILABLE = True
22
+ except ImportError:
23
+ mcp_mesh_core = None # type: ignore[assignment]
24
+ _RUST_CORE_AVAILABLE = False
25
+ logger.warning(
26
+ "mcp_mesh_core not available - tracing features will be disabled. "
27
+ "Build/install mcp-mesh-core for full functionality."
28
+ )
29
+
17
30
 
18
31
  def is_tracing_enabled() -> bool:
19
- """Check if distributed tracing is enabled via environment variable.
32
+ """Check if distributed tracing is enabled via Rust core config resolution.
33
+
34
+ Delegates to mcp_mesh_core.is_tracing_enabled_py() for consistent behavior
35
+ across all language SDKs. Priority: ENV > param > default (false)
20
36
 
21
37
  Returns:
22
38
  True if tracing is enabled, False otherwise
23
39
  """
24
- return os.getenv("MCP_MESH_DISTRIBUTED_TRACING_ENABLED", "false").lower() in (
25
- "true",
26
- "1",
27
- "yes",
28
- "on",
29
- )
40
+ if not _RUST_CORE_AVAILABLE or mcp_mesh_core is None:
41
+ return False
42
+
43
+ return mcp_mesh_core.is_tracing_enabled_py()
30
44
 
31
45
 
32
46
  def generate_span_id() -> str:
33
- """Generate a unique span ID for tracing.
47
+ """Generate a unique span ID for tracing (OpenTelemetry compliant).
34
48
 
35
49
  Returns:
36
- UUID string for span identification
50
+ 16-character hex string (64-bit span ID per OTel spec)
37
51
  """
38
- return str(uuid.uuid4())
52
+ return uuid.uuid4().hex[:16]
39
53
 
40
54
 
41
55
  def generate_trace_id() -> str:
42
- """Generate a unique trace ID for tracing.
56
+ """Generate a unique trace ID for tracing (OpenTelemetry compliant).
43
57
 
44
58
  Returns:
45
- UUID string for trace identification
59
+ 32-character hex string (128-bit trace ID per OTel spec)
46
60
  """
47
- return str(uuid.uuid4())
61
+ return uuid.uuid4().hex
48
62
 
49
63
 
50
64
  def get_agent_metadata_with_fallback(logger_instance: logging.Logger) -> dict[str, Any]:
@@ -274,7 +274,8 @@ class FastMCPSchemaExtractor:
274
274
  return schema
275
275
 
276
276
  # Get McpMeshAgent parameter names from signature analysis
277
- from _mcp_mesh.engine.signature_analyzer import get_mesh_agent_parameter_names
277
+ from _mcp_mesh.engine.signature_analyzer import \
278
+ get_mesh_agent_parameter_names
278
279
 
279
280
  mesh_param_names = get_mesh_agent_parameter_names(function)
280
281
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mcp-mesh
3
- Version: 0.7.21
3
+ Version: 0.8.0b1
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
@@ -30,6 +30,7 @@ Requires-Dist: fastmcp<3.0.0,>=2.8.0
30
30
  Requires-Dist: httpx<1.0.0,>=0.25.0
31
31
  Requires-Dist: jinja2>=3.1.0
32
32
  Requires-Dist: litellm>=1.30.0
33
+ Requires-Dist: mcp-mesh-core>=0.8.0b1
33
34
  Requires-Dist: mcp<2.0.0,>=1.9.0
34
35
  Requires-Dist: prometheus-client<1.0.0,>=0.19.0
35
36
  Requires-Dist: pydantic<3.0.0,>=2.4.0
@@ -0,0 +1,85 @@
1
+ _mcp_mesh/__init__.py,sha256=Hmsj3lCnO9-6rV8hN5SVUNdzKWxdXIsO-WcGCvbt1dw,2721
2
+ _mcp_mesh/reload.py,sha256=5Yll9n0bqxM7pmTjfAaKWg-WT_Vi0YTh0_UNWbCNCIQ,6217
3
+ _mcp_mesh/reload_runner.py,sha256=SgQKzzO2yHfSUBq8s3SpAnovWA0rveimVNaxeLCEo_0,1310
4
+ _mcp_mesh/engine/__init__.py,sha256=U_6Kw3vA_3RiNK0Oln5c5C7WvA9lSONV22wWzfxYHNw,2975
5
+ _mcp_mesh/engine/async_mcp_client.py,sha256=Sz-rXTkb1Mng_f0SpLqLuOdPJ8vZjv3DFy0i8yYOqYk,8792
6
+ _mcp_mesh/engine/base_injector.py,sha256=qzRLZqFP2VvEFagVovkpdldvDmm3VwPHm6tHwV58a2k,5648
7
+ _mcp_mesh/engine/decorator_registry.py,sha256=cch2QdQ6bKjHKEGi1XWp1YcLLO3uI2YlxwWBO7Np65E,28229
8
+ _mcp_mesh/engine/dependency_injector.py,sha256=-CeIGvB-zqrGxkRpFE53C6_zEmmBoyBXftvE-H9OyAY,31593
9
+ _mcp_mesh/engine/http_wrapper.py,sha256=Simd6IEsLO2FXQOuf1WEx57SBN6DSr5RzphXnk0asHM,24152
10
+ _mcp_mesh/engine/llm_config.py,sha256=95bOsGWro5E1JGq7oZtEYhVdrzcIJqjht_r5vEdJVz4,2049
11
+ _mcp_mesh/engine/llm_errors.py,sha256=h7BiI14u-jL8vtvBfFbFDDrN7gIw8PQjXIl5AP1SBuA,3276
12
+ _mcp_mesh/engine/mesh_llm_agent.py,sha256=sVh7lPnvixDVJ-p1ONzbeakiEzhsl0HmdmrLPZA2FzQ,34237
13
+ _mcp_mesh/engine/mesh_llm_agent_injector.py,sha256=Y6KkqqUAyP7QsCU2DDX_UIg9RhF4xu9p731jbfMMN-A,28373
14
+ _mcp_mesh/engine/response_parser.py,sha256=g3VNoFJotaLrOAS0pL_OTCrv9t9XQe9Iiz1plsm28bQ,10280
15
+ _mcp_mesh/engine/self_dependency_proxy.py,sha256=OkKt0-B_ADnJlWtHiHItoZCBZ7Su0iz2unEPFfXvrs4,3302
16
+ _mcp_mesh/engine/session_aware_client.py,sha256=QejKag5zYNos5BVffQvNXFMECHFMLNOv78By4e_JzQE,10589
17
+ _mcp_mesh/engine/session_manager.py,sha256=MCr0_fXBaUjXM51WU5EhDkiGvBdfzYQFVNb9DCXXL0A,10418
18
+ _mcp_mesh/engine/signature_analyzer.py,sha256=ftn9XsX0ZHWIaACdjgBVtCuIdqVU_4ST8cvcpzu4HTk,12339
19
+ _mcp_mesh/engine/tool_executor.py,sha256=Bf_9d02EEY9_yHm1p1-5YZ4rY6MPxn4SVpI6-3sm1uo,5456
20
+ _mcp_mesh/engine/tool_schema_builder.py,sha256=SQCxQIrSfdLu9-dLqiFurQLK7dhl0dc0xa0ibaxU-iE,3644
21
+ _mcp_mesh/engine/unified_mcp_proxy.py,sha256=Ee11K5HXuPXvdjqB7fmv0sMEo9ML-SMtQx2EUtYpfrY,37847
22
+ _mcp_mesh/engine/provider_handlers/__init__.py,sha256=8hEc4CheKfXWU3ny4YDktxNxLCWxgfMtyDW9CblPOvs,888
23
+ _mcp_mesh/engine/provider_handlers/base_provider_handler.py,sha256=Lb0U6gAEseU7Ix1eeV4T0WP1ClmeXUz87Nx_iplUYSI,8077
24
+ _mcp_mesh/engine/provider_handlers/claude_handler.py,sha256=iYAmllL5rTWFFTAjbR62Ra9eMWNZjA72a02tppxjgOQ,14343
25
+ _mcp_mesh/engine/provider_handlers/gemini_handler.py,sha256=SrJuhlaoPPHGRQH4jFXR1C_M0FtKeFcvJHERkpIPRNA,6055
26
+ _mcp_mesh/engine/provider_handlers/generic_handler.py,sha256=rAE3QzoB7vz4zbBPPDJTI0MOuJrfhrOdXSyzsob4uVI,5489
27
+ _mcp_mesh/engine/provider_handlers/openai_handler.py,sha256=1WhiHqf72N3584tJDVaBonDmu64tPuuiP12vzPrUNO0,6204
28
+ _mcp_mesh/engine/provider_handlers/provider_handler_registry.py,sha256=klBZW8iX6Jk88TASAUyP8oPo4wvLB3DaTNFHeYvGLiA,5708
29
+ _mcp_mesh/pipeline/__init__.py,sha256=MgPwpwbiD62ND4HXKKNGcnreDk-TvPmQOs5WmjtHQ3M,1263
30
+ _mcp_mesh/pipeline/api_heartbeat/__init__.py,sha256=qGjEgxbGJFSl9Qm3bwu3X5yizAMbN4WpFtIUekDSFuU,690
31
+ _mcp_mesh/pipeline/api_heartbeat/api_lifespan_integration.py,sha256=h0mTmLyPlGDqomSHpbW7S-AZNz1Tyvg1kpy9aeWkQsU,3879
32
+ _mcp_mesh/pipeline/api_heartbeat/rust_api_heartbeat.py,sha256=vrld873jS2zCfJCndldx2XLDjxp_bRY7qq9CNBqZ8wI,15579
33
+ _mcp_mesh/pipeline/api_startup/__init__.py,sha256=eivolkSKot2bJTWP2BV8-RKRT1Zm7SGQYuEUiTxusOQ,577
34
+ _mcp_mesh/pipeline/api_startup/api_pipeline.py,sha256=I9-Q0o2py5oAHZO2DJOeTD1uZo1-Dpn258k5Tr0dv9o,2474
35
+ _mcp_mesh/pipeline/api_startup/api_server_setup.py,sha256=72oCMkCzRfxYrE5sfFJbr57BYJwRSyKxBMISTOHmKyc,14919
36
+ _mcp_mesh/pipeline/api_startup/fastapi_discovery.py,sha256=B-JeZTj2KZ17Sutyw31mpISlBMSF8-5ClV7W5SOPdXg,5606
37
+ _mcp_mesh/pipeline/api_startup/middleware_integration.py,sha256=J7Ux_nJ1VsMqVzl5ApmtlixjUpJV09rtvU4YZ-aiXFk,6241
38
+ _mcp_mesh/pipeline/api_startup/route_collection.py,sha256=WPr4hRPLIWnNIJCoRHZ141ph9tAa_-Pm_j2TiCuWS4k,2002
39
+ _mcp_mesh/pipeline/api_startup/route_integration.py,sha256=qq1AVaWna-CWEXyehyDL3EyeYKgo5aMtei8uBNdvkZ8,12448
40
+ _mcp_mesh/pipeline/mcp_heartbeat/__init__.py,sha256=mhDcSquoHkhRItqgbM8iFfAKC2m7qMW_0smqtUgSl-w,389
41
+ _mcp_mesh/pipeline/mcp_heartbeat/rust_heartbeat.py,sha256=cB7IO0au3097MGpC6JwvYtPt4cVnl_spCkHfJIgD6Ks,25953
42
+ _mcp_mesh/pipeline/mcp_startup/__init__.py,sha256=qy960dnAoHLXMcL_y_rcro9Km2AoCVzC7_CxMwao564,1166
43
+ _mcp_mesh/pipeline/mcp_startup/configuration.py,sha256=OnumIPRVBTne2OEU2VWLZovLKvWcNF9iJVQtlVwuim0,2805
44
+ _mcp_mesh/pipeline/mcp_startup/decorator_collection.py,sha256=RHC6MHtfP9aP0hZ-IJjISZu72e0Pml3LU0qr7dc284w,2294
45
+ _mcp_mesh/pipeline/mcp_startup/fastapiserver_setup.py,sha256=y0xsM6no-yH9OhiYjg0LJN4hTW0vw15iuVK_4DNMxFQ,34032
46
+ _mcp_mesh/pipeline/mcp_startup/fastmcpserver_discovery.py,sha256=Pm24wrSuRGsgeUrHvMPDnNh6RhIZoznnMAUwAkllohk,10661
47
+ _mcp_mesh/pipeline/mcp_startup/heartbeat_loop.py,sha256=4Fgp0_68tlSicyLHkJGB-41Av0jl5sqUeriuu-StNJU,3812
48
+ _mcp_mesh/pipeline/mcp_startup/heartbeat_preparation.py,sha256=sOpzxRc0kYiXwSW9lvv8DSjliT85oZCWPODeJRuiqgg,15635
49
+ _mcp_mesh/pipeline/mcp_startup/lifespan_factory.py,sha256=Hu7IvrhVH9sM7-XQDyWAGA3rgOnNIRyWFBtobkUQ5Es,4404
50
+ _mcp_mesh/pipeline/mcp_startup/server_discovery.py,sha256=VuqqaBE00h6AerPjk-Ab-g51x6jODCbMX4nemLRQIIQ,8375
51
+ _mcp_mesh/pipeline/mcp_startup/startup_orchestrator.py,sha256=bo2LeQlIsktbMFfYhX3xlnjAGT9Yj7wG96JYVT5nsyw,25893
52
+ _mcp_mesh/pipeline/mcp_startup/startup_pipeline.py,sha256=56lZzuCo23y3bZkDir05Ip9QlZ7uzt_gbOR32V4tAvo,2350
53
+ _mcp_mesh/pipeline/shared/__init__.py,sha256=s9xmdf6LkoetrVRGd7Zp3NUxcJCW6YZ_yNKzUBcnYys,352
54
+ _mcp_mesh/pipeline/shared/base_step.py,sha256=kyPbNUX79NyGrE_0Q-e-Aek7m1J0TW036njWfv0iZ0I,1080
55
+ _mcp_mesh/pipeline/shared/mesh_pipeline.py,sha256=Lt_Qo46vhIcLR6xcvG0zGZiCvJED1Z1rBoOkZhHgQjk,6496
56
+ _mcp_mesh/pipeline/shared/pipeline_types.py,sha256=iKSgzCoYu3bpIwLViw6lE7T7irEzOm7gpie29lyy7SQ,1504
57
+ _mcp_mesh/shared/__init__.py,sha256=1hDV83TUDjCbgGepMsyf85kzHG1YV25vIvldOITANDo,959
58
+ _mcp_mesh/shared/config_resolver.py,sha256=c6KI4DdpAhIrvuUrw60Of7V4ocA7R6aQB-vkSZSodwc,9708
59
+ _mcp_mesh/shared/content_extractor.py,sha256=culjhieFl_J6EMDv1VFKvS38O3IMhWMs8fHhNuR2rVk,3656
60
+ _mcp_mesh/shared/defaults.py,sha256=DueUHUwHV_FVUwPuuvViJtekyHSpxjqNpoBh9Q7w1mM,4480
61
+ _mcp_mesh/shared/fast_heartbeat_status.py,sha256=OquEsX9ZTbxY1lIsll0Mbb2KDzSJD76sLMOlr3Z73Sc,5188
62
+ _mcp_mesh/shared/fastapi_middleware_manager.py,sha256=LT0Auo2FaCkeSSofFKrZPrYo4XtfYL6ed3CkhcBxSDQ,15513
63
+ _mcp_mesh/shared/health_check_manager.py,sha256=xZjQp-mWdPD64djp06nU5fN-fqi3Q_cIc1PAwMQTRBY,10362
64
+ _mcp_mesh/shared/host_resolver.py,sha256=0BtVSWBDa4ziBB4gieKaf4WJvfqOOGxL32QyE7vy5uE,1617
65
+ _mcp_mesh/shared/logging_config.py,sha256=hf3DCEMDN2WwEaETK721iQkFxX9TENNGmF9H1QhVSls,9076
66
+ _mcp_mesh/shared/server_discovery.py,sha256=Bt6IqU5wHNCjzMiOikMLEI87Id_OMI_F1rsvfzzl0pc,13219
67
+ _mcp_mesh/shared/simple_shutdown.py,sha256=R8jKLasfyx1tuE-UnSUiRHZvDdwONDN9qU97YySnF_I,6634
68
+ _mcp_mesh/shared/sse_parser.py,sha256=1NgnTMr4LQ-tW_cKJYj2oY0B5KDNskNeGlE23LcTOVk,8128
69
+ _mcp_mesh/shared/support_types.py,sha256=k-ICF_UwDkHxQ1D5LwFZrp-UrNb4E5dzw02CRuLW9iI,7264
70
+ _mcp_mesh/tracing/agent_context_helper.py,sha256=BIJ3Kc4Znd6emMAu97aUhSoxSIza3qYUmObLgc9ONiA,4765
71
+ _mcp_mesh/tracing/context.py,sha256=2ozqKEYfx4Qxj64DnbwoVIbMkhNLbaV8BNWtkzAPA7I,2516
72
+ _mcp_mesh/tracing/execution_tracer.py,sha256=dvM6QSbxk5s5rZZsCgVNaXWrr2J4_5I6XAfI1aM0sSA,10268
73
+ _mcp_mesh/tracing/fastapi_tracing_middleware.py,sha256=FXjhA1A1Krk-ngyuOZPc1Ic4Llggv4Wide9OuPmkwCY,6959
74
+ _mcp_mesh/tracing/redis_metadata_publisher.py,sha256=DeFrMt0ZX7k6393dH-xoRS2V5apPR-k80X8ZjrKBHMU,2890
75
+ _mcp_mesh/tracing/trace_context_helper.py,sha256=A0UipvDExePaX-E-4SAp4M8n8uwed9PMo8gibXt1v_Q,6513
76
+ _mcp_mesh/tracing/utils.py,sha256=GWwfvab0tYGr9QAe_zgZjZxgDKTTs0p5Mf8w6WJeWC0,4486
77
+ _mcp_mesh/utils/fastmcp_schema_extractor.py,sha256=NOz3dht21JRKVb_kCTrUhT2MZMmZJz04G6ARcNatVzk,17267
78
+ mesh/__init__.py,sha256=NDQXXD7uuL8Ph48w-Xf7ntEUx5HkB1oZMu3hjGdntTY,3890
79
+ mesh/decorators.py,sha256=sflOWhuJooqIs1tH7DqjOEaGMaVRj4GEDz7R3IQ4fPM,65163
80
+ mesh/helpers.py,sha256=1Y7V6aQvpV8BKfEeeKfjwPJ5g9FjMCzSNifs3se1jkA,12935
81
+ mesh/types.py,sha256=n0MxrBYZJ84xyQWGf_X2ZbVWSAaIcEBkRV7qaCmX6Ac,17008
82
+ mcp_mesh-0.8.0b1.dist-info/METADATA,sha256=uBP_kKN1LJer1-DiU3hwyYvMwO6JJI6BgPjvNZifVwA,5045
83
+ mcp_mesh-0.8.0b1.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
84
+ mcp_mesh-0.8.0b1.dist-info/licenses/LICENSE,sha256=_EBQHRQThv9FPOLc5eFOUdeeRO0mYwChC7cx60dM1tM,1078
85
+ mcp_mesh-0.8.0b1.dist-info/RECORD,,
mesh/__init__.py CHANGED
@@ -19,7 +19,8 @@ Use 'import mesh' and then '@mesh.tool()' for consistency with MCP patterns.
19
19
  """
20
20
 
21
21
  from . import decorators
22
- from .types import LlmMeta, McpMeshAgent, MeshContextModel, MeshLlmAgent, MeshLlmRequest
22
+ from .types import (LlmMeta, McpMeshAgent, MeshContextModel, MeshLlmAgent,
23
+ MeshLlmRequest)
23
24
 
24
25
  # Note: helpers.llm_provider is imported lazily in __getattr__ to avoid
25
26
  # initialization timing issues with @mesh.agent auto_run in tests
mesh/decorators.py CHANGED
@@ -90,9 +90,10 @@ def _start_uvicorn_immediately(http_host: str, http_port: int):
90
90
  """Pure ASGI middleware for trace context and header injection.
91
91
 
92
92
  This middleware:
93
- 1. Extracts trace context from incoming request headers
94
- 2. Sets up trace context for the request lifecycle
95
- 3. Injects trace headers into the response (works with SSE)
93
+ 1. Extracts trace context from incoming request headers AND arguments
94
+ 2. Strips trace fields (_trace_id, _parent_span) from arguments to avoid validation errors
95
+ 3. Sets up trace context for the request lifecycle
96
+ 4. Injects trace headers into the response (works with SSE)
96
97
  """
97
98
 
98
99
  def __init__(self, app):
@@ -127,7 +128,7 @@ def _start_uvicorn_immediately(http_host: str, http_port: int):
127
128
  headers_list, "x-parent-span"
128
129
  )
129
130
 
130
- # Setup trace context
131
+ # Setup trace context from headers
131
132
  trace_context = {
132
133
  "trace_id": (
133
134
  incoming_trace_id if incoming_trace_id else None
@@ -151,6 +152,87 @@ def _start_uvicorn_immediately(http_host: str, http_port: int):
151
152
  except Exception as e:
152
153
  logger.warning(f"Failed to set trace context: {e}")
153
154
 
155
+ # Create body-modifying receive wrapper to strip trace fields from arguments
156
+ # This handles the case where trace context is passed in JSON-RPC arguments
157
+ import json as json_module
158
+
159
+ async def receive_with_trace_stripping():
160
+ message = await receive()
161
+ if message["type"] == "http.request":
162
+ body = message.get("body", b"")
163
+ if body:
164
+ try:
165
+ payload = json_module.loads(
166
+ body.decode("utf-8")
167
+ )
168
+ if payload.get("method") == "tools/call":
169
+ arguments = payload.get("params", {}).get(
170
+ "arguments", {}
171
+ )
172
+
173
+ # Extract trace context from arguments if not in headers
174
+ nonlocal trace_id, span_id, parent_span
175
+ if not trace_id and arguments.get(
176
+ "_trace_id"
177
+ ):
178
+ try:
179
+ from _mcp_mesh.tracing.context import (
180
+ TraceContext,
181
+ )
182
+ from _mcp_mesh.tracing.trace_context_helper import (
183
+ TraceContextHelper,
184
+ )
185
+
186
+ arg_trace_id = arguments.get(
187
+ "_trace_id"
188
+ )
189
+ arg_parent_span = arguments.get(
190
+ "_parent_span"
191
+ )
192
+ trace_context = {
193
+ "trace_id": arg_trace_id,
194
+ "parent_span": arg_parent_span,
195
+ }
196
+ TraceContextHelper.setup_request_trace_context(
197
+ trace_context, logger
198
+ )
199
+ current_trace = (
200
+ TraceContext.get_current()
201
+ )
202
+ if current_trace:
203
+ trace_id = (
204
+ current_trace.trace_id
205
+ )
206
+ span_id = current_trace.span_id
207
+ parent_span = (
208
+ current_trace.parent_span
209
+ )
210
+ except Exception:
211
+ pass
212
+
213
+ # Strip trace context fields from arguments
214
+ if (
215
+ "_trace_id" in arguments
216
+ or "_parent_span" in arguments
217
+ ):
218
+ arguments.pop("_trace_id", None)
219
+ arguments.pop("_parent_span", None)
220
+ modified_body = json_module.dumps(
221
+ payload
222
+ ).encode("utf-8")
223
+ logger.debug(
224
+ "[TRACE] Stripped trace fields from arguments"
225
+ )
226
+ return {
227
+ **message,
228
+ "body": modified_body,
229
+ }
230
+ except Exception as e:
231
+ logger.debug(
232
+ f"[TRACE] Failed to process body: {e}"
233
+ )
234
+ return message
235
+
154
236
  # Wrap send to inject headers before response starts
155
237
  async def send_with_trace_headers(message):
156
238
  if message["type"] == "http.response.start" and trace_id:
@@ -166,7 +248,9 @@ def _start_uvicorn_immediately(http_host: str, http_port: int):
166
248
  message = {**message, "headers": headers}
167
249
  await send(message)
168
250
 
169
- await self.app(scope, receive, send_with_trace_headers)
251
+ await self.app(
252
+ scope, receive_with_trace_stripping, send_with_trace_headers
253
+ )
170
254
 
171
255
  app.add_middleware(TraceContextMiddleware)
172
256
  logger.debug(
@@ -1,50 +0,0 @@
1
- mcp_mesh_registry_client/__init__.py
2
- mcp_mesh_registry_client/api/__init__.py
3
- mcp_mesh_registry_client/api/agents_api.py
4
- mcp_mesh_registry_client/api/health_api.py
5
- mcp_mesh_registry_client/api/tracing_api.py
6
- mcp_mesh_registry_client/api_client.py
7
- mcp_mesh_registry_client/api_response.py
8
- mcp_mesh_registry_client/configuration.py
9
- mcp_mesh_registry_client/exceptions.py
10
- mcp_mesh_registry_client/models/__init__.py
11
- mcp_mesh_registry_client/models/agent_info.py
12
- mcp_mesh_registry_client/models/agent_metadata.py
13
- mcp_mesh_registry_client/models/agent_metadata_dependencies_inner.py
14
- mcp_mesh_registry_client/models/agent_metadata_dependencies_inner_one_of.py
15
- mcp_mesh_registry_client/models/agent_registration.py
16
- mcp_mesh_registry_client/models/agent_registration_metadata.py
17
- mcp_mesh_registry_client/models/agents_list_response.py
18
- mcp_mesh_registry_client/models/capability_info.py
19
- mcp_mesh_registry_client/models/decorator_agent_metadata.py
20
- mcp_mesh_registry_client/models/decorator_agent_request.py
21
- mcp_mesh_registry_client/models/decorator_info.py
22
- mcp_mesh_registry_client/models/dependency_info.py
23
- mcp_mesh_registry_client/models/dependency_resolution_info.py
24
- mcp_mesh_registry_client/models/error_response.py
25
- mcp_mesh_registry_client/models/health_response.py
26
- mcp_mesh_registry_client/models/heartbeat_request.py
27
- mcp_mesh_registry_client/models/heartbeat_request_metadata.py
28
- mcp_mesh_registry_client/models/heartbeat_response.py
29
- mcp_mesh_registry_client/models/llm_provider.py
30
- mcp_mesh_registry_client/models/llm_provider_resolution_info.py
31
- mcp_mesh_registry_client/models/llm_tool_filter.py
32
- mcp_mesh_registry_client/models/llm_tool_filter_filter_inner.py
33
- mcp_mesh_registry_client/models/llm_tool_filter_filter_inner_one_of.py
34
- mcp_mesh_registry_client/models/llm_tool_info.py
35
- mcp_mesh_registry_client/models/llm_tool_resolution_info.py
36
- mcp_mesh_registry_client/models/mesh_agent_register_metadata.py
37
- mcp_mesh_registry_client/models/mesh_agent_registration.py
38
- mcp_mesh_registry_client/models/mesh_registration_response.py
39
- mcp_mesh_registry_client/models/mesh_registration_response_dependencies_resolved_value_inner.py
40
- mcp_mesh_registry_client/models/mesh_tool_dependency_registration.py
41
- mcp_mesh_registry_client/models/mesh_tool_register_metadata.py
42
- mcp_mesh_registry_client/models/mesh_tool_registration.py
43
- mcp_mesh_registry_client/models/registration_response.py
44
- mcp_mesh_registry_client/models/resolved_llm_provider.py
45
- mcp_mesh_registry_client/models/rich_dependency.py
46
- mcp_mesh_registry_client/models/root_response.py
47
- mcp_mesh_registry_client/models/standardized_dependency.py
48
- mcp_mesh_registry_client/models/trace_event.py
49
- mcp_mesh_registry_client/py.typed
50
- mcp_mesh_registry_client/rest.py
@@ -1 +0,0 @@
1
- 7.13.0
@@ -1,15 +0,0 @@
1
- # Skip packaging files - we use this as part of our main package
2
- pyproject.toml
3
- setup.py
4
- setup.cfg
5
- requirements.txt
6
- test-requirements.txt
7
- README.md
8
- tox.ini
9
- .travis.yml
10
- .gitlab-ci.yml
11
- .github/
12
- git_push.sh
13
- .gitignore
14
- test/
15
- docs/