Repository navigation
feat(mcp): load MCP tools on demand with load_tools - #56
Merged
Merged
Conversation
The agent no longer connects to every MCP server and binds all its tools on each request. It sees a short list of capabilities plus load_tools, which searches a cached catalog (BM25) and adds the best matches to the tools parameter. A server connects only when one of its tools is called, through a pooled connection that closes when idle. - Add the @agentailor/mcp-disclosure workspace package: catalog, search, connection pool and middleware. It imports no app code and no MCP client. - Add the mcp_server_catalog table and refresh it on create, enable, edit, OAuth completion and on demand. - Keep loaded tools for the thread: append only, because changing the tool list costs a prompt-cache miss. - Report servers needing sign-in from stored state, without connecting. - Send MCP schemas to the model unchanged. - Describe servers with an owner-written description, else a summary generated on the owner's model. - Trace offered tool definitions and provider cache reads and writes. - Add eval cases on in-process mock MCP servers. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Pool: a running call holds its session (acquire/release), so a call longer than the idle timeout is not closed under itself; closeAll now awaits every close. - load_tools: an exact tool name honors the `server` scope. - Tool routing: an ambiguous `__` prefix resolves to the server whose catalog lists the tool. - Catalog: chat messages back off for 5 minutes after a failed refresh of the same server version; the freshness check goes through the same per-version dedup; a description change refreshes the summary. - Fix the doc reference in the catalog schema comment. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A component diagram (catalog write vs. read paths, pool, checkpointer) and a one-message sequence showing load_tools never connects. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Every enabled MCP server used to be connected on each request, with all of its tools sent to the model. Context grew with every server, tool choice got worse, and each server cost a connection whether it was used or not.
With this change the model sees a short list of capabilities and one tool,
load_tools. It searches a cached catalog of every server's tools and adds the best matches to the model's tools for the rest of the thread. A server connects only when one of its tools is called, through a pooled connection that closes after 5 idle minutes.Full design: docs/MCP_DISCLOSURE.md.
What's in it
packages/mcp-disclosure(@agentailor/mcp-disclosure), a workspace package with the catalog, BM25 search, connection pool and middleware. It imports no app code and no MCP client library;src/lib/mcp/connector.tsis the only agent-path file that uses@langchain/mcp-adapters.load_tools({ query, server?, limit? })loads 5 matches by default, at most 10. An exact tool name loads only that tool, and a search with no match returns the tool names to try instead.load_toolsnever loads their tools and tells the model to ask for a reconnect on the Connections page.0004adds themcp_server_catalogtable and0005addsmcp_server.description. Runpnpm db:migrate.With no MCP server enabled, the model sees no
load_toolsand no capability list, so prompts and tools are unchanged.Testing
pnpm test,tsc --noEmit,pnpm typecheck:evalandpnpm buildpass.eval/cases/mcp.cases.mts, on in-process mock MCP servers (opt in withmcp: true). All 4 passed with one run each: searching before using a tool, finding a tool from different words, loading nothing for a ledger question, and reporting a server that needs sign-in. Other cases see no MCP servers.Known limits
🤖 Generated with Claude Code