> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.nvidia.com/nemo/datadesigner/llms.txt.
> For full documentation content, see https://docs.nvidia.com/nemo/datadesigner/llms-full.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.nvidia.com/nemo/datadesigner/_mcp/server.

# data\_designer.engine.mcp.io

Low-level MCP I/O operations with caching and session pooling.

This module provides stateless functions for MCP communication using an actor-style
service that owns all async state within a single background event loop. Public APIs
are synchronous wrappers that submit coroutines to the loop and wait for results.

Architecture:
All MCP I/O is funneled through a single dedicated asyncio event loop running
in a background daemon thread. This avoids the complexity of managing multiple
event loops and allows sessions to be reused across calls from any thread.

Worker Thread 1 ──┐
Worker Thread 2 ──┼──► MCP Event Loop Thread ──► MCP Servers
Worker Thread N ──┘    (all sessions live here)

Request Coalescing:
When multiple threads request tools from the same provider simultaneously,
only one request is made to the MCP server. Other callers wait for the
in-flight request to complete and share the result. This prevents N
concurrent workers from making N separate ListToolsRequest calls.

The caller (MCPFacade) is responsible for resolving any secret references in
provider api\_key fields before passing providers to these functions.

## Module Contents

### Classes

| Name                                                    | Description                                         |
| ------------------------------------------------------- | --------------------------------------------------- |
| [`MCPIOService`](#data_designerenginemcpiomcpioservice) | Actor-style MCP I/O service owning all async state. |

### Functions

| Name                                                                                        | Description                                                       |
| ------------------------------------------------------------------------------------------- | ----------------------------------------------------------------- |
| [`_provider_cache_key`](#data_designerenginemcpio_provider_cache_key)                       | Create a stable cache key for a provider.                         |
| [`list_tools`](#data_designerenginemcpiolist_tools)                                         | List tools from an MCP provider (cached with request coalescing). |
| [`list_tool_names`](#data_designerenginemcpiolist_tool_names)                               | Return the names of all tools available on an MCP provider.       |
| [`call_tools`](#data_designerenginemcpiocall_tools)                                         | Call multiple tools in parallel.                                  |
| [`clear_provider_caches`](#data_designerenginemcpioclear_provider_caches)                   | Clear all caches for specific MCP providers.                      |
| [`clear_tools_cache`](#data_designerenginemcpioclear_tools_cache)                           | Clear the list\_tools cache.                                      |
| [`get_cache_info`](#data_designerenginemcpioget_cache_info)                                 | Get cache statistics for list\_tools.                             |
| [`clear_session_pool`](#data_designerenginemcpioclear_session_pool)                         | Clear all pooled MCP sessions.                                    |
| [`get_session_pool_info`](#data_designerenginemcpioget_session_pool_info)                   | Get information about the session pool.                           |
| [`_build_auth_headers`](#data_designerenginemcpio_build_auth_headers)                       | Build authentication headers for remote MCP clients.              |
| [`_coerce_tool_definition`](#data_designerenginemcpio_coerce_tool_definition)               | Coerce a tool from various formats into MCPToolDefinition.        |
| [`_serialize_tool_result_content`](#data_designerenginemcpio_serialize_tool_result_content) | Serialize tool result content to a string.                        |

### Data

[`logger`](#data_designerenginemcpiologger)
[`_MCP_IO_SERVICE`](#data_designerenginemcpio_mcp_io_service)

### API

```python
logger = getLogger(...)
```

```python
data_designer.engine.mcp.io._provider_cache_key(provider: data_designer.config.mcp.MCPProviderT) -> str
```

Create a stable cache key for a provider.

```python
class data_designer.engine.mcp.io.MCPIOService
```

Actor-style MCP I/O service owning all async state.

```python
list_tools(
    provider: data_designer.config.mcp.MCPProviderT,
    timeout_sec: float | None = None
) -> tuple[data_designer.engine.mcp.registry.MCPToolDefinition, ...]
```

List tools from an MCP provider (cached with request coalescing).

```python
call_tools(
    calls: list[tuple[data_designer.config.mcp.MCPProviderT, str, dict[str, typing.Any]]],
    *,
    timeout_sec: float | None = None
) -> list[data_designer.engine.mcp.registry.MCPToolResult]
```

Call multiple tools in parallel.

```python
clear_provider_caches(providers: list[data_designer.config.mcp.MCPProviderT]) -> int
```

Clear caches and session pool entries for specific providers.

```python
clear_tools_cache() -> None
```

Clear the list\_tools cache (best effort).

```python
get_cache_info() -> dict[str, typing.Any]
```

Get cache statistics for list\_tools.

```python
clear_session_pool() -> None
```

Clear all pooled MCP sessions (best effort).

```python
get_session_pool_info() -> dict[str, typing.Any]
```

Get information about the session pool.

```python
shutdown() -> None
```

Shutdown the MCP event loop and close all sessions.

```python
_ensure_loop() -> asyncio.AbstractEventLoop
```

```python
_run_loop(loop: asyncio.AbstractEventLoop) -> None
```

```python
_run_on_loop(
    coro: collections.abc.Coroutine[typing.Any, typing.Any, typing.Any],
    timeout_sec: float | None
) -> typing.Any
```

```python
_get_or_create_session(provider: data_designer.config.mcp.MCPProviderT) -> mcp.ClientSession
```

```python
_list_tools_async(provider: data_designer.config.mcp.MCPProviderT) -> tuple[data_designer.engine.mcp.registry.MCPToolDefinition, ...]
```

```python
_call_tool_async(
    provider: data_designer.config.mcp.MCPProviderT,
    tool_name: str,
    arguments: dict[str, typing.Any]
) -> data_designer.engine.mcp.registry.MCPToolResult
```

```python
_call_tools_async(calls: list[tuple[data_designer.config.mcp.MCPProviderT, str, dict[str, typing.Any]]]) -> list[data_designer.engine.mcp.registry.MCPToolResult]
```

```python
_clear_provider_caches_async(providers: list[data_designer.config.mcp.MCPProviderT]) -> int
```

```python
_clear_provider_caches_sync(providers: list[data_designer.config.mcp.MCPProviderT]) -> int
```

```python
_clear_tools_cache_async() -> None
```

```python
_clear_tools_cache_sync() -> None
```

```python
_get_cache_info_async() -> dict[str, typing.Any]
```

```python
_close_all_sessions_async() -> None
```

```python
_clear_session_pool_sync() -> None
```

```python
_get_session_pool_info_async() -> dict[str, typing.Any]
```

```python
_invalidate_tools_cache(keys: collections.abc.Iterable[str]) -> None
```

```python
_all_tools_keys() -> set[str]
```

```python
_reset_state() -> None
```

```python
_MCP_IO_SERVICE = MCPIOService(...)
```

```python
data_designer.engine.mcp.io.list_tools(
    provider: data_designer.config.mcp.MCPProviderT,
    timeout_sec: float | None = None
) -> tuple[data_designer.engine.mcp.registry.MCPToolDefinition, ...]
```

List tools from an MCP provider (cached with request coalescing).

```python
data_designer.engine.mcp.io.list_tool_names(
    provider: data_designer.config.mcp.MCPProviderT,
    timeout_sec: float
) -> list[str]
```

Return the names of all tools available on an MCP provider.

```python
data_designer.engine.mcp.io.call_tools(
    calls: list[tuple[data_designer.config.mcp.MCPProviderT, str, dict[str, typing.Any]]],
    *,
    timeout_sec: float | None = None
) -> list[data_designer.engine.mcp.registry.MCPToolResult]
```

Call multiple tools in parallel.

```python
data_designer.engine.mcp.io.clear_provider_caches(providers: list[data_designer.config.mcp.MCPProviderT]) -> int
```

Clear all caches for specific MCP providers.

```python
data_designer.engine.mcp.io.clear_tools_cache() -> None
```

Clear the list\_tools cache.

```python
data_designer.engine.mcp.io.get_cache_info() -> dict[str, typing.Any]
```

Get cache statistics for list\_tools.

```python
data_designer.engine.mcp.io.clear_session_pool() -> None
```

Clear all pooled MCP sessions.

```python
data_designer.engine.mcp.io.get_session_pool_info() -> dict[str, typing.Any]
```

Get information about the session pool.

```python
data_designer.engine.mcp.io._build_auth_headers(api_key: str | None) -> dict[str, typing.Any] | None
```

Build authentication headers for remote MCP clients.

```python
data_designer.engine.mcp.io._coerce_tool_definition(
    tool: typing.Any,
    tool_definition_cls: type[data_designer.engine.mcp.registry.MCPToolDefinition]
) -> data_designer.engine.mcp.registry.MCPToolDefinition
```

Coerce a tool from various formats into MCPToolDefinition.

```python
data_designer.engine.mcp.io._serialize_tool_result_content(result: typing.Any) -> str
```

Serialize tool result content to a string.