mcp-mesh 0.7.14__py3-none-any.whl → 0.7.15__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.
- _mcp_mesh/__init__.py +1 -1
- _mcp_mesh/engine/unified_mcp_proxy.py +56 -27
- {mcp_mesh-0.7.14.dist-info → mcp_mesh-0.7.15.dist-info}/METADATA +1 -1
- {mcp_mesh-0.7.14.dist-info → mcp_mesh-0.7.15.dist-info}/RECORD +6 -6
- {mcp_mesh-0.7.14.dist-info → mcp_mesh-0.7.15.dist-info}/WHEEL +0 -0
- {mcp_mesh-0.7.14.dist-info → mcp_mesh-0.7.15.dist-info}/licenses/LICENSE +0 -0
_mcp_mesh/__init__.py
CHANGED
|
@@ -80,16 +80,17 @@ class UnifiedMCPProxy:
|
|
|
80
80
|
return False
|
|
81
81
|
|
|
82
82
|
def _create_fastmcp_client(self, endpoint: str):
|
|
83
|
-
"""Create FastMCP client with
|
|
83
|
+
"""Create FastMCP client with dynamic trace header injection.
|
|
84
84
|
|
|
85
|
-
|
|
86
|
-
|
|
85
|
+
Uses httpx event_hooks to inject trace headers at REQUEST TIME rather than
|
|
86
|
+
at transport construction time. This ensures the current trace context is
|
|
87
|
+
captured when the HTTP request is actually made, fixing the trace hierarchy bug.
|
|
87
88
|
|
|
88
89
|
Args:
|
|
89
90
|
endpoint: MCP endpoint URL
|
|
90
91
|
|
|
91
92
|
Returns:
|
|
92
|
-
FastMCP Client instance with
|
|
93
|
+
FastMCP Client instance with dynamic trace header injection
|
|
93
94
|
"""
|
|
94
95
|
try:
|
|
95
96
|
# Extract hostname from endpoint URL for DNS detection
|
|
@@ -101,42 +102,70 @@ class UnifiedMCPProxy:
|
|
|
101
102
|
# DNS resolution works perfectly with FastMCP - no need to force HTTP fallback
|
|
102
103
|
self.logger.debug(f"✅ Using FastMCP client for endpoint: {hostname}")
|
|
103
104
|
|
|
105
|
+
# Use stream_timeout for read timeout (default 300s for LLM calls)
|
|
106
|
+
import httpx
|
|
104
107
|
from fastmcp import Client
|
|
105
108
|
from fastmcp.client.transports import StreamableHttpTransport
|
|
106
109
|
|
|
107
|
-
#
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
# Use stream_timeout for read timeout (default 300s for LLM calls)
|
|
111
|
-
# Note: sse_read_timeout is deprecated, use httpx_client_factory instead
|
|
112
|
-
import httpx
|
|
110
|
+
# Capture self for use in nested function
|
|
111
|
+
proxy_instance = self
|
|
113
112
|
|
|
114
113
|
def create_httpx_client(**kwargs):
|
|
114
|
+
"""Create httpx client with dynamic trace header injection via event hooks."""
|
|
115
|
+
|
|
116
|
+
def inject_trace_headers_hook(request: httpx.Request) -> None:
|
|
117
|
+
"""Inject trace headers at REQUEST TIME for correct context propagation.
|
|
118
|
+
|
|
119
|
+
This hook runs just before each HTTP request is sent, capturing the
|
|
120
|
+
current trace context at that moment. This fixes the trace hierarchy
|
|
121
|
+
bug where headers were captured at client creation time instead.
|
|
122
|
+
"""
|
|
123
|
+
try:
|
|
124
|
+
from ..tracing.context import TraceContext
|
|
125
|
+
from ..tracing.utils import is_tracing_enabled
|
|
126
|
+
|
|
127
|
+
if not is_tracing_enabled():
|
|
128
|
+
return
|
|
129
|
+
|
|
130
|
+
trace_context = TraceContext.get_current()
|
|
131
|
+
if trace_context:
|
|
132
|
+
request.headers["X-Trace-ID"] = trace_context.trace_id
|
|
133
|
+
request.headers["X-Parent-Span"] = trace_context.span_id
|
|
134
|
+
proxy_instance.logger.trace(
|
|
135
|
+
f"🔗 TRACE_HOOK: Injecting at request time - "
|
|
136
|
+
f"trace_id={trace_context.trace_id[:8]}... "
|
|
137
|
+
f"parent_span={trace_context.span_id[:8]}..."
|
|
138
|
+
)
|
|
139
|
+
except Exception as e:
|
|
140
|
+
# Never fail HTTP requests due to tracing issues
|
|
141
|
+
proxy_instance.logger.trace(
|
|
142
|
+
f"🔗 TRACE_HOOK: Failed to inject headers: {e}"
|
|
143
|
+
)
|
|
144
|
+
|
|
115
145
|
# Override timeout to use stream_timeout for long-running LLM calls
|
|
116
146
|
kwargs["timeout"] = httpx.Timeout(
|
|
117
|
-
timeout=
|
|
147
|
+
timeout=proxy_instance.stream_timeout,
|
|
118
148
|
connect=30.0, # 30s for connection
|
|
119
|
-
read=
|
|
149
|
+
read=proxy_instance.stream_timeout, # Long read timeout for SSE streams
|
|
120
150
|
write=30.0, # 30s for writes
|
|
121
151
|
pool=30.0, # 30s for pool
|
|
122
152
|
)
|
|
153
|
+
|
|
154
|
+
# Add event hook for dynamic trace header injection
|
|
155
|
+
existing_hooks = kwargs.get("event_hooks", {})
|
|
156
|
+
request_hooks = existing_hooks.get("request", [])
|
|
157
|
+
request_hooks.append(inject_trace_headers_hook)
|
|
158
|
+
existing_hooks["request"] = request_hooks
|
|
159
|
+
kwargs["event_hooks"] = existing_hooks
|
|
160
|
+
|
|
123
161
|
return httpx.AsyncClient(**kwargs)
|
|
124
162
|
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
)
|
|
132
|
-
return Client(transport)
|
|
133
|
-
else:
|
|
134
|
-
# Create standard client when no trace context available
|
|
135
|
-
transport = StreamableHttpTransport(
|
|
136
|
-
url=endpoint,
|
|
137
|
-
httpx_client_factory=create_httpx_client,
|
|
138
|
-
)
|
|
139
|
-
return Client(transport)
|
|
163
|
+
# Create client WITHOUT static headers - headers injected via hook at request time
|
|
164
|
+
transport = StreamableHttpTransport(
|
|
165
|
+
url=endpoint,
|
|
166
|
+
httpx_client_factory=create_httpx_client,
|
|
167
|
+
)
|
|
168
|
+
return Client(transport)
|
|
140
169
|
|
|
141
170
|
except ImportError as e:
|
|
142
171
|
# DNS names or FastMCP not available - this will trigger HTTP fallback
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: mcp-mesh
|
|
3
|
-
Version: 0.7.
|
|
3
|
+
Version: 0.7.15
|
|
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
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
_mcp_mesh/__init__.py,sha256
|
|
1
|
+
_mcp_mesh/__init__.py,sha256=xx8r72WkHqUhfJc2KwE6aOwUNPw5F5OuDJs4znH8B3g,2720
|
|
2
2
|
_mcp_mesh/engine/__init__.py,sha256=U_6Kw3vA_3RiNK0Oln5c5C7WvA9lSONV22wWzfxYHNw,2975
|
|
3
3
|
_mcp_mesh/engine/async_mcp_client.py,sha256=Sz-rXTkb1Mng_f0SpLqLuOdPJ8vZjv3DFy0i8yYOqYk,8792
|
|
4
4
|
_mcp_mesh/engine/base_injector.py,sha256=qzRLZqFP2VvEFagVovkpdldvDmm3VwPHm6tHwV58a2k,5648
|
|
@@ -16,7 +16,7 @@ _mcp_mesh/engine/session_manager.py,sha256=MCr0_fXBaUjXM51WU5EhDkiGvBdfzYQFVNb9D
|
|
|
16
16
|
_mcp_mesh/engine/signature_analyzer.py,sha256=ftn9XsX0ZHWIaACdjgBVtCuIdqVU_4ST8cvcpzu4HTk,12339
|
|
17
17
|
_mcp_mesh/engine/tool_executor.py,sha256=Bf_9d02EEY9_yHm1p1-5YZ4rY6MPxn4SVpI6-3sm1uo,5456
|
|
18
18
|
_mcp_mesh/engine/tool_schema_builder.py,sha256=SQCxQIrSfdLu9-dLqiFurQLK7dhl0dc0xa0ibaxU-iE,3644
|
|
19
|
-
_mcp_mesh/engine/unified_mcp_proxy.py,sha256=
|
|
19
|
+
_mcp_mesh/engine/unified_mcp_proxy.py,sha256=4Zi2jGu16B7ObJ3YymD4gsUHdWdbmtX2hc0srUVTfsc,38175
|
|
20
20
|
_mcp_mesh/engine/provider_handlers/__init__.py,sha256=LLTCOgnuM3dlogbLmrpiMK3oB5L22eAmDC4BfxJ-L2I,593
|
|
21
21
|
_mcp_mesh/engine/provider_handlers/base_provider_handler.py,sha256=J-SPFFFG1eFSUVvfsv7y4EuNM4REjSxaYWC5E_lC6Pc,4195
|
|
22
22
|
_mcp_mesh/engine/provider_handlers/claude_handler.py,sha256=CCmlsWiCfIcgrLbAZzeSnl0g2pq0uDffT8zOj4F-sPQ,15727
|
|
@@ -144,7 +144,7 @@ mesh/__init__.py,sha256=Va5XRBWgejQurad7Maz3E-zPY7vu431B2_4sAdCu1zk,3868
|
|
|
144
144
|
mesh/decorators.py,sha256=v0l_0oAS_UZBQLC1WwhJQTil9AvGMCFL9kYS-N7febk,59627
|
|
145
145
|
mesh/helpers.py,sha256=ITua2zdxbXeBLF5qS46A6A1P2GQNbfL_2_BMCKazQ4U,12575
|
|
146
146
|
mesh/types.py,sha256=n0MxrBYZJ84xyQWGf_X2ZbVWSAaIcEBkRV7qaCmX6Ac,17008
|
|
147
|
-
mcp_mesh-0.7.
|
|
148
|
-
mcp_mesh-0.7.
|
|
149
|
-
mcp_mesh-0.7.
|
|
150
|
-
mcp_mesh-0.7.
|
|
147
|
+
mcp_mesh-0.7.15.dist-info/METADATA,sha256=pV9YaeDfY1G07nCjfD-s24ggiQcKZ3-9zk75uev9VAc,4973
|
|
148
|
+
mcp_mesh-0.7.15.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
|
|
149
|
+
mcp_mesh-0.7.15.dist-info/licenses/LICENSE,sha256=_EBQHRQThv9FPOLc5eFOUdeeRO0mYwChC7cx60dM1tM,1078
|
|
150
|
+
mcp_mesh-0.7.15.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|