kailash 0.6.2__py3-none-any.whl → 0.6.4__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 (131) hide show
  1. kailash/__init__.py +3 -3
  2. kailash/api/custom_nodes_secure.py +3 -3
  3. kailash/api/gateway.py +1 -1
  4. kailash/api/studio.py +2 -3
  5. kailash/api/workflow_api.py +3 -4
  6. kailash/core/resilience/bulkhead.py +460 -0
  7. kailash/core/resilience/circuit_breaker.py +92 -10
  8. kailash/edge/discovery.py +86 -0
  9. kailash/mcp_server/__init__.py +334 -0
  10. kailash/mcp_server/advanced_features.py +1022 -0
  11. kailash/{mcp → mcp_server}/ai_registry_server.py +29 -4
  12. kailash/mcp_server/auth.py +789 -0
  13. kailash/mcp_server/client.py +712 -0
  14. kailash/mcp_server/discovery.py +1593 -0
  15. kailash/mcp_server/errors.py +673 -0
  16. kailash/mcp_server/oauth.py +1727 -0
  17. kailash/mcp_server/protocol.py +1126 -0
  18. kailash/mcp_server/registry_integration.py +587 -0
  19. kailash/mcp_server/server.py +1747 -0
  20. kailash/{mcp → mcp_server}/servers/ai_registry.py +2 -2
  21. kailash/mcp_server/transports.py +1169 -0
  22. kailash/mcp_server/utils/cache.py +510 -0
  23. kailash/middleware/auth/auth_manager.py +3 -3
  24. kailash/middleware/communication/api_gateway.py +2 -9
  25. kailash/middleware/communication/realtime.py +1 -1
  26. kailash/middleware/mcp/client_integration.py +1 -1
  27. kailash/middleware/mcp/enhanced_server.py +2 -2
  28. kailash/nodes/__init__.py +2 -0
  29. kailash/nodes/admin/audit_log.py +6 -6
  30. kailash/nodes/admin/permission_check.py +8 -8
  31. kailash/nodes/admin/role_management.py +32 -28
  32. kailash/nodes/admin/schema.sql +6 -1
  33. kailash/nodes/admin/schema_manager.py +13 -13
  34. kailash/nodes/admin/security_event.py +16 -20
  35. kailash/nodes/admin/tenant_isolation.py +3 -3
  36. kailash/nodes/admin/transaction_utils.py +3 -3
  37. kailash/nodes/admin/user_management.py +21 -22
  38. kailash/nodes/ai/a2a.py +11 -11
  39. kailash/nodes/ai/ai_providers.py +9 -12
  40. kailash/nodes/ai/embedding_generator.py +13 -14
  41. kailash/nodes/ai/intelligent_agent_orchestrator.py +19 -19
  42. kailash/nodes/ai/iterative_llm_agent.py +3 -3
  43. kailash/nodes/ai/llm_agent.py +213 -36
  44. kailash/nodes/ai/self_organizing.py +2 -2
  45. kailash/nodes/alerts/discord.py +4 -4
  46. kailash/nodes/api/graphql.py +6 -6
  47. kailash/nodes/api/http.py +12 -17
  48. kailash/nodes/api/rate_limiting.py +4 -4
  49. kailash/nodes/api/rest.py +15 -15
  50. kailash/nodes/auth/mfa.py +3 -4
  51. kailash/nodes/auth/risk_assessment.py +2 -2
  52. kailash/nodes/auth/session_management.py +5 -5
  53. kailash/nodes/auth/sso.py +143 -0
  54. kailash/nodes/base.py +6 -2
  55. kailash/nodes/base_async.py +16 -2
  56. kailash/nodes/base_with_acl.py +2 -2
  57. kailash/nodes/cache/__init__.py +9 -0
  58. kailash/nodes/cache/cache.py +1172 -0
  59. kailash/nodes/cache/cache_invalidation.py +870 -0
  60. kailash/nodes/cache/redis_pool_manager.py +595 -0
  61. kailash/nodes/code/async_python.py +2 -1
  62. kailash/nodes/code/python.py +196 -35
  63. kailash/nodes/compliance/data_retention.py +6 -6
  64. kailash/nodes/compliance/gdpr.py +5 -5
  65. kailash/nodes/data/__init__.py +10 -0
  66. kailash/nodes/data/optimistic_locking.py +906 -0
  67. kailash/nodes/data/readers.py +8 -8
  68. kailash/nodes/data/redis.py +349 -0
  69. kailash/nodes/data/sql.py +314 -3
  70. kailash/nodes/data/streaming.py +21 -0
  71. kailash/nodes/enterprise/__init__.py +8 -0
  72. kailash/nodes/enterprise/audit_logger.py +285 -0
  73. kailash/nodes/enterprise/batch_processor.py +22 -3
  74. kailash/nodes/enterprise/data_lineage.py +1 -1
  75. kailash/nodes/enterprise/mcp_executor.py +205 -0
  76. kailash/nodes/enterprise/service_discovery.py +150 -0
  77. kailash/nodes/enterprise/tenant_assignment.py +108 -0
  78. kailash/nodes/logic/async_operations.py +2 -2
  79. kailash/nodes/logic/convergence.py +1 -1
  80. kailash/nodes/logic/operations.py +1 -1
  81. kailash/nodes/monitoring/__init__.py +11 -1
  82. kailash/nodes/monitoring/health_check.py +456 -0
  83. kailash/nodes/monitoring/log_processor.py +817 -0
  84. kailash/nodes/monitoring/metrics_collector.py +627 -0
  85. kailash/nodes/monitoring/performance_benchmark.py +137 -11
  86. kailash/nodes/rag/advanced.py +7 -7
  87. kailash/nodes/rag/agentic.py +49 -2
  88. kailash/nodes/rag/conversational.py +3 -3
  89. kailash/nodes/rag/evaluation.py +3 -3
  90. kailash/nodes/rag/federated.py +3 -3
  91. kailash/nodes/rag/graph.py +3 -3
  92. kailash/nodes/rag/multimodal.py +3 -3
  93. kailash/nodes/rag/optimized.py +5 -5
  94. kailash/nodes/rag/privacy.py +3 -3
  95. kailash/nodes/rag/query_processing.py +6 -6
  96. kailash/nodes/rag/realtime.py +1 -1
  97. kailash/nodes/rag/registry.py +2 -6
  98. kailash/nodes/rag/router.py +1 -1
  99. kailash/nodes/rag/similarity.py +7 -7
  100. kailash/nodes/rag/strategies.py +4 -4
  101. kailash/nodes/security/abac_evaluator.py +6 -6
  102. kailash/nodes/security/behavior_analysis.py +5 -6
  103. kailash/nodes/security/credential_manager.py +1 -1
  104. kailash/nodes/security/rotating_credentials.py +11 -11
  105. kailash/nodes/security/threat_detection.py +8 -8
  106. kailash/nodes/testing/credential_testing.py +2 -2
  107. kailash/nodes/transform/processors.py +5 -5
  108. kailash/runtime/local.py +162 -14
  109. kailash/runtime/parameter_injection.py +425 -0
  110. kailash/runtime/parameter_injector.py +657 -0
  111. kailash/runtime/testing.py +2 -2
  112. kailash/testing/fixtures.py +2 -2
  113. kailash/workflow/builder.py +99 -18
  114. kailash/workflow/builder_improvements.py +207 -0
  115. kailash/workflow/input_handling.py +170 -0
  116. {kailash-0.6.2.dist-info → kailash-0.6.4.dist-info}/METADATA +21 -8
  117. {kailash-0.6.2.dist-info → kailash-0.6.4.dist-info}/RECORD +126 -101
  118. kailash/mcp/__init__.py +0 -53
  119. kailash/mcp/client.py +0 -445
  120. kailash/mcp/server.py +0 -292
  121. kailash/mcp/server_enhanced.py +0 -449
  122. kailash/mcp/utils/cache.py +0 -267
  123. /kailash/{mcp → mcp_server}/client_new.py +0 -0
  124. /kailash/{mcp → mcp_server}/utils/__init__.py +0 -0
  125. /kailash/{mcp → mcp_server}/utils/config.py +0 -0
  126. /kailash/{mcp → mcp_server}/utils/formatters.py +0 -0
  127. /kailash/{mcp → mcp_server}/utils/metrics.py +0 -0
  128. {kailash-0.6.2.dist-info → kailash-0.6.4.dist-info}/WHEEL +0 -0
  129. {kailash-0.6.2.dist-info → kailash-0.6.4.dist-info}/entry_points.txt +0 -0
  130. {kailash-0.6.2.dist-info → kailash-0.6.4.dist-info}/licenses/LICENSE +0 -0
  131. {kailash-0.6.2.dist-info → kailash-0.6.4.dist-info}/top_level.txt +0 -0
@@ -23,6 +23,7 @@ Example:
23
23
 
24
24
  import asyncio
25
25
  import logging
26
+ import random
26
27
  import time
27
28
  from collections import deque
28
29
  from dataclasses import dataclass, field
@@ -61,6 +62,15 @@ class CircuitBreakerConfig:
61
62
  window_size: int = 100 # Rolling window for error rate
62
63
  excluded_exceptions: List[type] = field(default_factory=list) # Don't count these
63
64
 
65
+ # Enhanced configurable thresholds
66
+ min_calls_before_evaluation: int = 10 # Min calls before evaluating error rate
67
+ slow_call_threshold: float = 5.0 # Seconds to consider a call slow
68
+ slow_call_rate_threshold: float = 0.8 # Rate of slow calls to trigger open
69
+ max_wait_duration_in_half_open: int = 60 # Max wait in half-open state
70
+ exponential_backoff_multiplier: float = 2.0 # Backoff multiplier for recovery
71
+ jitter_enabled: bool = True # Add jitter to recovery timeout
72
+ max_jitter_percentage: float = 0.1 # Maximum jitter as percentage of timeout
73
+
64
74
 
65
75
  @dataclass
66
76
  class CircuitBreakerMetrics:
@@ -70,36 +80,59 @@ class CircuitBreakerMetrics:
70
80
  successful_calls: int = 0
71
81
  failed_calls: int = 0
72
82
  rejected_calls: int = 0
83
+ slow_calls: int = 0 # New: Track slow calls
73
84
  state_transitions: List[Dict[str, Any]] = field(default_factory=list)
74
85
  last_failure_time: Optional[float] = None
75
86
  consecutive_failures: int = 0
76
87
  consecutive_successes: int = 0
88
+ avg_call_duration: float = 0.0 # New: Average call duration
89
+ total_call_duration: float = 0.0 # New: Total duration for average calculation
77
90
 
78
- def record_success(self):
91
+ def record_success(self, duration: float = 0.0):
79
92
  """Record successful call."""
80
93
  self.total_calls += 1
81
94
  self.successful_calls += 1
82
95
  self.consecutive_successes += 1
83
96
  self.consecutive_failures = 0
97
+ self._update_duration(duration)
84
98
 
85
- def record_failure(self):
99
+ def record_failure(self, duration: float = 0.0):
86
100
  """Record failed call."""
87
101
  self.total_calls += 1
88
102
  self.failed_calls += 1
89
103
  self.consecutive_failures += 1
90
104
  self.consecutive_successes = 0
91
105
  self.last_failure_time = time.time()
106
+ self._update_duration(duration)
92
107
 
93
108
  def record_rejection(self):
94
109
  """Record rejected call (circuit open)."""
95
110
  self.rejected_calls += 1
96
111
 
112
+ def record_slow_call(self):
113
+ """Record slow call."""
114
+ self.slow_calls += 1
115
+
116
+ def _update_duration(self, duration: float):
117
+ """Update duration metrics."""
118
+ if duration > 0:
119
+ self.total_call_duration += duration
120
+ # Update rolling average
121
+ if self.total_calls > 0:
122
+ self.avg_call_duration = self.total_call_duration / self.total_calls
123
+
97
124
  def get_error_rate(self) -> float:
98
125
  """Calculate current error rate."""
99
126
  if self.total_calls == 0:
100
127
  return 0.0
101
128
  return self.failed_calls / self.total_calls
102
129
 
130
+ def get_slow_call_rate(self) -> float:
131
+ """Calculate current slow call rate."""
132
+ if self.total_calls == 0:
133
+ return 0.0
134
+ return self.slow_calls / self.total_calls
135
+
103
136
 
104
137
  class ConnectionCircuitBreaker(Generic[T]):
105
138
  """Circuit breaker for database connections and operations.
@@ -159,14 +192,21 @@ class ConnectionCircuitBreaker(Generic[T]):
159
192
  start_time = time.time()
160
193
  try:
161
194
  result = await func(*args, **kwargs)
162
- await self._record_success()
195
+ execution_time = time.time() - start_time
196
+
197
+ # Check if this was a slow call
198
+ is_slow = execution_time > self.config.slow_call_threshold
199
+
200
+ await self._record_success(execution_time, is_slow)
163
201
  return result
164
202
  except Exception as e:
203
+ execution_time = time.time() - start_time
204
+
165
205
  # Check if this exception should be counted
166
206
  if not any(
167
207
  isinstance(e, exc_type) for exc_type in self.config.excluded_exceptions
168
208
  ):
169
- await self._record_failure(e)
209
+ await self._record_failure(e, execution_time)
170
210
  raise
171
211
 
172
212
  async def _check_state_transition(self):
@@ -191,6 +231,10 @@ class ConnectionCircuitBreaker(Generic[T]):
191
231
 
192
232
  def _should_open(self) -> bool:
193
233
  """Determine if circuit should open based on failures."""
234
+ # Only evaluate if we have minimum number of calls
235
+ if self.metrics.total_calls < self.config.min_calls_before_evaluation:
236
+ return False
237
+
194
238
  # Check consecutive failures
195
239
  if self.metrics.consecutive_failures >= self.config.failure_threshold:
196
240
  return True
@@ -202,22 +246,32 @@ class ConnectionCircuitBreaker(Generic[T]):
202
246
  if error_rate >= self.config.error_rate_threshold:
203
247
  return True
204
248
 
249
+ # Check slow call rate
250
+ slow_call_rate = self.metrics.get_slow_call_rate()
251
+ if slow_call_rate >= self.config.slow_call_rate_threshold:
252
+ return True
253
+
205
254
  return False
206
255
 
207
- async def _record_success(self):
256
+ async def _record_success(self, duration: float = 0.0, is_slow: bool = False):
208
257
  """Record successful execution."""
209
258
  async with self._lock:
210
- self.metrics.record_success()
259
+ self.metrics.record_success(duration)
260
+ if is_slow:
261
+ self.metrics.record_slow_call()
211
262
  self._rolling_window.append(True)
212
263
 
213
264
  if self.state == CircuitState.HALF_OPEN:
214
265
  if self.metrics.consecutive_successes >= self.config.success_threshold:
215
266
  await self._transition_to(CircuitState.CLOSED)
216
267
 
217
- async def _record_failure(self, error: Exception):
268
+ async def _record_failure(self, error: Exception, duration: float = 0.0):
218
269
  """Record failed execution."""
219
270
  async with self._lock:
220
- self.metrics.record_failure()
271
+ self.metrics.record_failure(duration)
272
+ # Consider slow failures as additional burden
273
+ if duration > self.config.slow_call_threshold:
274
+ self.metrics.record_slow_call()
221
275
  self._rolling_window.append(False)
222
276
 
223
277
  if self.state == CircuitState.HALF_OPEN:
@@ -280,11 +334,31 @@ class ConnectionCircuitBreaker(Generic[T]):
280
334
  return "Unknown reason"
281
335
 
282
336
  def _time_until_recovery(self) -> float:
283
- """Calculate seconds until recovery attempt."""
337
+ """Calculate seconds until recovery attempt with jitter and backoff."""
284
338
  if self.state != CircuitState.OPEN:
285
339
  return 0.0
340
+
286
341
  elapsed = time.time() - self._last_state_change
287
- remaining = self.config.recovery_timeout - elapsed
342
+
343
+ # Apply exponential backoff based on number of state transitions to OPEN
344
+ open_transitions = sum(
345
+ 1
346
+ for t in self.metrics.state_transitions
347
+ if t.get("to") == CircuitState.OPEN.value
348
+ )
349
+ backoff_multiplier = self.config.exponential_backoff_multiplier ** max(
350
+ 0, open_transitions - 1
351
+ )
352
+
353
+ base_timeout = self.config.recovery_timeout * backoff_multiplier
354
+
355
+ # Add jitter if enabled
356
+ if self.config.jitter_enabled:
357
+ jitter_range = base_timeout * self.config.max_jitter_percentage
358
+ jitter = random.uniform(-jitter_range, jitter_range)
359
+ base_timeout += jitter
360
+
361
+ remaining = base_timeout - elapsed
288
362
  return max(0.0, remaining)
289
363
 
290
364
  async def force_open(self, reason: str = "Manual override"):
@@ -331,7 +405,10 @@ class ConnectionCircuitBreaker(Generic[T]):
331
405
  "successful_calls": self.metrics.successful_calls,
332
406
  "failed_calls": self.metrics.failed_calls,
333
407
  "rejected_calls": self.metrics.rejected_calls,
408
+ "slow_calls": self.metrics.slow_calls,
334
409
  "error_rate": self.metrics.get_error_rate(),
410
+ "slow_call_rate": self.metrics.get_slow_call_rate(),
411
+ "avg_call_duration": self.metrics.avg_call_duration,
335
412
  "consecutive_failures": self.metrics.consecutive_failures,
336
413
  "consecutive_successes": self.metrics.consecutive_successes,
337
414
  },
@@ -340,6 +417,11 @@ class ConnectionCircuitBreaker(Generic[T]):
340
417
  "success_threshold": self.config.success_threshold,
341
418
  "recovery_timeout": self.config.recovery_timeout,
342
419
  "error_rate_threshold": self.config.error_rate_threshold,
420
+ "slow_call_threshold": self.config.slow_call_threshold,
421
+ "slow_call_rate_threshold": self.config.slow_call_rate_threshold,
422
+ "min_calls_before_evaluation": self.config.min_calls_before_evaluation,
423
+ "exponential_backoff_multiplier": self.config.exponential_backoff_multiplier,
424
+ "jitter_enabled": self.config.jitter_enabled,
343
425
  },
344
426
  "time_until_recovery": (
345
427
  self._time_until_recovery() if self.state == CircuitState.OPEN else None
kailash/edge/discovery.py CHANGED
@@ -199,6 +199,92 @@ class EdgeDiscovery:
199
199
  self._last_health_check[location.location_id] = datetime.now(UTC)
200
200
  logger.info(f"Added edge location: {location.name}")
201
201
 
202
+ async def register_edge(self, edge_config: Dict[str, Any]):
203
+ """Register an edge location from configuration dictionary.
204
+
205
+ Args:
206
+ edge_config: Dictionary containing edge location configuration
207
+ """
208
+ from .location import (
209
+ ComplianceZone,
210
+ EdgeCapabilities,
211
+ EdgeLocation,
212
+ EdgeRegion,
213
+ GeographicCoordinates,
214
+ )
215
+
216
+ # Extract basic info
217
+ location_id = edge_config["id"]
218
+ region_str = edge_config.get("region", "us-east")
219
+
220
+ # Map region string to enum
221
+ region_map = {
222
+ "us-east-1": EdgeRegion.US_EAST,
223
+ "us-west-1": EdgeRegion.US_WEST,
224
+ "eu-west-1": EdgeRegion.EU_WEST,
225
+ "eu-central-1": EdgeRegion.EU_CENTRAL,
226
+ "asia-southeast-1": EdgeRegion.ASIA_SOUTHEAST,
227
+ }
228
+ region = region_map.get(region_str, EdgeRegion.US_EAST)
229
+
230
+ # Default coordinates based on region
231
+ coord_map = {
232
+ EdgeRegion.US_EAST: GeographicCoordinates(39.0458, -76.6413), # Virginia
233
+ EdgeRegion.US_WEST: GeographicCoordinates(37.7749, -122.4194), # California
234
+ EdgeRegion.EU_WEST: GeographicCoordinates(53.3498, -6.2603), # Ireland
235
+ EdgeRegion.EU_CENTRAL: GeographicCoordinates(50.1109, 8.6821), # Frankfurt
236
+ EdgeRegion.ASIA_SOUTHEAST: GeographicCoordinates(
237
+ 1.3521, 103.8198
238
+ ), # Singapore
239
+ }
240
+ coordinates = coord_map.get(region, GeographicCoordinates(39.0458, -76.6413))
241
+
242
+ # Create capabilities
243
+ capabilities = EdgeCapabilities(
244
+ cpu_cores=edge_config.get("capacity", 1000) // 100, # Rough mapping
245
+ memory_gb=edge_config.get("capacity", 1000) // 50,
246
+ storage_gb=edge_config.get("capacity", 1000) * 2,
247
+ bandwidth_gbps=10.0,
248
+ database_support=["postgresql", "redis"],
249
+ ai_models_available=["llama", "claude"],
250
+ )
251
+
252
+ # Create edge location
253
+ location = EdgeLocation(
254
+ location_id=location_id,
255
+ name=f"Edge {region_str.title()}",
256
+ region=region,
257
+ coordinates=coordinates,
258
+ capabilities=capabilities,
259
+ endpoint_url=edge_config.get(
260
+ "endpoint", f"http://{location_id}.edge.local:8080"
261
+ ),
262
+ )
263
+
264
+ # Set health status
265
+ from .location import EdgeStatus
266
+
267
+ if edge_config.get("healthy", True):
268
+ location.status = EdgeStatus.ACTIVE
269
+ self._health_results[location_id] = HealthCheckResult.HEALTHY
270
+ else:
271
+ location.status = EdgeStatus.OFFLINE
272
+ self._health_results[location_id] = HealthCheckResult.UNHEALTHY
273
+
274
+ # Update metrics
275
+ location.metrics.latency_p50_ms = edge_config.get("latency_ms", 10)
276
+ location.metrics.cpu_utilization = edge_config.get(
277
+ "current_load", 0
278
+ ) / edge_config.get("capacity", 1000)
279
+
280
+ # Add to locations
281
+ self.locations[location_id] = location
282
+ self._last_health_check[location_id] = datetime.now(UTC)
283
+
284
+ logger.info(f"Registered edge location: {location_id} in {region_str}")
285
+
286
+ return location
287
+
202
288
  def remove_location(self, location_id: str):
203
289
  """Remove an edge location from the discovery pool."""
204
290
  if location_id in self.locations:
@@ -0,0 +1,334 @@
1
+ """Enhanced Model Context Protocol (MCP) Service Layer with Service Discovery.
2
+
3
+ This module provides production-ready MCP client and server functionality with
4
+ comprehensive service discovery, authentication, monitoring, and resilience
5
+ features. Built on top of the official Anthropic MCP Python SDK.
6
+
7
+ Enhanced Features:
8
+ - Service Discovery: Automatic server registration and discovery
9
+ - Authentication: Multiple auth providers (API Key, JWT, OAuth)
10
+ - Load Balancing: Intelligent server selection and failover
11
+ - Health Monitoring: Automatic health checking and status tracking
12
+ - Circuit Breaker: Failure detection and recovery patterns
13
+ - Metrics Collection: Comprehensive performance monitoring
14
+ - Network Discovery: UDP broadcast/multicast server discovery
15
+ - Error Handling: Structured error codes and retry strategies
16
+
17
+ Design Philosophy:
18
+ Provides production-ready distributed systems infrastructure for MCP
19
+ while maintaining compatibility with the official SDK. Enhances the
20
+ basic protocol implementation with enterprise-grade features.
21
+
22
+ Key Components:
23
+ - MCPClient: Enhanced client with auth, retry, and multi-transport support
24
+ - MCPServer: Production-ready server with all enterprise features
25
+ - ServiceRegistry: Central registry for server discovery and management
26
+ - ServiceMesh: Intelligent routing and load balancing
27
+ - ServerRegistrar: Automatic server registration and lifecycle management
28
+
29
+ Service Discovery Features:
30
+ - File-based registry with JSON storage
31
+ - Network discovery via UDP broadcast/multicast
32
+ - Health checking and automatic status updates
33
+ - Capability-based server filtering
34
+ - Load balancing with priority scoring
35
+ - Automatic failover and circuit breaker patterns
36
+
37
+ Examples:
38
+ Enhanced MCP client with discovery:
39
+
40
+ >>> from kailash.mcp_server import get_mcp_client, discover_mcp_servers
41
+ >>> # Discover servers with specific capability
42
+ >>> servers = await discover_mcp_servers(capability="search")
43
+ >>> # Get best client for capability
44
+ >>> client = await get_mcp_client("search")
45
+ >>> result = await client.call_tool(server_config, "search", {"query": "AI"})
46
+
47
+ Production MCP server with auto-discovery:
48
+
49
+ >>> from kailash.mcp_server import MCPServer, enable_auto_discovery
50
+ >>> from kailash.mcp_server.auth import APIKeyAuth
51
+ >>>
52
+ >>> # Create server with authentication
53
+ >>> auth = APIKeyAuth({"user1": "secret-key"})
54
+ >>> server = MCPServer(
55
+ ... "my-tools",
56
+ ... auth_provider=auth,
57
+ ... enable_metrics=True,
58
+ ... circuit_breaker_config={"failure_threshold": 5}
59
+ ... )
60
+ >>>
61
+ >>> @server.tool(required_permission="tools.calculate")
62
+ ... def calculate(a: int, b: int) -> int:
63
+ ... return a + b
64
+ >>>
65
+ >>> # Enable auto-discovery and start
66
+ >>> registrar = enable_auto_discovery(server, enable_network_discovery=True)
67
+ >>> registrar.start_with_registration()
68
+
69
+ Service mesh with failover:
70
+
71
+ >>> from kailash.mcp_server import ServiceRegistry, ServiceMesh
72
+ >>> registry = ServiceRegistry()
73
+ >>> mesh = ServiceMesh(registry)
74
+ >>>
75
+ >>> # Call with automatic failover
76
+ >>> result = await mesh.call_with_failover(
77
+ ... "search", "web_search", {"query": "Python"}, max_retries=3
78
+ ... )
79
+ """
80
+
81
+ # Advanced Features
82
+ from .advanced_features import (
83
+ BinaryResourceHandler,
84
+ CancellationContext,
85
+ ChangeType,
86
+ Content,
87
+ ContentType,
88
+ ElicitationSystem,
89
+ MultiModalContent,
90
+ ProgressReporter,
91
+ ResourceChange,
92
+ )
93
+ from .advanced_features import ResourceTemplate as AdvancedResourceTemplate
94
+ from .advanced_features import (
95
+ SchemaValidator,
96
+ StreamingHandler,
97
+ StructuredTool,
98
+ ToolAnnotation,
99
+ create_cancellation_context,
100
+ create_progress_reporter,
101
+ structured_tool,
102
+ )
103
+
104
+ # Authentication framework
105
+ from .auth import (
106
+ APIKeyAuth,
107
+ AuthManager,
108
+ AuthProvider,
109
+ BasicAuth,
110
+ BearerTokenAuth,
111
+ JWTAuth,
112
+ PermissionManager,
113
+ RateLimiter,
114
+ )
115
+ from .client import MCPClient
116
+
117
+ # Service Discovery System
118
+ from .discovery import (
119
+ DiscoveryBackend,
120
+ FileBasedDiscovery,
121
+ HealthChecker,
122
+ LoadBalancer,
123
+ NetworkDiscovery,
124
+ ServerInfo,
125
+ ServiceMesh,
126
+ ServiceRegistry,
127
+ create_default_registry,
128
+ discover_mcp_servers,
129
+ get_mcp_client,
130
+ )
131
+
132
+ # Enhanced error handling
133
+ from .errors import (
134
+ AuthenticationError,
135
+ AuthorizationError,
136
+ CircuitBreakerRetry,
137
+ ErrorAggregator,
138
+ ExponentialBackoffRetry,
139
+ MCPError,
140
+ MCPErrorCode,
141
+ RateLimitError,
142
+ ResourceError,
143
+ RetryableOperation,
144
+ RetryStrategy,
145
+ ServiceDiscoveryError,
146
+ ToolError,
147
+ TransportError,
148
+ ValidationError,
149
+ )
150
+
151
+ # OAuth 2.1 Authentication
152
+ from .oauth import (
153
+ AccessToken,
154
+ AuthorizationCode,
155
+ AuthorizationServer,
156
+ ClientStore,
157
+ ClientType,
158
+ GrantType,
159
+ InMemoryClientStore,
160
+ InMemoryTokenStore,
161
+ JWTManager,
162
+ OAuth2Client,
163
+ OAuthClient,
164
+ RefreshToken,
165
+ ResourceServer,
166
+ TokenStore,
167
+ TokenType,
168
+ )
169
+
170
+ # Complete Protocol Implementation
171
+ from .protocol import (
172
+ CancellationManager,
173
+ CancelledNotification,
174
+ CompletionManager,
175
+ CompletionRequest,
176
+ CompletionResult,
177
+ MessageType,
178
+ MetaData,
179
+ ProgressManager,
180
+ ProgressNotification,
181
+ ProgressToken,
182
+ ProtocolManager,
183
+ ResourceTemplate,
184
+ RootsManager,
185
+ SamplingManager,
186
+ SamplingRequest,
187
+ ToolResult,
188
+ cancel_request,
189
+ complete_progress,
190
+ get_protocol_manager,
191
+ is_cancelled,
192
+ start_progress,
193
+ update_progress,
194
+ )
195
+
196
+ # Registry Integration
197
+ from .registry_integration import (
198
+ NetworkAnnouncer,
199
+ ServerRegistrar,
200
+ enable_auto_discovery,
201
+ register_server_manually,
202
+ )
203
+
204
+ # Enhanced server with production features
205
+ from .server import MCPServer, MCPServerBase, SimpleMCPServer
206
+
207
+ # Enhanced Transport Layer
208
+ from .transports import (
209
+ BaseTransport,
210
+ EnhancedStdioTransport,
211
+ SSETransport,
212
+ StreamableHTTPTransport,
213
+ TransportManager,
214
+ TransportSecurity,
215
+ WebSocketTransport,
216
+ get_transport_manager,
217
+ )
218
+
219
+ __all__ = [
220
+ # Core MCP Components
221
+ "MCPClient",
222
+ "MCPServer",
223
+ "MCPServerBase",
224
+ # Prototyping server
225
+ "SimpleMCPServer",
226
+ # Service Discovery System
227
+ "ServiceRegistry",
228
+ "ServerInfo",
229
+ "DiscoveryBackend",
230
+ "FileBasedDiscovery",
231
+ "NetworkDiscovery",
232
+ "HealthChecker",
233
+ "LoadBalancer",
234
+ "ServiceMesh",
235
+ "create_default_registry",
236
+ "discover_mcp_servers",
237
+ "get_mcp_client",
238
+ # Registry Integration
239
+ "ServerRegistrar",
240
+ "NetworkAnnouncer",
241
+ "enable_auto_discovery",
242
+ "register_server_manually",
243
+ # Authentication
244
+ "AuthProvider",
245
+ "APIKeyAuth",
246
+ "BearerTokenAuth",
247
+ "JWTAuth",
248
+ "BasicAuth",
249
+ "AuthManager",
250
+ "PermissionManager",
251
+ "RateLimiter",
252
+ # Enhanced Error Handling
253
+ "MCPError",
254
+ "MCPErrorCode",
255
+ "AuthenticationError",
256
+ "AuthorizationError",
257
+ "RateLimitError",
258
+ "ToolError",
259
+ "ResourceError",
260
+ "TransportError",
261
+ "ServiceDiscoveryError",
262
+ "ValidationError",
263
+ "RetryStrategy",
264
+ "RetryableOperation",
265
+ "ExponentialBackoffRetry",
266
+ "CircuitBreakerRetry",
267
+ "ErrorAggregator",
268
+ # Complete Protocol Implementation
269
+ "MessageType",
270
+ "ProgressToken",
271
+ "MetaData",
272
+ "ProgressNotification",
273
+ "CancelledNotification",
274
+ "CompletionRequest",
275
+ "CompletionResult",
276
+ "SamplingRequest",
277
+ "ResourceTemplate",
278
+ "ToolResult",
279
+ "ProgressManager",
280
+ "CancellationManager",
281
+ "CompletionManager",
282
+ "SamplingManager",
283
+ "RootsManager",
284
+ "ProtocolManager",
285
+ "get_protocol_manager",
286
+ "start_progress",
287
+ "update_progress",
288
+ "complete_progress",
289
+ "is_cancelled",
290
+ "cancel_request",
291
+ # Enhanced Transport Layer
292
+ "BaseTransport",
293
+ "EnhancedStdioTransport",
294
+ "SSETransport",
295
+ "StreamableHTTPTransport",
296
+ "WebSocketTransport",
297
+ "TransportSecurity",
298
+ "TransportManager",
299
+ "get_transport_manager",
300
+ # OAuth 2.1 Authentication
301
+ "GrantType",
302
+ "TokenType",
303
+ "ClientType",
304
+ "OAuthClient",
305
+ "AccessToken",
306
+ "RefreshToken",
307
+ "AuthorizationCode",
308
+ "ClientStore",
309
+ "InMemoryClientStore",
310
+ "TokenStore",
311
+ "InMemoryTokenStore",
312
+ "JWTManager",
313
+ "AuthorizationServer",
314
+ "ResourceServer",
315
+ "OAuth2Client",
316
+ # Advanced Features
317
+ "ContentType",
318
+ "ChangeType",
319
+ "Content",
320
+ "ResourceChange",
321
+ "ToolAnnotation",
322
+ "MultiModalContent",
323
+ "SchemaValidator",
324
+ "StructuredTool",
325
+ "AdvancedResourceTemplate",
326
+ "BinaryResourceHandler",
327
+ "StreamingHandler",
328
+ "ElicitationSystem",
329
+ "ProgressReporter",
330
+ "CancellationContext",
331
+ "structured_tool",
332
+ "create_progress_reporter",
333
+ "create_cancellation_context",
334
+ ]