kailash 0.6.2__py3-none-any.whl → 0.6.3__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.
kailash/__init__.py CHANGED
@@ -33,7 +33,7 @@ except ImportError:
33
33
  # For backward compatibility
34
34
  WorkflowGraph = Workflow
35
35
 
36
- __version__ = "0.6.2"
36
+ __version__ = "0.6.3"
37
37
 
38
38
  __all__ = [
39
39
  # Core workflow components
@@ -12,8 +12,8 @@ Design Philosophy:
12
12
 
13
13
  Key Components:
14
14
  - MCPClient: Connects to MCP servers for tool and resource access
15
- - MCPServer: Base framework for creating custom MCP servers
16
- - SimpleMCPServer: Quick server creation for basic use cases
15
+ - MCPServer: Main production-ready server with all features
16
+ - MCPServerBase: Abstract base class for custom server implementations
17
17
 
18
18
  Upstream Dependencies:
19
19
  - Official Anthropic MCP Python SDK for protocol implementation
@@ -28,26 +28,31 @@ Downstream Consumers:
28
28
  Examples:
29
29
  Basic MCP client usage:
30
30
 
31
- >>> from kailash.mcp import MCPClient
31
+ >>> from kailash.mcp_server import MCPClient
32
32
  >>> client = MCPClient()
33
33
  >>> tools = await client.discover_tools(server_config)
34
34
  >>> result = await client.call_tool(server_config, "search", {"query": "AI"})
35
35
 
36
36
  Simple MCP server creation:
37
37
 
38
- >>> from kailash.mcp import SimpleMCPServer
39
- >>> server = SimpleMCPServer("my-tools")
38
+ >>> from kailash.mcp_server import MCPServer
39
+ >>> server = MCPServer("my-tools")
40
40
  >>> @server.tool()
41
41
  ... def calculate(a: int, b: int) -> int:
42
42
  ... return a + b
43
- >>> server.start()
43
+ >>> server.run()
44
44
  """
45
45
 
46
46
  from .client import MCPClient
47
- from .server_enhanced import MCPServer, SimpleMCPServer
47
+
48
+ # For backward compatibility
49
+ from .server import EnhancedMCPServer, MCPServer, MCPServerBase, SimpleMCPServer
48
50
 
49
51
  __all__ = [
50
52
  "MCPClient",
51
53
  "MCPServer",
54
+ "MCPServerBase",
55
+ # Backward compatibility
52
56
  "SimpleMCPServer",
57
+ "EnhancedMCPServer",
53
58
  ]
@@ -5,7 +5,7 @@ AI Registry MCP Server using Anthropic's Official MCP Python SDK.
5
5
  This creates a real MCP server that exposes AI Registry tools following
6
6
  the actual Model Context Protocol specification.
7
7
 
8
- Run as: python -m kailash.mcp.ai_registry_server
8
+ Run as: python -m kailash.mcp_server.ai_registry_server
9
9
  """
10
10
 
11
11
  import asyncio
@@ -708,5 +708,5 @@ if __name__ == "__main__":
708
708
 
709
709
  # For module execution
710
710
  def run_server():
711
- """Entry point for python -m kailash.mcp.ai_registry_server"""
711
+ """Entry point for python -m kailash.mcp_server.ai_registry_server"""
712
712
  asyncio.run(main())
@@ -1,16 +1,39 @@
1
1
  """
2
- Enhanced MCP Server with production-ready capabilities.
3
-
4
- This module provides an enhanced MCP server that includes caching, configuration,
5
- metrics, and other production features by default, while maintaining compatibility
6
- with the official Anthropic FastMCP framework.
2
+ MCP Server Framework with production-ready capabilities.
3
+
4
+ This module provides both basic and enhanced MCP server implementations using
5
+ the official FastMCP framework from Anthropic. Servers run as long-lived
6
+ services that expose tools, resources, and prompts to MCP clients.
7
+
8
+ Basic Usage:
9
+ Abstract base class for custom servers:
10
+
11
+ >>> class MyServer(MCPServerBase):
12
+ ... def setup(self):
13
+ ... @self.add_tool()
14
+ ... def calculate(a: int, b: int) -> int:
15
+ ... return a + b
16
+ >>> server = MyServer("calculator")
17
+ >>> server.start()
18
+
19
+ Production Usage:
20
+ Main server with all production features:
21
+
22
+ >>> from kailash.mcp_server import MCPServer
23
+ >>> server = MCPServer("my-server", enable_cache=True)
24
+ >>> @server.tool(cache_key="search", cache_ttl=600)
25
+ ... def search(query: str) -> dict:
26
+ ... return {"results": f"Found data for {query}"}
27
+ >>> server.run()
7
28
  """
8
29
 
9
30
  import asyncio
10
31
  import functools
11
32
  import logging
33
+ from abc import ABC, abstractmethod
34
+ from collections.abc import Callable
12
35
  from pathlib import Path
13
- from typing import Any, Callable, Dict, Optional, TypeVar, Union
36
+ from typing import Any, Dict, Optional, TypeVar, Union
14
37
 
15
38
  from .utils import CacheManager, ConfigManager, MetricsCollector, format_response
16
39
 
@@ -19,18 +42,199 @@ logger = logging.getLogger(__name__)
19
42
  F = TypeVar("F", bound=Callable[..., Any])
20
43
 
21
44
 
45
+ class MCPServerBase(ABC):
46
+ """Base class for MCP servers using FastMCP.
47
+
48
+ This provides a framework for creating MCP servers that expose
49
+ tools, resources, and prompts via the Model Context Protocol.
50
+
51
+ Examples:
52
+ Creating a custom server:
53
+
54
+ >>> class MyServer(MCPServerBase):
55
+ ... def setup(self):
56
+ ... @self.add_tool()
57
+ ... def search(query: str) -> str:
58
+ ... return f"Results for: {query}"
59
+ ... @self.add_resource("data://example")
60
+ ... def get_example():
61
+ ... return "Example data"
62
+ >>> server = MyServer("my-server", port=8080)
63
+ >>> server.start() # Runs until stopped
64
+ """
65
+
66
+ def __init__(self, name: str, port: int = 8080, host: str = "localhost"):
67
+ """Initialize the MCP server.
68
+
69
+ Args:
70
+ name: Name of the server.
71
+ port: Port to listen on (default: 8080).
72
+ host: Host to bind to (default: "localhost").
73
+ """
74
+ self.name = name
75
+ self.port = port
76
+ self.host = host
77
+ self._mcp = None
78
+ self._running = False
79
+
80
+ @abstractmethod
81
+ def setup(self):
82
+ """Setup server tools, resources, and prompts.
83
+
84
+ This method should be implemented by subclasses to define
85
+ the server's capabilities using decorators.
86
+
87
+ Note:
88
+ Use @self.add_tool(), @self.add_resource(uri), and
89
+ @self.add_prompt(name) decorators to register capabilities.
90
+ """
91
+
92
+ def add_tool(self):
93
+ """Decorator to add a tool to the server.
94
+
95
+ Returns:
96
+ Function decorator for registering tools.
97
+
98
+ Examples:
99
+ >>> @server.add_tool()
100
+ ... def calculate(a: int, b: int) -> int:
101
+ ... '''Add two numbers'''
102
+ ... return a + b
103
+ """
104
+
105
+ def decorator(func: Callable):
106
+ if self._mcp is None:
107
+ self._init_mcp()
108
+
109
+ # Use FastMCP's tool decorator
110
+ return self._mcp.tool()(func)
111
+
112
+ return decorator
113
+
114
+ def add_resource(self, uri: str):
115
+ """Decorator to add a resource to the server.
116
+
117
+ Args:
118
+ uri: URI pattern for the resource (supports wildcards).
119
+
120
+ Returns:
121
+ Function decorator for registering resources.
122
+
123
+ Examples:
124
+ >>> @server.add_resource("file:///data/*")
125
+ ... def get_file(path: str) -> str:
126
+ ... return f"Content of {path}"
127
+ """
128
+
129
+ def decorator(func: Callable):
130
+ if self._mcp is None:
131
+ self._init_mcp()
132
+
133
+ # Use FastMCP's resource decorator
134
+ return self._mcp.resource(uri)(func)
135
+
136
+ return decorator
137
+
138
+ def add_prompt(self, name: str):
139
+ """Decorator to add a prompt template to the server.
140
+
141
+ Args:
142
+ name: Name of the prompt.
143
+
144
+ Returns:
145
+ Function decorator for registering prompts.
146
+
147
+ Examples:
148
+ >>> @server.add_prompt("analyze")
149
+ ... def analyze_prompt(data: str) -> str:
150
+ ... return f"Please analyze the following data: {data}"
151
+ """
152
+
153
+ def decorator(func: Callable):
154
+ if self._mcp is None:
155
+ self._init_mcp()
156
+
157
+ # Use FastMCP's prompt decorator
158
+ return self._mcp.prompt(name)(func)
159
+
160
+ return decorator
161
+
162
+ def _init_mcp(self):
163
+ """Initialize the FastMCP instance."""
164
+ try:
165
+ from mcp.server import FastMCP
166
+
167
+ self._mcp = FastMCP(self.name)
168
+ except ImportError:
169
+ logger.error(
170
+ "FastMCP not available. Install with: pip install 'mcp[server]'"
171
+ )
172
+ raise
173
+
174
+ def start(self):
175
+ """Start the MCP server.
176
+
177
+ This runs the server as a long-lived process until stopped.
178
+
179
+ Raises:
180
+ ImportError: If FastMCP is not available.
181
+ Exception: If server fails to start.
182
+ """
183
+ if self._mcp is None:
184
+ self._init_mcp()
185
+
186
+ # Run setup to register tools/resources
187
+ self.setup()
188
+
189
+ logger.info(f"Starting MCP server '{self.name}' on {self.host}:{self.port}")
190
+ self._running = True
191
+
192
+ try:
193
+ # Run the FastMCP server
194
+ logger.info("Running FastMCP server in stdio mode")
195
+ self._mcp.run()
196
+ except Exception as e:
197
+ logger.error(f"Failed to start server: {e}")
198
+ raise
199
+ finally:
200
+ self._running = False
201
+
202
+ def stop(self):
203
+ """Stop the MCP server."""
204
+ logger.info(f"Stopping MCP server '{self.name}'")
205
+ self._running = False
206
+ # In a real implementation, we'd need to handle graceful shutdown
207
+
208
+
22
209
  class EnhancedMCPServer:
23
210
  """
24
- Production-ready MCP server with enhanced capabilities.
211
+ Production-ready MCP server (available as SimpleMCPServer).
25
212
 
26
- Features included by default:
27
- - Caching with TTL support
213
+ This is the main concrete MCP server implementation with all production
214
+ features available. Features can be enabled/disabled as needed.
215
+
216
+ Features available:
217
+ - Caching with TTL support (enable_cache=True)
218
+ - Metrics collection and monitoring (enable_metrics=True)
219
+ - Response formatting utilities (enable_formatting=True)
28
220
  - Hierarchical configuration management
29
- - Metrics collection and monitoring
30
- - Response formatting utilities
31
221
  - Error handling and logging
32
222
 
33
- All features can be disabled if not needed.
223
+ Examples:
224
+ Basic usage (recommended):
225
+ >>> from kailash.mcp_server import MCPServer
226
+ >>> server = MCPServer("my-server")
227
+ >>> @server.tool()
228
+ ... def search(query: str) -> dict:
229
+ ... return {"results": f"Found: {query}"}
230
+ >>> server.run()
231
+
232
+ With production features enabled:
233
+ >>> server = MCPServer("my-server", enable_cache=True, enable_metrics=True)
234
+ >>> @server.tool(cache_key="search", cache_ttl=600)
235
+ ... def search(query: str) -> dict:
236
+ ... return {"results": f"Found: {query}"}
237
+ >>> server.run()
34
238
  """
35
239
 
36
240
  def __init__(
@@ -104,15 +308,21 @@ class EnhancedMCPServer:
104
308
  return
105
309
 
106
310
  try:
107
- from mcp.server.fastmcp import FastMCP
311
+ # Now we can safely import from external mcp.server (no namespace collision)
312
+ from mcp.server import FastMCP
108
313
 
109
314
  self._mcp = FastMCP(self.name)
110
315
  logger.info(f"Initialized FastMCP server: {self.name}")
111
- except ImportError:
316
+ except ImportError as e:
317
+ logger.error(
318
+ f"FastMCP import failed with: {e}. Details: {type(e).__name__}"
319
+ )
112
320
  logger.error(
113
321
  "FastMCP not available. Install with: pip install 'mcp[server]'"
114
322
  )
115
- raise
323
+ raise ImportError(
324
+ "FastMCP not available. Install with: pip install 'mcp[server]'"
325
+ ) from e
116
326
 
117
327
  def tool(
118
328
  self,
@@ -413,37 +623,10 @@ class EnhancedMCPServer:
413
623
  self._running = False
414
624
 
415
625
 
416
- # For backward compatibility, make EnhancedMCPServer the default MCPServer
626
+ # Clean public API design:
627
+ # - MCPServerBase: Abstract base for custom implementations (e.g., AIRegistryServer)
628
+ # - MCPServer: Main concrete server with all production features
629
+ # - SimpleMCPServer: Alias for backward compatibility
630
+ # - EnhancedMCPServer: Alias for backward compatibility
417
631
  MCPServer = EnhancedMCPServer
418
-
419
-
420
- class SimpleMCPServer(EnhancedMCPServer):
421
- """
422
- Simplified MCP server with minimal configuration.
423
-
424
- This inherits all enhanced capabilities but disables some features
425
- by default for simpler use cases.
426
- """
427
-
428
- def __init__(self, name: str, description: str = ""):
429
- """
430
- Initialize simple MCP server.
431
-
432
- Args:
433
- name: Server name
434
- description: Server description
435
- """
436
- # Initialize with some features disabled for simplicity
437
- super().__init__(
438
- name=name,
439
- enable_cache=False, # Disable cache by default
440
- enable_metrics=False, # Disable metrics by default
441
- enable_formatting=True, # Keep formatting for better output
442
- )
443
-
444
- self.description = description
445
-
446
- # Update config for simple use
447
- self.config.update(
448
- {"server": {"name": name, "description": description, "version": "1.0.0"}}
449
- )
632
+ SimpleMCPServer = EnhancedMCPServer
@@ -9,10 +9,10 @@ import os
9
9
  from pathlib import Path
10
10
  from typing import Any
11
11
 
12
- from kailash.mcp.server import MCPServer
12
+ from kailash.mcp_server.server import MCPServerBase
13
13
 
14
14
 
15
- class AIRegistryServer(MCPServer):
15
+ class AIRegistryServer(MCPServerBase):
16
16
  """MCP server for AI use case registry.
17
17
 
18
18
  Provides tools and resources for exploring AI use cases from
@@ -10,12 +10,7 @@ This module provides production-ready utilities for MCP servers including:
10
10
 
11
11
  from .cache import CacheManager, LRUCache, cached_query
12
12
  from .config import ConfigManager
13
- from .formatters import (
14
- format_response,
15
- json_formatter,
16
- markdown_formatter,
17
- search_formatter,
18
- )
13
+ from .formatters import format_response, json_formatter, markdown_formatter, search_formatter
19
14
  from .metrics import MetricsCollector
20
15
 
21
16
  __all__ = [
@@ -20,7 +20,7 @@ from kailash.workflow.builder import WorkflowBuilder
20
20
 
21
21
  # Import existing Kailash MCP components
22
22
  try:
23
- from kailash.mcp import MCPClient
23
+ from kailash.mcp_server import MCPClient
24
24
 
25
25
  _KAILASH_MCP_AVAILABLE = True
26
26
  except ImportError:
@@ -24,8 +24,8 @@ from kailash.workflow.builder import WorkflowBuilder
24
24
 
25
25
  # Import existing Kailash MCP components
26
26
  try:
27
- from kailash.mcp import MCPServer, SimpleMCPServer
28
- from kailash.mcp.utils import CacheManager, ConfigManager, MetricsCollector
27
+ from kailash.mcp_server import MCPServer, SimpleMCPServer
28
+ from kailash.mcp_server.utils import CacheManager, ConfigManager, MetricsCollector
29
29
 
30
30
  _KAILASH_MCP_AVAILABLE = True
31
31
  except ImportError:
@@ -457,7 +457,7 @@ class IterativeLLMAgentNode(LLMAgentNode):
457
457
  try:
458
458
  # Ensure MCP client is initialized
459
459
  if not hasattr(self, "_mcp_client"):
460
- from kailash.mcp import MCPClient
460
+ from kailash.mcp_server import MCPClient
461
461
 
462
462
  self._mcp_client = MCPClient()
463
463
 
@@ -985,7 +985,7 @@ class LLMAgentNode(Node):
985
985
  import asyncio
986
986
  from datetime import datetime
987
987
 
988
- from kailash.mcp import MCPClient
988
+ from kailash.mcp_server import MCPClient
989
989
 
990
990
  # Initialize MCP client if not already done
991
991
  if not hasattr(self, "_mcp_client"):
@@ -1182,7 +1182,7 @@ class LLMAgentNode(Node):
1182
1182
 
1183
1183
  if use_real_mcp:
1184
1184
  try:
1185
- from kailash.mcp import MCPClient
1185
+ from kailash.mcp_server import MCPClient
1186
1186
 
1187
1187
  # Initialize MCP client if not already done
1188
1188
  if not hasattr(self, "_mcp_client"):
@@ -1767,7 +1767,7 @@ class LLMAgentNode(Node):
1767
1767
  server_config = mcp_tool.get("function", {}).get("mcp_server_config", {})
1768
1768
 
1769
1769
  try:
1770
- from kailash.mcp import MCPClient
1770
+ from kailash.mcp_server import MCPClient
1771
1771
 
1772
1772
  # Initialize MCP client if not already done
1773
1773
  if not hasattr(self, "_mcp_client"):
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: kailash
3
- Version: 0.6.2
3
+ Version: 0.6.3
4
4
  Summary: Python SDK for the Kailash container-node architecture
5
5
  Home-page: https://github.com/integrum/kailash-python-sdk
6
6
  Author: Integrum
@@ -21,7 +21,7 @@ Requires-Dist: matplotlib>=3.5
21
21
  Requires-Dist: pyyaml>=6.0
22
22
  Requires-Dist: click>=8.0
23
23
  Requires-Dist: pytest>=8.3.5
24
- Requires-Dist: mcp[cli]>=1.9.2
24
+ Requires-Dist: mcp[cli,server]>=1.9.2
25
25
  Requires-Dist: pandas>=2.2.3
26
26
  Requires-Dist: numpy>=2.2.5
27
27
  Requires-Dist: scipy>=1.15.3
@@ -1,4 +1,4 @@
1
- kailash/__init__.py,sha256=ZV1hjURaVjSCN-pI1JcNDbpBxyaYv5DYgnhgupZRzSc,1724
1
+ kailash/__init__.py,sha256=8W7LrVttYlpEMHu8_N4a5CilyUWMORrc8rnCbaAJ8HU,1724
2
2
  kailash/__main__.py,sha256=vr7TVE5o16V6LsTmRFKG6RDKUXHpIWYdZ6Dok2HkHnI,198
3
3
  kailash/access_control.py,sha256=2ctdRFeSeu-d7DU04Aovxh6Rt_4t3IyQfkKEjTeQiMM,25519
4
4
  kailash/access_control_abac.py,sha256=FPfa_8PuDP3AxTjdWfiH3ntwWO8NodA0py9W8SE5dno,30263
@@ -43,18 +43,17 @@ kailash/gateway/api.py,sha256=xpK8PIamsqQPpKAJwacyV7RA_Snjv2pc_0ljnnU9Oy4,9534
43
43
  kailash/gateway/enhanced_gateway.py,sha256=IlN1XV01FQrF4rGcq_z9LE4uUHAAAQoVsRNToXENen0,13399
44
44
  kailash/gateway/resource_resolver.py,sha256=IC1dceiKfjfUWToYCIBcrUapuR3LlDG6RJ4o7haLY10,7746
45
45
  kailash/gateway/security.py,sha256=kf4Quf6u7dqhs80fQQ982eHbRb4weDKG0DaYNeKntT4,7557
46
- kailash/mcp/__init__.py,sha256=jQHP7EVT126QXmi0TqR1mU3QNrUeEB4oIC4sD4B2a8c,1813
47
- kailash/mcp/ai_registry_server.py,sha256=9pOzJnJFpxJnZPfLo2QvVZ5yvAq5IRqzXPbQL1rL1ns,28104
48
- kailash/mcp/client.py,sha256=sTouSiuiu1nbahMXSWcP8-mr1k7cqdBCzSxm8G7le-s,16058
49
- kailash/mcp/client_new.py,sha256=YU671JvAM0uvuX0uhGZCIKI8co3fqz0cs6HqLZ59Xyo,10285
50
- kailash/mcp/server.py,sha256=aWU0DHj89FN_eEgH6aVjA05WjthugrXMHdPlgwJ6kZg,8246
51
- kailash/mcp/server_enhanced.py,sha256=lRIDSNs0c8urMq_SURwi7eBhTWKa-rq2FAB8xZf9CwI,14724
52
- kailash/mcp/servers/ai_registry.py,sha256=7k17ld0DUQYL476N5EbiNpPy8D0HqPRhrl8Wk1ajjj8,9992
53
- kailash/mcp/utils/__init__.py,sha256=R20N-iiKXUPxc9MOh6vPO1vIfkPmwhEQ5KNFgGd4xSs,771
54
- kailash/mcp/utils/cache.py,sha256=dLEseovPaXL4lRzMSw7tqd3tJHwnWfhdZ-HKGyScJXI,8414
55
- kailash/mcp/utils/config.py,sha256=DyZxgdy3vqI5pwhQ_E-42mhueVGNHiuOtTUOrM9HC_U,8124
56
- kailash/mcp/utils/formatters.py,sha256=D-2j1nvmprApiUI13HWY-L2_WPSAcJDtVdHcshAuOdo,9740
57
- kailash/mcp/utils/metrics.py,sha256=MNUjWGQyq1EGdeqzAKCCZJNgcWHOyaYAV8MlS2cb-4k,13754
46
+ kailash/mcp_server/__init__.py,sha256=ETEeaRTqj2xeX07MyaRgcPiaomdLoJ24iNmRbRjJQok,1953
47
+ kailash/mcp_server/ai_registry_server.py,sha256=BkkZcohRyGlSbiUkpRTaIA6M_yJUgtgtMda-dvbT86s,28118
48
+ kailash/mcp_server/client.py,sha256=sTouSiuiu1nbahMXSWcP8-mr1k7cqdBCzSxm8G7le-s,16058
49
+ kailash/mcp_server/client_new.py,sha256=YU671JvAM0uvuX0uhGZCIKI8co3fqz0cs6HqLZ59Xyo,10285
50
+ kailash/mcp_server/server.py,sha256=z-72J5MKq98_j7zwo0HJMbMI9bp5yuNpyfIzD9N23yw,20600
51
+ kailash/mcp_server/servers/ai_registry.py,sha256=IdF_keUuJlMsvjLjSAykxxbm46K4qA7eCj7T-lYSrzk,10007
52
+ kailash/mcp_server/utils/__init__.py,sha256=VjGFpvugTYUxoNgtwVEKkmrkVS3iZ_kIbP4jR1PRM6E,750
53
+ kailash/mcp_server/utils/cache.py,sha256=dLEseovPaXL4lRzMSw7tqd3tJHwnWfhdZ-HKGyScJXI,8414
54
+ kailash/mcp_server/utils/config.py,sha256=DyZxgdy3vqI5pwhQ_E-42mhueVGNHiuOtTUOrM9HC_U,8124
55
+ kailash/mcp_server/utils/formatters.py,sha256=D-2j1nvmprApiUI13HWY-L2_WPSAcJDtVdHcshAuOdo,9740
56
+ kailash/mcp_server/utils/metrics.py,sha256=MNUjWGQyq1EGdeqzAKCCZJNgcWHOyaYAV8MlS2cb-4k,13754
58
57
  kailash/middleware/__init__.py,sha256=ZGo0qujL-qWn82nIrojY96N1rMPTWFKHumW6CGGpb4Y,10409
59
58
  kailash/middleware/auth/__init__.py,sha256=VkKM8H-zVFx2PLGL7kyxE2IfSiV1HiwveSysbmxMcg0,2077
60
59
  kailash/middleware/auth/access_control.py,sha256=2FwQjp_fZm2fg-V_CIgAN69GGL9YwyZwsbQis0hbW7I,14848
@@ -87,8 +86,8 @@ kailash/middleware/gateway/durable_gateway.py,sha256=EsIgMNxS_no2W40AXDyE7FmVdnG
87
86
  kailash/middleware/gateway/durable_request.py,sha256=SCnp-bF0tQX9oahr9reqcZjJ_YhyJkeYYl-un9rJ6lo,15437
88
87
  kailash/middleware/gateway/event_store.py,sha256=A3Kh2MhVVPbXWvjeo550SqEGPiJYyspAfu6Gv7UZzo4,16131
89
88
  kailash/middleware/mcp/__init__.py,sha256=EdZB8zOMSBEEmudRzs8ksz9QZJYWQMEx7Tm1MOwIWnI,922
90
- kailash/middleware/mcp/client_integration.py,sha256=opzhB5TUts_ND8gARXh93nKCc1u4kwo6SqNMMWqMcSU,18258
91
- kailash/middleware/mcp/enhanced_server.py,sha256=XUjQt0KyRX207FVYAFenkYHa_K8FWWKquROgXQWkoOQ,18453
89
+ kailash/middleware/mcp/client_integration.py,sha256=dY1RmX-g5E6JzUFuWxk7viuOYIh8bMwoUSvHQMVEsYk,18265
90
+ kailash/middleware/mcp/enhanced_server.py,sha256=vVd7WE95c-5861VtKfmTZ91iUWFRw-aKEKwHlu6edQo,18467
92
91
  kailash/nodes/__init__.py,sha256=E6CEp1ooq4GgFhKtwVAczOhPt5N3x-AVQ-R0n3_IFyA,936
93
92
  kailash/nodes/base.py,sha256=Fu9c2I5k_Ke192y4fj2NVhf-Y_I0nPr0sDE1zMSRCJY,55417
94
93
  kailash/nodes/base_async.py,sha256=mpntaeFMbUYLIyTvjsb221mXckx_H2dGX2LhxeKhhfA,6569
@@ -112,8 +111,8 @@ kailash/nodes/ai/agents.py,sha256=CRA3cdapQjpuvOniXUh6ZVWAlRxUIepVw1BROW6QzdY,20
112
111
  kailash/nodes/ai/ai_providers.py,sha256=XeDIaYH7PrX8frWCVV6CYFNQXFjHX_61T3eR1yullqs,65355
113
112
  kailash/nodes/ai/embedding_generator.py,sha256=rsos3B6oWrgGTMIbwSWIBzGH9kq3SFVD_-bEDrujBRs,31860
114
113
  kailash/nodes/ai/intelligent_agent_orchestrator.py,sha256=xw44C-CkcNH3SVmEJ49o4oNV3o4ZqjLE9aLpggwoIXs,83021
115
- kailash/nodes/ai/iterative_llm_agent.py,sha256=pv54W_YDfDPDl6DJf0ul9_rs2mL2kE_C59sSAJ4CRn8,52884
116
- kailash/nodes/ai/llm_agent.py,sha256=-E95jRYZMJzZz7Y4jh4HYHmx7Hoid5ZvZqcEP-OsHqE,82177
114
+ kailash/nodes/ai/iterative_llm_agent.py,sha256=14SxTRGGGYRqNC0SFMaKAFplUcsQXAVzXKcjri_0oWM,52891
115
+ kailash/nodes/ai/llm_agent.py,sha256=0N5NU2HLwbh2_zFxrgwq2FlkVS6fifpEcMSI0BGX7ZQ,82198
117
116
  kailash/nodes/ai/models.py,sha256=wsEeUTuegy87mnLtKgSTg7ggCXvC1n3MsL-iZ4qujHs,16393
118
117
  kailash/nodes/ai/self_organizing.py,sha256=M7yCLkN4I1JCNU7PWuwrqwQSlaG9MJVxYIR44TV52MM,62877
119
118
  kailash/nodes/ai/vision_utils.py,sha256=OHD9cVH_mq0WpJyQkNTj_mpipIVWfSV_bF9eA6CdyeA,4166
@@ -271,9 +270,9 @@ kailash/workflow/state.py,sha256=UTZxs5-Ona6uvBhx1__i6-RX8gB4qazkBIWE7uyRmWQ,760
271
270
  kailash/workflow/templates.py,sha256=98EN5H4fO9b4xeczk20Hu5L8hNcAuRQNGayT6vnZYCw,48540
272
271
  kailash/workflow/validation.py,sha256=JIbIajWVIaWHSvWtgZ4WUVJaBaUOCz5B9cyTwM--dL4,33060
273
272
  kailash/workflow/visualization.py,sha256=ICMWCWqh5fOQ7eJygbvu2PMWHxe-H5_0epwdZuz8cMw,19737
274
- kailash-0.6.2.dist-info/licenses/LICENSE,sha256=Axe6g7bTrJkToK9h9j2SpRUKKNaDZDCo2lQ2zPxCE6s,1065
275
- kailash-0.6.2.dist-info/METADATA,sha256=lksSZ5ngxdJDTik-awxRlqV87v3BoZe82PPS6biRnww,25925
276
- kailash-0.6.2.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
277
- kailash-0.6.2.dist-info/entry_points.txt,sha256=M_q3b8PG5W4XbhSgESzIJjh3_4OBKtZFYFsOdkr2vO4,45
278
- kailash-0.6.2.dist-info/top_level.txt,sha256=z7GzH2mxl66498pVf5HKwo5wwfPtt9Aq95uZUpH6JV0,8
279
- kailash-0.6.2.dist-info/RECORD,,
273
+ kailash-0.6.3.dist-info/licenses/LICENSE,sha256=Axe6g7bTrJkToK9h9j2SpRUKKNaDZDCo2lQ2zPxCE6s,1065
274
+ kailash-0.6.3.dist-info/METADATA,sha256=PH0D-ORbBHT7eJjuIEMbrcr1CWNlQpY36Ncy4jGJ-wg,25932
275
+ kailash-0.6.3.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
276
+ kailash-0.6.3.dist-info/entry_points.txt,sha256=M_q3b8PG5W4XbhSgESzIJjh3_4OBKtZFYFsOdkr2vO4,45
277
+ kailash-0.6.3.dist-info/top_level.txt,sha256=z7GzH2mxl66498pVf5HKwo5wwfPtt9Aq95uZUpH6JV0,8
278
+ kailash-0.6.3.dist-info/RECORD,,
kailash/mcp/server.py DELETED
@@ -1,292 +0,0 @@
1
- """MCP Server Framework using official Anthropic SDK.
2
-
3
- This module provides a comprehensive framework for creating MCP servers using
4
- the official FastMCP framework from Anthropic. Servers run as long-lived
5
- services that expose tools, resources, and prompts to MCP clients, enabling
6
- dynamic capability extension for AI workflows.
7
-
8
- Note:
9
- This module requires the FastMCP framework to be installed.
10
- Install with: pip install 'mcp[server]'
11
-
12
- Examples:
13
- Basic server with tools:
14
-
15
- >>> from kailash.mcp.server import MCPServer
16
- >>> class MyServer(MCPServer):
17
- ... def setup(self):
18
- ... @self.add_tool()
19
- ... def calculate(a: int, b: int) -> int:
20
- ... return a + b
21
- >>> server = MyServer("calculator", port=8080)
22
- >>> server.start()
23
-
24
- Quick server creation:
25
-
26
- >>> from kailash.mcp.server import SimpleMCPServer
27
- >>> server = SimpleMCPServer("my-tools")
28
- >>> @server.tool()
29
- ... def search(query: str) -> list:
30
- ... return [f"Result for {query}"]
31
- >>> server.start()
32
- """
33
-
34
- import logging
35
- from abc import ABC, abstractmethod
36
- from collections.abc import Callable
37
-
38
- logger = logging.getLogger(__name__)
39
-
40
-
41
- class MCPServer(ABC):
42
- """Base class for MCP servers using FastMCP.
43
-
44
- This provides a framework for creating MCP servers that expose
45
- tools, resources, and prompts via the Model Context Protocol.
46
-
47
- Examples:
48
- Creating a custom server:
49
-
50
- >>> class MyServer(MCPServer):
51
- ... def setup(self):
52
- ... @self.add_tool()
53
- ... def search(query: str) -> str:
54
- ... return f"Results for: {query}"
55
- ... @self.add_resource("data://example")
56
- ... def get_example():
57
- ... return "Example data"
58
- >>> server = MyServer("my-server", port=8080)
59
- >>> server.start() # Runs until stopped
60
- """
61
-
62
- def __init__(self, name: str, port: int = 8080, host: str = "localhost"):
63
- """Initialize the MCP server.
64
-
65
- Args:
66
- name: Name of the server.
67
- port: Port to listen on (default: 8080).
68
- host: Host to bind to (default: "localhost").
69
- """
70
- self.name = name
71
- self.port = port
72
- self.host = host
73
- self._mcp = None
74
- self._running = False
75
-
76
- @abstractmethod
77
- def setup(self):
78
- """Setup server tools, resources, and prompts.
79
-
80
- This method should be implemented by subclasses to define
81
- the server's capabilities using decorators.
82
-
83
- Note:
84
- Use @self.add_tool(), @self.add_resource(uri), and
85
- @self.add_prompt(name) decorators to register capabilities.
86
- """
87
-
88
- def add_tool(self):
89
- """Decorator to add a tool to the server.
90
-
91
- Returns:
92
- Function decorator for registering tools.
93
-
94
- Examples:
95
- >>> @server.add_tool()
96
- ... def calculate(a: int, b: int) -> int:
97
- ... '''Add two numbers'''
98
- ... return a + b
99
- """
100
-
101
- def decorator(func: Callable):
102
- if self._mcp is None:
103
- self._init_mcp()
104
-
105
- # Use FastMCP's tool decorator
106
- return self._mcp.tool()(func)
107
-
108
- return decorator
109
-
110
- def add_resource(self, uri: str):
111
- """Decorator to add a resource to the server.
112
-
113
- Args:
114
- uri: URI pattern for the resource (supports wildcards).
115
-
116
- Returns:
117
- Function decorator for registering resources.
118
-
119
- Examples:
120
- >>> @server.add_resource("file:///data/*")
121
- ... def get_file(path: str) -> str:
122
- ... return f"Content of {path}"
123
- """
124
-
125
- def decorator(func: Callable):
126
- if self._mcp is None:
127
- self._init_mcp()
128
-
129
- # Use FastMCP's resource decorator
130
- return self._mcp.resource(uri)(func)
131
-
132
- return decorator
133
-
134
- def add_prompt(self, name: str):
135
- """Decorator to add a prompt template to the server.
136
-
137
- Args:
138
- name: Name of the prompt.
139
-
140
- Returns:
141
- Function decorator for registering prompts.
142
-
143
- Examples:
144
- >>> @server.add_prompt("analyze")
145
- ... def analyze_prompt(data: str) -> str:
146
- ... return f"Please analyze the following data: {data}"
147
- """
148
-
149
- def decorator(func: Callable):
150
- if self._mcp is None:
151
- self._init_mcp()
152
-
153
- # Use FastMCP's prompt decorator
154
- return self._mcp.prompt(name)(func)
155
-
156
- return decorator
157
-
158
- def _init_mcp(self):
159
- """Initialize the FastMCP instance."""
160
- try:
161
- from mcp.server.fastmcp import FastMCP
162
-
163
- self._mcp = FastMCP(self.name)
164
- except ImportError:
165
- logger.error(
166
- "FastMCP not available. Install with: pip install 'mcp[server]'"
167
- )
168
- raise
169
-
170
- def start(self):
171
- """Start the MCP server.
172
-
173
- This runs the server as a long-lived process until stopped.
174
-
175
- Raises:
176
- ImportError: If FastMCP is not available.
177
- Exception: If server fails to start.
178
- """
179
- if self._mcp is None:
180
- self._init_mcp()
181
-
182
- # Run setup to register tools/resources
183
- self.setup()
184
-
185
- logger.info(f"Starting MCP server '{self.name}' on {self.host}:{self.port}")
186
- self._running = True
187
-
188
- try:
189
- # Run the FastMCP server
190
- logger.info("Running FastMCP server in stdio mode")
191
- self._mcp.run()
192
- except Exception as e:
193
- logger.error(f"Failed to start server: {e}")
194
- raise
195
- finally:
196
- self._running = False
197
-
198
- def stop(self):
199
- """Stop the MCP server."""
200
- logger.info(f"Stopping MCP server '{self.name}'")
201
- self._running = False
202
- # In a real implementation, we'd need to handle graceful shutdown
203
-
204
-
205
- class SimpleMCPServer(MCPServer):
206
- """Simple MCP server for basic use cases.
207
-
208
- This provides an easy way to create MCP servers without subclassing.
209
-
210
- Examples:
211
- >>> server = SimpleMCPServer("my-server")
212
- >>> @server.tool()
213
- ... def add(a: int, b: int) -> int:
214
- ... return a + b
215
- >>> server.start()
216
- """
217
-
218
- def __init__(self, name: str, port: int = 8080, host: str = "localhost"):
219
- """Initialize the simple MCP server.
220
-
221
- Args:
222
- name: Name of the server.
223
- port: Port to listen on (default: 8080).
224
- host: Host to bind to (default: "localhost").
225
- """
226
- super().__init__(name, port, host)
227
- self._tools = []
228
- self._resources = []
229
- self._prompts = []
230
-
231
- def tool(self):
232
- """Decorator to add a tool.
233
-
234
- Returns:
235
- Function decorator for registering tools.
236
- """
237
-
238
- def decorator(func):
239
- self._tools.append(func)
240
- return func
241
-
242
- return decorator
243
-
244
- def resource(self, uri: str):
245
- """Decorator to add a resource.
246
-
247
- Args:
248
- uri: URI pattern for the resource.
249
-
250
- Returns:
251
- Function decorator for registering resources.
252
- """
253
-
254
- def decorator(func):
255
- self._resources.append((uri, func))
256
- return func
257
-
258
- return decorator
259
-
260
- def prompt(self, name: str):
261
- """Decorator to add a prompt.
262
-
263
- Args:
264
- name: Name of the prompt.
265
-
266
- Returns:
267
- Function decorator for registering prompts.
268
- """
269
-
270
- def decorator(func):
271
- self._prompts.append((name, func))
272
- return func
273
-
274
- return decorator
275
-
276
- def setup(self):
277
- """Setup the server with registered components.
278
-
279
- Registers all tools, resources, and prompts that were decorated
280
- before calling start().
281
- """
282
- # Register all tools
283
- for tool_func in self._tools:
284
- self.add_tool()(tool_func)
285
-
286
- # Register all resources
287
- for uri, resource_func in self._resources:
288
- self.add_resource(uri)(resource_func)
289
-
290
- # Register all prompts
291
- for name, prompt_func in self._prompts:
292
- self.add_prompt(name)(prompt_func)
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes