kailash 0.3.2__py3-none-any.whl → 0.4.1__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 (151) hide show
  1. kailash/__init__.py +33 -1
  2. kailash/access_control/__init__.py +129 -0
  3. kailash/access_control/managers.py +461 -0
  4. kailash/access_control/rule_evaluators.py +467 -0
  5. kailash/access_control_abac.py +825 -0
  6. kailash/config/__init__.py +27 -0
  7. kailash/config/database_config.py +359 -0
  8. kailash/database/__init__.py +28 -0
  9. kailash/database/execution_pipeline.py +499 -0
  10. kailash/middleware/__init__.py +306 -0
  11. kailash/middleware/auth/__init__.py +33 -0
  12. kailash/middleware/auth/access_control.py +436 -0
  13. kailash/middleware/auth/auth_manager.py +422 -0
  14. kailash/middleware/auth/jwt_auth.py +477 -0
  15. kailash/middleware/auth/kailash_jwt_auth.py +616 -0
  16. kailash/middleware/communication/__init__.py +37 -0
  17. kailash/middleware/communication/ai_chat.py +989 -0
  18. kailash/middleware/communication/api_gateway.py +802 -0
  19. kailash/middleware/communication/events.py +470 -0
  20. kailash/middleware/communication/realtime.py +710 -0
  21. kailash/middleware/core/__init__.py +21 -0
  22. kailash/middleware/core/agent_ui.py +890 -0
  23. kailash/middleware/core/schema.py +643 -0
  24. kailash/middleware/core/workflows.py +396 -0
  25. kailash/middleware/database/__init__.py +63 -0
  26. kailash/middleware/database/base.py +113 -0
  27. kailash/middleware/database/base_models.py +525 -0
  28. kailash/middleware/database/enums.py +106 -0
  29. kailash/middleware/database/migrations.py +12 -0
  30. kailash/{api/database.py → middleware/database/models.py} +183 -291
  31. kailash/middleware/database/repositories.py +685 -0
  32. kailash/middleware/database/session_manager.py +19 -0
  33. kailash/middleware/mcp/__init__.py +38 -0
  34. kailash/middleware/mcp/client_integration.py +585 -0
  35. kailash/middleware/mcp/enhanced_server.py +576 -0
  36. kailash/nodes/__init__.py +27 -3
  37. kailash/nodes/admin/__init__.py +42 -0
  38. kailash/nodes/admin/audit_log.py +794 -0
  39. kailash/nodes/admin/permission_check.py +864 -0
  40. kailash/nodes/admin/role_management.py +823 -0
  41. kailash/nodes/admin/security_event.py +1523 -0
  42. kailash/nodes/admin/user_management.py +944 -0
  43. kailash/nodes/ai/a2a.py +24 -7
  44. kailash/nodes/ai/ai_providers.py +248 -40
  45. kailash/nodes/ai/embedding_generator.py +11 -11
  46. kailash/nodes/ai/intelligent_agent_orchestrator.py +99 -11
  47. kailash/nodes/ai/llm_agent.py +436 -5
  48. kailash/nodes/ai/self_organizing.py +85 -10
  49. kailash/nodes/ai/vision_utils.py +148 -0
  50. kailash/nodes/alerts/__init__.py +26 -0
  51. kailash/nodes/alerts/base.py +234 -0
  52. kailash/nodes/alerts/discord.py +499 -0
  53. kailash/nodes/api/auth.py +287 -6
  54. kailash/nodes/api/rest.py +151 -0
  55. kailash/nodes/auth/__init__.py +17 -0
  56. kailash/nodes/auth/directory_integration.py +1228 -0
  57. kailash/nodes/auth/enterprise_auth_provider.py +1328 -0
  58. kailash/nodes/auth/mfa.py +2338 -0
  59. kailash/nodes/auth/risk_assessment.py +872 -0
  60. kailash/nodes/auth/session_management.py +1093 -0
  61. kailash/nodes/auth/sso.py +1040 -0
  62. kailash/nodes/base.py +344 -13
  63. kailash/nodes/base_cycle_aware.py +4 -2
  64. kailash/nodes/base_with_acl.py +1 -1
  65. kailash/nodes/code/python.py +283 -10
  66. kailash/nodes/compliance/__init__.py +9 -0
  67. kailash/nodes/compliance/data_retention.py +1888 -0
  68. kailash/nodes/compliance/gdpr.py +2004 -0
  69. kailash/nodes/data/__init__.py +22 -2
  70. kailash/nodes/data/async_connection.py +469 -0
  71. kailash/nodes/data/async_sql.py +757 -0
  72. kailash/nodes/data/async_vector.py +598 -0
  73. kailash/nodes/data/readers.py +767 -0
  74. kailash/nodes/data/retrieval.py +360 -1
  75. kailash/nodes/data/sharepoint_graph.py +397 -21
  76. kailash/nodes/data/sql.py +94 -5
  77. kailash/nodes/data/streaming.py +68 -8
  78. kailash/nodes/data/vector_db.py +54 -4
  79. kailash/nodes/enterprise/__init__.py +13 -0
  80. kailash/nodes/enterprise/batch_processor.py +741 -0
  81. kailash/nodes/enterprise/data_lineage.py +497 -0
  82. kailash/nodes/logic/convergence.py +31 -9
  83. kailash/nodes/logic/operations.py +14 -3
  84. kailash/nodes/mixins/__init__.py +8 -0
  85. kailash/nodes/mixins/event_emitter.py +201 -0
  86. kailash/nodes/mixins/mcp.py +9 -4
  87. kailash/nodes/mixins/security.py +165 -0
  88. kailash/nodes/monitoring/__init__.py +7 -0
  89. kailash/nodes/monitoring/performance_benchmark.py +2497 -0
  90. kailash/nodes/rag/__init__.py +284 -0
  91. kailash/nodes/rag/advanced.py +1615 -0
  92. kailash/nodes/rag/agentic.py +773 -0
  93. kailash/nodes/rag/conversational.py +999 -0
  94. kailash/nodes/rag/evaluation.py +875 -0
  95. kailash/nodes/rag/federated.py +1188 -0
  96. kailash/nodes/rag/graph.py +721 -0
  97. kailash/nodes/rag/multimodal.py +671 -0
  98. kailash/nodes/rag/optimized.py +933 -0
  99. kailash/nodes/rag/privacy.py +1059 -0
  100. kailash/nodes/rag/query_processing.py +1335 -0
  101. kailash/nodes/rag/realtime.py +764 -0
  102. kailash/nodes/rag/registry.py +547 -0
  103. kailash/nodes/rag/router.py +837 -0
  104. kailash/nodes/rag/similarity.py +1854 -0
  105. kailash/nodes/rag/strategies.py +566 -0
  106. kailash/nodes/rag/workflows.py +575 -0
  107. kailash/nodes/security/__init__.py +19 -0
  108. kailash/nodes/security/abac_evaluator.py +1411 -0
  109. kailash/nodes/security/audit_log.py +103 -0
  110. kailash/nodes/security/behavior_analysis.py +1893 -0
  111. kailash/nodes/security/credential_manager.py +401 -0
  112. kailash/nodes/security/rotating_credentials.py +760 -0
  113. kailash/nodes/security/security_event.py +133 -0
  114. kailash/nodes/security/threat_detection.py +1103 -0
  115. kailash/nodes/testing/__init__.py +9 -0
  116. kailash/nodes/testing/credential_testing.py +499 -0
  117. kailash/nodes/transform/__init__.py +10 -2
  118. kailash/nodes/transform/chunkers.py +592 -1
  119. kailash/nodes/transform/processors.py +484 -14
  120. kailash/nodes/validation.py +321 -0
  121. kailash/runtime/access_controlled.py +1 -1
  122. kailash/runtime/async_local.py +41 -7
  123. kailash/runtime/docker.py +1 -1
  124. kailash/runtime/local.py +474 -55
  125. kailash/runtime/parallel.py +1 -1
  126. kailash/runtime/parallel_cyclic.py +1 -1
  127. kailash/runtime/testing.py +210 -2
  128. kailash/security.py +1 -1
  129. kailash/utils/migrations/__init__.py +25 -0
  130. kailash/utils/migrations/generator.py +433 -0
  131. kailash/utils/migrations/models.py +231 -0
  132. kailash/utils/migrations/runner.py +489 -0
  133. kailash/utils/secure_logging.py +342 -0
  134. kailash/workflow/__init__.py +16 -0
  135. kailash/workflow/cyclic_runner.py +3 -4
  136. kailash/workflow/graph.py +70 -2
  137. kailash/workflow/resilience.py +249 -0
  138. kailash/workflow/templates.py +726 -0
  139. {kailash-0.3.2.dist-info → kailash-0.4.1.dist-info}/METADATA +256 -20
  140. kailash-0.4.1.dist-info/RECORD +227 -0
  141. kailash/api/__init__.py +0 -17
  142. kailash/api/__main__.py +0 -6
  143. kailash/api/studio_secure.py +0 -893
  144. kailash/mcp/__main__.py +0 -13
  145. kailash/mcp/server_new.py +0 -336
  146. kailash/mcp/servers/__init__.py +0 -12
  147. kailash-0.3.2.dist-info/RECORD +0 -136
  148. {kailash-0.3.2.dist-info → kailash-0.4.1.dist-info}/WHEEL +0 -0
  149. {kailash-0.3.2.dist-info → kailash-0.4.1.dist-info}/entry_points.txt +0 -0
  150. {kailash-0.3.2.dist-info → kailash-0.4.1.dist-info}/licenses/LICENSE +0 -0
  151. {kailash-0.3.2.dist-info → kailash-0.4.1.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,576 @@
1
+ """
2
+ Enhanced MCP Server for Kailash Middleware
3
+
4
+ Built entirely with Kailash SDK components - consolidates existing MCP
5
+ implementations with middleware-specific features for enterprise use.
6
+ """
7
+
8
+ import asyncio
9
+ import json
10
+ import logging
11
+ import uuid
12
+ from datetime import datetime, timezone
13
+ from typing import Any, Callable, Dict, List, Optional
14
+
15
+ from kailash.nodes.ai import LLMAgentNode
16
+
17
+ # Import Kailash SDK components
18
+ from kailash.nodes.base import Node, NodeParameter
19
+ from kailash.nodes.code import PythonCodeNode
20
+ from kailash.nodes.data import JSONReaderNode
21
+ from kailash.nodes.logic import SwitchNode
22
+ from kailash.runtime.local import LocalRuntime
23
+ from kailash.workflow.builder import WorkflowBuilder
24
+
25
+ # Import existing Kailash MCP components
26
+ try:
27
+ from kailash.mcp import MCPServer, SimpleMCPServer
28
+ from kailash.mcp.utils import CacheManager, ConfigManager, MetricsCollector
29
+
30
+ _KAILASH_MCP_AVAILABLE = True
31
+ except ImportError:
32
+ _KAILASH_MCP_AVAILABLE = False
33
+
34
+ # Import middleware components
35
+ from ..communication.events import EventStream, EventType
36
+ from ..core.agent_ui import AgentUIMiddleware
37
+
38
+ logger = logging.getLogger(__name__)
39
+
40
+
41
+ class MCPServerConfig:
42
+ """Configuration for Middleware MCP Server using Kailash patterns."""
43
+
44
+ def __init__(self):
45
+ self.name = "kailash-middleware-mcp"
46
+ self.version = "1.0.0"
47
+ self.description = "Enhanced MCP server built with Kailash SDK"
48
+
49
+ # Kailash-specific settings
50
+ self.enable_caching = True
51
+ self.cache_ttl = 300
52
+ self.enable_metrics = True
53
+ self.enable_events = True
54
+
55
+ # Server settings
56
+ self.max_tools = 100
57
+ self.max_resources = 50
58
+ self.enable_streaming = True
59
+
60
+
61
+ class MCPToolNode(Node):
62
+ """Kailash node representing an MCP tool."""
63
+
64
+ def __init__(
65
+ self,
66
+ name: str,
67
+ tool_name: str,
68
+ description: str = "",
69
+ parameters_schema: Dict[str, Any] = None,
70
+ ):
71
+ super().__init__(name)
72
+ self.tool_name = tool_name
73
+ self.description = description
74
+ self.parameters_schema = parameters_schema or {}
75
+ self.execution_count = 0
76
+ self.last_executed = None
77
+
78
+ def get_parameters(self) -> Dict[str, NodeParameter]:
79
+ """Generate parameters from tool schema."""
80
+ params = {}
81
+
82
+ # Always include tool input parameter
83
+ params["tool_input"] = NodeParameter(
84
+ name="tool_input",
85
+ type=dict,
86
+ required=True,
87
+ description="Input data for the MCP tool",
88
+ )
89
+
90
+ # Add schema-specific parameters
91
+ for param_name, param_info in self.parameters_schema.items():
92
+ params[param_name] = NodeParameter(
93
+ name=param_name,
94
+ type=param_info.get("type", str),
95
+ required=param_info.get("required", False),
96
+ description=param_info.get("description", f"Parameter {param_name}"),
97
+ )
98
+
99
+ return params
100
+
101
+ def process(self, inputs: Dict[str, Any]) -> Dict[str, Any]:
102
+ """Process MCP tool execution."""
103
+ self.execution_count += 1
104
+ self.last_executed = datetime.now(timezone.utc)
105
+
106
+ # This would be overridden by specific tool implementations
107
+ return {
108
+ "tool_result": f"Executed MCP tool {self.tool_name}",
109
+ "execution_count": self.execution_count,
110
+ "executed_at": self.last_executed.isoformat(),
111
+ }
112
+
113
+
114
+ class MCPResourceNode(Node):
115
+ """Kailash node representing an MCP resource."""
116
+
117
+ def __init__(
118
+ self,
119
+ name: str,
120
+ resource_uri: str,
121
+ resource_type: str = "text",
122
+ description: str = "",
123
+ ):
124
+ super().__init__(name)
125
+ self.resource_uri = resource_uri
126
+ self.resource_type = resource_type
127
+ self.description = description
128
+ self.access_count = 0
129
+
130
+ def get_parameters(self) -> Dict[str, NodeParameter]:
131
+ return {
132
+ "resource_uri": NodeParameter(
133
+ name="resource_uri",
134
+ type=str,
135
+ required=False,
136
+ default=self.resource_uri,
137
+ description="URI of the resource to access",
138
+ )
139
+ }
140
+
141
+ def process(self, inputs: Dict[str, Any]) -> Dict[str, Any]:
142
+ """Process MCP resource access."""
143
+ self.access_count += 1
144
+
145
+ # This would be overridden by specific resource implementations
146
+ return {
147
+ "resource_content": f"Content from {self.resource_uri}",
148
+ "resource_type": self.resource_type,
149
+ "access_count": self.access_count,
150
+ }
151
+
152
+
153
+ class MiddlewareMCPServer:
154
+ """
155
+ Enhanced MCP Server built with Kailash SDK components.
156
+
157
+ Integrates with the middleware layer for real-time events,
158
+ session management, and AI agent communication.
159
+ """
160
+
161
+ def __init__(
162
+ self,
163
+ config: MCPServerConfig = None,
164
+ event_stream: EventStream = None,
165
+ agent_ui: AgentUIMiddleware = None,
166
+ ):
167
+ self.config = config or MCPServerConfig()
168
+ self.event_stream = event_stream
169
+ self.agent_ui = agent_ui
170
+
171
+ # Kailash components
172
+ self.runtime = LocalRuntime()
173
+ self.workflows: Dict[str, WorkflowBuilder] = {}
174
+
175
+ # MCP registry using Kailash patterns
176
+ self.tools: Dict[str, MCPToolNode] = {}
177
+ self.resources: Dict[str, MCPResourceNode] = {}
178
+ self.prompts: Dict[str, Dict[str, Any]] = {}
179
+
180
+ # State management
181
+ self.server_id = str(uuid.uuid4())
182
+ self.started_at = None
183
+ self.client_connections: Dict[str, Dict[str, Any]] = {}
184
+
185
+ # Use existing Kailash MCP server if available
186
+ self.base_server = None
187
+ if _KAILASH_MCP_AVAILABLE:
188
+ try:
189
+ self.base_server = MCPServer(self.config.name)
190
+ except Exception as e:
191
+ logger.warning(f"Could not initialize base MCP server: {e}")
192
+
193
+ # Create MCP management workflows
194
+ self._create_management_workflows()
195
+
196
+ def _create_management_workflows(self):
197
+ """Create Kailash workflows for MCP operations."""
198
+
199
+ # Tool Registration Workflow
200
+ self.tool_register_workflow = WorkflowBuilder()
201
+
202
+ validator = PythonCodeNode(
203
+ name="validate_tool",
204
+ code="""
205
+ # Validate tool registration using Kailash patterns
206
+ tool_data = input_data.get('tool_data', {})
207
+
208
+ required_fields = ['name', 'description']
209
+ missing_fields = [f for f in required_fields if not tool_data.get(f)]
210
+
211
+ if missing_fields:
212
+ result = {
213
+ 'valid': False,
214
+ 'error': f'Missing required fields: {missing_fields}',
215
+ 'tool_data': tool_data
216
+ }
217
+ else:
218
+ result = {
219
+ 'valid': True,
220
+ 'tool_data': tool_data,
221
+ 'validation_passed': True
222
+ }
223
+ """,
224
+ )
225
+
226
+ register_handler = PythonCodeNode(
227
+ name="register_tool",
228
+ code="""
229
+ # Register tool using Kailash patterns
230
+ validation_result = input_data.get('validation_result', {})
231
+
232
+ if not validation_result.get('valid'):
233
+ result = {
234
+ 'success': False,
235
+ 'error': validation_result.get('error', 'Validation failed'),
236
+ 'tool_registered': False
237
+ }
238
+ else:
239
+ tool_data = validation_result.get('tool_data', {})
240
+ result = {
241
+ 'success': True,
242
+ 'tool_name': tool_data.get('name'),
243
+ 'tool_registered': True,
244
+ 'registration_time': datetime.now().isoformat()
245
+ }
246
+ """,
247
+ )
248
+
249
+ self.tool_register_workflow.add_node(validator)
250
+ self.tool_register_workflow.add_node(register_handler)
251
+ self.tool_register_workflow.connect(
252
+ validator, register_handler, mapping={"result": "validation_result"}
253
+ )
254
+
255
+ # Tool Execution Workflow
256
+ self.tool_execute_workflow = WorkflowBuilder()
257
+
258
+ executor = PythonCodeNode(
259
+ name="execute_tool",
260
+ code="""
261
+ # Execute MCP tool using Kailash patterns
262
+ tool_name = input_data.get('tool_name')
263
+ tool_args = input_data.get('arguments', {})
264
+
265
+ # Simulate tool execution
266
+ execution_result = {
267
+ 'tool_name': tool_name,
268
+ 'arguments': tool_args,
269
+ 'result': f'Executed {tool_name} with args: {tool_args}',
270
+ 'execution_time': datetime.now().isoformat(),
271
+ 'success': True
272
+ }
273
+
274
+ result = {'execution_result': execution_result}
275
+ """,
276
+ )
277
+
278
+ self.tool_execute_workflow.add_node(executor)
279
+
280
+ async def register_tool(
281
+ self,
282
+ name: str,
283
+ description: str,
284
+ handler: Callable = None,
285
+ parameters_schema: Dict[str, Any] = None,
286
+ ) -> Dict[str, Any]:
287
+ """Register MCP tool using Kailash workflow."""
288
+
289
+ # Use Kailash workflow for tool registration
290
+ tool_data = {
291
+ "name": name,
292
+ "description": description,
293
+ "parameters_schema": parameters_schema or {},
294
+ }
295
+
296
+ workflow = self.tool_register_workflow.build()
297
+ results, _ = self.runtime.execute(workflow, parameters={"tool_data": tool_data})
298
+
299
+ registration_result = results.get("register_tool", {})
300
+
301
+ if registration_result.get("success"):
302
+ # Create Kailash tool node
303
+ tool_node = MCPToolNode(
304
+ name=f"mcp_tool_{name}",
305
+ tool_name=name,
306
+ description=description,
307
+ parameters_schema=parameters_schema,
308
+ )
309
+
310
+ # Override process method if handler provided
311
+ if handler:
312
+ original_process = tool_node.process
313
+
314
+ def custom_process(inputs):
315
+ try:
316
+ # Call the custom handler
317
+ result = handler(inputs.get("tool_input", {}))
318
+ return {"tool_result": result}
319
+ except Exception as e:
320
+ return {"tool_result": None, "error": str(e)}
321
+
322
+ tool_node.process = custom_process
323
+
324
+ self.tools[name] = tool_node
325
+
326
+ # Emit middleware event
327
+ if self.event_stream:
328
+ await self._emit_mcp_event(
329
+ "tool_registered", {"tool_name": name, "description": description}
330
+ )
331
+
332
+ logger.info(f"Registered MCP tool: {name}")
333
+
334
+ return registration_result
335
+
336
+ async def register_resource(
337
+ self,
338
+ uri: str,
339
+ resource_type: str = "text",
340
+ description: str = "",
341
+ handler: Callable = None,
342
+ ) -> Dict[str, Any]:
343
+ """Register MCP resource using Kailash patterns."""
344
+
345
+ resource_node = MCPResourceNode(
346
+ name=f"mcp_resource_{uri.replace('/', '_')}",
347
+ resource_uri=uri,
348
+ resource_type=resource_type,
349
+ description=description,
350
+ )
351
+
352
+ # Override process method if handler provided
353
+ if handler:
354
+
355
+ def custom_process(inputs):
356
+ try:
357
+ result = handler(inputs.get("resource_uri", uri))
358
+ return {"resource_content": result}
359
+ except Exception as e:
360
+ return {"resource_content": None, "error": str(e)}
361
+
362
+ resource_node.process = custom_process
363
+
364
+ self.resources[uri] = resource_node
365
+
366
+ # Emit middleware event
367
+ if self.event_stream:
368
+ await self._emit_mcp_event(
369
+ "resource_registered",
370
+ {"resource_uri": uri, "resource_type": resource_type},
371
+ )
372
+
373
+ logger.info(f"Registered MCP resource: {uri}")
374
+ return {"success": True, "resource_uri": uri}
375
+
376
+ async def execute_tool(
377
+ self, tool_name: str, arguments: Dict[str, Any], session_id: str = None
378
+ ) -> Dict[str, Any]:
379
+ """Execute MCP tool using Kailash workflow."""
380
+
381
+ if tool_name not in self.tools:
382
+ return {
383
+ "success": False,
384
+ "error": f"Tool {tool_name} not found",
385
+ "available_tools": list(self.tools.keys()),
386
+ }
387
+
388
+ # Execute using Kailash tool node
389
+ tool_node = self.tools[tool_name]
390
+
391
+ try:
392
+ result = tool_node.process({"tool_input": arguments})
393
+
394
+ # Emit middleware event
395
+ if self.event_stream:
396
+ await self._emit_mcp_event(
397
+ "tool_executed",
398
+ {
399
+ "tool_name": tool_name,
400
+ "arguments": arguments,
401
+ "session_id": session_id,
402
+ "success": True,
403
+ },
404
+ )
405
+
406
+ return {
407
+ "success": True,
408
+ "tool_name": tool_name,
409
+ "result": result,
410
+ "execution_count": tool_node.execution_count,
411
+ }
412
+
413
+ except Exception as e:
414
+ # Emit error event
415
+ if self.event_stream:
416
+ await self._emit_mcp_event(
417
+ "tool_execution_failed",
418
+ {"tool_name": tool_name, "error": str(e), "session_id": session_id},
419
+ )
420
+
421
+ return {"success": False, "error": str(e), "tool_name": tool_name}
422
+
423
+ async def get_resource(self, uri: str, session_id: str = None) -> Dict[str, Any]:
424
+ """Get MCP resource using Kailash patterns."""
425
+
426
+ if uri not in self.resources:
427
+ return {
428
+ "success": False,
429
+ "error": f"Resource {uri} not found",
430
+ "available_resources": list(self.resources.keys()),
431
+ }
432
+
433
+ resource_node = self.resources[uri]
434
+
435
+ try:
436
+ result = resource_node.process({"resource_uri": uri})
437
+
438
+ # Emit middleware event
439
+ if self.event_stream:
440
+ await self._emit_mcp_event(
441
+ "resource_accessed",
442
+ {"resource_uri": uri, "session_id": session_id, "success": True},
443
+ )
444
+
445
+ return {
446
+ "success": True,
447
+ "resource_uri": uri,
448
+ "content": result,
449
+ "access_count": resource_node.access_count,
450
+ }
451
+
452
+ except Exception as e:
453
+ return {"success": False, "error": str(e), "resource_uri": uri}
454
+
455
+ async def list_capabilities(self) -> Dict[str, Any]:
456
+ """List MCP server capabilities using Kailash patterns."""
457
+
458
+ return {
459
+ "server_info": {
460
+ "name": self.config.name,
461
+ "version": self.config.version,
462
+ "description": self.config.description,
463
+ "server_id": self.server_id,
464
+ "implementation": "Kailash SDK Middleware",
465
+ },
466
+ "tools": {
467
+ name: {
468
+ "description": tool.description,
469
+ "parameters_schema": tool.parameters_schema,
470
+ "execution_count": tool.execution_count,
471
+ "last_executed": (
472
+ tool.last_executed.isoformat() if tool.last_executed else None
473
+ ),
474
+ }
475
+ for name, tool in self.tools.items()
476
+ },
477
+ "resources": {
478
+ uri: {
479
+ "resource_type": resource.resource_type,
480
+ "description": resource.description,
481
+ "access_count": resource.access_count,
482
+ }
483
+ for uri, resource in self.resources.items()
484
+ },
485
+ "features": {
486
+ "caching": self.config.enable_caching,
487
+ "metrics": self.config.enable_metrics,
488
+ "events": self.config.enable_events,
489
+ "streaming": self.config.enable_streaming,
490
+ "kailash_integration": True,
491
+ },
492
+ }
493
+
494
+ async def start(self):
495
+ """Start MCP server with Kailash integration."""
496
+ self.started_at = datetime.now(timezone.utc)
497
+
498
+ # Start base server if available
499
+ if self.base_server:
500
+ # This would start the actual MCP protocol server
501
+ pass
502
+
503
+ # Emit startup event
504
+ if self.event_stream:
505
+ await self._emit_mcp_event(
506
+ "server_started",
507
+ {"server_id": self.server_id, "name": self.config.name},
508
+ )
509
+
510
+ logger.info(f"Started Kailash MCP Server: {self.config.name}")
511
+
512
+ async def stop(self):
513
+ """Stop MCP server."""
514
+ # Emit shutdown event
515
+ if self.event_stream:
516
+ await self._emit_mcp_event(
517
+ "server_stopped",
518
+ {
519
+ "server_id": self.server_id,
520
+ "uptime_seconds": (
521
+ (datetime.now(timezone.utc) - self.started_at).total_seconds()
522
+ if self.started_at
523
+ else 0
524
+ ),
525
+ },
526
+ )
527
+
528
+ logger.info(f"Stopped Kailash MCP Server: {self.config.name}")
529
+
530
+ async def _emit_mcp_event(self, event_type: str, data: Dict[str, Any]):
531
+ """Emit MCP event to middleware event stream."""
532
+
533
+ from ..events import WorkflowEvent
534
+
535
+ event = WorkflowEvent(
536
+ type=EventType.SYSTEM_STATUS,
537
+ workflow_id="mcp_server",
538
+ data={
539
+ "mcp_event_type": event_type,
540
+ "server_id": self.server_id,
541
+ "server_name": self.config.name,
542
+ **data,
543
+ },
544
+ )
545
+
546
+ await self.event_stream.emit(event)
547
+
548
+ def get_stats(self) -> Dict[str, Any]:
549
+ """Get MCP server statistics."""
550
+ uptime = (
551
+ (datetime.now(timezone.utc) - self.started_at).total_seconds()
552
+ if self.started_at
553
+ else 0
554
+ )
555
+
556
+ return {
557
+ "server_info": {
558
+ "server_id": self.server_id,
559
+ "name": self.config.name,
560
+ "uptime_seconds": uptime,
561
+ "started_at": self.started_at.isoformat() if self.started_at else None,
562
+ },
563
+ "tools": {
564
+ "total_tools": len(self.tools),
565
+ "total_executions": sum(
566
+ tool.execution_count for tool in self.tools.values()
567
+ ),
568
+ },
569
+ "resources": {
570
+ "total_resources": len(self.resources),
571
+ "total_accesses": sum(
572
+ res.access_count for res in self.resources.values()
573
+ ),
574
+ },
575
+ "implementation": "Kailash SDK Middleware MCP Server",
576
+ }
kailash/nodes/__init__.py CHANGED
@@ -1,15 +1,32 @@
1
1
  """Node system for the Kailash SDK."""
2
2
 
3
3
  # Import all node modules to ensure registration
4
- from kailash.nodes import ai, api, code, data, logic, mixins, transform
4
+ from kailash.nodes import (
5
+ ai,
6
+ alerts,
7
+ api,
8
+ auth,
9
+ code,
10
+ compliance,
11
+ data,
12
+ enterprise,
13
+ logic,
14
+ mixins,
15
+ monitoring,
16
+ security,
17
+ testing,
18
+ transform,
19
+ )
5
20
  from kailash.nodes.base import Node, NodeParameter, NodeRegistry, register_node
6
- from kailash.nodes.base_async import AsyncNode
7
21
  from kailash.nodes.base_cycle_aware import CycleAwareNode
8
22
  from kailash.nodes.code import PythonCodeNode
9
23
 
24
+ # Compatibility alias - AsyncNode is now just Node
25
+ AsyncNode = Node
26
+
10
27
  __all__ = [
11
28
  "Node",
12
- "AsyncNode",
29
+ "AsyncNode", # Compatibility alias
13
30
  "CycleAwareNode",
14
31
  "NodeParameter",
15
32
  "NodeRegistry",
@@ -17,10 +34,17 @@ __all__ = [
17
34
  "PythonCodeNode",
18
35
  # Node modules
19
36
  "ai",
37
+ "alerts",
20
38
  "api",
39
+ "auth",
21
40
  "code",
41
+ "compliance",
22
42
  "data",
43
+ "enterprise",
23
44
  "logic",
24
45
  "mixins",
46
+ "monitoring",
47
+ "security",
48
+ "testing",
25
49
  "transform",
26
50
  ]
@@ -0,0 +1,42 @@
1
+ """Admin tool framework for enterprise user and permission management.
2
+
3
+ This module provides comprehensive admin functionality including user management,
4
+ role-based access control (RBAC), attribute-based access control (ABAC),
5
+ audit logging, and security event tracking.
6
+
7
+ Architecture:
8
+ - Built on Session 065's async database and ABAC infrastructure
9
+ - Django Admin-inspired features with SDK-native implementation
10
+ - Enterprise-grade scalability (500+ concurrent users)
11
+ - Multi-tenant support with data isolation
12
+ - Comprehensive audit trails for compliance
13
+
14
+ Core Components:
15
+ - UserManagementNode: Complete user lifecycle management
16
+ - RoleManagementNode: Role assignment and hierarchy management
17
+ - PermissionCheckNode: Real-time permission evaluation
18
+ - AuditLogNode: Comprehensive activity logging
19
+ - SecurityEventNode: Security incident tracking
20
+ """
21
+
22
+ from .audit_log import EnterpriseAuditLogNode
23
+ from .permission_check import PermissionCheckNode
24
+ from .role_management import RoleManagementNode
25
+ from .security_event import EnterpriseSecurityEventNode
26
+ from .user_management import UserManagementNode
27
+
28
+ # For backward compatibility, expose both old and new names
29
+ AuditLogNode = EnterpriseAuditLogNode
30
+ SecurityEventNode = EnterpriseSecurityEventNode
31
+
32
+ __all__ = [
33
+ # Core admin nodes
34
+ "UserManagementNode",
35
+ "RoleManagementNode",
36
+ "PermissionCheckNode",
37
+ "EnterpriseAuditLogNode",
38
+ "EnterpriseSecurityEventNode",
39
+ # Backward compatibility aliases
40
+ "AuditLogNode",
41
+ "SecurityEventNode",
42
+ ]