Background Agent MCP Connections Destroyed After Text-Only Turn
- Ngôn ngữ chính
- Shell
- Star
- 11.2k
- Fork
- 1.9k
- Merge trung bình
- 14 giờ 16 phút
- Pull request đã merge (30 ngày)
- 6
Mô tả
### Describe the bug
MCP tools in background agents (launched via the `task` tool) are unreliable. The CLI framework destroys MCP transport connections after any turn where the LLM produces a text-only response (no tool calls). This means background agents that depend on MCP tools intermittently fail with `"Not connected"` or `"Connection closed"` errors - even when the MCP server is healthy and reachable.
This is a blocking issue for using custom agents with MCP servers in background mode. Any non-trivial agent workflow that involves MCP tools will eventually hit this bug because the LLM occasionally produces a text-only response before making a tool call (~10% of the time with default prompts, 100% when the system prompt encourages reasoning before acting).
The bug does not affect standalone agent invocations (`copilot --agent -p `) or the parent session's own MCP connections - only background agents.
### Affected version
GitHub Copilot CLI 1.0.35
### Steps to reproduce the behavior
### Prerequisites
- Python 3.10+ with `aiohttp` (`pip install aiohttp`)
### 1. Add the attached server
```py
from mcp.server.fastmcp import FastMCP
mcp = FastMCP("repro-mcp-server", port=8099)
@mcp.tool()
def fast_tool(query: str) -> str:
"""Returns immediately. Echoes the query back. For testing MCP transport reliability."""
return f'{{"status": "ok", "query": "{query}"}}'
if __name__ == "__main__":
mcp.run(transport="sse")
```
Save to `~/.copilot/repro_mcp_server.py`
This is a minimal MCP SSE server that exposes a single `fast_tool` which immediately echoes back its input.
### 2. Create the agent definition
Save as `~/.copilot/agents/repro-test-agent.agent.md`:
```markdown
---
name: repro-test-agent
description: "Minimal agent for reproducing background-agent MCP bug."
mcp-servers:
repro:
type: sse
url: "http://localhost:8099/sse"
tools: ["*"]
tools: ['repro/*']
---
You are a test agent with a STRICT protocol. You MUST follow this exact sequence
for EVERY request:
Turn 1: Reply with ONLY this exact text: "Processing request." — absolutely NO
tool calls on this turn.
Turn 2: Now call the requested tool.
CRITICAL RULE: You are FORBIDDEN from calling any tool on your first turn. Your
first message MUST be pure text with zero tool calls.
```
The system prompt forces a text-only first turn. This simulates the natural LLM behaviour of reasoning before acting, which triggers the bug deterministically.
When run, the background agent produces "Processing request." on turn 1, calls `repro-fast_tool` on turn 2, and returns `{"status": "ok", "query": "test-bug"}`.
### Expected behavior
I expect that MCP tool calling is reliable for any background agent session.
### What actually happens
The agent produces text on turn 1. The framework fires internal `response` and `messages_snapshot` events which tear down the MCP transport. The agent either never gets a turn 2, or turn 2's tool call fails on a dead connection.
Debug log signature (`~/.copilot/logs/process-*.log`):
```
[DEBUG] response (Request-ID null):
[DEBUG] Ignoring event of kind: response
[DEBUG] Ignoring event of kind: messages_snapshot
[ERROR] MCP transport for repro closed
[ERROR] MCP client for repro closed
```
**Repro rate: 3/3 (100%)** with the included agent definition.
### Intermittent variant without special system prompt
The "text first" system prompt makes the bug deterministic, but it also occurs naturally. With a neutral system prompt ("call the tool and report the result"), the LLM occasionally produces text before a tool call. In testing:
- 2 failures out of ~20 background agent invocations with neutral prompts (~10%)
### Non-background agents are not affected
- `copilot --agent -p ` (standalone mode): MCP survives across turns. 0/15 failures.
- Parent session MCP tools: text-only turns do not destroy connections.
- The bug is specific to background agents spawned via the `task` tool.
### Additional context
### CLI log: standalone agent (works — MCP survives)
```
copilot --agent repro-test-agent -p 'Call repro-fast_tool with query "standalone-test".' --allow-all-tools
```
```
09:24:25.374 [ERROR] Starting remote MCP client for repro with url: http://localhost:8099/sse
09:24:25.402 [ERROR] MCP client for repro connected, took 27ms
09:24:25.533 [DEBUG] Adding tool: repro-fast_tool
09:24:27.996 [DEBUG] Making Anthropic Messages streaming request with messages: [
09:24:32.836 [DEBUG] response (Request-ID null): ← LLM response arrives
09:24:40.914 [DEBUG] Tool calls count: 2 ← includes tool_use
09:24:40.915 [DEBUG] Permission request (kind=mcp) ← tool executes
09:24:40.971 [DEBUG] Tool invocation result: {"result":"{\"status\": \"ok\", \"query\": \"standalone-test\"}"}
09:24:40.997 [DEBUG] Making Anthropic Messages streaming request ← turn 2 (report result)
09:24:43.433 [DEBUG] response (Request-ID null):
09:24:43.434 [DEBUG] Ignoring event of kind: response ← event fires...
09:24:43.434 [DEBUG] Ignoring event of kind: messages_snapshot
← but NO MCP teardown
```
### CLI log: background agent (fails — MCP destroyed)
```
copilot -p '...launch background agent...' --allow-all-tools
```
```
09:19:17.426 [INFO] Started background agent with id: bug-repro
09:19:17.486 [INFO] Custom agent "repro-test-agent" invoked
09:19:17.545 [ERROR] Starting remote MCP client for repro with url: http://localhost:8099/sse
09:19:17.573 [ERROR] MCP client for repro connected, took 27ms
09:19:17.664 [DEBUG] Adding tool: repro-fast_tool
09:19:17.666 [INFO] Found 1 MCP tools from server 'repro'
09:19:17.671 [INFO] Custom agent "repro-test-agent" using tools: repro-fast_tool, view
09:19:18.074 [DEBUG] Making Anthropic Messages streaming request ← child agent turn 1
09:19:20.632 [DEBUG] response (Request-ID null): ← text-only "Processing request."
(no "Tool calls count" line)
09:19:20.715 [INFO] System notification: Agent "bug-repro" has finished processing
← agent treated as DONE after text-only turn
...
09:19:54.619 [DEBUG] response (Request-ID null):
09:19:54.621 [DEBUG] Ignoring event of kind: response ← same event as standalone...
09:19:54.623 [DEBUG] Ignoring event of kind: messages_snapshot
09:19:54.629 [ERROR] MCP transport for repro closed ← ...but HERE it kills MCP
09:19:54.629 [ERROR] MCP client for repro closed
```
Note: both modes fire `Ignoring event of kind: response`, but only the background agent path destroys the MCP transport afterward.
Hướng dẫn đóng góp
Hướng nghiên cứu
Bắt đầu bằng cách tái hiện vấn đề với máy chủ SSE Python được cung cấp và repro-test-agent.agent.md, được khởi chạy thông qua task tool. So sánh đường dẫn background-agent với chế độ standalone và kiểm tra ~/.copilot/logs/process-*.log xung quanh các sự kiện response và messages_snapshot. Được xem là hoàn tất khi một lượt text-only vẫn để kết nối MCP có thể sử dụng và lệnh gọi công cụ tiếp theo thành công.
Do mô hình lập chỉ mục viết ra từ nội dung của issue.
Đánh giá
- Công nghệ
- python
- Lĩnh vực
- cli, networking
- Loại issue
- Lỗi
- Độ khó
- 4/5
- Thời gian dự kiến
- 3-5 ngày
- Mức độ hoạt động
- Ít trao đổi
- Độ rõ ràng
- Khá rõ ràng
- Mức phù hợp với người mới
- 48/100