Skip to content

datarobot_genai.crewai.mcp

mcp

MCP integration for CrewAI.

Loads MCP tools via mcpadapt, keeping each tool's server inputSchema as the LLM-facing function-call parameters so the schema stays provider-portable (see _RawSchemaCrewAIAdapter).

mcp_tools_context async

mcp_tools_context(mcp_config: MCPConfig) -> AsyncGenerator[list[BaseTool], None]

Context manager for MCP tools that handles connection lifecycle.

Source code in datarobot_genai/crewai/mcp.py
@asynccontextmanager
async def mcp_tools_context(mcp_config: MCPConfig) -> AsyncGenerator[list[BaseTool], None]:
    """Context manager for MCP tools that handles connection lifecycle."""
    # If no MCP server configured, return empty tools list
    if not mcp_config.server_config:
        logger.info("No MCP server configured, using empty tools list")
        yield []
        return

    url = mcp_config.server_config["url"]

    # A local MCP server that isn't running would otherwise block ~30s and dump
    # a background-thread traceback; skip the adapter and degrade cleanly.
    if mcp_config.is_local_server and not _local_server_reachable(url):
        logger.warning(
            "Local MCP server at %s is not reachable. Continuing without MCP tools.",
            url,
        )
        yield []
        return

    logger.info("Connecting to MCP server: %s", url)

    try:
        adapter = MCPAdapt(mcp_config.server_config, _RawSchemaCrewAIAdapter())
        tools = adapter.__enter__()
    except Exception as exc:
        logger.warning(
            "Failed to connect to MCP server at %s: %s. Continuing without MCP tools.",
            url,
            exc,
        )
        yield []
        return

    try:
        logger.info("Successfully connected to MCP server, got %d tools", len(tools))
        yield tools
    finally:
        adapter.__exit__(None, None, None)