BerriAI/litellm · error · ValueError

stdio_config is required for stdio transport

Error message

stdio_config is required for stdio transport

What it means

The MCP client picks a transport by transport_type. When transport_type is stdio, it must build StdioServerParameters from a stdio_config dict (command, args, env); if stdio_config is missing or empty the client cannot spawn the server process and raises ValueError immediately.

Source

Thrown at litellm/experimental_mcp_client/client.py:269

        self._elicitation_callback: Callable | None = elicitation_callback
        self._logging_callback: Callable | None = logging_callback
        # handle the basic auth value if provided
        if auth_value:
            self.update_auth_value(auth_value)

    def _create_transport_context(
        self,
    ) -> tuple[Any, httpx.AsyncClient | None]:
        """
        Create the appropriate transport context based on transport type.
        Returns:
            Tuple of (transport_context, http_client).
            http_client is only set for HTTP transport and needs cleanup.
        """
        http_client: httpx.AsyncClient | None = None
        if self.transport_type == MCPTransport.stdio:
            if not self.stdio_config:
                raise ValueError("stdio_config is required for stdio transport")
            server_params: Final = StdioServerParameters(
                command=self.stdio_config.get("command", ""),
                args=self.stdio_config.get("args", []),
                env=self._get_safe_stdio_env(self.stdio_config.get("env")),
            )
            return stdio_client(server_params), None
        if self.transport_type == MCPTransport.sse:
            headers = self._get_auth_headers()
            httpx_client_factory = self._create_httpx_client_factory()
            return (
                sse_client(
                    url=self.server_url,
                    timeout=self.timeout,
                    headers=headers,
                    httpx_client_factory=httpx_client_factory,
                ),
                None,
            )

View on GitHub (pinned to 6c2dcb801b)

Solutions

  1. Add a stdio_config block with at least command (and usually args): stdio_config: {command: 'npx', args: ['-y', '@modelcontextprotocol/server-everything']}
  2. Verify transport_type matches the config: use transport_type='http'/'sse' with url for remote servers, 'stdio' with stdio_config for local processes
  3. Check YAML indentation so stdio_config is a sibling of transport_type under the server entry, not nested elsewhere
  4. Confirm stdio_config is non-empty after litellm's config loading (os.environ/ prefixed values must resolve to real strings)

Example fix

# before
mcp_servers:
  my_server:
    transport_type: stdio
    url: http://localhost:8000/mcp

# after
mcp_servers:
  my_server:
    transport_type: stdio
    stdio_config:
      command: npx
      args: ["-y", "@modelcontextprotocol/server-everything"]
Defensive patterns

Strategy: validation

Validate before calling

def validate_mcp_server_entry(server: dict) -> None:
    if server.get("transport_type", "stdio") == "stdio":
        sc = server.get("stdio_config")
        if not sc or not sc.get("command"):
            raise ValueError("stdio servers need stdio_config.command")
    else:
        if not server.get("url"):
            raise ValueError("http/sse servers need url")

Type guard

def is_valid_stdio_config(cfg: object) -> bool:
    return (
        isinstance(cfg, dict)
        and isinstance(cfg.get("command"), str)
        and cfg["command"].strip() != ""
        and isinstance(cfg.get("args", []), list)
    )

Prevention

When it happens

Trigger: Registering an MCP server with transport_type='stdio' (or omitting transport_type so it defaults to stdio) but only supplying url/ without any stdio_config block; typoing the key as stdio or stdin_config; passing stdio_config: {} which is falsy.

Common situations: Converting an HTTP MCP server entry to stdio and forgetting to add the command block; YAML config indentation putting stdio_config under the wrong key; assuming url alone works for every transport type.

Related errors


AI-assisted analysis of BerriAI/litellm@6c2dcb801b (2026-08-15). Data as JSON: /api/errors/a03a5c4056604d4b. Report an issue: GitHub.