Skip to content

Refactor dynamic tool provider lifecycle out of AgentLoop #4858

Description

@chengyongru

Problem

MCP is currently modeled directly in AgentLoop through MCP-specific state and lifecycle methods such as _mcp_servers, _mcp_stacks, _connect_mcp(), and close_mcp(). This works for the immediate reconnect/crash fix in #4843, but it leaks a tool-specific provider lifecycle into the core agent loop.

MCP is not a single static tool. It is a tool provider: it connects to external servers, dynamically registers multiple tools/resources/prompts, supports reconnect and hot reload, and owns long-lived async transport cleanup. Those responsibilities are closer to nanobot/agent/tools/mcp.py or a general tool-provider runtime layer than to AgentLoop.

Why this matters

  • AgentLoop should coordinate turns, sessions, tasks, and shutdown, not know MCP transport details.
  • MCP-specific cleanup concerns such as retired stacks, AnyIO cancel-scope behavior, and streamable-http teardown should stay behind the MCP/tool boundary.
  • Future dynamic tool providers will likely need similar lifecycle hooks; copying MCP-style special cases into AgentLoop would make the core path harder to maintain.

Desired direction

Introduce a small tool-provider lifecycle abstraction, or an equivalent local boundary, so providers can own their own runtime state and cleanup:

  • provider start/connect against a ToolRegistry
  • provider close/drain cleanup
  • provider reload/hot-reload hook where applicable
  • provider runtime-context lines where applicable
  • grouping/ownership of dynamically registered tools

MCP can then become the first implementation, with _mcp_servers, _mcp_stacks, retired stacks, reconnect, reload, and cleanup owned outside AgentLoop.

Scope notes

This should be a follow-up refactor after #4843, not part of the production crash fix. #4843 should stay focused on #4302 and its regression coverage.

Metadata

Metadata

Assignees

No one assigned

    Labels

    priority: p2Normal backlog: minor bug, enhancement, docs, cleanup, edge case, or unvalidated proposal.refactor

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions