anthropics / anthropics/claude-agent-sdk-typescript
MCP server responses don't reset lastActivityTime, causing Stream closed errors or excessive query duration
- Langage dominant
- Shell
- Étoiles
- 1.8k
- Forks
- 226
- Métriques de merge des PR
- Aucune PR mergée en 30 j
Description
## Problem
When SDK MCP servers respond to tool calls, the response resolution doesn't reset `lastActivityTime`, causing the `waitForInactivity()` timeout to fire prematurely or requiring excessively long timeouts.
**Related:** #41 (concurrent tool call failures)
## The Bug
In `sdk.mjs` around line 8160, when an MCP server response arrives via `sendMcpServerMessageToCli()`:
```javascript
// sdk.mjs:8158-8162
const pending = this.pendingMcpResponses.get(key);
if (pending) {
pending.resolve(message); // <-- Resolves the promise
this.pendingMcpResponses.delete(key);
return;
// Missing: this.resetLastActivityTime();
}
```
The `pending.resolve(message)` correctly delivers the MCP response, but it **doesn't reset `lastActivityTime`**. This means while an MCP tool is executing, the SDK thinks there's "inactivity" even though work is actively happening.
## Expected Flow (what should happen)
```
Claude finishes turn → MCP tool executes (15s) → Response resets timer → 5s idle → Query ends
Total: ~20s
```
## Actual Flow (what happens now)
```
Claude finishes turn → MCP tool executes (15s) → No timer reset → TIMEOUT at 5s → Stream closed!
```
**OR with high timeout workaround:**
```
Claude finishes turn → MCP tool executes (15s) → No timer reset → Wait full 120s → Query ends
Total: 135s (unnecessarily long)
```
## Evidence
We traced this in production with varying `CLAUDE_CODE_STREAM_CLOSE_TIMEOUT` values:
| Timeout | Result |
|---------|--------|
| 15s | "Stream closed" errors on MCP calls >15s |
| 120s | 0 errors, but query duration = Claude time + 120s |
| 60s | 0 errors, but query duration = Claude time + 60s |
**Key finding:** `timeout += 30s` → `duration += 30s` (1:1 correlation)
This correlation proves the SDK always waits the full timeout because MCP responses never reset the activity timer.
## Proposed Fix
Add `resetLastActivityTime()` call when MCP response resolves:
```javascript
// sdk.mjs:8158-8163
const pending = this.pendingMcpResponses.get(key);
if (pending) {
pending.resolve(message);
this.pendingMcpResponses.delete(key);
this.resetLastActivityTime(); // <-- Add this line
return;
}
```
This would allow:
1. Short default timeout (5s) works correctly
2. MCP responses keep the connection alive as long as tools are active
3. Query ends promptly after final activity instead of waiting full timeout
## Environment
- `@anthropic-ai/claude-agent-sdk@0.1.70`
- Node.js 20.x
- SDK MCP servers via `createSdkMcpServer`
## Workaround
Set `CLAUDE_CODE_STREAM_CLOSE_TIMEOUT` to longer than your slowest MCP tool. This prevents "Stream closed" but adds unnecessary latency to every query.
Guide de contribution
Aucun guide de contribution indexé pour ce dépôt
Évaluation
Cette issue n'a pas encore été évaluée.