@leo000001/claude-code-mcp 2.4.3 → 2.4.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +6 -0
- package/README.md +5 -2
- package/dist/index.js +72 -19
- package/dist/index.js.map +1 -1
- package/package.json +5 -2
package/CHANGELOG.md
CHANGED
|
@@ -8,6 +8,8 @@
|
|
|
8
8
|
|
|
9
9
|
### Improvements
|
|
10
10
|
|
|
11
|
+
- Upgrade `@anthropic-ai/claude-agent-sdk` to `^0.2.49` and align MCP-facing schemas with the current SDK surface.
|
|
12
|
+
- Permission mode enum now follows SDK 0.2.49 (`default`, `acceptEdits`, `bypassPermissions`, `plan`, `dontAsk`; `delegate` removed).
|
|
11
13
|
- Session cleanup now marks timed-out running/waiting sessions as `cancelled` for consistent status semantics.
|
|
12
14
|
- `SessionManager.destroy()` now clears in-memory session/runtime maps after aborting active runs, so post-destroy reads are no longer stale.
|
|
13
15
|
- Event buffer eviction now uses batch compaction (instead of repeated `findIndex` + `splice`) and `readEvents` now uses binary search for cursor start.
|
|
@@ -15,9 +17,13 @@
|
|
|
15
17
|
- Runtime tool-discovery updates now notify both tools and resources (internal-tools resource change notification).
|
|
16
18
|
- Enrich compatibility resources with package version, disk-resume diagnostics, and runtime limits.
|
|
17
19
|
- Remove deprecated `claude_code` parameter aliases: top-level `sessionInitTimeoutMs` and `advanced.effort` / `advanced.thinking`.
|
|
20
|
+
- Add support for SDK `promptSuggestions` option passthrough and expose `promptSuggestions` in `advanced`/`diskResumeConfig`.
|
|
21
|
+
- Query consumer now maps additional SDK stream messages (`system/task_started`, `rate_limit`, `prompt_suggestion`) to progress events.
|
|
18
22
|
|
|
19
23
|
### Documentation
|
|
20
24
|
|
|
25
|
+
- Restructure documentation architecture: `AGENTS.md` is now execution-first, while `docs/DESIGN.md` is the single detailed source for interface/mapping semantics.
|
|
26
|
+
- Add explicit doc-governance rules, upgrade submission template, and document DoD to reduce AGENTS/DESIGN duplication regression.
|
|
21
27
|
- Align README/DESIGN/AGENTS with current defaults and behavior (timeout clamp, advanced parameter count, lifecycle semantics).
|
|
22
28
|
- Clarify package positioning as CLI-first and remove stale guidance that implied a public programmatic API surface.
|
|
23
29
|
- Update CONTRIBUTING with local environment requirements (Node/npm and Windows Git Bash notes).
|
package/README.md
CHANGED
|
@@ -117,7 +117,7 @@ Start a new Claude Code session. The agent autonomously performs coding tasks: r
|
|
|
117
117
|
| `advanced` | object | No | Advanced/low-frequency parameters (see below) |
|
|
118
118
|
|
|
119
119
|
<details>
|
|
120
|
-
<summary><code>advanced</code> object parameters (
|
|
120
|
+
<summary><code>advanced</code> object parameters (21 low-frequency parameters)</summary>
|
|
121
121
|
|
|
122
122
|
| Parameter | Type | Description |
|
|
123
123
|
| ------------------------------------- | ------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
@@ -136,6 +136,7 @@ Start a new Claude Code session. The agent autonomously performs coding tasks: r
|
|
|
136
136
|
| `advanced.fallbackModel` | string | Fallback model if the primary model fails or is unavailable. Default: none |
|
|
137
137
|
| `advanced.enableFileCheckpointing` | boolean | Enable file checkpointing to track file changes during the session. Default: `false` |
|
|
138
138
|
| `advanced.includePartialMessages` | boolean | When true, includes intermediate streaming messages in the response. Useful for real-time progress monitoring. Default: false |
|
|
139
|
+
| `advanced.promptSuggestions` | boolean | When true, emits post-turn prompt suggestion events (`prompt_suggestion`). Default: `false` |
|
|
139
140
|
| `advanced.strictMcpConfig` | boolean | Enforce strict validation of MCP server configurations. Default: `false` |
|
|
140
141
|
| `advanced.settingSources` | string[] | Which filesystem settings to load. Defaults to `["user", "project", "local"]` (loads all settings and CLAUDE.md). Pass `[]` for SDK isolation mode |
|
|
141
142
|
| `advanced.debug` | boolean | Enable debug mode for verbose logging. Default: `false` |
|
|
@@ -177,7 +178,7 @@ Continue an existing session by sending a follow-up message. The agent retains f
|
|
|
177
178
|
| `diskResumeConfig` | object | No | Disk resume parameters (see below). Used when `CLAUDE_CODE_MCP_ALLOW_DISK_RESUME=1` and in-memory session is missing |
|
|
178
179
|
|
|
179
180
|
<details>
|
|
180
|
-
<summary><code>diskResumeConfig</code> object parameters (
|
|
181
|
+
<summary><code>diskResumeConfig</code> object parameters (31 disk-resume-only parameters)</summary>
|
|
181
182
|
|
|
182
183
|
| Parameter | Type | Description |
|
|
183
184
|
| --------------------------------------------- | ------------------ | ----------------------------------------------------------------------------------------------- |
|
|
@@ -185,6 +186,7 @@ Continue an existing session by sending a follow-up message. The agent retains f
|
|
|
185
186
|
| `diskResumeConfig.cwd` | string | Working directory. Required for disk resume. |
|
|
186
187
|
| `diskResumeConfig.allowedTools` | string[] | Auto-approved tool names (see `claude_code`). Default: `[]` |
|
|
187
188
|
| `diskResumeConfig.disallowedTools` | string[] | Forbidden tool names (see `claude_code`). Default: `[]` |
|
|
189
|
+
| `diskResumeConfig.strictAllowedTools` | boolean | Enforce strict allow-list behavior for `allowedTools`. Default: `false` |
|
|
188
190
|
| `diskResumeConfig.tools` | string[] \| object | Base tool set (see `claude_code`). Default: SDK/Claude Code default |
|
|
189
191
|
| `diskResumeConfig.persistSession` | boolean | Persist session history to disk. Default: `true` |
|
|
190
192
|
| `diskResumeConfig.maxTurns` | number | Maximum number of agent reasoning steps. Default: SDK/Claude Code default |
|
|
@@ -205,6 +207,7 @@ Continue an existing session by sending a follow-up message. The agent retains f
|
|
|
205
207
|
| `diskResumeConfig.fallbackModel` | string | Fallback model. Default: none |
|
|
206
208
|
| `diskResumeConfig.enableFileCheckpointing` | boolean | Enable file checkpointing. Default: `false` |
|
|
207
209
|
| `diskResumeConfig.includePartialMessages` | boolean | Include intermediate streaming messages. Default: `false` |
|
|
210
|
+
| `diskResumeConfig.promptSuggestions` | boolean | Emit post-turn prompt suggestion events (`prompt_suggestion`). Default: `false` |
|
|
208
211
|
| `diskResumeConfig.strictMcpConfig` | boolean | Strict MCP config validation. Default: `false` |
|
|
209
212
|
| `diskResumeConfig.settingSources` | string[] | Which filesystem settings to load. Default: `["user", "project", "local"]` |
|
|
210
213
|
| `diskResumeConfig.debug` | boolean | Debug mode. Default: `false` |
|
package/dist/index.js
CHANGED
|
@@ -232,6 +232,7 @@ var SessionManager = class _SessionManager {
|
|
|
232
232
|
fallbackModel: params.fallbackModel,
|
|
233
233
|
enableFileCheckpointing: params.enableFileCheckpointing,
|
|
234
234
|
includePartialMessages: params.includePartialMessages,
|
|
235
|
+
promptSuggestions: params.promptSuggestions,
|
|
235
236
|
strictMcpConfig: params.strictMcpConfig,
|
|
236
237
|
settingSources: params.settingSources,
|
|
237
238
|
debug: params.debug,
|
|
@@ -328,7 +329,9 @@ var SessionManager = class _SessionManager {
|
|
|
328
329
|
if (info.status === "waiting_permission") {
|
|
329
330
|
this.finishAllPending(
|
|
330
331
|
sessionId,
|
|
331
|
-
|
|
332
|
+
// Similar to cancel(), avoid emitting interrupt=true while the query stream is
|
|
333
|
+
// being torn down to reduce SDK-level write/teardown races on stdio clients.
|
|
334
|
+
{ behavior: "deny", message: opts?.reason ?? "Session interrupted", interrupt: false },
|
|
332
335
|
"interrupt"
|
|
333
336
|
);
|
|
334
337
|
}
|
|
@@ -1236,6 +1239,26 @@ function messageToEvent(msg) {
|
|
|
1236
1239
|
}
|
|
1237
1240
|
};
|
|
1238
1241
|
}
|
|
1242
|
+
if (msg.type === "system" && msg.subtype === "task_started") {
|
|
1243
|
+
return {
|
|
1244
|
+
type: "progress",
|
|
1245
|
+
data: {
|
|
1246
|
+
type: "task_started",
|
|
1247
|
+
task_id: msg.task_id,
|
|
1248
|
+
tool_use_id: msg.tool_use_id,
|
|
1249
|
+
description: msg.description,
|
|
1250
|
+
task_type: msg.task_type
|
|
1251
|
+
}
|
|
1252
|
+
};
|
|
1253
|
+
}
|
|
1254
|
+
if (msg.type === "rate_limit" || msg.type === "prompt_suggestion") {
|
|
1255
|
+
const rest = { ...msg };
|
|
1256
|
+
delete rest.type;
|
|
1257
|
+
return {
|
|
1258
|
+
type: "progress",
|
|
1259
|
+
data: { type: msg.type, ...rest }
|
|
1260
|
+
};
|
|
1261
|
+
}
|
|
1239
1262
|
return null;
|
|
1240
1263
|
}
|
|
1241
1264
|
function consumeQuery(params) {
|
|
@@ -1401,6 +1424,7 @@ function consumeQuery(params) {
|
|
|
1401
1424
|
let retryCount = 0;
|
|
1402
1425
|
let currentStream = activeQuery;
|
|
1403
1426
|
while (true) {
|
|
1427
|
+
let streamReceivedResult = false;
|
|
1404
1428
|
try {
|
|
1405
1429
|
for await (const message of currentStream) {
|
|
1406
1430
|
if (isSystemInitMessage(message)) {
|
|
@@ -1441,6 +1465,7 @@ function consumeQuery(params) {
|
|
|
1441
1465
|
continue;
|
|
1442
1466
|
}
|
|
1443
1467
|
if (message.type === "result") {
|
|
1468
|
+
streamReceivedResult = true;
|
|
1444
1469
|
const sessionId2 = message.session_id ?? await getSessionId();
|
|
1445
1470
|
const agentResult = sdkResultToAgentResult(message);
|
|
1446
1471
|
const current = params.sessionManager.get(sessionId2);
|
|
@@ -1483,7 +1508,7 @@ function consumeQuery(params) {
|
|
|
1483
1508
|
queryInterrupt: void 0
|
|
1484
1509
|
});
|
|
1485
1510
|
}
|
|
1486
|
-
|
|
1511
|
+
continue;
|
|
1487
1512
|
}
|
|
1488
1513
|
const sessionId = message.session_id ?? await getSessionId();
|
|
1489
1514
|
const event = messageToEvent(message);
|
|
@@ -1501,7 +1526,7 @@ function consumeQuery(params) {
|
|
|
1501
1526
|
`Error [${"INTERNAL" /* INTERNAL */}]: query stream ended before receiving session init.`
|
|
1502
1527
|
)
|
|
1503
1528
|
);
|
|
1504
|
-
} else if (activeSessionId) {
|
|
1529
|
+
} else if (activeSessionId && !streamReceivedResult) {
|
|
1505
1530
|
const sessionId = activeSessionId;
|
|
1506
1531
|
const current = params.sessionManager.get(sessionId);
|
|
1507
1532
|
if (current && current.status !== "cancelled") {
|
|
@@ -1548,6 +1573,9 @@ function consumeQuery(params) {
|
|
|
1548
1573
|
);
|
|
1549
1574
|
return;
|
|
1550
1575
|
}
|
|
1576
|
+
if (streamReceivedResult) {
|
|
1577
|
+
return;
|
|
1578
|
+
}
|
|
1551
1579
|
if (!activeSessionId) return;
|
|
1552
1580
|
const sessionId = activeSessionId;
|
|
1553
1581
|
if (errClass === "transient" && retryCount < MAX_TRANSIENT_RETRIES) {
|
|
@@ -1712,6 +1740,7 @@ function buildOptions(src) {
|
|
|
1712
1740
|
opts.enableFileCheckpointing = src.enableFileCheckpointing;
|
|
1713
1741
|
if (src.includePartialMessages !== void 0)
|
|
1714
1742
|
opts.includePartialMessages = src.includePartialMessages;
|
|
1743
|
+
if (src.promptSuggestions !== void 0) opts.promptSuggestions = src.promptSuggestions;
|
|
1715
1744
|
if (src.strictMcpConfig !== void 0) opts.strictMcpConfig = src.strictMcpConfig;
|
|
1716
1745
|
if (src.settingSources !== void 0) opts.settingSources = src.settingSources;
|
|
1717
1746
|
else opts.settingSources = DEFAULT_SETTING_SOURCES;
|
|
@@ -1750,6 +1779,7 @@ function toSessionCreateParams(input) {
|
|
|
1750
1779
|
fallbackModel: src.fallbackModel,
|
|
1751
1780
|
enableFileCheckpointing: src.enableFileCheckpointing,
|
|
1752
1781
|
includePartialMessages: src.includePartialMessages,
|
|
1782
|
+
promptSuggestions: src.promptSuggestions,
|
|
1753
1783
|
strictMcpConfig: src.strictMcpConfig,
|
|
1754
1784
|
settingSources: src.settingSources ?? DEFAULT_SETTING_SOURCES,
|
|
1755
1785
|
debug: src.debug,
|
|
@@ -2466,11 +2496,14 @@ function detectPathCompatibilityWarnings(session) {
|
|
|
2466
2496
|
}
|
|
2467
2497
|
return warnings;
|
|
2468
2498
|
}
|
|
2469
|
-
function
|
|
2470
|
-
|
|
2499
|
+
function isSuspiciousPosixAbsolutePathOnWindows(value) {
|
|
2500
|
+
if (!value.startsWith("/") || value.startsWith("//")) return false;
|
|
2501
|
+
return /^\/home\/[^/\s]+(?:\/|$)/.test(value) || /^\/(?:mnt\/)?[a-zA-Z](?:\/|$)/.test(value) || /^\/(tmp|var|etc|opt|usr|bin|sbin)(?:\/|$)/.test(value);
|
|
2471
2502
|
}
|
|
2472
|
-
function
|
|
2473
|
-
const match = value.match(
|
|
2503
|
+
function extractSuspiciousPosixAbsolutePath(value) {
|
|
2504
|
+
const match = value.match(
|
|
2505
|
+
/\/(?:home\/[^/\s"'`]+(?:\/[^\s"'`]*)?|(?:mnt\/)?[a-zA-Z](?:\/[^\s"'`]*)?|(?:tmp|var|etc|opt|usr|bin|sbin)(?:\/[^\s"'`]*)?)/
|
|
2506
|
+
);
|
|
2474
2507
|
return match?.[0];
|
|
2475
2508
|
}
|
|
2476
2509
|
function detectPendingPermissionPathWarnings(pending, session) {
|
|
@@ -2499,13 +2532,13 @@ function detectPendingPermissionPathWarnings(pending, session) {
|
|
|
2499
2532
|
}
|
|
2500
2533
|
const command = req.input.command;
|
|
2501
2534
|
if (typeof command === "string") {
|
|
2502
|
-
const embeddedPath =
|
|
2535
|
+
const embeddedPath = extractSuspiciousPosixAbsolutePath(command);
|
|
2503
2536
|
if (embeddedPath) candidates.push(embeddedPath);
|
|
2504
2537
|
}
|
|
2505
|
-
const badPath = candidates.find((p) =>
|
|
2538
|
+
const badPath = candidates.find((p) => isSuspiciousPosixAbsolutePathOnWindows(p));
|
|
2506
2539
|
if (!badPath) continue;
|
|
2507
2540
|
warnings.push(
|
|
2508
|
-
`Permission request '${req.requestId}' uses POSIX
|
|
2541
|
+
`Permission request '${req.requestId}' uses POSIX absolute path '${badPath}' on Windows. Prefer an absolute Windows path${cwdHint} to avoid out-of-bounds permission prompts.`
|
|
2509
2542
|
);
|
|
2510
2543
|
}
|
|
2511
2544
|
return warnings;
|
|
@@ -3562,7 +3595,7 @@ function registerResources(server, deps) {
|
|
|
3562
3595
|
}
|
|
3563
3596
|
|
|
3564
3597
|
// src/server.ts
|
|
3565
|
-
var SERVER_VERSION = true ? "2.4.
|
|
3598
|
+
var SERVER_VERSION = true ? "2.4.8" : "0.0.0-dev";
|
|
3566
3599
|
function createServerContext(serverCwd) {
|
|
3567
3600
|
const sessionManager = new SessionManager();
|
|
3568
3601
|
const server = new McpServer(
|
|
@@ -3652,6 +3685,7 @@ function createServerContext(serverCwd) {
|
|
|
3652
3685
|
fallbackModel: z.string().optional().describe("Default: none"),
|
|
3653
3686
|
enableFileCheckpointing: z.boolean().optional().describe("Default: false"),
|
|
3654
3687
|
includePartialMessages: z.boolean().optional().describe("Default: false"),
|
|
3688
|
+
promptSuggestions: z.boolean().optional().describe("Default: false"),
|
|
3655
3689
|
strictMcpConfig: z.boolean().optional().describe("Default: false"),
|
|
3656
3690
|
settingSources: z.array(z.enum(["user", "project", "local"])).optional().describe("Default: ['user','project','local']. []=isolation"),
|
|
3657
3691
|
debug: z.boolean().optional().describe("Default: false"),
|
|
@@ -4000,7 +4034,8 @@ var BENIGN_MESSAGE_PATTERNS = [
|
|
|
4000
4034
|
"write after end",
|
|
4001
4035
|
"stream was destroyed",
|
|
4002
4036
|
"cannot call write after a stream was destroyed",
|
|
4003
|
-
"the pipe is being closed"
|
|
4037
|
+
"the pipe is being closed",
|
|
4038
|
+
"query closed before response received"
|
|
4004
4039
|
];
|
|
4005
4040
|
function isBenignRuntimeError(error) {
|
|
4006
4041
|
if (!(error instanceof Error)) return false;
|
|
@@ -4012,6 +4047,15 @@ function isBenignRuntimeError(error) {
|
|
|
4012
4047
|
return BENIGN_MESSAGE_PATTERNS.some((pattern) => message.includes(pattern));
|
|
4013
4048
|
}
|
|
4014
4049
|
|
|
4050
|
+
// src/utils/stdin-shutdown.ts
|
|
4051
|
+
function decideStdinShutdown(params) {
|
|
4052
|
+
if (!params.stdinUnavailable) return "clear";
|
|
4053
|
+
if (params.isConnected) return "reschedule";
|
|
4054
|
+
if (!params.hasActiveSessions) return "shutdown_now";
|
|
4055
|
+
if (params.elapsedMs >= params.maxWaitMs) return "shutdown_timeout";
|
|
4056
|
+
return "reschedule";
|
|
4057
|
+
}
|
|
4058
|
+
|
|
4015
4059
|
// src/index.ts
|
|
4016
4060
|
var STDIN_SHUTDOWN_CHECK_MS = 750;
|
|
4017
4061
|
var STDIN_SHUTDOWN_MAX_WAIT_MS = process.platform === "win32" ? 15e3 : 1e4;
|
|
@@ -4088,19 +4132,26 @@ async function main() {
|
|
|
4088
4132
|
const evaluateStdinTermination = () => {
|
|
4089
4133
|
if (closing || stdinClosedAt === void 0) return;
|
|
4090
4134
|
const stdinUnavailable = process.stdin.destroyed || process.stdin.readableEnded || !process.stdin.readable;
|
|
4091
|
-
|
|
4135
|
+
const elapsedMs = Date.now() - stdinClosedAt;
|
|
4136
|
+
const active = hasActiveSessions();
|
|
4137
|
+
const connected = server.isConnected();
|
|
4138
|
+
const decision = decideStdinShutdown({
|
|
4139
|
+
stdinUnavailable,
|
|
4140
|
+
elapsedMs,
|
|
4141
|
+
maxWaitMs: STDIN_SHUTDOWN_MAX_WAIT_MS,
|
|
4142
|
+
hasActiveSessions: active,
|
|
4143
|
+
isConnected: connected
|
|
4144
|
+
});
|
|
4145
|
+
if (decision === "clear") {
|
|
4092
4146
|
stdinClosedAt = void 0;
|
|
4093
4147
|
stdinClosedReason = void 0;
|
|
4094
4148
|
return;
|
|
4095
4149
|
}
|
|
4096
|
-
|
|
4097
|
-
const active = hasActiveSessions();
|
|
4098
|
-
const connected = server.isConnected();
|
|
4099
|
-
if (!active && !connected) {
|
|
4150
|
+
if (decision === "shutdown_now") {
|
|
4100
4151
|
void shutdown(`stdin_${stdinClosedReason ?? "closed"}`);
|
|
4101
4152
|
return;
|
|
4102
4153
|
}
|
|
4103
|
-
if (
|
|
4154
|
+
if (decision === "shutdown_timeout") {
|
|
4104
4155
|
void shutdown(`stdin_${stdinClosedReason ?? "closed"}_timeout`);
|
|
4105
4156
|
return;
|
|
4106
4157
|
}
|
|
@@ -4137,7 +4188,9 @@ async function main() {
|
|
|
4137
4188
|
void shutdown("SIGHUP");
|
|
4138
4189
|
});
|
|
4139
4190
|
process.on("beforeExit", () => {
|
|
4140
|
-
|
|
4191
|
+
if (!server.isConnected()) {
|
|
4192
|
+
void shutdown("beforeExit");
|
|
4193
|
+
}
|
|
4141
4194
|
});
|
|
4142
4195
|
process.on("uncaughtException", handleUnexpectedError);
|
|
4143
4196
|
process.on("unhandledRejection", handleUnexpectedError);
|