alita-sdk 0.3.430__py3-none-any.whl → 0.3.432__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.
@@ -28,7 +28,7 @@ class McpToolkit(BaseToolkit):
28
28
  """
29
29
 
30
30
  tools: List[BaseTool] = []
31
- server_name: Optional[str] = None
31
+ toolkit_name: Optional[str] = None
32
32
 
33
33
  # Class variable (not Pydantic field) for tool name length limit
34
34
  toolkit_max_length: ClassVar[int] = 0 # No limit for MCP tool names
@@ -63,15 +63,6 @@ class McpToolkit(BaseToolkit):
63
63
 
64
64
  return create_model(
65
65
  'mcp',
66
- server_name=(
67
- str,
68
- Field(
69
- description="MCP server name/identifier",
70
- json_schema_extra={
71
- 'tooltip': 'Unique identifier for this MCP server'
72
- }
73
- )
74
- ),
75
66
  url=(
76
67
  str,
77
68
  Field(
@@ -160,7 +151,6 @@ class McpToolkit(BaseToolkit):
160
151
  @classmethod
161
152
  def get_toolkit(
162
153
  cls,
163
- server_name: str,
164
154
  url: str,
165
155
  headers: Optional[Dict[str, str]] = None,
166
156
  timeout: int = 60,
@@ -169,7 +159,7 @@ class McpToolkit(BaseToolkit):
169
159
  selected_tools: List[str] = None,
170
160
  enable_caching: bool = True,
171
161
  cache_ttl: int = 300,
172
- toolkit_name: Optional[str] = None,
162
+ toolkit_name: str = None,
173
163
  client = None,
174
164
  **kwargs
175
165
  ) -> 'McpToolkit':
@@ -183,7 +173,6 @@ class McpToolkit(BaseToolkit):
183
173
  4. Return all tools via get_tools() method
184
174
 
185
175
  Args:
186
- server_name: MCP server name/identifier
187
176
  url: MCP server HTTP URL
188
177
  headers: HTTP headers for authentication
189
178
  timeout: Request timeout in seconds
@@ -192,7 +181,7 @@ class McpToolkit(BaseToolkit):
192
181
  selected_tools: List of specific tools to enable (empty = all tools)
193
182
  enable_caching: Whether to enable caching
194
183
  cache_ttl: Cache TTL in seconds
195
- toolkit_name: Optional name prefix for tools
184
+ toolkit_name: Toolkit name/identifier and prefix for tools
196
185
  client: Alita client for MCP communication
197
186
  **kwargs: Additional configuration options
198
187
 
@@ -201,8 +190,11 @@ class McpToolkit(BaseToolkit):
201
190
  """
202
191
  if selected_tools is None:
203
192
  selected_tools = []
193
+
194
+ if not toolkit_name:
195
+ raise ValueError("toolkit_name is required")
204
196
 
205
- logger.info(f"Creating MCP toolkit for server: {server_name}")
197
+ logger.info(f"Creating MCP toolkit: {toolkit_name}")
206
198
 
207
199
  # Parse headers if they're provided as a JSON string
208
200
  parsed_headers = headers
@@ -232,15 +224,14 @@ class McpToolkit(BaseToolkit):
232
224
  raise ValueError(f"Invalid MCP connection configuration: {e}")
233
225
 
234
226
  # Create toolkit instance
235
- toolkit = cls(server_name=server_name)
227
+ toolkit = cls(toolkit_name=toolkit_name)
236
228
 
237
229
  # Generate tools from the MCP server
238
230
  toolkit.tools = cls._create_tools_from_server(
239
- server_name=server_name,
231
+ toolkit_name=toolkit_name,
240
232
  connection_config=connection_config,
241
233
  timeout=timeout,
242
234
  selected_tools=selected_tools,
243
- toolkit_name=toolkit_name,
244
235
  client=client,
245
236
  discovery_mode=discovery_mode
246
237
  )
@@ -250,11 +241,10 @@ class McpToolkit(BaseToolkit):
250
241
  @classmethod
251
242
  def _create_tools_from_server(
252
243
  cls,
253
- server_name: str,
244
+ toolkit_name: str,
254
245
  connection_config: McpConnectionConfig,
255
246
  timeout: int,
256
247
  selected_tools: List[str],
257
- toolkit_name: Optional[str],
258
248
  client,
259
249
  discovery_mode: str = "dynamic"
260
250
  ) -> List[BaseTool]:
@@ -265,11 +255,11 @@ class McpToolkit(BaseToolkit):
265
255
 
266
256
  # First, try direct HTTP discovery since we have valid connection config
267
257
  try:
268
- logger.info(f"Discovering tools from MCP server '{server_name}' at {connection_config.url}")
258
+ logger.info(f"Discovering tools from MCP toolkit '{toolkit_name}' at {connection_config.url}")
269
259
 
270
260
  # Use synchronous HTTP discovery for toolkit initialization
271
261
  tool_metadata_list = cls._discover_tools_sync(
272
- server_name=server_name,
262
+ toolkit_name=toolkit_name,
273
263
  connection_config=connection_config,
274
264
  timeout=timeout
275
265
  )
@@ -286,8 +276,7 @@ class McpToolkit(BaseToolkit):
286
276
  for tool_metadata in tool_metadata_list:
287
277
  server_tool = cls._create_tool_from_dict(
288
278
  tool_dict=tool_metadata,
289
- server_name=server_name,
290
- toolkit_name=toolkit_name or server_name,
279
+ toolkit_name=toolkit_name,
291
280
  timeout=timeout,
292
281
  client=client
293
282
  )
@@ -295,34 +284,33 @@ class McpToolkit(BaseToolkit):
295
284
  if server_tool:
296
285
  tools.append(server_tool)
297
286
 
298
- logger.info(f"Successfully created {len(tools)} MCP tools from server '{server_name}' via direct discovery")
287
+ logger.info(f"Successfully created {len(tools)} MCP tools from toolkit '{toolkit_name}' via direct discovery")
299
288
 
300
289
  except Exception as e:
301
- logger.error(f"Direct discovery failed for MCP server '{server_name}': {e}")
290
+ logger.error(f"Direct discovery failed for MCP toolkit '{toolkit_name}': {e}")
302
291
 
303
292
  # Fallback to static mode if available and not already static
304
293
  if client and discovery_mode != "static":
305
- logger.info(f"Falling back to static discovery for server '{server_name}'")
306
- tools = cls._create_tools_static(server_name, selected_tools, toolkit_name, timeout, client)
294
+ logger.info(f"Falling back to static discovery for toolkit '{toolkit_name}'")
295
+ tools = cls._create_tools_static(toolkit_name, selected_tools, timeout, client)
307
296
  else:
308
- logger.warning(f"No fallback available for server '{server_name}' - returning empty tools list")
297
+ logger.warning(f"No fallback available for toolkit '{toolkit_name}' - returning empty tools list")
309
298
 
310
299
  # Always add the inspection tool (not subject to selected_tools filtering)
311
300
  inspection_tool = cls._create_inspection_tool(
312
- server_name=server_name,
313
- connection_config=connection_config,
314
- toolkit_name=toolkit_name or server_name
301
+ toolkit_name=toolkit_name,
302
+ connection_config=connection_config
315
303
  )
316
304
  if inspection_tool:
317
305
  tools.append(inspection_tool)
318
- logger.info(f"Added MCP inspection tool for server '{server_name}'")
306
+ logger.info(f"Added MCP inspection tool for toolkit '{toolkit_name}'")
319
307
 
320
308
  return tools
321
309
 
322
310
  @classmethod
323
311
  def _discover_tools_sync(
324
312
  cls,
325
- server_name: str,
313
+ toolkit_name: str,
326
314
  connection_config: McpConnectionConfig,
327
315
  timeout: int
328
316
  ) -> List[Dict[str, Any]]:
@@ -340,7 +328,10 @@ class McpToolkit(BaseToolkit):
340
328
  "params": {}
341
329
  }
342
330
 
343
- headers = {"Content-Type": "application/json"}
331
+ headers = {
332
+ "Content-Type": "application/json",
333
+ "Accept": "application/json, text/event-stream"
334
+ }
344
335
  if connection_config.headers:
345
336
  headers.update(connection_config.headers)
346
337
 
@@ -355,26 +346,33 @@ class McpToolkit(BaseToolkit):
355
346
  if response.status_code != 200:
356
347
  raise Exception(f"HTTP {response.status_code}: {response.text}")
357
348
 
358
- data = response.json()
349
+ # Check if response is actually JSON
350
+ content_type = response.headers.get('Content-Type', '')
351
+ if 'application/json' not in content_type:
352
+ raise Exception(f"Expected JSON response but got Content-Type: {content_type}. Response: {response.text[:200]}")
353
+
354
+ try:
355
+ data = response.json()
356
+ except ValueError as json_err:
357
+ raise Exception(f"Invalid JSON response: {json_err}. Response text: {response.text[:200]}")
359
358
 
360
359
  if "error" in data:
361
360
  raise Exception(f"MCP Error: {data['error']}")
362
361
 
363
362
  # Parse MCP response and extract tools
364
363
  tools_data = data.get("result", {}).get("tools", [])
365
- logger.info(f"Discovered {len(tools_data)} tools from MCP server '{server_name}'")
364
+ logger.info(f"Discovered {len(tools_data)} tools from MCP toolkit '{toolkit_name}'")
366
365
 
367
366
  return tools_data
368
367
 
369
368
  except Exception as e:
370
- logger.error(f"Failed to discover tools from MCP server '{server_name}': {e}")
369
+ logger.error(f"Failed to discover tools from MCP toolkit '{toolkit_name}': {e}")
371
370
  raise
372
371
 
373
372
  @classmethod
374
373
  def _create_tool_from_dict(
375
374
  cls,
376
375
  tool_dict: Dict[str, Any],
377
- server_name: str,
378
376
  toolkit_name: str,
379
377
  timeout: int,
380
378
  client
@@ -384,31 +382,30 @@ class McpToolkit(BaseToolkit):
384
382
  # Store toolkit_max_length in local variable to avoid contextual access issues
385
383
  max_length_value = cls.toolkit_max_length
386
384
 
387
- # Clean server name for prefixing (use server_name instead of toolkit_name)
388
- clean_prefix = clean_string(server_name, max_length_value)
385
+ # Clean toolkit name for prefixing
386
+ clean_prefix = clean_string(toolkit_name, max_length_value)
389
387
 
390
388
  full_tool_name = f'{clean_prefix}{TOOLKIT_SPLITTER}{tool_dict.get("name", "unknown")}'
391
389
 
392
390
  return McpServerTool(
393
391
  name=full_tool_name,
394
- description=f"MCP tool '{tool_dict.get('name')}' from server '{server_name}': {tool_dict.get('description', '')}",
392
+ description=f"MCP tool '{tool_dict.get('name')}' from toolkit '{toolkit_name}': {tool_dict.get('description', '')}",
395
393
  args_schema=McpServerTool.create_pydantic_model_from_schema(
396
394
  tool_dict.get("inputSchema", {})
397
395
  ),
398
396
  client=client,
399
- server=server_name,
397
+ server=toolkit_name,
400
398
  tool_timeout_sec=timeout
401
399
  )
402
400
  except Exception as e:
403
- logger.error(f"Failed to create MCP tool '{tool_dict.get('name')}' from server '{server_name}': {e}")
401
+ logger.error(f"Failed to create MCP tool '{tool_dict.get('name')}' from toolkit '{toolkit_name}': {e}")
404
402
  return None
405
403
 
406
404
  @classmethod
407
405
  def _create_tools_static(
408
406
  cls,
409
- server_name: str,
407
+ toolkit_name: str,
410
408
  selected_tools: List[str],
411
- toolkit_name: Optional[str],
412
409
  timeout: int,
413
410
  client
414
411
  ) -> List[BaseTool]:
@@ -421,10 +418,10 @@ class McpToolkit(BaseToolkit):
421
418
 
422
419
  try:
423
420
  all_toolkits = client.get_mcp_toolkits()
424
- server_toolkit = next((tk for tk in all_toolkits if tk.get('name') == server_name), None)
421
+ server_toolkit = next((tk for tk in all_toolkits if tk.get('name') == toolkit_name), None)
425
422
 
426
423
  if not server_toolkit:
427
- logger.warning(f"MCP server '{server_name}' not found in available toolkits")
424
+ logger.warning(f"MCP toolkit '{toolkit_name}' not found in available toolkits")
428
425
  return tools
429
426
 
430
427
  # Extract tools from the toolkit
@@ -440,8 +437,7 @@ class McpToolkit(BaseToolkit):
440
437
 
441
438
  # Create the tool
442
439
  server_tool = cls._create_single_tool(
443
- server_name=server_name,
444
- toolkit_name=toolkit_name or server_name,
440
+ toolkit_name=toolkit_name,
445
441
  available_tool=available_tool,
446
442
  timeout=timeout,
447
443
  client=client
@@ -450,7 +446,7 @@ class McpToolkit(BaseToolkit):
450
446
  if server_tool:
451
447
  tools.append(server_tool)
452
448
 
453
- logger.info(f"Successfully created {len(tools)} MCP tools from server '{server_name}' using static mode")
449
+ logger.info(f"Successfully created {len(tools)} MCP tools from toolkit '{toolkit_name}' using static mode")
454
450
 
455
451
  except Exception as e:
456
452
  logger.error(f"Error in static tool creation: {e}")
@@ -461,15 +457,15 @@ class McpToolkit(BaseToolkit):
461
457
  # We don't have full connection config in static mode, so create a basic one
462
458
  # The inspection tool will work as long as the server is accessible
463
459
  inspection_tool = McpInspectTool(
464
- name=f"{clean_string(server_name, 50)}{TOOLKIT_SPLITTER}mcp_inspect",
465
- server_name=server_name,
460
+ name=f"{clean_string(toolkit_name, 50)}{TOOLKIT_SPLITTER}mcp_inspect",
461
+ server_name=toolkit_name,
466
462
  server_url="", # Will be populated by the client if available
467
- description=f"Inspect available tools, prompts, and resources from MCP server '{server_name}'"
463
+ description=f"Inspect available tools, prompts, and resources from MCP toolkit '{toolkit_name}'"
468
464
  )
469
465
  tools.append(inspection_tool)
470
- logger.info(f"Added MCP inspection tool for server '{server_name}' (static mode)")
466
+ logger.info(f"Added MCP inspection tool for toolkit '{toolkit_name}' (static mode)")
471
467
  except Exception as e:
472
- logger.warning(f"Failed to create inspection tool for {server_name}: {e}")
468
+ logger.warning(f"Failed to create inspection tool for {toolkit_name}: {e}")
473
469
 
474
470
  return tools
475
471
 
@@ -505,7 +501,6 @@ class McpToolkit(BaseToolkit):
505
501
  @classmethod
506
502
  def _create_single_tool(
507
503
  cls,
508
- server_name: str,
509
504
  toolkit_name: str,
510
505
  available_tool: Dict[str, Any],
511
506
  timeout: int,
@@ -516,51 +511,50 @@ class McpToolkit(BaseToolkit):
516
511
  # Store toolkit_max_length in local variable to avoid contextual access issues
517
512
  max_length_value = cls.toolkit_max_length
518
513
 
519
- # Clean server name for prefixing (use server_name instead of toolkit_name)
520
- clean_prefix = clean_string(server_name, max_length_value)
514
+ # Clean toolkit name for prefixing
515
+ clean_prefix = clean_string(toolkit_name, max_length_value)
521
516
 
522
517
  full_tool_name = f'{clean_prefix}{TOOLKIT_SPLITTER}{available_tool["name"]}'
523
518
 
524
519
  return McpServerTool(
525
520
  name=full_tool_name,
526
- description=f"MCP tool '{available_tool['name']}' from server '{server_name}': {available_tool.get('description', '')}",
521
+ description=f"MCP tool '{available_tool['name']}' from toolkit '{toolkit_name}': {available_tool.get('description', '')}",
527
522
  args_schema=McpServerTool.create_pydantic_model_from_schema(
528
523
  available_tool.get("inputSchema", {})
529
524
  ),
530
525
  client=client,
531
- server=server_name,
526
+ server=toolkit_name,
532
527
  tool_timeout_sec=timeout
533
528
  )
534
529
  except Exception as e:
535
- logger.error(f"Failed to create MCP tool '{available_tool.get('name')}' from server '{server_name}': {e}")
530
+ logger.error(f"Failed to create MCP tool '{available_tool.get('name')}' from toolkit '{toolkit_name}': {e}")
536
531
  return None
537
532
 
538
533
  @classmethod
539
534
  def _create_inspection_tool(
540
535
  cls,
541
- server_name: str,
542
- connection_config: McpConnectionConfig,
543
- toolkit_name: str
536
+ toolkit_name: str,
537
+ connection_config: McpConnectionConfig
544
538
  ) -> Optional[BaseTool]:
545
- """Create the inspection tool for the MCP server."""
539
+ """Create the inspection tool for the MCP toolkit."""
546
540
  try:
547
541
  # Store toolkit_max_length in local variable to avoid contextual access issues
548
542
  max_length_value = cls.toolkit_max_length
549
543
 
550
- # Clean server name for prefixing (use server_name instead of toolkit_name)
551
- clean_prefix = clean_string(server_name, max_length_value)
544
+ # Clean toolkit name for prefixing
545
+ clean_prefix = clean_string(toolkit_name, max_length_value)
552
546
 
553
547
  full_tool_name = f'{clean_prefix}{TOOLKIT_SPLITTER}mcp_inspect'
554
548
 
555
549
  return McpInspectTool(
556
550
  name=full_tool_name,
557
- server_name=server_name,
551
+ server_name=toolkit_name,
558
552
  server_url=connection_config.url,
559
553
  server_headers=connection_config.headers,
560
- description=f"Inspect available tools, prompts, and resources from MCP server '{server_name}'"
554
+ description=f"Inspect available tools, prompts, and resources from MCP toolkit '{toolkit_name}'"
561
555
  )
562
556
  except Exception as e:
563
- logger.error(f"Failed to create MCP inspection tool for server '{server_name}': {e}")
557
+ logger.error(f"Failed to create MCP inspection tool for toolkit '{toolkit_name}': {e}")
564
558
  return None
565
559
 
566
560
  def get_tools(self) -> List[BaseTool]:
@@ -568,31 +562,31 @@ class McpToolkit(BaseToolkit):
568
562
  return self.tools
569
563
 
570
564
  async def refresh_tools(self):
571
- """Manually refresh tools from the MCP server."""
572
- if not self.server_name:
573
- logger.warning("Cannot refresh tools: server_name not set")
565
+ """Manually refresh tools from the MCP toolkit."""
566
+ if not self.toolkit_name:
567
+ logger.warning("Cannot refresh tools: toolkit_name not set")
574
568
  return
575
569
 
576
570
  try:
577
571
  from ..clients.mcp_manager import get_mcp_manager
578
572
  manager = get_mcp_manager()
579
- await manager.refresh_server(self.server_name)
580
- logger.info(f"Successfully refreshed tools for server {self.server_name}")
573
+ await manager.refresh_server(self.toolkit_name)
574
+ logger.info(f"Successfully refreshed tools for toolkit {self.toolkit_name}")
581
575
  except Exception as e:
582
- logger.error(f"Failed to refresh tools for server {self.server_name}: {e}")
576
+ logger.error(f"Failed to refresh tools for toolkit {self.toolkit_name}: {e}")
583
577
 
584
578
  async def get_server_health(self) -> Dict[str, Any]:
585
- """Get health status of the configured MCP server."""
586
- if not self.server_name:
579
+ """Get health status of the configured MCP toolkit."""
580
+ if not self.toolkit_name:
587
581
  return {"status": "not_configured"}
588
582
 
589
583
  try:
590
584
  from ..clients.mcp_manager import get_mcp_manager
591
585
  manager = get_mcp_manager()
592
- health_info = await manager.get_server_health(self.server_name)
586
+ health_info = await manager.get_server_health(self.toolkit_name)
593
587
  return health_info
594
588
  except Exception as e:
595
- logger.error(f"Failed to get server health for {self.server_name}: {e}")
589
+ logger.error(f"Failed to get server health for {self.toolkit_name}: {e}")
596
590
  return {"status": "error", "error": str(e)}
597
591
 
598
592
 
@@ -611,14 +605,14 @@ def get_tools(tool_config: dict, alita_client, llm=None, memory_store=None) -> L
611
605
  List of configured MCP tools
612
606
  """
613
607
  settings = tool_config.get('settings', {})
608
+ toolkit_name = tool_config.get('toolkit_name')
614
609
 
615
610
  # Extract required fields
616
- server_name = settings.get('server_name')
617
611
  url = settings.get('url')
618
612
  headers = settings.get('headers')
619
613
 
620
- if not server_name:
621
- logger.error("MCP toolkit configuration missing required 'server_name'")
614
+ if not toolkit_name:
615
+ logger.error("MCP toolkit configuration missing required 'toolkit_name'")
622
616
  return []
623
617
 
624
618
  if not url:
@@ -626,16 +620,15 @@ def get_tools(tool_config: dict, alita_client, llm=None, memory_store=None) -> L
626
620
  return []
627
621
 
628
622
  return McpToolkit.get_toolkit(
629
- server_name=server_name,
630
623
  url=url,
631
624
  headers=headers,
632
625
  timeout=settings.get('timeout', 60),
633
- discovery_mode=settings.get('discovery_mode', 'hybrid'),
626
+ discovery_mode=settings.get('discovery_mode', 'dynamic'),
634
627
  discovery_interval=settings.get('discovery_interval', 300),
635
628
  selected_tools=settings.get('selected_tools', []),
636
629
  enable_caching=settings.get('enable_caching', True),
637
630
  cache_ttl=settings.get('cache_ttl', 300),
638
- toolkit_name=tool_config.get('toolkit_name'),
631
+ toolkit_name=toolkit_name,
639
632
  client=alita_client
640
633
  ).get_tools()
641
634
 
@@ -653,11 +646,11 @@ async def stop_global_discovery():
653
646
  await shutdown_discovery_service()
654
647
 
655
648
 
656
- async def register_mcp_server_for_discovery(server_name: str, connection_config):
649
+ async def register_mcp_server_for_discovery(toolkit_name: str, connection_config):
657
650
  """Register an MCP server for global discovery."""
658
651
  from ..clients.mcp_discovery import get_discovery_service
659
652
  service = get_discovery_service()
660
- await service.register_server(server_name, connection_config)
653
+ await service.register_server(toolkit_name, connection_config)
661
654
 
662
655
 
663
656
  def get_all_discovered_servers():
@@ -128,7 +128,8 @@ def get_tools(tools_list: list, alita_client, llm, memory_store: BaseStore = Non
128
128
  tools += community_tools(tools_list, alita_client, llm)
129
129
  # Add alita tools
130
130
  tools += alita_tools(tools_list, alita_client, llm, memory_store)
131
- # Add MCP tools
131
+ # Add MCP tools registered via alita-mcp CLI (static registry)
132
+ # Note: Tools with type='mcp' are already handled in main loop above
132
133
  tools += _mcp_tools(tools_list, alita_client)
133
134
 
134
135
  # Sanitize tool names to meet OpenAI's function naming requirements
@@ -183,6 +184,10 @@ def _sanitize_tool_names(tools: list) -> list:
183
184
 
184
185
 
185
186
  def _mcp_tools(tools_list, alita):
187
+ """
188
+ Handle MCP tools registered via alita-mcp CLI (static registry).
189
+ Skips tools with type='mcp' as those are handled by dynamic discovery.
190
+ """
186
191
  try:
187
192
  all_available_toolkits = alita.get_mcp_toolkits()
188
193
  toolkit_lookup = {tk["name"]: tk for tk in all_available_toolkits}
@@ -190,6 +195,11 @@ def _mcp_tools(tools_list, alita):
190
195
  #
191
196
  for selected_toolkit in tools_list:
192
197
  server_toolkit_name = selected_toolkit['type']
198
+
199
+ # Skip tools with type='mcp' - they're handled by dynamic discovery
200
+ if server_toolkit_name == 'mcp':
201
+ continue
202
+
193
203
  toolkit_conf = toolkit_lookup.get(server_toolkit_name)
194
204
  #
195
205
  if not toolkit_conf:
@@ -65,21 +65,17 @@ class McpInspectTool(BaseTool):
65
65
  def _run(self, resource_type: str = "all") -> str:
66
66
  """Inspect the MCP server for available resources."""
67
67
  try:
68
- # Run the async inspection
69
- loop = asyncio.get_event_loop()
70
- if loop.is_running():
71
- # If we're in an async context, we need to create a new event loop
72
- import concurrent.futures
73
- with concurrent.futures.ThreadPoolExecutor() as executor:
74
- future = executor.submit(self._run_async_inspection, resource_type)
75
- return future.result(timeout=self.timeout)
76
- else:
77
- return loop.run_until_complete(self._run_async_inspection(resource_type))
68
+ # Always create a new event loop for sync context
69
+ # This avoids issues with existing event loops in threads
70
+ import concurrent.futures
71
+ with concurrent.futures.ThreadPoolExecutor() as executor:
72
+ future = executor.submit(self._run_in_new_loop, resource_type)
73
+ return future.result(timeout=self.timeout)
78
74
  except Exception as e:
79
75
  logger.error(f"Error inspecting MCP server '{self.server_name}': {e}")
80
76
  return f"Error inspecting MCP server: {e}"
81
77
 
82
- def _run_async_inspection(self, resource_type: str) -> str:
78
+ def _run_in_new_loop(self, resource_type: str) -> str:
83
79
  """Run the async inspection in a new event loop."""
84
80
  return asyncio.run(self._inspect_server(resource_type))
85
81
 
@@ -132,7 +128,11 @@ class McpInspectTool(BaseTool):
132
128
  "params": {}
133
129
  }
134
130
 
135
- headers = {"Content-Type": "application/json", **self.server_headers}
131
+ headers = {
132
+ "Content-Type": "application/json",
133
+ "Accept": "application/json, text/event-stream",
134
+ **self.server_headers
135
+ }
136
136
 
137
137
  async with session.post(self.server_url, json=request, headers=headers) as response:
138
138
  if response.status != 200:
@@ -154,7 +154,11 @@ class McpInspectTool(BaseTool):
154
154
  "params": {}
155
155
  }
156
156
 
157
- headers = {"Content-Type": "application/json", **self.server_headers}
157
+ headers = {
158
+ "Content-Type": "application/json",
159
+ "Accept": "application/json, text/event-stream",
160
+ **self.server_headers
161
+ }
158
162
 
159
163
  async with session.post(self.server_url, json=request, headers=headers) as response:
160
164
  if response.status != 200:
@@ -176,7 +180,11 @@ class McpInspectTool(BaseTool):
176
180
  "params": {}
177
181
  }
178
182
 
179
- headers = {"Content-Type": "application/json", **self.server_headers}
183
+ headers = {
184
+ "Content-Type": "application/json",
185
+ "Accept": "application/json, text/event-stream",
186
+ **self.server_headers
187
+ }
180
188
 
181
189
  async with session.post(self.server_url, json=request, headers=headers) as response:
182
190
  if response.status != 200:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: alita_sdk
3
- Version: 0.3.430
3
+ Version: 0.3.432
4
4
  Summary: SDK for building langchain agents using resources from Alita
5
5
  Author-email: Artem Rozumenko <artyom.rozumenko@gmail.com>, Mikalai Biazruchka <mikalai_biazruchka@epam.com>, Roman Mitusov <roman_mitusov@epam.com>, Ivan Krakhmaliuk <lifedj27@gmail.com>, Artem Dubrovskiy <ad13box@gmail.com>
6
6
  License-Expression: Apache-2.0
@@ -103,10 +103,10 @@ alita_sdk/runtime/toolkits/application.py,sha256=HHAKgwKOckxc7EQG-AV7rz4POOzQJKF
103
103
  alita_sdk/runtime/toolkits/artifact.py,sha256=YChNCX4QhVpaQG7Jk4TS-Wl0Aruc4slQ2K21zh9nNO0,3176
104
104
  alita_sdk/runtime/toolkits/configurations.py,sha256=kIDAlnryPQfbZyFxV-9SzN2-Vefzx06TX1BBdIIpN90,141
105
105
  alita_sdk/runtime/toolkits/datasource.py,sha256=qk78OdPoReYPCWwahfkKLbKc4pfsu-061oXRryFLP6I,2498
106
- alita_sdk/runtime/toolkits/mcp.py,sha256=KLiNWiKH95r9OAmfleVFCe8MwYNawF_FANgNz_-Ta5k,25936
106
+ alita_sdk/runtime/toolkits/mcp.py,sha256=lh1REOY680Q3yP4DfmzFLllmJIZy1IM90NZd1CwLrDY,25730
107
107
  alita_sdk/runtime/toolkits/prompt.py,sha256=WIpTkkVYWqIqOWR_LlSWz3ug8uO9tm5jJ7aZYdiGRn0,1192
108
108
  alita_sdk/runtime/toolkits/subgraph.py,sha256=wwUK8JjPXkGzyVZ3tAukmvST6eGbqx_U11rpnmbrvtg,2105
109
- alita_sdk/runtime/toolkits/tools.py,sha256=By1G9gPlp-ZgOriWJm3b77A3ukb3Cs-SZ8dpNs0JaZw,10490
109
+ alita_sdk/runtime/toolkits/tools.py,sha256=YCTjrTJuwj2V2C8ZQqXhFvUbVr7NQcUHZlCQLLvoeGA,10946
110
110
  alita_sdk/runtime/toolkits/vectorstore.py,sha256=BGppQADa1ZiLO17fC0uCACTTEvPHlodEDYEzUcBRbAA,2901
111
111
  alita_sdk/runtime/tools/__init__.py,sha256=Fx7iHqkzA90-KfjdcUUzMUI_7kDarjuTsSpSzOW2pN0,568
112
112
  alita_sdk/runtime/tools/agent.py,sha256=m98QxOHwnCRTT9j18Olbb5UPS8-ZGeQaGiUyZJSyFck,3162
@@ -121,7 +121,7 @@ alita_sdk/runtime/tools/indexer_tool.py,sha256=whSLPevB4WD6dhh2JDXEivDmTvbjiMV1M
121
121
  alita_sdk/runtime/tools/llm.py,sha256=iRG_wU4T01LRsjEMPZe5Uah7LiMqDc-vspwkMuQtltk,16136
122
122
  alita_sdk/runtime/tools/loop.py,sha256=uds0WhZvwMxDVFI6MZHrcmMle637cQfBNg682iLxoJA,8335
123
123
  alita_sdk/runtime/tools/loop_output.py,sha256=U4hO9PCQgWlXwOq6jdmCGbegtAxGAPXObSxZQ3z38uk,8069
124
- alita_sdk/runtime/tools/mcp_inspect_tool.py,sha256=EW81_XlXX5C4lxT-gHMehHcZhtbuG-8DQzo0NuDkCA4,10160
124
+ alita_sdk/runtime/tools/mcp_inspect_tool.py,sha256=wgnv0z9MvB-PWriGKHHpY2IMxjBkd7Cbz4kvwGp9aq8,10243
125
125
  alita_sdk/runtime/tools/mcp_server_tool.py,sha256=y6y0j3JeUajNatpsLVJfP0JEknhlRcDRJ0PlJ3Ch8fA,6626
126
126
  alita_sdk/runtime/tools/pgvector_search.py,sha256=NN2BGAnq4SsDHIhUcFZ8d_dbEOM8QwB0UwpsWCYruXU,11692
127
127
  alita_sdk/runtime/tools/prompt.py,sha256=nJafb_e5aOM1Rr3qGFCR-SKziU9uCsiP2okIMs9PppM,741
@@ -358,8 +358,8 @@ alita_sdk/tools/zephyr_scale/api_wrapper.py,sha256=kT0TbmMvuKhDUZc0i7KO18O38JM9S
358
358
  alita_sdk/tools/zephyr_squad/__init__.py,sha256=0ne8XLJEQSLOWfzd2HdnqOYmQlUliKHbBED5kW_Vias,2895
359
359
  alita_sdk/tools/zephyr_squad/api_wrapper.py,sha256=kmw_xol8YIYFplBLWTqP_VKPRhL_1ItDD0_vXTe_UuI,14906
360
360
  alita_sdk/tools/zephyr_squad/zephyr_squad_cloud_client.py,sha256=R371waHsms4sllHCbijKYs90C-9Yu0sSR3N4SUfQOgU,5066
361
- alita_sdk-0.3.430.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
362
- alita_sdk-0.3.430.dist-info/METADATA,sha256=FRH-k7SYr8J7tTXEOK09ofk2t2dWqUMpJgzjHVZjhmo,19071
363
- alita_sdk-0.3.430.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
364
- alita_sdk-0.3.430.dist-info/top_level.txt,sha256=0vJYy5p_jK6AwVb1aqXr7Kgqgk3WDtQ6t5C-XI9zkmg,10
365
- alita_sdk-0.3.430.dist-info/RECORD,,
361
+ alita_sdk-0.3.432.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
362
+ alita_sdk-0.3.432.dist-info/METADATA,sha256=5ta9EQvl3qdFIGaqQCAQLW9VWo7PYJRHdNmffxCbdK8,19071
363
+ alita_sdk-0.3.432.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
364
+ alita_sdk-0.3.432.dist-info/top_level.txt,sha256=0vJYy5p_jK6AwVb1aqXr7Kgqgk3WDtQ6t5C-XI9zkmg,10
365
+ alita_sdk-0.3.432.dist-info/RECORD,,