Skip to content

External MCP Server issueΒ #859

@edshere001

Description

@edshere001

πŸ› Remote SSE MCP Servers Fail with "No active context found"

πŸ“‹ Summary

Agent Zero successfully connects to remote SSE-based MCP servers and loads their tools, but all tool execution attempts fail with "No active context found" error.

Root Cause: Agent Zero creates a new connection for each tool call instead of maintaining a persistent session, breaking SSE session continuity.

πŸ” Environment

  • Agent Zero Version: Latest (Docker deployment)
  • Deployment Method: Docker container
  • MCP Transport: SSE (Server-Sent Events)
  • MCP Servers Tested:
    • mcp-memory (9 tools loaded βœ…, execution fails ❌)
    • mcp-n8n (25 tools loaded βœ…, execution fails ❌)
    • mcp-midamserv (18 tools loaded βœ…, execution fails ❌)

πŸ”„ Steps to Reproduce

  1. Configure remote SSE MCP server in Agent Zero settings (tmp/settings.json):

    [
      {
        "name": "mcp-memory",
        "url": "http://your-server:3000/sse",
        "headers": {
          "Authorization": "Bearer your-token"
        }
      }
    ]
  2. Start Agent Zero and observe successful connection in logs:

    MCPClientBase (mcp_memory): Tools updated. Found 9 tools.
    
  3. Attempt to use any MCP tool:

    mcp_memory.memory_retrieve(key="test")
  4. Observe error:

    MCPTool::Failed to call mcp tool mcp_memory.memory_retrieve:
    No active context found.
    

βœ… Expected Behavior

The tool should execute successfully, maintaining the session context established during the initial connection (similar to how Cursor AI and Open WebUI handle the same MCP servers).

❌ Actual Behavior

All tool calls fail with "No active context found" despite:

  • βœ… Successful initial connection
  • βœ… Tools loaded correctly
  • βœ… MCP server responding (verified with curl)
  • βœ… Same servers work in Cursor AI and Open WebUI

πŸ”¬ Root Cause Analysis

Technical Details

Location: /a0/python/helpers/mcp_handler.py

Problem 1: New Connection Per Tool Call

Line 822 in _execute_with_session():

async def _execute_with_session(
    self,
    coro_func: Callable[[ClientSession], Awaitable[T]],
    read_timeout_seconds=60,
) -> T:
    """Manages the lifecycle of an MCP session for a single operation."""
    async with AsyncExitStack() as temp_stack:
        # ❌ Creates NEW connection for EVERY tool call
        stdio, write = await self._create_stdio_transport(temp_stack)
        
        # ❌ Creates NEW session for EVERY tool call
        session = await temp_stack.enter_async_context(
            ClientSession(stdio, write, read_timeout_seconds=...)
        )
        await session.initialize()
        
        result = await coro_func(session)
        return result

Problem 2: SSE Connection Not Reused

Lines 1046-1053 in MCPClientRemote._create_stdio_transport():

async def _create_stdio_transport(self, current_exit_stack: AsyncExitStack):
    # ❌ Creates NEW SSE connection every time this is called
    transport_result = await current_exit_stack.enter_async_context(
        streamablehttp_client(
            url=server.url,
            headers=server.headers,
            timeout=timedelta(seconds=init_timeout),
            sse_read_timeout=timedelta(seconds=tool_timeout),
        )
    )
    read_stream, write_stream, get_session_id_callback = transport_result
    self.session_id_callback = get_session_id_callback  # ❌ Overwritten each time
    return read_stream, write_stream

Why This Breaks SSE Servers

Initial Connection (works βœ…):

  1. Agent Zero connects to SSE server
  2. Server establishes session_id
  3. Tools are loaded successfully
  4. Connection is closed

Tool Execution (fails ❌):

  1. _execute_with_session() is called
  2. Creates NEW connection via _create_stdio_transport()
  3. Server sees this as a different session (no session_id)
  4. Original session context is lost
  5. Result: "No active context found"

Comparison with Working Implementations

Cursor AI and Open WebUI work correctly because they:

  • βœ… Establish connection once
  • βœ… Reuse the same session for all tool calls
  • βœ… Maintain persistent session_id throughout

βœ”οΈ Verification

Proof MCP Servers Work Correctly

  1. Direct curl test (14-second response time is normal):

    curl -N -H "Authorization: Bearer token" http://server:3000/sse
    # Returns SSE stream successfully
  2. Cursor AI - Works perfectly:

    • Retrieved 10 items from mcp-memory instantly
    • All tools execute successfully
    • Multiple tool calls work without issues
  3. Open WebUI - Works perfectly:

    • Lists memory items successfully
    • Maintains session across multiple calls

Proof Issue is Agent Zero Specific

  • βœ… Connection succeeds: MCPClientBase (mcp_memory): Tools updated. Found 9 tools.
  • ❌ Every tool call fails: No active context found
  • ❌ Full server reboot doesn't help (confirms code-level issue)
  • ❌ Affects all remote SSE MCP servers regardless of implementation

πŸ’‘ Suggested Fix

Option 1: Persistent Connection Pool (Recommended)

Maintain a persistent session per MCP server:

class MCPClientRemote(MCPClientBase):
    def __init__(self, server: MCPServerRemote):
        super().__init__(server)
        self._persistent_session: Optional[ClientSession] = None
        self._session_lock = asyncio.Lock()
        self._exit_stack: Optional[AsyncExitStack] = None
    
    async def _get_or_create_session(self) -> ClientSession:
        """Get existing session or create new one if needed."""
        async with self._session_lock:
            if self._persistent_session is None:
                self._exit_stack = AsyncExitStack()
                stdio, write = await self._create_stdio_transport(self._exit_stack)
                self._persistent_session = await self._exit_stack.enter_async_context(
                    ClientSession(stdio, write, read_timeout_seconds=...)
                )
                await self._persistent_session.initialize()
            return self._persistent_session
    
    async def _execute_with_session(self, coro_func, read_timeout_seconds=60):
        """Execute operation using persistent session."""
        session = await self._get_or_create_session()
        return await coro_func(session)

Option 2: Session Reuse Flag

Add a flag to control session lifecycle:

class MCPClientRemote(MCPClientBase):
    def __init__(self, server: MCPServerRemote):
        super().__init__(server)
        self.reuse_sessions = _is_streaming_http_type(server.type)  # True for SSE

πŸ“Š Impact

  • Severity: πŸ”΄ High - Completely blocks remote SSE MCP server usage
  • Affected Users: Anyone using remote MCP servers with SSE transport
  • Workaround: Use Cursor AI or Open WebUI for MCP access
  • Scope: Does not affect local MCP servers (stdio transport)

🏷️ Suggested Labels

  • bug
  • mcp
  • remote-servers
  • sse
  • high-priority

πŸ“Ž Additional Context

  • Timeout configuration was also an issue (hardcoded 10s minimum) but has been addressed separately
  • Issue reproducible across multiple MCP server implementations
  • Full investigation logs available if needed
  • Tested on 2025-12-28

Note: This issue prevents Agent Zero from working with the growing ecosystem of remote MCP servers. Fixing this would enable Agent Zero to leverage community-built MCP servers for enhanced capabilities.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions