feat(agents): MCP server support with per-agent enablement#823
Open
ericvicenti wants to merge 8 commits into
Open
feat(agents): MCP server support with per-agent enablement#823ericvicenti wants to merge 8 commits into
ericvicenti wants to merge 8 commits into
Conversation
Add two model-facing web research tools to the Agents runtime, fully self-hosted with no third-party API keys: - web_search: queries a self-hosted SearXNG instance (GET /search?format=json) with engine-rotation retry on upstream blocking and a degraded flag for partial coverage. - web_read: tiered cheapest-first reader returning the first tier that yields substantial content: MediaWiki REST/Parsoid API -> in-process static extraction (@mozilla/readability on a linkedom DOM + Turndown) -> optional Crawl4AI headless-browser /md escalation (one retry). Output bounded to 200 KiB. Implementation in agents/src/web-tools.ts; config (SEED_AGENTS_SEARXNG_URL, SEED_AGENTS_CRAWLER_URL, SEED_AGENTS_CRAWLER_TOKEN) threaded from Service into the tool context; registry entries in tool-registry.ts; desktop Tools-tab web group. Tools are opt-in per agent and degrade gracefully when unconfigured (web_search errors; web_read uses MediaWiki + static tiers only). Tested against live SearXNG + Crawl4AI 0.9.0 containers; unit tests in web-tools.test.ts and an end-to-end tool-call test in api-service.test.ts. A ready-to-run local backend compose lives in agents/dev/web-backends/. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
- Add web_read `raw: true` option: returns the verbatim response body (HTML/JSON/source code/text) with no extraction or markdown conversion, bounded to the size limit and rejecting binary content types. For reading source files (raw.githubusercontent.com), JSON APIs, and config files. source is 'raw' and the result includes contentType. - Replace the internal tier name in the user-facing summary with plain language: "via the wiki API" / "via direct fetch" / "with a browser" (the machine-readable `source` field is unchanged). Adds unit tests for raw mode (verbatim body + binary guard) and the summary wording; live-checked raw mode against a GitHub raw file and the GitHub JSON API. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Server now advertises optional web-tool backends in its health response
(webTools: {search, readBrowser}, derived from SEED_AGENTS_SEARXNG_URL /
SEED_AGENTS_CRAWLER_URL via Service.webToolCapabilities()).
Desktop Tools tab:
- Reads the server health capabilities and greys out tools the server cannot
run, with an explanation (e.g. web_search greyed when SearXNG isn't
configured; web_read notes when browser rendering is unavailable). A group's
toggle is disabled only when none of its tools can run. Unknown/older servers
(no capability flags) are treated as available.
- Lists each group's individual member tools, each with an info (i) button
opening a dialog (ToolInfoDialog) showing the exact model-facing description
and the input/output JSON schemas from the shared tool registry, so an agent
owner can see precisely what prompting/context each tool passes to the model.
Adds a server test asserting health reflects configured web backends.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Populate the previously-empty outputSchema slot for both web tools so the desktop tool-info dialog shows their output contract (results/degraded/markdown for web_search; finalUrl/source/contentType/truncated/markdown for web_read), not just the input schema. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
- tools.md: order web_read as tiered chain first, then raw mode; add a "Server capability and desktop visibility" subsection covering output schemas, the health webTools capability, and the desktop greying + per-tool info dialog. - operations.md: note production sidecar deployment lives in the infrastructure repo; reflow. - desktop-ui.md: reflow of the Tools tab capability/info-dialog notes. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Integrate the evaluation/rationale from the original planning doc into implementation-history.md: why SearXNG + Crawl4AI + in-process MediaWiki/static extraction were kept and why ReaderLM-v2, ArchiveBox, Firecrawl, Wayback, and Trafilatura were dropped for a reliable, easy-to-host, fully self-hostable suite. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
`bun run dev` now defaults SEED_AGENTS_SEARXNG_URL (:8899), SEED_AGENTS_CRAWLER_URL (:11235), and SEED_AGENTS_CRAWLER_TOKEN (dev-crawl-token) to the agents/dev/web-backends compose values, so web_search/web_read work in dev with no manual env. The defaults are overridable (export the env vars). Documented the simplified dev flow in operations.md and the compose header. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Add account-scoped remote MCP (Model Context Protocol) servers that extend agents with external tools. Servers are configured per account (like model providers) and enabled per agent; their tools are discovered at run start, exposed to the model under an `mcp__<server>__<tool>` namespace, proxied back to the server, and disconnected when the run ends. - protocol: McpServerConfig/RedactedMcpServer/McpToolInfo, mcpServers on AgentDefinition, and ListMcpServers/SetMcpServer/DeleteMcpServer/ ListMcpServerTools actions + responses. - persistence: mcp_servers table (baseline schema + migration). - service: agents/src/mcp.ts (Streamable HTTP/SSE connect, list, proxy via @modelcontextprotocol/sdk) plus CRUD handlers and runtime wiring with failure isolation. - desktop: Tools-tab MCP section (add/enable/inspect/remove) + hooks + types. Behavior fixes from review: - UpdateAgent aborts in-flight runs when tools/mcpServers change, so changes take effect immediately instead of only on the next message. - MCP connect/listing failures surface as a visible session error event instead of failing silently. - DeleteMcpServer scrubs the server name from all agents' mcpServers so runs never reference a deleted server. Only remote HTTP/SSE transports are supported (no stdio); auth is via static headers (secret-backed), not interactive OAuth. Docs added in agents/docs/mcp.md and cross-referenced from the agents knowledgebase. Co-Authored-By: Claude Opus 4.8 <[email protected]>
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.
Summary
Adds account-scoped remote MCP (Model Context Protocol) servers that extend agents with external tools. Servers are configured per account (like model providers) and enabled per agent. When an agent runs, the service connects to its enabled MCP servers, lists their tools, exposes them to the model under an
mcp__<server>__<tool>namespace, proxies tool calls back to the server, and disconnects when the run ends.You can add and manage MCP servers from the agent Tools tab: add a server (name, URL, transport, optional encrypted auth header), enable it per agent with a checkbox, inspect the tools it advertises, and remove it.
What's included
agents/protocol/src/index.ts):McpServerConfig,RedactedMcpServer,McpToolInfo,mcpServersonAgentDefinition;ListMcpServers/SetMcpServer/DeleteMcpServer/ListMcpServerToolsactions + responses.mcp_serverstable (baseline schema + prepend migration, with the migration test updated).agents/src/mcp.ts(Streamable HTTP/SSE connect, tool listing, namespacing, and tool-call proxying via@modelcontextprotocol/sdk); CRUD handlers and runtime wiring inapi-service.tswith failure isolation.agents/docs/mcp.md, cross-referenced from the agents knowledgebase (readme/tools/security/persistence/signed-api/desktop-ui).Behavior fixes from review
UpdateAgentaborts in-flight runs whentools/mcpServerschange, so changes take effect right away instead of only on the next message. Scoped to capability changes, so prompt/name/model autosaves don't interrupt a running response.errorsession event (instead of failing silently), so a missing tool is explained in the chat.DeleteMcpServerscrubs the server name from all agents'mcpServers, so runs never reference a deleted server.Scope / limitations
stdiosubprocesses.Testing
agents/src/mcp.test.ts— namespacing/header helpers plus an end-to-end test that stands up a real Streamable HTTP MCP server and verifies connect → list tools → proxy a tool call (including the auth header).agents/src/api-service.test.ts— MCP CRUD, redaction, header-secret cleanup on delete, URL validation,mcpServerspersistence, delete-scrubs-agents, and a visible-error-on-connect-failure test.bun check(typecheck + format) andpnpm typecheckclean.🤖 Generated with Claude Code