Skip to content

Add MCP server support to live agent with Firecrawl web search#245

Closed
alexkroman wants to merge 2 commits into
mainfrom
claude/kind-goodall-rzbqka
Closed

Add MCP server support to live agent with Firecrawl web search#245
alexkroman wants to merge 2 commits into
mainfrom
claude/kind-goodall-rzbqka

Conversation

@alexkroman

Copy link
Copy Markdown
Collaborator

Adds Model Context Protocol (MCP) server integration to the assembly live voice agent, enabling it to use external tools mid-conversation. This includes a curated default toolset and support for user-configured servers via --mcp-config.

Summary

The live agent can now load tools from MCP servers, both a curated default set (time, fetch, memory, filesystem, weather) and user-provided servers from standard mcpServers JSON config files. Web search is now powered by Firecrawl (when FIRECRAWL_API_KEY is set) instead of Tavily, and MCP tools are advertised in the system prompt alongside built-in capabilities.

Key Changes

  • New MCP tools module (aai_cli/agent_cascade/mcp_tools.py):

    • default_servers() provides five curated, no-auth MCP servers
    • parse_mcp_config() reads standard Claude Desktop/Code mcpServers JSON files
    • load_mcp_tools() launches servers and collects their tools, with best-effort per-server error handling (one broken server doesn't sink the session)
    • Connection translation for stdio (command/args/env) and HTTP (url) transports
  • Firecrawl web search (aai_cli/code_agent/firecrawl_search.py):

    • Replaces Tavily as the default web search tool
    • Gated on FIRECRAWL_API_KEY environment variable
    • Returns None when key is absent (graceful degradation)
  • Brain system prompt updates (aai_cli/agent_cascade/brain.py):

    • _extra_capability() generates generic tool-listing guidance for MCP tools
    • build_system_prompt() now accepts extra_tools parameter for MCP tools
    • build_graph() accepts mcp_tools parameter and binds them alongside built-in tools
    • Updated docstrings to reference Firecrawl instead of Tavily
  • Command integration (aai_cli/commands/agent_cascade/):

    • New --mcp-config flag (repeatable) for user-provided server configs
    • _resolve_mcp_servers() merges defaults with config files (later files win)
    • _warn_without_web_search() emits a notice when FIRECRAWL_API_KEY is absent
    • Config flows into CascadeConfig.mcp_servers
  • Config updates (aai_cli/agent_cascade/config.py):

    • CascadeConfig.mcp_servers field holds the resolved server specs
  • Comprehensive test coverage (tests/test_agent_cascade_mcp.py):

    • 213 lines of tests covering config parsing, validation, connection translation, and tool loading
    • Tests for error cases (malformed JSON, missing keys, invalid specs)
    • Tests for best-effort server loading (one broken server doesn't block others)
    • Injected loader pattern for hermetic testing without subprocesses
  • Documentation (REFERENCE.md):

    • Added "Live agent tools (MCP)" section explaining the feature, defaults, and --mcp-config usage

Implementation Details

  • Best-effort loading: Each MCP server is launched independently via _safe_load(), which catches exceptions and returns an empty tool list on failure. This ensures a missing npx/uvx or offline host doesn't abort the session.
  • Config merging: Default servers are loaded first, then overlaid with parsed config files. Later files override earlier ones by name, allowing users to extend or customize the defaults.
  • Filesystem scoping: The default filesystem server is rooted at the working directory, limiting file access to one folder.
  • Async adapter: Uses langchain-mcp-adapters MultiServerMCPClient to fetch tools from each server, driven by asyncio.run().
  • Graceful degradation: Web search is optional (gated on FIRECRAWL_API_KEY); other tools load

https://claude.ai/code/session_01S2tt5oaMXD2RCVoAqGbqyR

claude added 2 commits June 18, 2026 17:26
Thread Model Context Protocol servers into the deepagents brain behind
`assembly live`, so a spoken conversation can reach real tools mid-turn —
bringing it toward Gemini-Live / ChatGPT-voice parity.

- `--mcp-config FILE` (repeatable) loads tools from standard `mcpServers`
  JSON, the same shape Claude Desktop / Claude Code use.
- `--demo-tools` loads a curated, no-auth set (time, fetch, memory,
  filesystem, weather) for a reliable on-stage demo.

Each server launches best-effort and independently, so one that won't start
(missing npx/uvx, offline host) drops only its own tools and never sinks the
session. The system prompt advertises MCP tools generically by name so the
agent reaches for them without promising capabilities it lacks.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01S2tt5oaMXD2RCVoAqGbqyR
Drop the --demo-tools opt-in: `assembly live` now loads the curated MCP
toolset (time, fetch, memory, filesystem, weather) by default, alongside its
built-in URL fetch and the AssemblyAI docs MCP. --mcp-config still layers your
own servers on top (and can override a default by name).

Switch the default web search from Tavily to Firecrawl, reusing Firecrawl's
official LangChain integration (langchain-firecrawl's FirecrawlSearch). It
loads when FIRECRAWL_API_KEY is set; when it isn't, the session prints a
one-line notice and runs without web search (every other default tool is
no-auth). `assembly code` keeps its Tavily search unchanged.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01S2tt5oaMXD2RCVoAqGbqyR
@alexkroman alexkroman enabled auto-merge June 18, 2026 17:54
answer. With no tools at all the model is told to answer from its own knowledge.
The guidance is tailored to the bound tools so the model is only told about
capabilities it actually has — advertising a missing tool (web search without a
``TAVILY_API_KEY``) made the agent announce an action it then couldn't take, leaving

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doc text still says web search depends on TAVILY_API_KEY, but this module now uses Firecrawl. This contradicts actual runtime gating and misstates when search is available.

Details

✨ AI Reasoning
​The surrounding implementation now uses Firecrawl for web search gating, yet the guidance text still says missing web search is tied to a different API key name. That mismatch makes the documented condition impossible to satisfy as written and can mislead future maintenance and debugging.

🔧 How do I fix it?
Trace execution paths carefully. Ensure precondition checks happen before using values, validate ranges before checking impossible conditions, and don't check for states that the code has already ruled out.

Reply @AikidoSec feedback: [FEEDBACK] to get better review comments in the future.
Reply @AikidoSec ignore: [REASON] to ignore this issue.
More info

# Extra streaming-TTS query params (the --tts-config escape hatch).
tts_extra: Mapping[str, str] = field(default_factory=dict[str, str])
# MCP servers (name -> launch spec) whose tools the deepagents brain can call. Empty
# by default; populated from --mcp-config files and/or the --demo-tools curated set.

@aikido-pr-checks aikido-pr-checks Bot Jun 18, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment says mcp_servers is populated via --demo-tools, but that flag is not part of the current live command flow. The documented population path is no longer true.

Suggested change
# by default; populated from --mcp-config files and/or the --demo-tools curated set.
# by default; populated from --mcp-config files.
Details

✨ AI Reasoning
​The configuration field description claims population via a flag that is no longer part of the command flow. This creates an impossible source path per the current code and can cause incorrect assumptions about how mcp_servers gets populated.

Reply @AikidoSec feedback: [FEEDBACK] to get better review comments in the future.
Reply @AikidoSec ignore: [REASON] to ignore this issue.
More info

@alexkroman alexkroman added this pull request to the merge queue Jun 18, 2026
@alexkroman alexkroman removed this pull request from the merge queue due to a manual request Jun 18, 2026
@alexkroman alexkroman closed this Jun 18, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants