mcp-mesh 0.5.7__py3-none-any.whl → 0.6.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.
Files changed (39) hide show
  1. _mcp_mesh/__init__.py +1 -1
  2. _mcp_mesh/engine/base_injector.py +171 -0
  3. _mcp_mesh/engine/decorator_registry.py +136 -33
  4. _mcp_mesh/engine/dependency_injector.py +91 -18
  5. _mcp_mesh/engine/http_wrapper.py +5 -22
  6. _mcp_mesh/engine/llm_config.py +41 -0
  7. _mcp_mesh/engine/llm_errors.py +115 -0
  8. _mcp_mesh/engine/mesh_llm_agent.py +440 -0
  9. _mcp_mesh/engine/mesh_llm_agent_injector.py +487 -0
  10. _mcp_mesh/engine/response_parser.py +240 -0
  11. _mcp_mesh/engine/signature_analyzer.py +229 -99
  12. _mcp_mesh/engine/tool_executor.py +169 -0
  13. _mcp_mesh/engine/tool_schema_builder.py +125 -0
  14. _mcp_mesh/engine/unified_mcp_proxy.py +14 -12
  15. _mcp_mesh/generated/.openapi-generator/FILES +4 -0
  16. _mcp_mesh/generated/mcp_mesh_registry_client/__init__.py +81 -44
  17. _mcp_mesh/generated/mcp_mesh_registry_client/models/__init__.py +72 -35
  18. _mcp_mesh/generated/mcp_mesh_registry_client/models/llm_tool_filter.py +132 -0
  19. _mcp_mesh/generated/mcp_mesh_registry_client/models/llm_tool_filter_filter_inner.py +172 -0
  20. _mcp_mesh/generated/mcp_mesh_registry_client/models/llm_tool_filter_filter_inner_one_of.py +92 -0
  21. _mcp_mesh/generated/mcp_mesh_registry_client/models/llm_tool_info.py +121 -0
  22. _mcp_mesh/generated/mcp_mesh_registry_client/models/mesh_agent_registration.py +98 -51
  23. _mcp_mesh/generated/mcp_mesh_registry_client/models/mesh_registration_response.py +93 -44
  24. _mcp_mesh/generated/mcp_mesh_registry_client/models/mesh_tool_registration.py +84 -41
  25. _mcp_mesh/pipeline/api_heartbeat/api_dependency_resolution.py +9 -72
  26. _mcp_mesh/pipeline/mcp_heartbeat/heartbeat_pipeline.py +6 -3
  27. _mcp_mesh/pipeline/mcp_heartbeat/llm_tools_resolution.py +222 -0
  28. _mcp_mesh/pipeline/mcp_startup/fastmcpserver_discovery.py +7 -0
  29. _mcp_mesh/pipeline/mcp_startup/heartbeat_preparation.py +65 -4
  30. _mcp_mesh/pipeline/mcp_startup/startup_pipeline.py +2 -2
  31. _mcp_mesh/shared/registry_client_wrapper.py +60 -4
  32. _mcp_mesh/utils/fastmcp_schema_extractor.py +476 -0
  33. {mcp_mesh-0.5.7.dist-info → mcp_mesh-0.6.0.dist-info}/METADATA +1 -1
  34. {mcp_mesh-0.5.7.dist-info → mcp_mesh-0.6.0.dist-info}/RECORD +39 -25
  35. mesh/__init__.py +8 -4
  36. mesh/decorators.py +344 -2
  37. mesh/types.py +145 -94
  38. {mcp_mesh-0.5.7.dist-info → mcp_mesh-0.6.0.dist-info}/WHEEL +0 -0
  39. {mcp_mesh-0.5.7.dist-info → mcp_mesh-0.6.0.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,476 @@
1
+ """
2
+ FastMCP Schema Extractor
3
+
4
+ Extracts inputSchema from FastMCP tool objects for LLM integration.
5
+ This enables the registry to store tool schemas for tool discovery.
6
+
7
+ Part of Phase 2: Schema Collection & Propagation
8
+ Part of Phase 2.5: Schema Filtering - removes dependency injection parameters
9
+ Part of Phase 0: Enhanced Schema Extraction - MeshContextModel support
10
+ """
11
+
12
+ import inspect
13
+ import logging
14
+ from typing import Any, Dict, Optional, get_args, get_origin, get_type_hints
15
+
16
+ logger = logging.getLogger(__name__)
17
+
18
+
19
+ class FastMCPSchemaExtractor:
20
+ """
21
+ Extracts inputSchema from FastMCP tools.
22
+
23
+ FastMCP automatically generates JSON schemas from Python type hints.
24
+ This class extracts those schemas so they can be sent to the registry
25
+ for LLM tool discovery.
26
+
27
+ Phase 2.5: Filters out McpMeshAgent parameters from schemas since
28
+ they are dependency injection parameters and should not be visible to LLMs.
29
+
30
+ Phase 0: Enhances schemas with MeshContextModel Field descriptions for
31
+ better LLM chain composition.
32
+ """
33
+
34
+ @staticmethod
35
+ def is_mesh_context_model(type_hint: Any) -> bool:
36
+ """
37
+ Check if a type hint is MeshContextModel or a subclass.
38
+
39
+ Handles:
40
+ - Direct MeshContextModel subclass
41
+ - Optional[MeshContextModel] (Union with None)
42
+ - Forward references
43
+
44
+ Args:
45
+ type_hint: Type annotation to check
46
+
47
+ Returns:
48
+ True if type is MeshContextModel or subclass
49
+
50
+ Example:
51
+ class ChatContext(MeshContextModel):
52
+ ...
53
+
54
+ is_mesh_context_model(ChatContext) # True
55
+ is_mesh_context_model(Optional[ChatContext]) # True
56
+ is_mesh_context_model(str) # False
57
+ """
58
+ try:
59
+ from mesh.types import MeshContextModel
60
+
61
+ # Handle None
62
+ if type_hint is None:
63
+ return False
64
+
65
+ # Handle Union types (like Optional[MeshContextModel])
66
+ origin = get_origin(type_hint)
67
+ if origin is not None:
68
+ # For Union types, check all args
69
+ args = get_args(type_hint)
70
+ for arg in args:
71
+ if arg is not type(
72
+ None
73
+ ) and FastMCPSchemaExtractor.is_mesh_context_model(arg):
74
+ return True
75
+ return False
76
+
77
+ # Direct type check
78
+ if inspect.isclass(type_hint):
79
+ return issubclass(type_hint, MeshContextModel)
80
+
81
+ except (ImportError, TypeError):
82
+ # MeshContextModel not available or type checking failed
83
+ pass
84
+
85
+ return False
86
+
87
+ @staticmethod
88
+ def extract_context_schema(model_class: type) -> dict[str, Any]:
89
+ """
90
+ Extract enhanced schema from MeshContextModel with Field descriptions.
91
+
92
+ Uses Pydantic's model_json_schema() to get complete schema including:
93
+ - Field descriptions from Field(description=...)
94
+ - Default values
95
+ - Type information
96
+ - Nested models
97
+
98
+ Args:
99
+ model_class: MeshContextModel subclass
100
+
101
+ Returns:
102
+ Enhanced JSON Schema dict with descriptions
103
+
104
+ Example:
105
+ class AnalysisContext(MeshContextModel):
106
+ domain: str = Field(description="Analysis domain")
107
+ user_level: str = Field(default="beginner")
108
+
109
+ schema = extract_context_schema(AnalysisContext)
110
+ # Returns:
111
+ # {
112
+ # "type": "object",
113
+ # "properties": {
114
+ # "domain": {"type": "string", "description": "Analysis domain"},
115
+ # "user_level": {"type": "string", "default": "beginner"}
116
+ # },
117
+ # "required": ["domain"]
118
+ # }
119
+ """
120
+ try:
121
+ # Get Pydantic's JSON schema which includes all Field metadata
122
+ schema = model_class.model_json_schema()
123
+
124
+ # Add marker that this is a context for prompt template
125
+ if "description" not in schema:
126
+ schema["description"] = "Context for prompt template"
127
+ else:
128
+ # Append to existing description
129
+ schema["description"] = (
130
+ f"{schema['description']} (Context for prompt template)"
131
+ )
132
+
133
+ logger.debug(
134
+ f"Extracted enhanced schema for {model_class.__name__}: "
135
+ f"{list(schema.get('properties', {}).keys())}"
136
+ )
137
+
138
+ return schema
139
+
140
+ except Exception as e:
141
+ logger.warning(f"Failed to extract schema from {model_class.__name__}: {e}")
142
+ return {"type": "object"}
143
+
144
+ @staticmethod
145
+ def enhance_schema_with_context_models(
146
+ schema: dict[str, Any], function: Any
147
+ ) -> dict[str, Any]:
148
+ """
149
+ Enhance schema by detecting MeshContextModel parameters and extracting
150
+ their Field descriptions.
151
+
152
+ Phase 0: For each parameter that is a MeshContextModel subclass, replace
153
+ the basic schema with an enhanced schema that includes Field descriptions.
154
+ This helps calling LLM agents construct context objects correctly.
155
+
156
+ Args:
157
+ schema: The inputSchema dict to enhance
158
+ function: The function whose parameters to analyze
159
+
160
+ Returns:
161
+ Enhanced schema with MeshContextModel Field descriptions
162
+
163
+ Example:
164
+ Before:
165
+ {
166
+ "properties": {
167
+ "ctx": {"type": "object"} # Basic
168
+ }
169
+ }
170
+
171
+ After:
172
+ {
173
+ "properties": {
174
+ "ctx": {
175
+ "type": "object",
176
+ "description": "Context for prompt template",
177
+ "properties": {
178
+ "domain": {
179
+ "type": "string",
180
+ "description": "Analysis domain: infrastructure, security"
181
+ }
182
+ }
183
+ }
184
+ }
185
+ }
186
+ """
187
+ if not schema or not isinstance(schema, dict):
188
+ return schema
189
+
190
+ try:
191
+ # Get type hints from function
192
+ type_hints = get_type_hints(function)
193
+ except Exception as e:
194
+ func_name = getattr(function, "__name__", "<unknown>")
195
+ logger.debug(f"Could not get type hints for {func_name}: {e}")
196
+ return schema
197
+
198
+ # Create a copy to avoid modifying original
199
+ enhanced_schema = schema.copy()
200
+ if "properties" not in enhanced_schema:
201
+ return enhanced_schema
202
+
203
+ enhanced_props = enhanced_schema["properties"].copy()
204
+
205
+ # Check each parameter
206
+ for param_name, param_schema in schema.get("properties", {}).items():
207
+ type_hint = type_hints.get(param_name)
208
+
209
+ if type_hint and FastMCPSchemaExtractor.is_mesh_context_model(type_hint):
210
+ # Found MeshContextModel parameter!
211
+ # Extract the actual model class (handle Optional)
212
+ model_class = type_hint
213
+ origin = get_origin(type_hint)
214
+ if origin is not None:
215
+ args = get_args(type_hint)
216
+ for arg in args:
217
+ if arg is not type(None):
218
+ model_class = arg
219
+ break
220
+
221
+ # Extract enhanced schema with Field descriptions
222
+ context_schema = FastMCPSchemaExtractor.extract_context_schema(
223
+ model_class
224
+ )
225
+
226
+ # Replace basic schema with enhanced schema
227
+ enhanced_props[param_name] = context_schema
228
+
229
+ logger.debug(
230
+ f"Enhanced {param_name} parameter with MeshContextModel schema: "
231
+ f"{list(context_schema.get('properties', {}).keys())}"
232
+ )
233
+
234
+ enhanced_schema["properties"] = enhanced_props
235
+ return enhanced_schema
236
+
237
+ @staticmethod
238
+ def filter_dependency_parameters(
239
+ schema: dict[str, Any], function: Any
240
+ ) -> dict[str, Any]:
241
+ """
242
+ Filter out McpMeshAgent dependency injection parameters from schema.
243
+
244
+ Phase 2.5: Remove dependency injection parameters from LLM-facing schemas.
245
+ These parameters are injected at runtime by MCP Mesh and should not be
246
+ visible to LLMs or included in tool discovery.
247
+
248
+ Args:
249
+ schema: The inputSchema dict to filter
250
+ function: The function whose parameters to analyze
251
+
252
+ Returns:
253
+ Filtered schema with dependency parameters removed
254
+
255
+ Example:
256
+ Input schema:
257
+ {
258
+ "properties": {
259
+ "name": {"type": "string"},
260
+ "date_service": {"anyOf": [{}, {"type": "null"}], "default": null}
261
+ },
262
+ "required": ["name"]
263
+ }
264
+
265
+ Output schema (date_service removed):
266
+ {
267
+ "properties": {
268
+ "name": {"type": "string"}
269
+ },
270
+ "required": ["name"]
271
+ }
272
+ """
273
+ if not schema or not isinstance(schema, dict):
274
+ return schema
275
+
276
+ # Get McpMeshAgent parameter names from signature analysis
277
+ from _mcp_mesh.engine.signature_analyzer import get_mesh_agent_parameter_names
278
+
279
+ mesh_param_names = get_mesh_agent_parameter_names(function)
280
+
281
+ if not mesh_param_names:
282
+ # No dependency parameters to filter
283
+ return schema
284
+
285
+ # Create a copy to avoid modifying original
286
+ filtered_schema = schema.copy()
287
+
288
+ # Filter properties
289
+ if "properties" in filtered_schema:
290
+ original_props = filtered_schema["properties"]
291
+ filtered_props = {
292
+ param_name: param_schema
293
+ for param_name, param_schema in original_props.items()
294
+ if param_name not in mesh_param_names
295
+ }
296
+ filtered_schema["properties"] = filtered_props
297
+
298
+ logger.debug(
299
+ f"🔧 Filtered {len(original_props) - len(filtered_props)} dependency parameters "
300
+ f"from schema: {mesh_param_names}"
301
+ )
302
+
303
+ # Filter required array
304
+ if "required" in filtered_schema:
305
+ original_required = filtered_schema["required"]
306
+ filtered_required = [
307
+ param_name
308
+ for param_name in original_required
309
+ if param_name not in mesh_param_names
310
+ ]
311
+ filtered_schema["required"] = filtered_required
312
+
313
+ return filtered_schema
314
+
315
+ @staticmethod
316
+ def extract_input_schema(function: Any) -> Optional[dict[str, Any]]:
317
+ """
318
+ Extract inputSchema from a function that may have a FastMCP tool attached.
319
+
320
+ Args:
321
+ function: The function object (possibly decorated with @app.tool())
322
+
323
+ Returns:
324
+ inputSchema dict if FastMCP tool found, None otherwise
325
+
326
+ The inputSchema format follows JSON Schema specification:
327
+ {
328
+ "type": "object",
329
+ "properties": {
330
+ "param_name": {"type": "string", "description": "..."},
331
+ ...
332
+ },
333
+ "required": ["param1", "param2"]
334
+ }
335
+ """
336
+ # Check if function has FastMCP tool reference
337
+ if not hasattr(function, "_fastmcp_tool"):
338
+ logger.debug(
339
+ f"Function {getattr(function, '__name__', '<unknown>')} has no FastMCP tool"
340
+ )
341
+ return None
342
+
343
+ fastmcp_tool = function._fastmcp_tool
344
+
345
+ # Extract inputSchema from FastMCP tool
346
+ # FastMCP uses 'parameters' attribute, not 'inputSchema'
347
+ if hasattr(fastmcp_tool, "parameters"):
348
+ schema = fastmcp_tool.parameters
349
+ logger.debug(
350
+ f"Extracted schema from {getattr(function, '__name__', '<unknown>')}: "
351
+ f"{list(schema.get('properties', {}).keys()) if isinstance(schema, dict) else 'invalid'}"
352
+ )
353
+ # Phase 2.5: Filter out dependency injection parameters
354
+ filtered_schema = FastMCPSchemaExtractor.filter_dependency_parameters(
355
+ schema, function
356
+ )
357
+
358
+ # Phase 0: Enhance schema with MeshContextModel Field descriptions
359
+ enhanced_schema = FastMCPSchemaExtractor.enhance_schema_with_context_models(
360
+ filtered_schema, function
361
+ )
362
+
363
+ return enhanced_schema
364
+
365
+ logger.debug(
366
+ f"FastMCP tool for {getattr(function, '__name__', '<unknown>')} "
367
+ f"has no parameters attribute"
368
+ )
369
+ return None
370
+
371
+ @staticmethod
372
+ def extract_from_fastmcp_servers(
373
+ function: Any, fastmcp_servers: Optional[dict[str, Any]]
374
+ ) -> Optional[dict[str, Any]]:
375
+ """
376
+ Extract inputSchema by looking up function in FastMCP server tool managers.
377
+
378
+ This is the primary method for extracting schemas when using FastMCP.
379
+ It searches all discovered FastMCP servers for a tool whose function
380
+ matches the given function, then extracts its inputSchema.
381
+
382
+ Args:
383
+ function: The function to find schema for
384
+ fastmcp_servers: Dict from fastmcp-server-discovery step context
385
+ (maps server_name -> server_info dict)
386
+
387
+ Returns:
388
+ inputSchema dict if found, None otherwise
389
+ """
390
+ if not fastmcp_servers:
391
+ return None
392
+
393
+ func_id = id(function)
394
+ func_name = getattr(function, "__name__", "<unknown>")
395
+
396
+ # Search all FastMCP servers for this function
397
+ for server_name, server_info in fastmcp_servers.items():
398
+ tools_dict = server_info.get("tools", {})
399
+
400
+ # Look through all tools in this server
401
+ for tool_name, tool_obj in tools_dict.items():
402
+ # Match by function identity
403
+ tool_fn = getattr(tool_obj, "fn", None)
404
+ if tool_fn is not None and id(tool_fn) == func_id:
405
+ # Found matching tool! Extract schema
406
+ # FastMCP stores schema in 'parameters' attribute (not 'inputSchema')
407
+ if hasattr(tool_obj, "parameters"):
408
+ schema = tool_obj.parameters
409
+ logger.debug(
410
+ f"✅ Matched function {func_name} to FastMCP tool '{tool_name}' "
411
+ f"with schema: {list(schema.get('properties', {}).keys()) if isinstance(schema, dict) else 'invalid'}"
412
+ )
413
+ # Phase 2.5: Filter out dependency injection parameters
414
+ filtered_schema = (
415
+ FastMCPSchemaExtractor.filter_dependency_parameters(
416
+ schema, function
417
+ )
418
+ )
419
+
420
+ # Phase 0: Enhance schema with MeshContextModel Field descriptions
421
+ enhanced_schema = (
422
+ FastMCPSchemaExtractor.enhance_schema_with_context_models(
423
+ filtered_schema, function
424
+ )
425
+ )
426
+
427
+ return enhanced_schema
428
+ else:
429
+ logger.debug(
430
+ f"⚠️ Matched function {func_name} to FastMCP tool '{tool_name}' "
431
+ f"but no parameters attribute found"
432
+ )
433
+ return None
434
+
435
+ logger.debug(
436
+ f"Function {func_name} not found in any FastMCP server tool managers"
437
+ )
438
+ return None
439
+
440
+ @staticmethod
441
+ def extract_all_schemas_from_tools(
442
+ mesh_tools: dict[str, Any], fastmcp_servers: Optional[dict[str, Any]] = None
443
+ ) -> dict[str, Optional[dict[str, Any]]]:
444
+ """
445
+ Extract inputSchemas from all tools in a mesh_tools dict.
446
+
447
+ Args:
448
+ mesh_tools: Dict of function_name -> DecoratedFunction
449
+ fastmcp_servers: Optional dict of FastMCP server info from discovery step
450
+
451
+ Returns:
452
+ Dict mapping function_name -> inputSchema (or None)
453
+ """
454
+ schemas = {}
455
+
456
+ for func_name, decorated_func in mesh_tools.items():
457
+ function = decorated_func.function
458
+
459
+ # First try the FastMCP server lookup (primary method)
460
+ schema = FastMCPSchemaExtractor.extract_from_fastmcp_servers(
461
+ function, fastmcp_servers
462
+ )
463
+
464
+ # Fallback to _fastmcp_tool attribute (for backward compatibility with tests)
465
+ if schema is None:
466
+ schema = FastMCPSchemaExtractor.extract_input_schema(function)
467
+
468
+ schemas[func_name] = schema
469
+
470
+ logger.info(
471
+ f"Extracted schemas for {len(mesh_tools)} tools: "
472
+ f"{sum(1 for s in schemas.values() if s is not None)} with schemas, "
473
+ f"{sum(1 for s in schemas.values() if s is None)} without"
474
+ )
475
+
476
+ return schemas
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mcp-mesh
3
- Version: 0.5.7
3
+ Version: 0.6.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
@@ -1,20 +1,28 @@
1
- _mcp_mesh/__init__.py,sha256=CTRyqemXkVmKL85NBmkaOB9AN-FOZxseOKEnV_s7AMk,2719
1
+ _mcp_mesh/__init__.py,sha256=HW8krPO-11yYkgOXvo9W9J2oPcBQ58kOyYgabuEdlZs,2719
2
2
  _mcp_mesh/engine/__init__.py,sha256=2ennzbo7yJcpkXO9BqN69TruLjJfmJY4Y5VEsG644K4,3630
3
3
  _mcp_mesh/engine/async_mcp_client.py,sha256=UcbQjxtgVfeRw6DHTZhAzN1gkcKlTg-lUPEePRPQWAU,6306
4
- _mcp_mesh/engine/decorator_registry.py,sha256=0-GI7DILpbB6GRLIYhZu0DcdHEA62d89jDYxkK1ywiM,22422
5
- _mcp_mesh/engine/dependency_injector.py,sha256=k6PzG9te1J5DbuDV2OrErXM3AcV1X6_ZvCy5KFYo1nk,27496
4
+ _mcp_mesh/engine/base_injector.py,sha256=qzRLZqFP2VvEFagVovkpdldvDmm3VwPHm6tHwV58a2k,5648
5
+ _mcp_mesh/engine/decorator_registry.py,sha256=89uNOod-3VG9mpD_MoqxmFnXfS3u2Zw54QTZNL61rN0,25932
6
+ _mcp_mesh/engine/dependency_injector.py,sha256=aKES6fHSUph1c5--IOVzsbzXC_3V7NkcsIPlN1Y69sI,30634
6
7
  _mcp_mesh/engine/full_mcp_proxy.py,sha256=PlRv7GSKqn5riOCqeCVulVdtq3z1Ug76mOkwMsOFHXw,25297
7
- _mcp_mesh/engine/http_wrapper.py,sha256=PeYR7HkJVX7Hb0W-uYSMO-Y14VqCyrPlWzA6vnwf1Tw,21640
8
+ _mcp_mesh/engine/http_wrapper.py,sha256=T9VQ2LZbGgCzyOVXVwdqas7-W3Wid0EwRboFUpdYWtM,20718
9
+ _mcp_mesh/engine/llm_config.py,sha256=eaBXtCmmM-gyD3enKuhhHHdOkSZVMHxb-T9D89Wgc9M,1156
10
+ _mcp_mesh/engine/llm_errors.py,sha256=h7BiI14u-jL8vtvBfFbFDDrN7gIw8PQjXIl5AP1SBuA,3276
8
11
  _mcp_mesh/engine/mcp_client_proxy.py,sha256=eJStwy_VQJexYYD8bOh_m4Ld3Bb8Ae_dt8N1CC41qBc,17625
12
+ _mcp_mesh/engine/mesh_llm_agent.py,sha256=0XbrZlddUxbfXw8hnqztwsomzbYbBGnYHMHiEviVN00,15912
13
+ _mcp_mesh/engine/mesh_llm_agent_injector.py,sha256=46lyf12uX54lAJVWWdZpmnOo009RllUkAxmcmi2rY1k,19322
14
+ _mcp_mesh/engine/response_parser.py,sha256=aOO5nhlmZrpucrLiI-19VHBgEwE774EAYfvsgsPrL_c,8490
9
15
  _mcp_mesh/engine/self_dependency_proxy.py,sha256=OkKt0-B_ADnJlWtHiHItoZCBZ7Su0iz2unEPFfXvrs4,3302
10
16
  _mcp_mesh/engine/session_aware_client.py,sha256=mc9eh-aCvUvfllORiXTf_X8_jPqV-32QdWKlr8tHLkU,10600
11
17
  _mcp_mesh/engine/session_manager.py,sha256=MCr0_fXBaUjXM51WU5EhDkiGvBdfzYQFVNb9DCXXL0A,10418
12
- _mcp_mesh/engine/signature_analyzer.py,sha256=w5mvnRo1cc31the6OZln5keOVJphL26V6jDAHVNA29A,7946
13
- _mcp_mesh/engine/unified_mcp_proxy.py,sha256=33xm-jABTYUwr_uIB6mx4yNlNJrsvstCHJOMTdcm-pg,36365
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=8t-DAPfNzXWAa5ktolwZJulyAJp8sYg6--VYznWqd7E,3580
21
+ _mcp_mesh/engine/unified_mcp_proxy.py,sha256=SmhLWXdjmgvJWOLGQk-cXrvYjGSzx98HzL0Q5jpMNIY,36326
14
22
  _mcp_mesh/generated/.openapi-generator-ignore,sha256=-d-Y-RVAZRrHw36jO0b79oDXpfA8rZdBGPCG4Vs_rUs,227
15
- _mcp_mesh/generated/.openapi-generator/FILES,sha256=BXFXHe4FTV5GFUTNjMhmvOrVcYVlHJc5O-3UXyp8OCY,2169
23
+ _mcp_mesh/generated/.openapi-generator/FILES,sha256=BfEjaFFKaP-O6syjKqu5C9P_6HuBPDTfYBkz4u7IXAo,2404
16
24
  _mcp_mesh/generated/.openapi-generator/VERSION,sha256=nMm490YXJUW3_vAdeAsg7E3yRgUqVwk5-50PuaFonM8,7
17
- _mcp_mesh/generated/mcp_mesh_registry_client/__init__.py,sha256=C_J51kNjdAQ2ikcXQzaIC0x9HQgbibT02x1rmWpeKGw,5604
25
+ _mcp_mesh/generated/mcp_mesh_registry_client/__init__.py,sha256=E8sKkIh1IUQ6VKVKvFgD3XiC0kE3odmXj0iWzUpZmxs,5937
18
26
  _mcp_mesh/generated/mcp_mesh_registry_client/api_client.py,sha256=SLzm-p1vhbhufVDn7sNKjq9aSBkZUXTdwRIf7Ne57l8,28104
19
27
  _mcp_mesh/generated/mcp_mesh_registry_client/api_response.py,sha256=eMxw1mpmJcoGZ3gs9z6jM4oYoZ10Gjk333s9sKxGv7s,652
20
28
  _mcp_mesh/generated/mcp_mesh_registry_client/configuration.py,sha256=PCZ03PQGCEG0lfIn4s1tk8WrB9HpQ-LCXIUK110F1gY,18544
@@ -25,7 +33,7 @@ _mcp_mesh/generated/mcp_mesh_registry_client/api/__init__.py,sha256=CP4BRsWFhioE
25
33
  _mcp_mesh/generated/mcp_mesh_registry_client/api/agents_api.py,sha256=rHY0h_wcv9eLRzOitkRZ7PDKtgWr5xism3azkZpuI6I,46445
26
34
  _mcp_mesh/generated/mcp_mesh_registry_client/api/health_api.py,sha256=BJsqdNHz-dZXJsvQmYdZLLM_vf1Lf6DKRH9xzpyfkuU,30552
27
35
  _mcp_mesh/generated/mcp_mesh_registry_client/api/tracing_api.py,sha256=2FmSDoWiAfx404kB5mkWvYviE37QVY-Cb-kA90o1rn8,13179
28
- _mcp_mesh/generated/mcp_mesh_registry_client/models/__init__.py,sha256=s54kd3wYhgltJgOFD0RLQX7prcuI4uDibwVXXo5SrTs,3968
36
+ _mcp_mesh/generated/mcp_mesh_registry_client/models/__init__.py,sha256=uJ0eFAM2V740prPrGV4xQo3YsPJGHiElezId3-5ZR28,4573
29
37
  _mcp_mesh/generated/mcp_mesh_registry_client/models/agent_info.py,sha256=ZD3qwc7GlKYV3Jlxbc79gEJWf-2_H0m07GVyHL4cCVw,5293
30
38
  _mcp_mesh/generated/mcp_mesh_registry_client/models/agent_metadata.py,sha256=_ixbM8wlhL5C7jx-NXoA0zdJSK88-TX8URuCIOv7_E8,6520
31
39
  _mcp_mesh/generated/mcp_mesh_registry_client/models/agent_metadata_dependencies_inner.py,sha256=LiO2JfFwasidNJ859LKmDHa6kV1boGIlTdhFwmpgoxw,6303
@@ -43,13 +51,17 @@ _mcp_mesh/generated/mcp_mesh_registry_client/models/health_response.py,sha256=vE
43
51
  _mcp_mesh/generated/mcp_mesh_registry_client/models/heartbeat_request.py,sha256=YRsl7YhZLBfudS_i5s7zRDkG6fO9S9c7TrveeKUV0aM,3901
44
52
  _mcp_mesh/generated/mcp_mesh_registry_client/models/heartbeat_request_metadata.py,sha256=A-L6mFz19Pa-QExvCihCHrJDHIlIV18w290usgD6_Yo,4317
45
53
  _mcp_mesh/generated/mcp_mesh_registry_client/models/heartbeat_response.py,sha256=dPJxz5XQukw4QejkeP7F3FAm8m0wW-5gm9xpajlkGqQ,4907
54
+ _mcp_mesh/generated/mcp_mesh_registry_client/models/llm_tool_filter.py,sha256=_cC9pBNQIrC9i9U-SCdi9APCyzgK3XbJRotou9nVZ7k,5228
55
+ _mcp_mesh/generated/mcp_mesh_registry_client/models/llm_tool_filter_filter_inner.py,sha256=dmjxwlS9NbNCvr2ntAaHou5BFm-v9wQySM5NnR0k-c8,6404
56
+ _mcp_mesh/generated/mcp_mesh_registry_client/models/llm_tool_filter_filter_inner_one_of.py,sha256=ozbjc1H9ZppodlMw-L-YDFsg-gA19RliXGESob6vjho,3405
57
+ _mcp_mesh/generated/mcp_mesh_registry_client/models/llm_tool_info.py,sha256=ocwVpJUHwCf_wee2DyV1QVDpEtGZDKasHPTHQ_mnKho,4624
46
58
  _mcp_mesh/generated/mcp_mesh_registry_client/models/mesh_agent_register_metadata.py,sha256=HGABUatJp_mu2uFWzC7HBEZACHXIKFmIeegFYfHEcN4,4820
47
- _mcp_mesh/generated/mcp_mesh_registry_client/models/mesh_agent_registration.py,sha256=qZiljiQH877iBN35poelxDPPnHwpjbu9J2yCwKmZgg8,6182
48
- _mcp_mesh/generated/mcp_mesh_registry_client/models/mesh_registration_response.py,sha256=tKG2maoADs_cXc2IdU-Pycsf0jyfOLnqeGZJtLXwf3E,5075
59
+ _mcp_mesh/generated/mcp_mesh_registry_client/models/mesh_agent_registration.py,sha256=6bzahvFFC3EFT_JzZmtbgG6hikNDppJBMx94E1e_q3Y,6812
60
+ _mcp_mesh/generated/mcp_mesh_registry_client/models/mesh_registration_response.py,sha256=BObxAkSORrykYo3GRqHifbdxC4NtgdaDoD3yB3CSNMM,6924
49
61
  _mcp_mesh/generated/mcp_mesh_registry_client/models/mesh_registration_response_dependencies_resolved_value_inner.py,sha256=tmcFBO8rbB_F-TfpU2lsG29CKTpQPfiuJqE62r81p0k,4071
50
62
  _mcp_mesh/generated/mcp_mesh_registry_client/models/mesh_tool_dependency_registration.py,sha256=PkY1rWdS3y5TTxRRFpATWmm3dhw_Qw2_4QBzCv_7ZuU,3658
51
63
  _mcp_mesh/generated/mcp_mesh_registry_client/models/mesh_tool_register_metadata.py,sha256=cvbVtiRMd-VfhrMNQX0bRcmW0_FyotYLwLPX8gAsl1o,4935
52
- _mcp_mesh/generated/mcp_mesh_registry_client/models/mesh_tool_registration.py,sha256=pCBgCwDYpAzqzqE2ksj91uk8PxMuZ9RhDGprbohsYKI,4957
64
+ _mcp_mesh/generated/mcp_mesh_registry_client/models/mesh_tool_registration.py,sha256=JZ6m1pBU0GGWpef0CAU0FklaHWa4tPDhAaCAdj1GYdc,5985
53
65
  _mcp_mesh/generated/mcp_mesh_registry_client/models/registration_response.py,sha256=XzIwhTaBrztXgIHQwvW9KRfWOY5GNjVV4RpZKEwxrV8,5030
54
66
  _mcp_mesh/generated/mcp_mesh_registry_client/models/rich_dependency.py,sha256=Y6TB1Zvfkq2U8YMSmWUmIcOZMU6ZZxRFmifUGwdRwa0,3591
55
67
  _mcp_mesh/generated/mcp_mesh_registry_client/models/root_response.py,sha256=Das3mRHvgqDJVuWsoWLtwUTv_I5nFejhV10U0JZ_CZM,3221
@@ -57,7 +69,7 @@ _mcp_mesh/generated/mcp_mesh_registry_client/models/standardized_dependency.py,s
57
69
  _mcp_mesh/generated/mcp_mesh_registry_client/models/trace_event.py,sha256=9Q_8WaVl0MxswRnHpkqq9GKnvOW54HW4tkrTM9oda14,4461
58
70
  _mcp_mesh/pipeline/__init__.py,sha256=9Aplh4m1z-rYTQys0JQLYlq9wTPdI72eSOhUPqcnvpA,1557
59
71
  _mcp_mesh/pipeline/api_heartbeat/__init__.py,sha256=IXTLoQLAPqQEWZ8VMWc5W_cQJkDv95rlVGXyXoQDjHk,473
60
- _mcp_mesh/pipeline/api_heartbeat/api_dependency_resolution.py,sha256=uVv7KjEfVO_5Ny3fgC_DD9B8dg_IIUdJmtGVrTaSStU,25312
72
+ _mcp_mesh/pipeline/api_heartbeat/api_dependency_resolution.py,sha256=jo5SmI52T7Vz9yEz5O78SHYh-HyJtpzdOxoa5EylHsI,22011
61
73
  _mcp_mesh/pipeline/api_heartbeat/api_fast_heartbeat_check.py,sha256=PY4bbuZgxy3r0ccuBl-OuJvcPSMhyGz4FomxwYFhuvM,4821
62
74
  _mcp_mesh/pipeline/api_heartbeat/api_health_check.py,sha256=kDmFeOG_4tyqyJSBZjPcc7xTzGpP4vq6ObW_WBqXvzM,5130
63
75
  _mcp_mesh/pipeline/api_heartbeat/api_heartbeat_orchestrator.py,sha256=uBswzWOBzU8p_C0AE2DF8UwIWG4rP2zecHfPqKzNuC0,10367
@@ -76,20 +88,21 @@ _mcp_mesh/pipeline/mcp_heartbeat/__init__.py,sha256=nRNjZ3VD_9bPLQuJ6Nc02gE7KSLc
76
88
  _mcp_mesh/pipeline/mcp_heartbeat/dependency_resolution.py,sha256=qQ1KhrRYroYL2nnjLufXsXaaAO593GnuvJrRy_Ws97k,17764
77
89
  _mcp_mesh/pipeline/mcp_heartbeat/fast_heartbeat_check.py,sha256=QTzYdL81WERkOaBVOgNbFQh1ddTn70urNtyIgtFTudA,4465
78
90
  _mcp_mesh/pipeline/mcp_heartbeat/heartbeat_orchestrator.py,sha256=uB9o298X7GbOaKUw4ij_fUAOCpK0n2brx_oWqWGTXFY,11296
79
- _mcp_mesh/pipeline/mcp_heartbeat/heartbeat_pipeline.py,sha256=Jb7EVJO13trUVO3aCSgzGqAtoc4vie5kDrYLZtOkiXg,11601
91
+ _mcp_mesh/pipeline/mcp_heartbeat/heartbeat_pipeline.py,sha256=g1Vl9Xt5ibZwZzrNZoWt4fxAf8ssRZaN6p7cXGeYhTQ,11766
80
92
  _mcp_mesh/pipeline/mcp_heartbeat/heartbeat_send.py,sha256=ydVx-Vb_RgW1WPCboHVdZfEwNbgDngFV6Y9elZIBrAw,3602
81
93
  _mcp_mesh/pipeline/mcp_heartbeat/lifespan_integration.py,sha256=4XPPlaJ6rz-FkDO3bxzVxHmVF-aq1CCaTW4vIBXrB0c,3016
94
+ _mcp_mesh/pipeline/mcp_heartbeat/llm_tools_resolution.py,sha256=uusZTIEL2VVjGezJKotjNV1-c5on56nDWL9FyPRpzw0,8803
82
95
  _mcp_mesh/pipeline/mcp_heartbeat/registry_connection.py,sha256=4abbOKN3echwX82PV0RvxF6cJZUu0pMgisOpILZ_ZzY,2875
83
96
  _mcp_mesh/pipeline/mcp_startup/__init__.py,sha256=gS0xNmVx66bkLUMw64olMsN40ZLPH3ymwlLixZ4NuTs,1239
84
97
  _mcp_mesh/pipeline/mcp_startup/configuration.py,sha256=6LRLIxrqFMU76qrBb6GjGknUlKPZZ9iqOlxE7F9ZhLs,2808
85
98
  _mcp_mesh/pipeline/mcp_startup/decorator_collection.py,sha256=RHC6MHtfP9aP0hZ-IJjISZu72e0Pml3LU0qr7dc284w,2294
86
99
  _mcp_mesh/pipeline/mcp_startup/fastapiserver_setup.py,sha256=ktCn1IB8J3Iz7T0iUJF_ytwwO_RRbJN3dNQ6qZLY6iI,40229
87
- _mcp_mesh/pipeline/mcp_startup/fastmcpserver_discovery.py,sha256=ktsE9EZYdyZbCtCKB6HVdzGFMQ0E9n0-7I55LRO99sE,10270
100
+ _mcp_mesh/pipeline/mcp_startup/fastmcpserver_discovery.py,sha256=9n8hlCn4TPHCYcQlAQwA6VnuXPf_MUjuVrszqFD9RYQ,10660
88
101
  _mcp_mesh/pipeline/mcp_startup/heartbeat_loop.py,sha256=v85B0ynomvYu87eIvLe-aSZ7-Iwov2VtM4Fg3PkmrZs,3865
89
- _mcp_mesh/pipeline/mcp_startup/heartbeat_preparation.py,sha256=v3Fl0PvW5s7Ib_Cy7WtXA7gDvsFGiz54a-IlQRTcLPg,10410
102
+ _mcp_mesh/pipeline/mcp_startup/heartbeat_preparation.py,sha256=cjekOrPTzlcuFZci4IoIWQBQeCWomyI0iiSRGJgiVgA,13530
90
103
  _mcp_mesh/pipeline/mcp_startup/server_discovery.py,sha256=i3t12Dd2nEg3nbifyMGvm2SYr3WYiYJbicBakS3ZeuM,8007
91
104
  _mcp_mesh/pipeline/mcp_startup/startup_orchestrator.py,sha256=KldSG3xfGNm0iexnCMPkDsi3nuIVXBwneDBuoT5gJO4,26756
92
- _mcp_mesh/pipeline/mcp_startup/startup_pipeline.py,sha256=Y_VeZcvyT3y9phWtGD7cX92NzKZIzF2J6kRJUO8q-9U,2291
105
+ _mcp_mesh/pipeline/mcp_startup/startup_pipeline.py,sha256=cAAbqioYRswf-P25OpZFX2yL_qN2sl_bVk-kcynFxPw,2347
93
106
  _mcp_mesh/pipeline/shared/__init__.py,sha256=s9xmdf6LkoetrVRGd7Zp3NUxcJCW6YZ_yNKzUBcnYys,352
94
107
  _mcp_mesh/pipeline/shared/base_step.py,sha256=kyPbNUX79NyGrE_0Q-e-Aek7m1J0TW036njWfv0iZ0I,1080
95
108
  _mcp_mesh/pipeline/shared/mesh_pipeline.py,sha256=UlQBrPWqbruFiUdVYgFKgPOpp_sMVsO97nZsWX90k9U,6498
@@ -103,7 +116,7 @@ _mcp_mesh/shared/fast_heartbeat_status.py,sha256=OquEsX9ZTbxY1lIsll0Mbb2KDzSJD76
103
116
  _mcp_mesh/shared/fastapi_middleware_manager.py,sha256=_h10dSL9mgQstpJW_ZM2cpkU6yTKaYKlZaKXMk2i6IA,14638
104
117
  _mcp_mesh/shared/host_resolver.py,sha256=ycs6gXnI1zJX5KiqiLJPX5GkHX8r4j8NMHQOlG2J2X8,2964
105
118
  _mcp_mesh/shared/logging_config.py,sha256=n9AqShZ5BZgyrkoTlvux6ECRVpM9dUYvmGB0NPMl-Ak,2477
106
- _mcp_mesh/shared/registry_client_wrapper.py,sha256=d8yL-MiCrQr_WYdRFStOd531qaLv9kZjh0zJAmCJ-Cc,16976
119
+ _mcp_mesh/shared/registry_client_wrapper.py,sha256=R7KBjIW_vlE_4iLY4xmUcbk5Zeln9iKVIrxfA0vrXbs,19779
107
120
  _mcp_mesh/shared/server_discovery.py,sha256=W5nsN-GvEVFD-7XkbMTxh-9FUIEiyWOxP3GYr8GNi3E,13142
108
121
  _mcp_mesh/shared/simple_shutdown.py,sha256=jnF1rTR2yR619LZnEjNlu-ZdKlB3PovxKqG0VZ3HDgE,8319
109
122
  _mcp_mesh/shared/sse_parser.py,sha256=OEPnfL9xL3rsjQrbyvfUO82WljPSDeO6Z61uUwN1NAo,8035
@@ -115,10 +128,11 @@ _mcp_mesh/tracing/fastapi_tracing_middleware.py,sha256=o-xyAb1hB_GIFXv0hqUeTwhDD
115
128
  _mcp_mesh/tracing/redis_metadata_publisher.py,sha256=F78E34qnI3D0tOmbHUTBsLbDst2G7Su2-0F37Rq0rcM,4652
116
129
  _mcp_mesh/tracing/trace_context_helper.py,sha256=6tEkwjWFqMBe45zBlhacktmIpzJWTF950ph3bwL3cNc,5994
117
130
  _mcp_mesh/tracing/utils.py,sha256=t9lJuTH7CeuzAiiAaD0WxsJMFJPdzZFR0w6-vyR9f2E,3849
118
- mesh/__init__.py,sha256=l5RSMV8Kx0h7cvku8YkZPbTHjEPWciGT0bcEB2O_eNU,3242
119
- mesh/decorators.py,sha256=oBWoRE-FA3qUGygAUtk3-eAYBckwTGfTzvXOgCag4ys,36678
120
- mesh/types.py,sha256=g37DXAzya-xGPa1_WKlW3T3_VqyTn8ZVepIDSrhBTkc,10815
121
- mcp_mesh-0.5.7.dist-info/METADATA,sha256=mouhZmaO4Ce2rGSiCRXJXVNA-aRxBc-seygYUCKmJhI,4879
122
- mcp_mesh-0.5.7.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
123
- mcp_mesh-0.5.7.dist-info/licenses/LICENSE,sha256=_EBQHRQThv9FPOLc5eFOUdeeRO0mYwChC7cx60dM1tM,1078
124
- mcp_mesh-0.5.7.dist-info/RECORD,,
131
+ _mcp_mesh/utils/fastmcp_schema_extractor.py,sha256=M54ffesC-56zl_fNJHj9dZxElDQaWFf1MXdSLCuFStg,17253
132
+ mesh/__init__.py,sha256=fiCNEhOPPDnElXdMQ_CJ1c1hhYopL6_rNw98PztPxYA,3405
133
+ mesh/decorators.py,sha256=gvtIBojywunvnM5xuye2nCMkleTxFBPQny4EDkqsVk4,50711
134
+ mesh/types.py,sha256=g5bU_FKuMoxESvLcgoiYTabQVv2tbjE5D8xpPlNoX1E,13309
135
+ mcp_mesh-0.6.0.dist-info/METADATA,sha256=4uMWsKPwpg5x0aK9a_Lb1p1iqscyVfIFImqqLC4mofI,4879
136
+ mcp_mesh-0.6.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
137
+ mcp_mesh-0.6.0.dist-info/licenses/LICENSE,sha256=_EBQHRQThv9FPOLc5eFOUdeeRO0mYwChC7cx60dM1tM,1078
138
+ mcp_mesh-0.6.0.dist-info/RECORD,,
mesh/__init__.py CHANGED
@@ -19,7 +19,7 @@ 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 McpAgent, McpMeshAgent
22
+ from .types import McpMeshAgent, MeshContextModel, MeshLlmAgent
23
23
 
24
24
  __version__ = "1.0.0"
25
25
 
@@ -87,7 +87,7 @@ def create_server(name: str | None = None) -> "FastMCP":
87
87
  return FastMCP(name=name)
88
88
 
89
89
 
90
- # Make decorators available as mesh.tool, mesh.agent, and mesh.route
90
+ # Make decorators available as mesh.tool, mesh.agent, mesh.route, and mesh.llm
91
91
  def __getattr__(name):
92
92
  if name == "tool":
93
93
  return decorators.tool
@@ -95,10 +95,14 @@ def __getattr__(name):
95
95
  return decorators.agent
96
96
  elif name == "route":
97
97
  return decorators.route
98
+ elif name == "llm":
99
+ return decorators.llm
98
100
  elif name == "McpMeshAgent":
99
101
  return McpMeshAgent
100
- elif name == "McpAgent":
101
- return McpAgent
102
+ elif name == "MeshContextModel":
103
+ return MeshContextModel
104
+ elif name == "MeshLlmAgent":
105
+ return MeshLlmAgent
102
106
  elif name == "create_server":
103
107
  return create_server
104
108
  raise AttributeError(f"module '{__name__}' has no attribute '{name}'")