Skip to content

restate.ext.pydantic requires pydantic-ai-slim[mcp] because _toolset.py imports pydantic_ai.mcp unguarded #221

Description

@touhonoob

restate.ext.pydantic can't be imported without pydantic-ai-slim[mcp], even with no MCP toolsets.

What happens

restate/ext/pydantic/__init__.py imports ._toolset, and _toolset.py:14 does an unguarded

from pydantic_ai.mcp import MCPToolset

pydantic_ai/mcp.py raises ImportError at import time when the mcp / fastmcp packages are absent, so with restate-sdk[pydantic-ai] + plain pydantic-ai-slim the whole extension fails to import:

$ pip install 'restate-sdk[pydantic-ai]==1.0.3' 'pydantic-ai-slim==2.12.0'
$ python -c "import restate.ext.pydantic"
ImportError: Please install the `mcp` package to use `MCPToolset`, you can use the `mcp` optional group — pip install "pydantic-ai-slim[mcp]"

Why it looks unintended

_agent.py already treats the same import as optional:

try:
    from pydantic_ai.mcp import MCPToolset
    from ._toolset import RestateMCPToolset
except ImportError:
    pass
else:
    if isinstance(toolset, MCPToolset):
        return RestateMCPToolset(toolset, run_options)

…but that guard can't help, because _agent.py unconditionally imports ._toolset a few lines earlier, and _toolset.py pulls pydantic_ai.mcp at module scope for RestateMCPToolset.

Impact

Anyone using RestateAgent with function tools only has to install pydantic-ai-slim[mcp] — 28 extra transitive packages in our case (fastmcp-slim, mcp, authlib, keyring, jsonschema, sse-starlette, secretstorage, …) — purely to satisfy an import for a class they never instantiate.

Suggested fix

Move RestateMCPToolset (and its MCPToolset import) into its own module imported lazily, or guard the import in _toolset.py the way _agent.py does and define RestateMCPToolset only when it succeeds.

Environment

restate-sdk 1.0.3, pydantic-ai-slim 2.12.0, Python 3.14.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions