opencode icon indicating copy to clipboard operation
opencode copied to clipboard

feat: Dynamic (lazy) mcp tool schema loading

Open DhruvAtreja opened this issue 2 days ago • 3 comments

What does this PR do?

  • Implement lazy loading for MCP tools to reduce initial context bloat by 95%+
  • Add mcp_load_tools meta-tool for on-demand tool loading
  • Add mcp_lazy_load experimental config flag (off by default)

Problem

When multiple MCP servers are enabled, all tool definitions load into the agent's context at session startup. A single MCP server like GitHub can add 15-20k+ tokens just for tool schemas. With several MCPs enabled, context bloat can exceed 50k tokens before the user even sends a message. This is even mentioned in the docs: https://opencode.ai/docs/mcp-servers/

Solution

Lazy loading pattern: Instead of loading full tool schemas at startup, we:

  1. Show a lightweight index in the system prompt with server names and tool names only (~150 tokens vs ~1.5k)
  2. Provide a mcp_load_tools meta-tool that loads specific tools on-demand
  3. The agent loop naturally picks up newly loaded tools on the next iteration

Example Flow

System prompt shows: "playwright (20 tools): browser_snapshot, browser_click, browser_navigate, ..."

User: "Take a screenshot of google.com"

Agent calls: mcp_load_tools("playwright", ["browser_navigate", "browser_snapshot"]) → Tools loaded into session state

Agent calls: playwright_browser_navigate({ url: "https://google.com" }) Agent calls: playwright_browser_snapshot()

Changes File: config/config.ts Changes: Add mcp_lazy_load to experimental options ──────────────────────────────────────── File: session/index.ts Changes: Add mcpLoadedTools to Session.Info schema ──────────────────────────────────────── File: mcp/index.ts Changes: Add index(), loadToolsForSession(), modify tools() and create() ──────────────────────────────────────── File: session/system.ts Changes: Add mcpIndex() for system prompt generation ──────────────────────────────────────── File: session/prompt.ts Changes: Include MCP index in system prompt, pass session state to MCP.tools() ──────────────────────────────────────── File: tool/mcp-load-tools.ts Changes: New meta-tool implementation ──────────────────────────────────────── File: tool/registry.ts Changes: Register meta-tool conditionally

How did you verify your code works?

  • Enable with "experimental": { "mcp_lazy_load": true } in config
  • Verify MCP servers appear in system prompt with tool names
  • Verify mcp_load_tools tool is available
  • Ask agent to use MCP tools, confirm it calls mcp_load_tools first
  • Verify loaded tools work correctly after loading
  • Verify backward compatibility with flag disabled (default)
Screenshot 2026-01-13 at 1 16 27 AM

Closes #8277

DhruvAtreja avatar Jan 13 '26 09:01 DhruvAtreja