agentscope-ai/agentscope · error · ValueError
The MCP client '{client.name}' is stateful, but not connecte
Error message
The MCP client '{client.name}' is stateful, but not connected. What it means
Toolkit.__init__ validates that every stateful MCP client inside its tool groups has an active connection before the toolkit is used. Stateful clients keep sessions open, so a disconnected one would fail on first tool call; the error is raised up front instead.
Source
Thrown at src/agentscope/tool/_toolkit.py:148
tools=tools or [],
skills_or_loaders=skills_or_loaders or [],
mcps=mcps or [],
),
] + (tool_groups or [])
# Check name conflict for tool groups
if len(set(_.name for _ in self.tool_groups)) != len(
self.tool_groups,
):
raise ValueError(
"Tool groups must not contain duplicate tool groups.",
)
# The stateful MCP clients should be initialized already
for group in self.tool_groups:
for client in group.mcps:
if client.is_stateful and not client.is_connected:
raise ValueError(
f"The MCP client '{client.name}' is stateful, but "
f"not connected.",
)
self.meta_tool_response_template = meta_tool_response_template
self.skill_instruction_template = skill_instruction_template
self.builtin_meta_tool = RegisteredTool(
tool=ResetTools(
# An inference value for groups so that it can generate the
# corresponding input schema.
groups=self.tool_groups,
response_template=meta_tool_response_template,
),
)
self.builtin_skill_viewer = RegisteredTool(
tool=SkillViewer(View on GitHub (pinned to e90f1c7592)
Solutions
- Call `await client.connect()` on every stateful MCP client before constructing the Toolkit
- Ensure connect() completed (await it, don't fire-and-forget) if connections are made in async setup
- If the client doesn't need a live session, use a stateless MCP client configuration instead
Example fix
# before client = MCPClient(...) toolkit = Toolkit(tool_groups=[ToolGroup(name='g', mcps=[client])]) # after client = MCPClient(...) await client.connect() toolkit = Toolkit(tool_groups=[ToolGroup(name='g', mcps=[client])])
Defensive patterns
Strategy: validation
Validate before calling
for g in tool_groups:
for c in g.mcps:
if c.is_stateful and not c.is_connected:
await c.connect()
toolkit = Toolkit(tool_groups=tool_groups) Try / catch
try:
toolkit = Toolkit(tool_groups=groups)
except ValueError as e:
if 'not connected' in str(e):
for c in all_mcps:
await c.connect()
toolkit = Toolkit(tool_groups=groups) Prevention
- Always await connect() in async setup before building the Toolkit
- Centralize MCP client creation + connection in one factory function
When it happens
Trigger: Passing a ToolGroup whose mcps include a stateful MCP client (is_stateful=True) that has not had await client.connect() called yet, or whose connection was closed before Toolkit creation.
Common situations: Forgetting to connect MCP clients before building the agent/toolkit; reconnecting flows where connect() is skipped after a disconnect; ordering bugs where Toolkit is constructed before async setup completes.
Related errors
- connect failed: {e}
- STDIO MCP does not support ephemeral mode. Use 'shared' or '
- Invalid values for MCP {card.name!r}: {e.message}
- MCP {card.name!r} needs a value for: {', '.join(sorted(missi
- MCP {card.name!r} produced an invalid client: {e}
AI-assisted analysis of agentscope-ai/agentscope@e90f1c7592 (2026-08-28).
Data as JSON: /api/errors/f79b5e599a14fc2f.
Report an issue: GitHub.