Summary
Agent-to-agent calls via MCP chat_with_agent timeout after 60 seconds regardless of the timeout_seconds parameter. This is caused by Claude Code's hardcoded 60-second MCP HTTP transport timeout. While this is a Claude Code limitation, Trinity could provide better patterns to work around it.
Component
MCP Server / Task Execution Service / Agent Runtime
Priority
P1 - Major feature (agent collaboration) is broken for any task taking >60 seconds
Current Behavior
- Agent A calls
mcp__trinity__chat_with_agent(agent_name="B", message="...", parallel=true, timeout_seconds=900)
- Trinity backend correctly sets 900s timeout and acquires slot with TTL=1200s (timeout + 5min buffer)
- Agent B starts processing
- After 60 seconds, Claude Code's MCP HTTP client times out the connection
- Agent A receives no response (connection dropped)
- Agent B may continue executing, but result is lost
- Execution shows:
Task execution timed out after 60 seconds
Evidence
Slot acquisition logs show the backend received the correct timeout:
[Slots] Agent 'target-agent' acquired slot 1/3 for execution XXX (TTL=360s)
TTL=360s = 60s timeout + 300s buffer, confirming Claude Code passed 60s despite tool schema defaulting to 600s.
Root Cause
Claude Code has a hardcoded 60-second timeout for MCP HTTP tool calls. This is documented in multiple Claude Code GitHub issues:
The MCP tool's timeout_seconds parameter controls backend execution time, but Claude Code kills the HTTP connection after 60s regardless.
Impact
- Oracle agents cannot query Cornelius (knowledge graph) for complex lookups
- Any agent-to-agent collaboration requiring >60s reasoning fails
- Scheduled tasks that delegate to other agents fail silently
- Users see "timed out after 60 seconds" errors despite configuring longer timeouts
Proposed Solutions
Option 1: Streaming/Chunked Response (Recommended)
Implement streaming responses for the task endpoint that send periodic heartbeats:
# Instead of waiting for full completion, stream progress
async def execute_task_streaming(agent_name, message, timeout_seconds):
execution_id = start_execution(agent_name, message)
async def stream_progress():
while not is_complete(execution_id):
yield f"data: {json.dumps({'status': 'running', 'id': execution_id})}\n\n"
await asyncio.sleep(5)
yield f"data: {json.dumps({'status': 'complete', 'result': get_result(execution_id)})}\n\n"
return StreamingResponse(stream_progress(), media_type="text/event-stream")
This may reset Claude Code's timeout on each chunk (needs testing).
Option 2: Async + Polling MCP Tools
Add dedicated MCP tools for async workflow:
// Start execution, return immediately
start_agent_task(agent_name, message) -> { execution_id: string }
// Check status (fast, <1s)
get_execution_status(execution_id) -> { status: "running" | "complete" | "failed" }
// Get result when complete (fast, <1s)
get_execution_result(execution_id) -> { result: string }
Calling agents would be instructed to poll in their CLAUDE.md:
For long-running agent calls:
1. Call start_agent_task() to get execution_id
2. Loop: sleep 10s, call get_execution_status()
3. When complete, call get_execution_result()
Option 3: Callback Pattern
Allow target agent to call back to source agent with results:
chat_with_agent(
agent_name: "target",
message: "...",
callback_agent: "source", // NEW: Target calls this agent when done
callback_message_template: "Result for execution {id}: {result}"
)
Requires bidirectional permissions.
Option 4: Documentation + Guidance
At minimum, document the 60s limitation clearly:
- In MCP tool descriptions
- In agent CLAUDE.md templates
- Recommend
async: true + manual polling pattern
Workarounds (Current)
Users can partially work around this by:
- Using
async: true and manually polling execution status via API
- Keeping agent responses under 60 seconds
- Using shared files/database for results instead of synchronous calls
Environment
- Trinity version:
77c88b0 and later
- Claude Code: Latest (60s limit confirmed in docs)
- Affects: All agent-to-agent MCP calls via HTTP transport
Related
Summary
Agent-to-agent calls via MCP
chat_with_agenttimeout after 60 seconds regardless of thetimeout_secondsparameter. This is caused by Claude Code's hardcoded 60-second MCP HTTP transport timeout. While this is a Claude Code limitation, Trinity could provide better patterns to work around it.Component
MCP Server / Task Execution Service / Agent Runtime
Priority
P1 - Major feature (agent collaboration) is broken for any task taking >60 seconds
Current Behavior
mcp__trinity__chat_with_agent(agent_name="B", message="...", parallel=true, timeout_seconds=900)Task execution timed out after 60 secondsEvidence
Slot acquisition logs show the backend received the correct timeout:
TTL=360s = 60s timeout + 300s buffer, confirming Claude Code passed 60s despite tool schema defaulting to 600s.
Root Cause
Claude Code has a hardcoded 60-second timeout for MCP HTTP tool calls. This is documented in multiple Claude Code GitHub issues:
The MCP tool's
timeout_secondsparameter controls backend execution time, but Claude Code kills the HTTP connection after 60s regardless.Impact
Proposed Solutions
Option 1: Streaming/Chunked Response (Recommended)
Implement streaming responses for the task endpoint that send periodic heartbeats:
This may reset Claude Code's timeout on each chunk (needs testing).
Option 2: Async + Polling MCP Tools
Add dedicated MCP tools for async workflow:
Calling agents would be instructed to poll in their CLAUDE.md:
Option 3: Callback Pattern
Allow target agent to call back to source agent with results:
Requires bidirectional permissions.
Option 4: Documentation + Guidance
At minimum, document the 60s limitation clearly:
async: true+ manual polling patternWorkarounds (Current)
Users can partially work around this by:
async: trueand manually polling execution status via APIEnvironment
77c88b0and laterRelated
src/mcp-server/src/tools/chat.ts- MCP tool definitionssrc/backend/routers/chat.py- Task endpointsrc/backend/services/task_execution_service.py- Execution logic