bytedance/deer-flow · error · HTTPException

MCP server '{body.server_name}' not found

Error message

MCP server '{body.server_name}' not found

What it means

404 raised by _apply_mcp_server_state_update (PATCH /mcp/config) when the extensions configuration file cannot be resolved or does not exist on disk. The per-server enable/disable path operates directly on extensions_config.json; with no config file there are no servers to toggle, so even a valid server name is reported as not found.

Source

Thrown at backend/app/gateway/routers/mcp.py:838

        config_data["skills"] = {name: {"enabled": skill.enabled} for name, skill in current_config.skills.items()}

        atomic_write_extensions_config(config_path, config_data)

        logger.info(f"MCP configuration updated and saved to: {config_path}")

        # Reload the Gateway configuration and update the global cache. The
        # agent runtime lives in Gateway, so this keeps API reads and tool
        # execution aligned after extensions_config.json changes.
        reloaded_config = reload_extensions_config()
        return reloaded_config.mcp_servers


def _apply_mcp_server_state_update(body: McpServerStateUpdateRequest) -> dict:
    """Update one server state while preserving the raw extensions config."""
    with extensions_config_write_lock:
        config_path = ExtensionsConfig.resolve_config_path()
        if config_path is None or not config_path.exists():
            raise HTTPException(
                status_code=status.HTTP_404_NOT_FOUND,
                detail=f"MCP server '{body.server_name}' not found",
            )

        with open(config_path, encoding="utf-8") as f:
            raw_data = json.load(f)

        raw_servers = raw_data.get("mcpServers", {})
        raw_server = raw_servers.get(body.server_name) if isinstance(raw_servers, dict) else None
        if not isinstance(raw_server, dict):
            raise HTTPException(
                status_code=status.HTTP_404_NOT_FOUND,
                detail=f"MCP server '{body.server_name}' not found",
            )

        if body.enabled:
            target_server = McpServerConfigResponse(**raw_server)
            _validate_mcp_update_request(

View on GitHub (pinned to 1dd6ba1acb)

Solutions

  1. Run `make config` (or copy extensions_config.example.json to extensions_config.json at the repo root) and retry
  2. Verify the config path the Gateway resolves (ExtensionsConfig.resolve_config_path) matches where the file lives
  3. In Docker, check the extensions config volume is mounted read-write into the Gateway container

Example fix

# before: PATCH immediately after clone -> 404
# after
cp extensions_config.example.json extensions_config.json
# then restart Gateway and PATCH /api/mcp/config with {"server_name": "x", "enabled": true}
Defensive patterns

Strategy: validation

Validate before calling

const health = await fetch('/api/mcp/config').then(r => r.status); if (health === 404 || health === 500) { console.error('extensions_config.json missing/corrupt — run setup (make config) before PATCHing server state'); }

Type guard

null

Try / catch

try { await patchMcpState(name, enabled); } catch (e) { if (e.status === 404) { const list = await getMcpConfig(); if (!Object.keys(list.mcp_servers).length) throw new Error('config file missing — run make config and restart Gateway'); } throw e; }

Prevention

When it happens

Trigger: PATCH /api/mcp/config on a fresh deployment where `make config` was never run (extensions_config.json missing); a container where the config volume is not mounted; the config file path override (env/config) pointing to a nonexistent location.

Common situations: Skipping the documented setup step of copying extensions_config.example.json to extensions_config.json; volume mount mistakes in Docker deploys; CI environments testing the API without provisioning config files.

Related errors


AI-assisted analysis of bytedance/deer-flow@1dd6ba1acb (2026-08-14). Data as JSON: /api/errors/48dcf20db5258fca. Report an issue: GitHub.