mcp-mesh 0.7.21__py3-none-any.whl → 0.8.0__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/dependency_injector.py +13 -15
- _mcp_mesh/engine/http_wrapper.py +69 -10
- _mcp_mesh/engine/mesh_llm_agent.py +29 -10
- _mcp_mesh/engine/mesh_llm_agent_injector.py +77 -41
- _mcp_mesh/engine/provider_handlers/__init__.py +14 -1
- _mcp_mesh/engine/provider_handlers/base_provider_handler.py +114 -8
- _mcp_mesh/engine/provider_handlers/claude_handler.py +15 -57
- _mcp_mesh/engine/provider_handlers/gemini_handler.py +181 -0
- _mcp_mesh/engine/provider_handlers/openai_handler.py +8 -63
- _mcp_mesh/engine/provider_handlers/provider_handler_registry.py +16 -10
- _mcp_mesh/engine/response_parser.py +61 -15
- _mcp_mesh/engine/signature_analyzer.py +58 -68
- _mcp_mesh/engine/unified_mcp_proxy.py +19 -35
- _mcp_mesh/pipeline/__init__.py +9 -20
- _mcp_mesh/pipeline/api_heartbeat/__init__.py +12 -7
- _mcp_mesh/pipeline/api_heartbeat/api_lifespan_integration.py +23 -49
- _mcp_mesh/pipeline/api_heartbeat/rust_api_heartbeat.py +429 -0
- _mcp_mesh/pipeline/api_startup/api_pipeline.py +7 -9
- _mcp_mesh/pipeline/api_startup/api_server_setup.py +91 -70
- _mcp_mesh/pipeline/api_startup/fastapi_discovery.py +22 -23
- _mcp_mesh/pipeline/api_startup/middleware_integration.py +32 -24
- _mcp_mesh/pipeline/api_startup/route_collection.py +2 -4
- _mcp_mesh/pipeline/mcp_heartbeat/__init__.py +5 -17
- _mcp_mesh/pipeline/mcp_heartbeat/rust_heartbeat.py +710 -0
- _mcp_mesh/pipeline/mcp_startup/__init__.py +2 -5
- _mcp_mesh/pipeline/mcp_startup/configuration.py +1 -1
- _mcp_mesh/pipeline/mcp_startup/fastapiserver_setup.py +31 -8
- _mcp_mesh/pipeline/mcp_startup/heartbeat_loop.py +6 -7
- _mcp_mesh/pipeline/mcp_startup/startup_orchestrator.py +23 -11
- _mcp_mesh/pipeline/mcp_startup/startup_pipeline.py +3 -8
- _mcp_mesh/pipeline/shared/mesh_pipeline.py +0 -2
- _mcp_mesh/reload.py +1 -3
- _mcp_mesh/shared/__init__.py +2 -8
- _mcp_mesh/shared/config_resolver.py +124 -80
- _mcp_mesh/shared/defaults.py +89 -14
- _mcp_mesh/shared/fastapi_middleware_manager.py +149 -91
- _mcp_mesh/shared/host_resolver.py +8 -46
- _mcp_mesh/shared/server_discovery.py +115 -86
- _mcp_mesh/shared/simple_shutdown.py +44 -86
- _mcp_mesh/tracing/execution_tracer.py +2 -6
- _mcp_mesh/tracing/redis_metadata_publisher.py +24 -79
- _mcp_mesh/tracing/trace_context_helper.py +3 -13
- _mcp_mesh/tracing/utils.py +29 -15
- _mcp_mesh/utils/fastmcp_schema_extractor.py +5 -4
- {mcp_mesh-0.7.21.dist-info → mcp_mesh-0.8.0.dist-info}/METADATA +7 -5
- mcp_mesh-0.8.0.dist-info/RECORD +85 -0
- mesh/__init__.py +12 -1
- mesh/decorators.py +248 -33
- mesh/helpers.py +52 -0
- mesh/types.py +40 -13
- _mcp_mesh/generated/.openapi-generator/FILES +0 -50
- _mcp_mesh/generated/.openapi-generator/VERSION +0 -1
- _mcp_mesh/generated/.openapi-generator-ignore +0 -15
- _mcp_mesh/generated/mcp_mesh_registry_client/__init__.py +0 -90
- _mcp_mesh/generated/mcp_mesh_registry_client/api/__init__.py +0 -6
- _mcp_mesh/generated/mcp_mesh_registry_client/api/agents_api.py +0 -1088
- _mcp_mesh/generated/mcp_mesh_registry_client/api/health_api.py +0 -764
- _mcp_mesh/generated/mcp_mesh_registry_client/api/tracing_api.py +0 -303
- _mcp_mesh/generated/mcp_mesh_registry_client/api_client.py +0 -798
- _mcp_mesh/generated/mcp_mesh_registry_client/api_response.py +0 -21
- _mcp_mesh/generated/mcp_mesh_registry_client/configuration.py +0 -577
- _mcp_mesh/generated/mcp_mesh_registry_client/exceptions.py +0 -217
- _mcp_mesh/generated/mcp_mesh_registry_client/models/__init__.py +0 -55
- _mcp_mesh/generated/mcp_mesh_registry_client/models/agent_info.py +0 -158
- _mcp_mesh/generated/mcp_mesh_registry_client/models/agent_metadata.py +0 -126
- _mcp_mesh/generated/mcp_mesh_registry_client/models/agent_metadata_dependencies_inner.py +0 -139
- _mcp_mesh/generated/mcp_mesh_registry_client/models/agent_metadata_dependencies_inner_one_of.py +0 -92
- _mcp_mesh/generated/mcp_mesh_registry_client/models/agent_registration.py +0 -103
- _mcp_mesh/generated/mcp_mesh_registry_client/models/agent_registration_metadata.py +0 -136
- _mcp_mesh/generated/mcp_mesh_registry_client/models/agents_list_response.py +0 -100
- _mcp_mesh/generated/mcp_mesh_registry_client/models/capability_info.py +0 -107
- _mcp_mesh/generated/mcp_mesh_registry_client/models/decorator_agent_metadata.py +0 -112
- _mcp_mesh/generated/mcp_mesh_registry_client/models/decorator_agent_request.py +0 -103
- _mcp_mesh/generated/mcp_mesh_registry_client/models/decorator_info.py +0 -105
- _mcp_mesh/generated/mcp_mesh_registry_client/models/dependency_info.py +0 -103
- _mcp_mesh/generated/mcp_mesh_registry_client/models/dependency_resolution_info.py +0 -106
- _mcp_mesh/generated/mcp_mesh_registry_client/models/error_response.py +0 -91
- _mcp_mesh/generated/mcp_mesh_registry_client/models/health_response.py +0 -103
- _mcp_mesh/generated/mcp_mesh_registry_client/models/heartbeat_request.py +0 -101
- _mcp_mesh/generated/mcp_mesh_registry_client/models/heartbeat_request_metadata.py +0 -111
- _mcp_mesh/generated/mcp_mesh_registry_client/models/heartbeat_response.py +0 -117
- _mcp_mesh/generated/mcp_mesh_registry_client/models/llm_provider.py +0 -93
- _mcp_mesh/generated/mcp_mesh_registry_client/models/llm_provider_resolution_info.py +0 -106
- _mcp_mesh/generated/mcp_mesh_registry_client/models/llm_tool_filter.py +0 -109
- _mcp_mesh/generated/mcp_mesh_registry_client/models/llm_tool_filter_filter_inner.py +0 -139
- _mcp_mesh/generated/mcp_mesh_registry_client/models/llm_tool_filter_filter_inner_one_of.py +0 -91
- _mcp_mesh/generated/mcp_mesh_registry_client/models/llm_tool_info.py +0 -101
- _mcp_mesh/generated/mcp_mesh_registry_client/models/llm_tool_resolution_info.py +0 -120
- _mcp_mesh/generated/mcp_mesh_registry_client/models/mesh_agent_register_metadata.py +0 -112
- _mcp_mesh/generated/mcp_mesh_registry_client/models/mesh_agent_registration.py +0 -129
- _mcp_mesh/generated/mcp_mesh_registry_client/models/mesh_registration_response.py +0 -153
- _mcp_mesh/generated/mcp_mesh_registry_client/models/mesh_registration_response_dependencies_resolved_value_inner.py +0 -101
- _mcp_mesh/generated/mcp_mesh_registry_client/models/mesh_tool_dependency_registration.py +0 -93
- _mcp_mesh/generated/mcp_mesh_registry_client/models/mesh_tool_register_metadata.py +0 -107
- _mcp_mesh/generated/mcp_mesh_registry_client/models/mesh_tool_registration.py +0 -117
- _mcp_mesh/generated/mcp_mesh_registry_client/models/registration_response.py +0 -119
- _mcp_mesh/generated/mcp_mesh_registry_client/models/resolved_llm_provider.py +0 -110
- _mcp_mesh/generated/mcp_mesh_registry_client/models/rich_dependency.py +0 -93
- _mcp_mesh/generated/mcp_mesh_registry_client/models/root_response.py +0 -92
- _mcp_mesh/generated/mcp_mesh_registry_client/models/standardized_dependency.py +0 -93
- _mcp_mesh/generated/mcp_mesh_registry_client/models/trace_event.py +0 -106
- _mcp_mesh/generated/mcp_mesh_registry_client/py.typed +0 -0
- _mcp_mesh/generated/mcp_mesh_registry_client/rest.py +0 -259
- _mcp_mesh/pipeline/api_heartbeat/api_dependency_resolution.py +0 -418
- _mcp_mesh/pipeline/api_heartbeat/api_fast_heartbeat_check.py +0 -117
- _mcp_mesh/pipeline/api_heartbeat/api_health_check.py +0 -140
- _mcp_mesh/pipeline/api_heartbeat/api_heartbeat_orchestrator.py +0 -243
- _mcp_mesh/pipeline/api_heartbeat/api_heartbeat_pipeline.py +0 -311
- _mcp_mesh/pipeline/api_heartbeat/api_heartbeat_send.py +0 -386
- _mcp_mesh/pipeline/api_heartbeat/api_registry_connection.py +0 -104
- _mcp_mesh/pipeline/mcp_heartbeat/dependency_resolution.py +0 -396
- _mcp_mesh/pipeline/mcp_heartbeat/fast_heartbeat_check.py +0 -116
- _mcp_mesh/pipeline/mcp_heartbeat/heartbeat_orchestrator.py +0 -311
- _mcp_mesh/pipeline/mcp_heartbeat/heartbeat_pipeline.py +0 -282
- _mcp_mesh/pipeline/mcp_heartbeat/heartbeat_send.py +0 -98
- _mcp_mesh/pipeline/mcp_heartbeat/lifespan_integration.py +0 -84
- _mcp_mesh/pipeline/mcp_heartbeat/llm_tools_resolution.py +0 -264
- _mcp_mesh/pipeline/mcp_heartbeat/registry_connection.py +0 -79
- _mcp_mesh/pipeline/shared/registry_connection.py +0 -80
- _mcp_mesh/shared/registry_client_wrapper.py +0 -515
- mcp_mesh-0.7.21.dist-info/RECORD +0 -152
- {mcp_mesh-0.7.21.dist-info → mcp_mesh-0.8.0.dist-info}/WHEEL +0 -0
- {mcp_mesh-0.7.21.dist-info → mcp_mesh-0.8.0.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
|
-
|
|
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
|
-
|
|
13
|
-
|
|
14
|
-
try:
|
|
15
|
-
import redis
|
|
11
|
+
import mcp_mesh_core
|
|
16
12
|
|
|
17
|
-
|
|
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
|
|
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 =
|
|
33
|
-
|
|
34
|
-
if
|
|
35
|
-
logger.
|
|
36
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
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
|
-
|
|
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
|
-
|
|
67
|
+
return {
|
|
106
68
|
"redis_available": self._available,
|
|
107
69
|
"tracing_enabled": self._tracing_enabled,
|
|
108
70
|
"stream_name": self.stream_name,
|
|
109
|
-
"
|
|
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
|
-
|
|
72
|
-
|
|
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}")
|
_mcp_mesh/tracing/utils.py
CHANGED
|
@@ -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
|
|
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
|
|
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
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
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
|
-
|
|
50
|
+
16-character hex string (64-bit span ID per OTel spec)
|
|
37
51
|
"""
|
|
38
|
-
return
|
|
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
|
-
|
|
59
|
+
32-character hex string (128-bit trace ID per OTel spec)
|
|
46
60
|
"""
|
|
47
|
-
return
|
|
61
|
+
return uuid.uuid4().hex
|
|
48
62
|
|
|
49
63
|
|
|
50
64
|
def get_agent_metadata_with_fallback(logger_instance: logging.Logger) -> dict[str, Any]:
|
|
@@ -24,7 +24,7 @@ class FastMCPSchemaExtractor:
|
|
|
24
24
|
This class extracts those schemas so they can be sent to the registry
|
|
25
25
|
for LLM tool discovery.
|
|
26
26
|
|
|
27
|
-
Phase 2.5: Filters out
|
|
27
|
+
Phase 2.5: Filters out McpMeshTool parameters from schemas since
|
|
28
28
|
they are dependency injection parameters and should not be visible to LLMs.
|
|
29
29
|
|
|
30
30
|
Phase 0: Enhances schemas with MeshContextModel Field descriptions for
|
|
@@ -239,7 +239,7 @@ class FastMCPSchemaExtractor:
|
|
|
239
239
|
schema: dict[str, Any], function: Any
|
|
240
240
|
) -> dict[str, Any]:
|
|
241
241
|
"""
|
|
242
|
-
Filter out
|
|
242
|
+
Filter out McpMeshTool dependency injection parameters from schema.
|
|
243
243
|
|
|
244
244
|
Phase 2.5: Remove dependency injection parameters from LLM-facing schemas.
|
|
245
245
|
These parameters are injected at runtime by MCP Mesh and should not be
|
|
@@ -273,8 +273,9 @@ class FastMCPSchemaExtractor:
|
|
|
273
273
|
if not schema or not isinstance(schema, dict):
|
|
274
274
|
return schema
|
|
275
275
|
|
|
276
|
-
# Get
|
|
277
|
-
from _mcp_mesh.engine.signature_analyzer import
|
|
276
|
+
# Get McpMeshTool parameter names from signature analysis
|
|
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.
|
|
3
|
+
Version: 0.8.0
|
|
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
|
|
@@ -18,6 +18,7 @@ Classifier: Operating System :: OS Independent
|
|
|
18
18
|
Classifier: Programming Language :: Python :: 3
|
|
19
19
|
Classifier: Programming Language :: Python :: 3.11
|
|
20
20
|
Classifier: Programming Language :: Python :: 3.12
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
21
22
|
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
22
23
|
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
23
24
|
Classifier: Topic :: System :: Distributed Computing
|
|
@@ -30,6 +31,7 @@ Requires-Dist: fastmcp<3.0.0,>=2.8.0
|
|
|
30
31
|
Requires-Dist: httpx<1.0.0,>=0.25.0
|
|
31
32
|
Requires-Dist: jinja2>=3.1.0
|
|
32
33
|
Requires-Dist: litellm>=1.30.0
|
|
34
|
+
Requires-Dist: mcp-mesh-core>=0.8.0
|
|
33
35
|
Requires-Dist: mcp<2.0.0,>=1.9.0
|
|
34
36
|
Requires-Dist: prometheus-client<1.0.0,>=0.19.0
|
|
35
37
|
Requires-Dist: pydantic<3.0.0,>=2.4.0
|
|
@@ -77,7 +79,7 @@ pip install mcp-mesh
|
|
|
77
79
|
import mesh
|
|
78
80
|
|
|
79
81
|
# Import types from public API
|
|
80
|
-
from mesh.types import
|
|
82
|
+
from mesh.types import McpMeshTool
|
|
81
83
|
|
|
82
84
|
# Define your agent
|
|
83
85
|
@mesh.agent(name="hello-world", http_port=9090)
|
|
@@ -91,11 +93,11 @@ class HelloWorldAgent:
|
|
|
91
93
|
dependencies=["date_service"],
|
|
92
94
|
description="Greeting function with date dependency injection"
|
|
93
95
|
)
|
|
94
|
-
def greet(name: str = "World",
|
|
96
|
+
def greet(name: str = "World", date_tool: McpMeshTool = None) -> str:
|
|
95
97
|
"""Greeting function with automatic dependency injection."""
|
|
96
|
-
if
|
|
98
|
+
if date_tool is not None:
|
|
97
99
|
try:
|
|
98
|
-
current_date =
|
|
100
|
+
current_date = date_tool()
|
|
99
101
|
return f"Hello, {name}! Today is {current_date}"
|
|
100
102
|
except Exception:
|
|
101
103
|
pass
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
_mcp_mesh/__init__.py,sha256=W1XsaJakRiPgbrjL1xVxU7PFZP7HUNn7PZ3y5dsp-Yw,2719
|
|
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=kjRUA4Lyj9zfYJ67NuFjx9YSdZEc3QtxTTpy3ww8YTg,31584
|
|
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=am4TG2Dd0KkgtZe0EJsVkkRi9srfbANEpO0cPS8m4w4,35320
|
|
13
|
+
_mcp_mesh/engine/mesh_llm_agent_injector.py,sha256=nPHLjz93uPLxI5ZviyE0RaXag3w4jMNQS2s9yQE3gaU,30193
|
|
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=bG9HEsDtJlzeS2ueypLpcp7qD4_zso4DH1SS_jWOHXA,11561
|
|
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=SZXlgdeNzlEGynwLLmmTi5R1-OrBaw4P8Izqhfn-zmI,37846
|
|
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=7Dv3lGTn2n2WrDpXoWqxUlqi6NwjPRH17-GVbsUckgE,15843
|
|
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=4cZT-_-j5clvR58QaLwo61EKJeZcPiKwWq9VXpm1kAY,26618
|
|
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=1Ylxv3zXBUyOHe05M8TqeiLEeg28R1U1zJRg18QQef0,35164
|
|
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=bnWeF90G3XGzfYwritlcE-EAbCZ9ThEqJfMfzRjOYVA,25871
|
|
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=fttO1EABbf4GWKjE9V5DimwbhzGY9DbfGWQ2ak4SRnE,17264
|
|
78
|
+
mesh/__init__.py,sha256=avMnUHkNAK7VgON2OhXkrFB290gr1HErghmTZpOXr-U,4207
|
|
79
|
+
mesh/decorators.py,sha256=Xru9NoOolmdm-awGuuQkUgBb-s5bq9UF4p5QdVidAvI,71374
|
|
80
|
+
mesh/helpers.py,sha256=UrYclIZzpOgoMQO-qWjeSshCdHCLokpByzuIUt5L7KM,15551
|
|
81
|
+
mesh/types.py,sha256=vr0CKyPbP6lHgxj9kh_GMSLo3xkJ66PFPV_opfRb1H4,17772
|
|
82
|
+
mcp_mesh-0.8.0.dist-info/METADATA,sha256=hwi1oVPcEbSJqeNIdYHqlis6CoHLsaNjBBxJv3c1ZuY,5087
|
|
83
|
+
mcp_mesh-0.8.0.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
|
|
84
|
+
mcp_mesh-0.8.0.dist-info/licenses/LICENSE,sha256=_EBQHRQThv9FPOLc5eFOUdeeRO0mYwChC7cx60dM1tM,1078
|
|
85
|
+
mcp_mesh-0.8.0.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,
|
|
22
|
+
from .types import (LlmMeta, McpMeshAgent, McpMeshTool, MeshContextModel,
|
|
23
|
+
MeshLlmAgent, 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
|
|
@@ -92,6 +93,8 @@ def create_server(name: str | None = None) -> "FastMCP":
|
|
|
92
93
|
|
|
93
94
|
# Make decorators available as mesh.tool, mesh.agent, mesh.route, mesh.llm, and mesh.llm_provider
|
|
94
95
|
def __getattr__(name):
|
|
96
|
+
import warnings
|
|
97
|
+
|
|
95
98
|
if name == "tool":
|
|
96
99
|
return decorators.tool
|
|
97
100
|
elif name == "agent":
|
|
@@ -105,7 +108,15 @@ def __getattr__(name):
|
|
|
105
108
|
from .helpers import llm_provider
|
|
106
109
|
|
|
107
110
|
return llm_provider
|
|
111
|
+
elif name == "McpMeshTool":
|
|
112
|
+
return McpMeshTool
|
|
108
113
|
elif name == "McpMeshAgent":
|
|
114
|
+
warnings.warn(
|
|
115
|
+
"McpMeshAgent is deprecated, use McpMeshTool instead. "
|
|
116
|
+
"McpMeshAgent will be removed in a future version.",
|
|
117
|
+
DeprecationWarning,
|
|
118
|
+
stacklevel=2,
|
|
119
|
+
)
|
|
109
120
|
return McpMeshAgent
|
|
110
121
|
elif name == "MeshContextModel":
|
|
111
122
|
return MeshContextModel
|