Files
EvoScientist-Multi/EvoScientist/mcp
Xi Zhang f41584e10b Refactor sub-agent architecture and introduce async support (#200)
* Refactor sub-agent architecture and introduce async support

- Removed the legacy subagent.yaml file and replaced it with individual YAML files for each sub-agent in the subagents directory.
- Updated the load_subagents function to support both directory and single file layouts for loading sub-agent configurations.
- Added new langgraph_dev module for managing async sub-agent lifecycle and deployment.
- Created graphs for async sub-agents (writing-agent, data-analysis-agent) and updated langgraph.json for deployment.
- Introduced new sub-agent definitions for planner, research, debug, code, and writing agents with appropriate system prompts and configurations.
- Enhanced package data inclusion in pyproject.toml to accommodate new sub-agent YAML files.

* Refactor code for improved readability by consolidating conditional statements and formatting

* feat: enhance async sub-agent support with workspace synchronization and user feedback

- Added console status messages during async sub-agent server startup and workspace synchronization to improve user experience.
- Implemented a new WorkspaceSyncWidget for live feedback during workspace sync operations.
- Updated onboarding to reject occupied ports and ensure proper workspace handling for async sub-agents.
- Introduced locking mechanisms to manage concurrent access to langgraph dev processes and workspace states.

* feat: add async sub-agent configuration and server management functions

* feat: improve port occupation handling and log file management in start_langgraph_dev

* feat: enhance async sub-agent handling and introduce comprehensive tests

- Updated `_maybe_swap_async_subagents` to improve async sub-agent management, ensuring internal flags are stripped before handoff.
- Enhanced port management in `onboard.py` to allow reuse of occupied ports if already running by the same service.
- Introduced file locking in `manager.py` to prevent race conditions during concurrent CLI invocations.
- Added new tests for async sub-agent swapping and langgraph manager functionalities to ensure reliability and correctness.
- Updated dependencies in `pyproject.toml` to include `psutil` and `filelock`.

* fix(docs): clarify sub-agent configuration in README

* test(manager): isolate _PID_DIR + tighten reuse-path assertion

Addresses CodeRabbit review on tests/test_langgraph_manager.py:

- Patch _PID_DIR to tmp_path so the FileLock setup in
  ensure_langgraph_dev doesn't mkdir the user's real
  ~/.config/evoscientist/ dir as a test side-effect.
- Tighten "result is None or hasattr(result, 'poll')" to a strict
  "result is None" — the reuse path returns None unconditionally,
  so the OR clause was hiding potential regressions.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* fix(manager): clean up stale PID file when unrelated process reuses PID

* feat(tests): add validation tests for async flag in load_subagents

* fix(load_subagents): restrict to .yaml files and clarify configuration handling

* fix(load_subagents): improve error handling for non-dict specifications in YAML

* feat(onboard): add "LangGraph Port" step to onboarding process

* feat(langgraph): add concurrency configuration for langgraph dev workers

* feat(async-subagents): enhance MCP tool routing for async sub-agents

* fix(manager): update exception handling for connection errors and prevent zombie processes

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-05 12:45:50 +01:00
..

Model Context Protocol Integration

Connects external systems to EvoScientist via Model Context Protocol (MCP).

Tip

Explore more servers: MCP Server Directory

📖 Contents

🔌 Quick Start

Option A: Terminal — before or outside an agent session

EvoSci mcp add sequential-thinking npx -- -y @modelcontextprotocol/server-sequential-thinking

Option B: In-session — inside a running agent session

/mcp add sequential-thinking npx -- -y @modelcontextprotocol/server-sequential-thinking

Note

After adding a new server in-session, reload the agent session (/new in interactive mode) or restart the CLI agent to load the new config.

Option C: Edit YAML directly - advanced customization

# ~/.config/evoscientist/mcp.yaml
sequential-thinking:
  transport: stdio
  command: npx
  args: ["-y", "@modelcontextprotocol/server-sequential-thinking"]

🛠️ Command Reference

Syntax

EvoSci mcp add <name> <command-or-url> [args...] \
  [--transport <transport>] \
  [--tools <tool1,tool2,...>] \
  [--expose-to <agent1,agent2,...>] \
  [--header <Key:Value>]... \
  [--env <KEY=VALUE>]... \
  [--env-ref <KEY>]...

Options:

Flag Short Description
--transport Transport type (auto-inferred if omitted)
--tools -t Comma-separated tool allowlist, supports glob wildcards (omit = all tools)
--expose-to -e Comma-separated target agents (default: main)
--header -H HTTP header as Key:Value (repeatable)
--env Env var as KEY=VALUE for stdio subprocess (repeatable)
--env-ref Reference an existing env var by name (repeatable)

Note

  • --transport is auto-inferred from target: http(s) URL → http, otherwise stdio.
  • -- is recommended before server args that start with -, so they are passed to the MCP server command.

Management

Command Description
EvoSci mcp List configured servers
EvoSci mcp list List configured servers
EvoSci mcp config Show detailed config for all servers
EvoSci mcp config <name> Show detailed config for one server
EvoSci mcp add ... Add a server
EvoSci mcp edit ... Edit an existing server
EvoSci mcp remove <name> Remove a server

Tip

All commands also work as interactive slash commands: /mcp, /mcp list, /mcp config, /mcp add ..., /mcp edit ..., /mcp remove <name>.

Examples

# Local stdio server
EvoSci mcp add sequential-thinking npx -- -y @modelcontextprotocol/server-sequential-thinking

# Remote HTTP server (transport auto-detected)
EvoSci mcp add docs-langchain https://docs.langchain.com/mcp

# SSE endpoint (explicit transport override)
EvoSci mcp add research-sse https://example.com/sse --transport sse

# With tool routing to sub-agent + env var reference
EvoSci mcp add brave-search npx --env-ref BRAVE_API_KEY -e research-agent -- -y @modelcontextprotocol/server-brave-search

# With tool allowlist (glob wildcards)
EvoSci mcp add fs npx -t "read_*,write_*" -- -y @modelcontextprotocol/server-filesystem /workspace

# Context7 routed to multiple agents
EvoSci mcp add context7 npx -e main,research-agent,code-agent -- -y @upstash/context7-mcp@latest
More examples
# stdio transport (auto-detected from command)
EvoSci mcp add filesystem npx -- -y @modelcontextprotocol/server-filesystem /tmp

# http transport (auto-detected from URL)
EvoSci mcp add brave-search http://localhost:8080/mcp -H "Authorization:Bearer ${BRAVE_API_KEY}"

# sse transport, routed to a specific agent
EvoSci mcp add my-sse http://localhost:9090/sse --transport sse -e research-agent

# With tool allowlist (supports glob wildcards)
EvoSci mcp add fs npx -- -y @modelcontextprotocol/server-filesystem /tmp -t "read_*,write_*"

Editing Servers

Update individual fields without re-adding:

# Change routing
EvoSci mcp edit filesystem --expose-to main,code-agent

# Set a tool allowlist (supports glob wildcards)
EvoSci mcp edit filesystem --tools "read_*,write_*"

# Clear a tool allowlist (pass all tools)
EvoSci mcp edit filesystem --tools none

# Change URL
EvoSci mcp edit my-api --url http://new-host:9090/mcp

🔀 Tool Routing

Use expose_to to control which agents receive each server's tools:

postgres:
  transport: stdio
  command: npx
  args: ["-y", "@modelcontextprotocol/server-postgres", "postgresql://localhost/mydb"]
  expose_to: [data-analysis-agent]

github:
  transport: stdio
  command: npx
  args: ["-y", "@modelcontextprotocol/server-github"]
  expose_to: [main, research-agent]

Available agents:

Agent Role
main Main orchestrator (default target)
planner-agent Experiment planning
research-agent Literature search
code-agent Code writing
debug-agent Debugging
data-analysis-agent Data analysis
writing-agent Report writing

Note

Tools routed to sub-agents are injected automatically — no need to edit any EvoScientist/subagents/*.yaml file.

🔍 Tool Filtering with Wildcards

Use the tools field to filter which tools from a server are exposed. Supports glob-style wildcards:

# Exact matching (original behavior)
exa:
  transport: http
  url: https://mcp.exa.ai/mcp
  tools:
    - web_search_exa
    - get_code_context_exa
    - company_research_exa

# Wildcard: all tools ending with _exa
exa:
  transport: http
  url: https://mcp.exa.ai/mcp
  tools:
    - "*_exa"

# Multiple patterns
filesystem:
  transport: stdio
  command: npx
  args: ["-y", "@modelcontextprotocol/server-filesystem", "/workspace"]
  tools:
    - "read_*"
    - "write_*"
    - "list_*"

# Mix wildcards and exact matches
mixed:
  transport: http
  url: https://example.com/mcp
  tools:
    - "search_*"
    - "get_metadata"

Wildcard Patterns

Pattern Matches Example
* Any sequence of characters *_exa matches web_search_exa, get_code_context_exa
? Any single character tool_? matches tool_1, tool_2 but not tool_10
[seq] Any character in sequence tool_[abc] matches tool_a, tool_b, tool_c
[0-9] Any character in range version_[0-9] matches version_0 through version_9
[!seq] Any character NOT in sequence tool_[!0-9] matches tool_a but not tool_1

📄 Config File

Path: ~/.config/evoscientist/mcp.yaml (or $XDG_CONFIG_HOME/evoscientist/mcp.yaml)

Config Fields

Field Required Description
transport Yes stdio, http, streamable_http, sse, websocket
command stdio only Command to run (e.g. npx)
args stdio only Arguments list
env No Environment variables for subprocess
url http/sse/ws Server URL
headers No HTTP headers (e.g. auth tokens)
tools No Tool allowlist with glob wildcards (omit = all tools)
expose_to No Target agents (default: ["main"])

Tip

Use ${VAR} in YAML values to reference environment variables. Missing variables are replaced with empty string and logged as a warning.

Supported Transports

Transport Config Fields
stdio command, args, env (optional)
http url, headers (optional)
streamable_http url, headers (optional)
sse url, headers (optional)
websocket url
Full YAML example with inline annotations
filesystem:
  transport: stdio
  command: npx
  args: ["-y", "@modelcontextprotocol/server-filesystem", "/path/to/dir"]
  tools: ["read_*", "write_*"]       # optional allowlist with wildcards (omit = all tools)
  expose_to: [main, code-agent]      # optional routing (omit = ["main"])

brave-search:
  transport: http
  url: "http://localhost:8080/mcp"
  headers:
    Authorization: "Bearer ${BRAVE_API_KEY}"
  expose_to: [research-agent]

⚙️ How It Works

  1. On agent startup (/new or create_cli_agent()), reads ~/.config/evoscientist/mcp.yaml
  2. Connects to each server via the configured transport
  3. Retrieves available tools from each server
  4. Filters tools by tools allowlist (if set)
  5. Routes tools to target agents by expose_to
  6. Tools are injected into the agent's tool list automatically

Note

MCP servers that fail to connect are skipped with a warning — they don't block startup. Tools are cached by config signature to avoid redundant loading.

🔧 Troubleshooting

Dependency missing (langchain-mcp-adapters)

Startup warning about MCP adapter missing:

pip install langchain-mcp-adapters
npx not available

stdio server fails to start — install Node.js and npx, or replace npx with a command available in your environment.

--env-ref or ${VAR} not resolving

Auth header/env becomes empty — ensure the variable exists in your environment before launching EvoScientist. ${VAR} interpolation happens at runtime; missing vars are replaced with empty strings and logged as warnings.

Server connects but no tools appear

Server exists in config but agent doesn't use MCP tools:

  • Confirm endpoint/command is healthy outside EvoScientist
  • Check auth headers/env
  • Check whether tools filter is too strict
Tool routing not taking effect

Tool is loaded but not available where expected:

  • Verify expose_to target names are correct (see Available agents above)
  • Reload the session with /new after config changes
  • Include main in expose_to if you need tools in the main agent

🔒 Security

Warning

Do not hardcode secrets in mcp.yaml. Use ${VAR} in YAML or --env-ref KEY in CLI to reference environment variables.

  • For filesystem-style servers, expose only minimum required paths
  • Use tools allowlists to limit which tools are loaded
  • Use expose_to to restrict which agents can access each server
  • Prefer least privilege for both tool scope and agent access