@leo000001/claude-code-mcp 2.8.0 → 2.8.3
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 +7 -0
- package/README.md +116 -85
- package/dist/index.js +334 -81
- package/dist/index.js.map +1 -1
- package/package.json +2 -1
package/dist/index.js
CHANGED
|
@@ -914,7 +914,7 @@ var SessionManager = class _SessionManager {
|
|
|
914
914
|
};
|
|
915
915
|
|
|
916
916
|
// src/tools/claude-code.ts
|
|
917
|
-
import { existsSync as
|
|
917
|
+
import { existsSync as existsSync3, statSync as statSync2 } from "fs";
|
|
918
918
|
|
|
919
919
|
// src/types.ts
|
|
920
920
|
var EFFORT_LEVELS = ["low", "medium", "high", "max"];
|
|
@@ -1949,6 +1949,131 @@ function toSessionCreateParams(input) {
|
|
|
1949
1949
|
};
|
|
1950
1950
|
}
|
|
1951
1951
|
|
|
1952
|
+
// src/utils/claude-executable.ts
|
|
1953
|
+
import { accessSync, constants, existsSync as existsSync2, statSync } from "fs";
|
|
1954
|
+
import path3 from "path";
|
|
1955
|
+
var DEFAULT_CLAUDE_COMMAND_ENV = "CLAUDE_CODE_MCP_DEFAULT_CLAUDE_COMMAND";
|
|
1956
|
+
var DEFAULT_CLAUDE_PATH_ENV = "CLAUDE_CODE_MCP_DEFAULT_CLAUDE_PATH";
|
|
1957
|
+
var AUTO_CLAUDE_COMMANDS = ["claude", "claude-internal"];
|
|
1958
|
+
function trimEnv(name) {
|
|
1959
|
+
const value = process.env[name];
|
|
1960
|
+
if (typeof value !== "string") return void 0;
|
|
1961
|
+
const trimmed = value.trim();
|
|
1962
|
+
return trimmed === "" ? void 0 : trimmed;
|
|
1963
|
+
}
|
|
1964
|
+
function normalizeMaybeQuotedPath2(raw) {
|
|
1965
|
+
return path3.normalize(raw.trim().replace(/^"|"$/g, ""));
|
|
1966
|
+
}
|
|
1967
|
+
function normalizeMaybeQuotedToken(raw) {
|
|
1968
|
+
return raw.trim().replace(/^"|"$/g, "");
|
|
1969
|
+
}
|
|
1970
|
+
function isExecutableFile(candidate) {
|
|
1971
|
+
try {
|
|
1972
|
+
const stat = statSync(candidate);
|
|
1973
|
+
if (!stat.isFile()) return false;
|
|
1974
|
+
if (process.platform === "win32") return true;
|
|
1975
|
+
accessSync(candidate, constants.X_OK);
|
|
1976
|
+
return true;
|
|
1977
|
+
} catch {
|
|
1978
|
+
return false;
|
|
1979
|
+
}
|
|
1980
|
+
}
|
|
1981
|
+
function isUsableExecutablePath(candidate) {
|
|
1982
|
+
return isExecutableFile(candidate);
|
|
1983
|
+
}
|
|
1984
|
+
function pathEntries2() {
|
|
1985
|
+
const raw = process.env.PATH;
|
|
1986
|
+
if (typeof raw !== "string" || raw.trim() === "") return [];
|
|
1987
|
+
return raw.split(path3.delimiter).map((entry) => entry.trim().replace(/^"|"$/g, "")).filter(Boolean).map((entry) => path3.normalize(entry));
|
|
1988
|
+
}
|
|
1989
|
+
function windowsExecutableNames(command) {
|
|
1990
|
+
const ext = path3.extname(command);
|
|
1991
|
+
if (ext) return [command];
|
|
1992
|
+
const pathExt = trimEnv("PATHEXT") ?? ".COM;.EXE;.BAT;.CMD";
|
|
1993
|
+
const exts = Array.from(
|
|
1994
|
+
new Set(
|
|
1995
|
+
pathExt.split(";").map((value) => value.trim()).filter(Boolean)
|
|
1996
|
+
)
|
|
1997
|
+
);
|
|
1998
|
+
return exts.map((suffix) => `${command}${suffix.toLowerCase()}`);
|
|
1999
|
+
}
|
|
2000
|
+
function resolveCommandFromPath(command) {
|
|
2001
|
+
if (command.includes("/") || command.includes("\\")) {
|
|
2002
|
+
throw new Error(
|
|
2003
|
+
`${DEFAULT_CLAUDE_COMMAND_ENV} must be a command name without path separators. Use ${DEFAULT_CLAUDE_PATH_ENV} for filesystem paths.`
|
|
2004
|
+
);
|
|
2005
|
+
}
|
|
2006
|
+
const names = process.platform === "win32" ? windowsExecutableNames(command) : [command];
|
|
2007
|
+
const uniqueNames = Array.from(new Set(names.filter(Boolean)));
|
|
2008
|
+
for (const dir of pathEntries2()) {
|
|
2009
|
+
for (const name of uniqueNames) {
|
|
2010
|
+
const candidate = path3.join(dir, name);
|
|
2011
|
+
if (existsSync2(candidate) && isExecutableFile(candidate)) {
|
|
2012
|
+
return path3.normalize(candidate);
|
|
2013
|
+
}
|
|
2014
|
+
}
|
|
2015
|
+
}
|
|
2016
|
+
return void 0;
|
|
2017
|
+
}
|
|
2018
|
+
function resolveConfiguredPath(rawPath) {
|
|
2019
|
+
const normalized = normalizeMaybeQuotedPath2(rawPath);
|
|
2020
|
+
const resolved = path3.isAbsolute(normalized) ? normalized : path3.resolve(normalized);
|
|
2021
|
+
if (!isUsableExecutablePath(resolved)) {
|
|
2022
|
+
throw new Error(`${DEFAULT_CLAUDE_PATH_ENV} does not point to an executable file: ${resolved}`);
|
|
2023
|
+
}
|
|
2024
|
+
return path3.normalize(resolved);
|
|
2025
|
+
}
|
|
2026
|
+
function resolveDefaultClaudeExecutable() {
|
|
2027
|
+
const configuredPath = trimEnv(DEFAULT_CLAUDE_PATH_ENV);
|
|
2028
|
+
const configuredCommandRaw = trimEnv(DEFAULT_CLAUDE_COMMAND_ENV);
|
|
2029
|
+
const configuredCommand = configuredCommandRaw ? normalizeMaybeQuotedToken(configuredCommandRaw) : void 0;
|
|
2030
|
+
if (configuredPath && configuredCommand) {
|
|
2031
|
+
throw new Error(
|
|
2032
|
+
`${DEFAULT_CLAUDE_PATH_ENV} and ${DEFAULT_CLAUDE_COMMAND_ENV} are mutually exclusive; set only one.`
|
|
2033
|
+
);
|
|
2034
|
+
}
|
|
2035
|
+
if (configuredPath) {
|
|
2036
|
+
return {
|
|
2037
|
+
source: "env_path",
|
|
2038
|
+
resolvedPath: resolveConfiguredPath(configuredPath)
|
|
2039
|
+
};
|
|
2040
|
+
}
|
|
2041
|
+
if (configuredCommand) {
|
|
2042
|
+
const resolved = resolveCommandFromPath(configuredCommand);
|
|
2043
|
+
if (!resolved) {
|
|
2044
|
+
throw new Error(
|
|
2045
|
+
`${DEFAULT_CLAUDE_COMMAND_ENV}='${configuredCommand}' was not found in PATH.`
|
|
2046
|
+
);
|
|
2047
|
+
}
|
|
2048
|
+
return {
|
|
2049
|
+
source: "env_command",
|
|
2050
|
+
command: configuredCommand,
|
|
2051
|
+
resolvedPath: resolved
|
|
2052
|
+
};
|
|
2053
|
+
}
|
|
2054
|
+
for (const candidate of AUTO_CLAUDE_COMMANDS) {
|
|
2055
|
+
const resolved = resolveCommandFromPath(candidate);
|
|
2056
|
+
if (!resolved) continue;
|
|
2057
|
+
return {
|
|
2058
|
+
source: candidate === "claude" ? "auto_claude" : "auto_claude_internal",
|
|
2059
|
+
command: candidate,
|
|
2060
|
+
resolvedPath: resolved
|
|
2061
|
+
};
|
|
2062
|
+
}
|
|
2063
|
+
return { source: "sdk_bundled" };
|
|
2064
|
+
}
|
|
2065
|
+
function getDefaultClaudeExecutablePath() {
|
|
2066
|
+
return resolveDefaultClaudeExecutable().resolvedPath;
|
|
2067
|
+
}
|
|
2068
|
+
function checkDefaultClaudeExecutableAvailability() {
|
|
2069
|
+
const resolution = resolveDefaultClaudeExecutable();
|
|
2070
|
+
if (!resolution.resolvedPath) return;
|
|
2071
|
+
const commandText = resolution.command ? `, command=${resolution.command}` : "";
|
|
2072
|
+
console.error(
|
|
2073
|
+
`[executable] Default Claude executable resolved: ${resolution.resolvedPath} (source=${resolution.source}${commandText})`
|
|
2074
|
+
);
|
|
2075
|
+
}
|
|
2076
|
+
|
|
1952
2077
|
// src/tools/claude-code.ts
|
|
1953
2078
|
async function executeClaudeCode(input, sessionManager, serverCwd, toolCache, requestSignal) {
|
|
1954
2079
|
const cwdProvided = input.cwd !== void 0;
|
|
@@ -1961,7 +2086,7 @@ async function executeClaudeCode(input, sessionManager, serverCwd, toolCache, re
|
|
|
1961
2086
|
};
|
|
1962
2087
|
}
|
|
1963
2088
|
const normalizedCwd = normalizeWindowsPathLike(cwd);
|
|
1964
|
-
if (cwdProvided && !
|
|
2089
|
+
if (cwdProvided && !existsSync3(normalizedCwd)) {
|
|
1965
2090
|
return {
|
|
1966
2091
|
sessionId: "",
|
|
1967
2092
|
status: "error",
|
|
@@ -1970,7 +2095,7 @@ async function executeClaudeCode(input, sessionManager, serverCwd, toolCache, re
|
|
|
1970
2095
|
}
|
|
1971
2096
|
if (cwdProvided) {
|
|
1972
2097
|
try {
|
|
1973
|
-
if (!
|
|
2098
|
+
if (!statSync2(normalizedCwd).isDirectory()) {
|
|
1974
2099
|
return {
|
|
1975
2100
|
sessionId: "",
|
|
1976
2101
|
status: "error",
|
|
@@ -2014,7 +2139,7 @@ async function executeClaudeCode(input, sessionManager, serverCwd, toolCache, re
|
|
|
2014
2139
|
cwd: normalizeWindowsPathLike(flat.cwd),
|
|
2015
2140
|
additionalDirectories: flat.additionalDirectories !== void 0 ? normalizeWindowsPathArray(flat.additionalDirectories) : void 0,
|
|
2016
2141
|
debugFile: flat.debugFile !== void 0 ? normalizeWindowsPathLike(flat.debugFile) : void 0,
|
|
2017
|
-
pathToClaudeCodeExecutable: flat.pathToClaudeCodeExecutable !== void 0 ? normalizeWindowsPathLike(flat.pathToClaudeCodeExecutable) :
|
|
2142
|
+
pathToClaudeCodeExecutable: flat.pathToClaudeCodeExecutable !== void 0 ? normalizeWindowsPathLike(flat.pathToClaudeCodeExecutable) : getDefaultClaudeExecutablePath()
|
|
2018
2143
|
};
|
|
2019
2144
|
try {
|
|
2020
2145
|
const handle = consumeQuery({
|
|
@@ -2064,19 +2189,19 @@ async function executeClaudeCode(input, sessionManager, serverCwd, toolCache, re
|
|
|
2064
2189
|
}
|
|
2065
2190
|
|
|
2066
2191
|
// src/tools/claude-code-reply.ts
|
|
2067
|
-
import { existsSync as
|
|
2192
|
+
import { existsSync as existsSync4, statSync as statSync3 } from "fs";
|
|
2068
2193
|
import os2 from "os";
|
|
2069
|
-
import
|
|
2194
|
+
import path4 from "path";
|
|
2070
2195
|
function normalizeAndAssertCwd(cwd, contextLabel) {
|
|
2071
2196
|
const normalizedCwd = normalizeWindowsPathLike(cwd);
|
|
2072
2197
|
const resolvedCwd = resolvePortableTmpAlias(normalizedCwd);
|
|
2073
|
-
if (!
|
|
2198
|
+
if (!existsSync4(resolvedCwd)) {
|
|
2074
2199
|
throw new Error(
|
|
2075
2200
|
`Error [${"INVALID_ARGUMENT" /* INVALID_ARGUMENT */}]: ${contextLabel} path does not exist: ${resolvedCwd}`
|
|
2076
2201
|
);
|
|
2077
2202
|
}
|
|
2078
2203
|
try {
|
|
2079
|
-
const stat =
|
|
2204
|
+
const stat = statSync3(resolvedCwd);
|
|
2080
2205
|
if (!stat.isDirectory()) {
|
|
2081
2206
|
throw new Error(
|
|
2082
2207
|
`Error [${"INVALID_ARGUMENT" /* INVALID_ARGUMENT */}]: ${contextLabel} must be a directory: ${resolvedCwd}`
|
|
@@ -2096,7 +2221,7 @@ function resolvePortableTmpAlias(cwd) {
|
|
|
2096
2221
|
const normalized = cwd.replace(/\\/g, "/");
|
|
2097
2222
|
if (normalized === "/tmp") return os2.tmpdir();
|
|
2098
2223
|
if (normalized.startsWith("/tmp/")) {
|
|
2099
|
-
return
|
|
2224
|
+
return path4.join(os2.tmpdir(), normalized.slice("/tmp/".length));
|
|
2100
2225
|
}
|
|
2101
2226
|
return cwd;
|
|
2102
2227
|
}
|
|
@@ -2120,10 +2245,14 @@ function buildOptionsFromDiskResume(dr) {
|
|
|
2120
2245
|
throw new Error(`Error [${"INVALID_ARGUMENT" /* INVALID_ARGUMENT */}]: cwd must be provided for disk resume.`);
|
|
2121
2246
|
}
|
|
2122
2247
|
const normalizedCwd = normalizeAndAssertCwd(dr.cwd, "disk resume cwd");
|
|
2123
|
-
|
|
2248
|
+
const options = buildOptions({
|
|
2124
2249
|
...dr,
|
|
2125
2250
|
cwd: normalizedCwd
|
|
2126
2251
|
});
|
|
2252
|
+
if (options.pathToClaudeCodeExecutable === void 0) {
|
|
2253
|
+
options.pathToClaudeCodeExecutable = getDefaultClaudeExecutablePath();
|
|
2254
|
+
}
|
|
2255
|
+
return options;
|
|
2127
2256
|
}
|
|
2128
2257
|
async function executeClaudeCodeReply(input, sessionManager, toolCache, requestSignal) {
|
|
2129
2258
|
const permissionRequestTimeoutMs = input.permissionRequestTimeoutMs ?? 6e4;
|
|
@@ -2290,6 +2419,10 @@ async function executeClaudeCodeReply(input, sessionManager, toolCache, requestS
|
|
|
2290
2419
|
const normalizedCwd = normalizeAndAssertCwd(session.cwd, "session cwd");
|
|
2291
2420
|
const options = buildOptions(session);
|
|
2292
2421
|
options.cwd = normalizedCwd;
|
|
2422
|
+
const resolvedDefaultExecutable = options.pathToClaudeCodeExecutable ?? getDefaultClaudeExecutablePath();
|
|
2423
|
+
if (resolvedDefaultExecutable !== void 0) {
|
|
2424
|
+
options.pathToClaudeCodeExecutable = resolvedDefaultExecutable;
|
|
2425
|
+
}
|
|
2293
2426
|
if (input.forkSession) options.forkSession = true;
|
|
2294
2427
|
if (input.forkSession && !sessionManager.hasCapacityFor(1)) {
|
|
2295
2428
|
sessionManager.update(input.sessionId, { status: originalStatus, abortController: void 0 });
|
|
@@ -2301,8 +2434,14 @@ async function executeClaudeCodeReply(input, sessionManager, toolCache, requestS
|
|
|
2301
2434
|
}
|
|
2302
2435
|
const sourceOverrides = {
|
|
2303
2436
|
effort: input.effort ?? session.effort,
|
|
2304
|
-
thinking: input.thinking ?? session.thinking
|
|
2437
|
+
thinking: input.thinking ?? session.thinking,
|
|
2438
|
+
pathToClaudeCodeExecutable: session.pathToClaudeCodeExecutable ?? resolvedDefaultExecutable ?? void 0
|
|
2305
2439
|
};
|
|
2440
|
+
if (session.pathToClaudeCodeExecutable === void 0 && resolvedDefaultExecutable !== void 0) {
|
|
2441
|
+
sessionManager.update(input.sessionId, {
|
|
2442
|
+
pathToClaudeCodeExecutable: resolvedDefaultExecutable
|
|
2443
|
+
});
|
|
2444
|
+
}
|
|
2306
2445
|
if (input.effort !== void 0) options.effort = input.effort;
|
|
2307
2446
|
if (input.thinking !== void 0) options.thinking = input.thinking;
|
|
2308
2447
|
if (!input.forkSession && (input.effort !== void 0 || input.thinking !== void 0)) {
|
|
@@ -2553,8 +2692,8 @@ function groupByCategory(tools) {
|
|
|
2553
2692
|
function buildInternalToolsDescription(tools) {
|
|
2554
2693
|
const grouped = groupByCategory(tools);
|
|
2555
2694
|
const categories = Object.keys(grouped).sort((a, b) => a.localeCompare(b));
|
|
2556
|
-
let desc = "Start a Claude Code
|
|
2557
|
-
desc += "Internal tools (
|
|
2695
|
+
let desc = "Start a background Claude Code run and return sessionId immediately. No final result is returned here.\nMain loop: call claude_code_check(action='poll'), store nextCursor, and keep polling until status becomes idle, error, or cancelled.\nIf actions[] contains permission requests, answer them with claude_code_check(action='respond_permission'). respond_user_input is not supported.\nAdjust polling cadence to progress: poll faster while new events/actions are arriving, and slower when the session is quietly thinking.\nLong-running work is normal: Claude Code can keep working for 10+ minutes, especially with high/max effort, so wait for polling to settle before assuming it is stuck.\nIf you want to continue after a run pauses or finishes, use claude_code_reply with the same sessionId instead of starting a new claude_code session.\nFor runtime-authoritative tool names, call claude_code_check with pollOptions.includeTools=true.\n\n";
|
|
2696
|
+
desc += "Internal tools (runtime list when includeTools=true):\n";
|
|
2558
2697
|
for (const category of categories) {
|
|
2559
2698
|
desc += `
|
|
2560
2699
|
[${category}]
|
|
@@ -2564,7 +2703,7 @@ function buildInternalToolsDescription(tools) {
|
|
|
2564
2703
|
`;
|
|
2565
2704
|
}
|
|
2566
2705
|
}
|
|
2567
|
-
desc += "\nPermission control: allowedTools
|
|
2706
|
+
desc += "\nPermission control: allowedTools pre-approves tools but is not a strict allowlist unless strictAllowedTools=true; disallowedTools always denies; other tools may require approval.\n";
|
|
2568
2707
|
return desc;
|
|
2569
2708
|
}
|
|
2570
2709
|
|
|
@@ -3161,6 +3300,7 @@ function executeClaudeCodeSession(input, sessionManager, requestSignal) {
|
|
|
3161
3300
|
// src/resources/register-resources.ts
|
|
3162
3301
|
import { ResourceTemplate } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
3163
3302
|
import { createHash } from "crypto";
|
|
3303
|
+
import { basename } from "path";
|
|
3164
3304
|
var RESOURCE_SCHEME = "claude-code-mcp";
|
|
3165
3305
|
var RESOURCE_URIS = {
|
|
3166
3306
|
serverInfo: `${RESOURCE_SCHEME}:///server-info`,
|
|
@@ -3312,7 +3452,7 @@ function asVersionedPayload(params) {
|
|
|
3312
3452
|
}
|
|
3313
3453
|
function registerResources(server, deps) {
|
|
3314
3454
|
const startedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
3315
|
-
const resourceSchemaVersion = "1.
|
|
3455
|
+
const resourceSchemaVersion = "1.4";
|
|
3316
3456
|
const mcpProtocolVersion = "2025-03-26";
|
|
3317
3457
|
const gotchasEntries = buildGotchasEntries();
|
|
3318
3458
|
const catalogToolNames = new Set(defaultCatalogTools().map((tool) => tool.name));
|
|
@@ -3403,7 +3543,7 @@ function registerResources(server, deps) {
|
|
|
3403
3543
|
gotchasUri.toString(),
|
|
3404
3544
|
{
|
|
3405
3545
|
title: "Gotchas",
|
|
3406
|
-
description: "
|
|
3546
|
+
description: "High-signal failure modes, symptoms, and remedies for this MCP workflow.",
|
|
3407
3547
|
mimeType: "text/markdown"
|
|
3408
3548
|
},
|
|
3409
3549
|
() => asTextResource(
|
|
@@ -3411,7 +3551,18 @@ function registerResources(server, deps) {
|
|
|
3411
3551
|
[
|
|
3412
3552
|
"# claude-code-mcp: gotchas",
|
|
3413
3553
|
"",
|
|
3414
|
-
|
|
3554
|
+
"Check these before assuming the session is broken.",
|
|
3555
|
+
"",
|
|
3556
|
+
...gotchasEntries.flatMap((entry) => [
|
|
3557
|
+
`## ${entry.title}`,
|
|
3558
|
+
`- Severity: ${entry.severity}`,
|
|
3559
|
+
`- Applies to: ${entry.appliesTo.join(", ")}`,
|
|
3560
|
+
`- Symptom: ${entry.symptom}`,
|
|
3561
|
+
`- Detection: ${entry.detection}`,
|
|
3562
|
+
`- Remedy: ${entry.remedy}`,
|
|
3563
|
+
...entry.example ? [`- Example: ${entry.example}`] : [],
|
|
3564
|
+
""
|
|
3565
|
+
]),
|
|
3415
3566
|
""
|
|
3416
3567
|
].join("\n"),
|
|
3417
3568
|
"text/markdown"
|
|
@@ -3424,7 +3575,7 @@ function registerResources(server, deps) {
|
|
|
3424
3575
|
quickstartUri.toString(),
|
|
3425
3576
|
{
|
|
3426
3577
|
title: "Quickstart",
|
|
3427
|
-
description: "
|
|
3578
|
+
description: "Canonical async start, poll, permission, and continue flow for MCP callers.",
|
|
3428
3579
|
mimeType: "text/markdown"
|
|
3429
3580
|
},
|
|
3430
3581
|
() => asTextResource(
|
|
@@ -3432,14 +3583,43 @@ function registerResources(server, deps) {
|
|
|
3432
3583
|
[
|
|
3433
3584
|
"# claude-code-mcp quickstart",
|
|
3434
3585
|
"",
|
|
3435
|
-
"
|
|
3436
|
-
"
|
|
3437
|
-
"
|
|
3438
|
-
"
|
|
3586
|
+
"## Required state",
|
|
3587
|
+
"",
|
|
3588
|
+
"Persist these client-side:",
|
|
3589
|
+
"- `sessionId`: returned by `claude_code` / `claude_code_reply`.",
|
|
3590
|
+
"- `nextCursor`: returned by each `claude_code_check(action='poll')` call.",
|
|
3591
|
+
"",
|
|
3592
|
+
"## Main loop",
|
|
3593
|
+
"",
|
|
3594
|
+
"1. Call `claude_code` with `{ prompt }`.",
|
|
3595
|
+
"2. Store `sessionId` from the start response.",
|
|
3596
|
+
"3. Poll with `claude_code_check(action='poll')`, passing the previous `nextCursor` back as `cursor`.",
|
|
3597
|
+
"4. If `actions[]` contains a permission request, answer it with `claude_code_check(action='respond_permission')`.",
|
|
3598
|
+
"5. Continue polling until `status` becomes `idle`, `error`, or `cancelled`.",
|
|
3599
|
+
"",
|
|
3600
|
+
"## Continue an existing run",
|
|
3601
|
+
"",
|
|
3602
|
+
"- If Claude Code stops and you want to keep going, call `claude_code_reply` with the existing `sessionId` instead of starting a fresh `claude_code` session.",
|
|
3603
|
+
"- `claude_code_reply` requires a persistent session, or `diskResumeConfig` when disk resume fallback is enabled and the in-memory session is missing.",
|
|
3604
|
+
"",
|
|
3605
|
+
"## Reminders",
|
|
3606
|
+
"",
|
|
3607
|
+
"- This backend is asynchronous: `claude_code` and `claude_code_reply` start work, and the final result arrives later via polling.",
|
|
3608
|
+
"- Claude Code may keep working for 10+ minutes on larger tasks, especially with `effort='high'` or `effort='max'`; keep polling and be patient before treating it as stuck.",
|
|
3609
|
+
"- Adjust poll intervals to the current progress: poll faster while new events or permission actions are arriving, and slower while the session is quietly thinking with no new output.",
|
|
3610
|
+
"- `model` is optional. If omitted, Claude Code chooses the effective model from its own defaults/settings.",
|
|
3611
|
+
"- `allowedTools` is pre-approval by default; set `strictAllowedTools=true` when you need a strict allowlist.",
|
|
3612
|
+
"- `allow_for_session` usually works best when the same tool will be used repeatedly in one session.",
|
|
3613
|
+
"",
|
|
3614
|
+
"## Common mistakes",
|
|
3615
|
+
"",
|
|
3616
|
+
"- Do not call `claude_code_reply` on a non-persistent session if you expect to continue later; keep `advanced.persistSession=true`.",
|
|
3617
|
+
"- Store `nextCursor` and feed it back into the next `claude_code_check(action='poll')`; otherwise you will keep replaying old events.",
|
|
3618
|
+
"- On Windows, set `CLAUDE_CODE_GIT_BASH_PATH` or Claude Code may fail before the session starts.",
|
|
3619
|
+
"- If `decision='allow_for_session'` still shows a permission request, inspect `actions[].suggestions` / `blockedPath`; directory access may need a more specific permission update.",
|
|
3439
3620
|
"",
|
|
3440
3621
|
"Notes:",
|
|
3441
|
-
"- `respond_user_input` is not supported
|
|
3442
|
-
"- `allowedTools` is pre-approval by default; set `strictAllowedTools=true` for strict allowlist behavior.",
|
|
3622
|
+
"- `respond_user_input` is not supported. Use only `respond_permission` for approvals.",
|
|
3443
3623
|
"- OpenCode/Codex-style clients usually work best when they store `sessionId` + `nextCursor` and answer approvals with `decision=allow_for_session`.",
|
|
3444
3624
|
"- Prefer `responseMode='delta_compact'` for high-frequency polling."
|
|
3445
3625
|
].join("\n"),
|
|
@@ -3499,6 +3679,7 @@ function registerResources(server, deps) {
|
|
|
3499
3679
|
const diskResumeEnabled = process.env.CLAUDE_CODE_MCP_ALLOW_DISK_RESUME === "1";
|
|
3500
3680
|
const resumeSecretConfigured = typeof process.env.CLAUDE_CODE_MCP_RESUME_SECRET === "string" && process.env.CLAUDE_CODE_MCP_RESUME_SECRET.trim() !== "";
|
|
3501
3681
|
const runtimeToolStats = deps.sessionManager.getRuntimeToolStats();
|
|
3682
|
+
const defaultClaudeExecutable = resolveDefaultClaudeExecutable();
|
|
3502
3683
|
const toolCatalogCount = deps.toolCache.getTools().length;
|
|
3503
3684
|
const detectedMismatches = [];
|
|
3504
3685
|
if (runtimeToolStats.sessionsWithInitTools > 0 && runtimeToolStats.runtimeDiscoveredUniqueCount < toolCatalogCount) {
|
|
@@ -3527,6 +3708,12 @@ function registerResources(server, deps) {
|
|
|
3527
3708
|
enabled: diskResumeEnabled,
|
|
3528
3709
|
resumeSecretConfigured
|
|
3529
3710
|
},
|
|
3711
|
+
defaultClaudeExecutable: {
|
|
3712
|
+
source: defaultClaudeExecutable.source,
|
|
3713
|
+
command: defaultClaudeExecutable.command,
|
|
3714
|
+
resolvedFileName: defaultClaudeExecutable.resolvedPath ? basename(defaultClaudeExecutable.resolvedPath) : void 0,
|
|
3715
|
+
usingBundled: defaultClaudeExecutable.resolvedPath === void 0
|
|
3716
|
+
},
|
|
3530
3717
|
features: {
|
|
3531
3718
|
resources: true,
|
|
3532
3719
|
resourceTemplates: true,
|
|
@@ -3553,8 +3740,10 @@ function registerResources(server, deps) {
|
|
|
3553
3740
|
},
|
|
3554
3741
|
guidance: [
|
|
3555
3742
|
"Some clients cache tool descriptions at connect time. Prefer claude_code_check(pollOptions.includeTools=true) for runtime-authoritative tool lists.",
|
|
3743
|
+
"Treat tool descriptions and MCP resources as agent-visible guidance; do not assume README-level documentation is visible to the model.",
|
|
3556
3744
|
"Use allowedTools/disallowedTools only with exact runtime tool names.",
|
|
3557
3745
|
"Set strictAllowedTools=true when you need allowedTools to behave as a strict allowlist.",
|
|
3746
|
+
"Default Claude executable selection prefers request path, then CLAUDE_CODE_MCP_DEFAULT_CLAUDE_PATH, then CLAUDE_CODE_MCP_DEFAULT_CLAUDE_COMMAND, then auto-detected 'claude'/'claude-internal', then SDK-bundled.",
|
|
3558
3747
|
"This server assumes MCP client and server run on the same machine/platform.",
|
|
3559
3748
|
"For high-frequency status checks, prefer responseMode='delta_compact'.",
|
|
3560
3749
|
"respond_user_input is not supported on this backend; use poll/respond_permission flow."
|
|
@@ -3723,7 +3912,8 @@ function registerResources(server, deps) {
|
|
|
3723
3912
|
detectedMismatches: [],
|
|
3724
3913
|
recommendations: [
|
|
3725
3914
|
"Prefer responseMode='delta_compact' for fast status loops.",
|
|
3726
|
-
"Enable pollOptions.includeTools=true when exact runtime tool names are required."
|
|
3915
|
+
"Enable pollOptions.includeTools=true when exact runtime tool names are required.",
|
|
3916
|
+
"Do not assume human-facing README guidance is visible to the agent; keep critical calling rules in tool descriptions or MCP resources."
|
|
3727
3917
|
]
|
|
3728
3918
|
};
|
|
3729
3919
|
}
|
|
@@ -3734,7 +3924,8 @@ function registerResources(server, deps) {
|
|
|
3734
3924
|
recommendations: [
|
|
3735
3925
|
"Use resources and resource templates for low-latency diagnostics.",
|
|
3736
3926
|
"Use allowedTools/disallowedTools with exact runtime names.",
|
|
3737
|
-
"Enable strictAllowedTools when running in locked-down governance mode."
|
|
3927
|
+
"Enable strictAllowedTools when running in locked-down governance mode.",
|
|
3928
|
+
"Keep protocol-critical calling rules in tool descriptions or resources, not only in README-like docs."
|
|
3738
3929
|
]
|
|
3739
3930
|
};
|
|
3740
3931
|
}
|
|
@@ -3755,7 +3946,8 @@ function registerResources(server, deps) {
|
|
|
3755
3946
|
detectedMismatches: [],
|
|
3756
3947
|
recommendations: [
|
|
3757
3948
|
"Persist nextCursor and de-duplicate by event.id.",
|
|
3758
|
-
"Use responseMode='delta_compact' for high-frequency polling, full mode only for diagnostics."
|
|
3949
|
+
"Use responseMode='delta_compact' for high-frequency polling, full mode only for diagnostics.",
|
|
3950
|
+
"Do not assume repository docs are model-visible; tool descriptions and resources are safer places for runtime guidance."
|
|
3759
3951
|
]
|
|
3760
3952
|
};
|
|
3761
3953
|
})();
|
|
@@ -3783,7 +3975,7 @@ function registerResources(server, deps) {
|
|
|
3783
3975
|
}
|
|
3784
3976
|
|
|
3785
3977
|
// src/server.ts
|
|
3786
|
-
var SERVER_VERSION = true ? "2.8.
|
|
3978
|
+
var SERVER_VERSION = true ? "2.8.3" : "0.0.0-dev";
|
|
3787
3979
|
function createServerContext(serverCwd) {
|
|
3788
3980
|
const sessionManager = new SessionManager();
|
|
3789
3981
|
const server = new McpServer(
|
|
@@ -3791,7 +3983,7 @@ function createServerContext(serverCwd) {
|
|
|
3791
3983
|
name: "claude-code-mcp",
|
|
3792
3984
|
version: SERVER_VERSION,
|
|
3793
3985
|
title: "Claude Code MCP",
|
|
3794
|
-
description: "MCP server that runs Claude Code via the Claude Agent SDK with
|
|
3986
|
+
description: "MCP server that runs Claude Code via the Claude Agent SDK. Starts and replies return quickly; callers poll with claude_code_check and answer permission requests explicitly.",
|
|
3795
3987
|
websiteUrl: "https://github.com/xihuai18/claude-code-mcp",
|
|
3796
3988
|
icons: []
|
|
3797
3989
|
},
|
|
@@ -3821,11 +4013,13 @@ function createServerContext(serverCwd) {
|
|
|
3821
4013
|
const agentDefinitionSchema = z.object({
|
|
3822
4014
|
description: z.string(),
|
|
3823
4015
|
prompt: z.string(),
|
|
3824
|
-
tools: z.array(z.string()).optional().describe("Default: inherit"),
|
|
4016
|
+
tools: z.array(z.string()).optional().describe("Allowed tool names for this subagent. Default: inherit"),
|
|
3825
4017
|
disallowedTools: z.array(z.string()).optional().describe("Default: none"),
|
|
3826
4018
|
model: z.string().optional().describe("Default: inherit"),
|
|
3827
4019
|
maxTurns: z.number().int().positive().optional().describe("Default: none"),
|
|
3828
|
-
mcpServers: z.array(z.union([z.string(), z.record(z.string(), z.unknown())])).optional().describe(
|
|
4020
|
+
mcpServers: z.array(z.union([z.string(), z.record(z.string(), z.unknown())])).optional().describe(
|
|
4021
|
+
"Additional MCP server names or inline process-transport specs for this subagent. Default: inherit"
|
|
4022
|
+
),
|
|
3829
4023
|
skills: z.array(z.string()).optional().describe("Default: none"),
|
|
3830
4024
|
criticalSystemReminder_EXPERIMENTAL: z.string().optional().describe("Default: none")
|
|
3831
4025
|
});
|
|
@@ -3848,7 +4042,7 @@ function createServerContext(serverCwd) {
|
|
|
3848
4042
|
z.object({ type: z.literal("adaptive") }),
|
|
3849
4043
|
z.object({
|
|
3850
4044
|
type: z.literal("enabled"),
|
|
3851
|
-
budgetTokens: z.number().int().positive()
|
|
4045
|
+
budgetTokens: z.number().int().positive().optional()
|
|
3852
4046
|
}),
|
|
3853
4047
|
z.object({ type: z.literal("disabled") })
|
|
3854
4048
|
]);
|
|
@@ -3859,51 +4053,71 @@ function createServerContext(serverCwd) {
|
|
|
3859
4053
|
schema: z.record(z.string(), z.unknown())
|
|
3860
4054
|
});
|
|
3861
4055
|
const sharedOptionFieldsSchemaShape = {
|
|
3862
|
-
tools: toolsConfigSchema.optional().describe(
|
|
4056
|
+
tools: toolsConfigSchema.optional().describe(
|
|
4057
|
+
"Visible built-in tool set. Use this to restrict what Claude can see/call: string[] of exact tool names, [] to disable built-ins, or {type:'preset',preset:'claude_code'}. Default: SDK"
|
|
4058
|
+
),
|
|
3863
4059
|
persistSession: z.boolean().optional().describe("Default: true"),
|
|
3864
|
-
agents: z.record(z.string(), agentDefinitionSchema).optional().describe("Default: none"),
|
|
4060
|
+
agents: z.record(z.string(), agentDefinitionSchema).optional().describe("Custom subagents keyed by agent name. Default: none"),
|
|
3865
4061
|
agent: z.string().optional().describe("Default: none"),
|
|
3866
4062
|
maxBudgetUsd: z.number().positive().optional().describe("Default: none"),
|
|
3867
4063
|
betas: z.array(z.string()).optional().describe("Default: none"),
|
|
3868
4064
|
additionalDirectories: z.array(z.string()).optional().describe("Default: none"),
|
|
3869
|
-
outputFormat: outputFormatSchema.optional().describe("Default: none"),
|
|
3870
|
-
pathToClaudeCodeExecutable: z.string().optional().describe(
|
|
3871
|
-
|
|
3872
|
-
|
|
4065
|
+
outputFormat: outputFormatSchema.optional().describe("Structured output config: {type:'json_schema', schema:{...}}. Default: none"),
|
|
4066
|
+
pathToClaudeCodeExecutable: z.string().optional().describe(
|
|
4067
|
+
"Explicit Claude executable path. Default: auto-detect 'claude', then 'claude-internal', else SDK-bundled. Server env vars can override the default."
|
|
4068
|
+
),
|
|
4069
|
+
mcpServers: z.record(z.string(), z.record(z.string(), z.unknown())).optional().describe("MCP server configs keyed by server name. Default: none"),
|
|
4070
|
+
sandbox: z.record(z.string(), z.unknown()).optional().describe(
|
|
4071
|
+
"Sandbox behavior config object. This controls sandbox behavior, not the actual allow/deny permission rules. Default: none"
|
|
4072
|
+
),
|
|
3873
4073
|
fallbackModel: z.string().optional().describe("Default: none"),
|
|
3874
4074
|
enableFileCheckpointing: z.boolean().optional().describe("Default: false"),
|
|
3875
|
-
toolConfig: z.record(z.string(), z.unknown()).optional().describe(
|
|
4075
|
+
toolConfig: z.record(z.string(), z.unknown()).optional().describe(
|
|
4076
|
+
"Per-tool built-in config object, e.g. {askUserQuestion:{previewFormat:'markdown'|'html'}}. Default: none"
|
|
4077
|
+
),
|
|
3876
4078
|
includePartialMessages: z.boolean().optional().describe("Default: false"),
|
|
3877
4079
|
promptSuggestions: z.boolean().optional().describe("Default: false"),
|
|
3878
4080
|
agentProgressSummaries: z.boolean().optional().describe("Default: false"),
|
|
3879
4081
|
strictMcpConfig: z.boolean().optional().describe("Default: false"),
|
|
3880
|
-
settings: z.union([z.string(), z.record(z.string(), z.unknown())]).optional().describe(
|
|
4082
|
+
settings: z.union([z.string(), z.record(z.string(), z.unknown())]).optional().describe(
|
|
4083
|
+
"Path to a settings JSON file or an inline settings object. Loaded as highest-priority flag settings. Default: none"
|
|
4084
|
+
),
|
|
3881
4085
|
settingSources: z.array(z.enum(["user", "project", "local"])).optional().describe("Default: ['user','project','local']. []=isolation"),
|
|
3882
4086
|
debug: z.boolean().optional().describe("Default: false"),
|
|
3883
|
-
debugFile: z.string().optional().describe("Default: none"),
|
|
3884
|
-
env: z.record(z.string(), z.string().optional()).optional().describe(
|
|
4087
|
+
debugFile: z.string().optional().describe("Write debug logs to this file and implicitly enable debug. Default: none"),
|
|
4088
|
+
env: z.record(z.string(), z.string().optional()).optional().describe(
|
|
4089
|
+
"Environment variables merged over process.env before launching Claude Code. Default: none"
|
|
4090
|
+
)
|
|
3885
4091
|
};
|
|
3886
4092
|
const advancedOptionFieldsSchemaShape = {
|
|
3887
4093
|
...sharedOptionFieldsSchemaShape
|
|
3888
4094
|
};
|
|
3889
4095
|
const diskResumeOptionFieldsSchemaShape = {
|
|
3890
4096
|
...sharedOptionFieldsSchemaShape,
|
|
3891
|
-
effort: effortOptionSchema.describe(
|
|
3892
|
-
|
|
4097
|
+
effort: effortOptionSchema.describe(
|
|
4098
|
+
"Effort string: 'low' | 'medium' | 'high' | 'max'. Default: SDK"
|
|
4099
|
+
),
|
|
4100
|
+
thinking: thinkingOptionSchema.describe(
|
|
4101
|
+
"Thinking config object, not a string. Use {type:'adaptive'} | {type:'enabled', budgetTokens?:N} | {type:'disabled'}. Default: SDK"
|
|
4102
|
+
)
|
|
3893
4103
|
};
|
|
3894
4104
|
const advancedOptionsSchema = z.object({
|
|
3895
4105
|
...advancedOptionFieldsSchemaShape,
|
|
3896
|
-
sessionInitTimeoutMs: z.number().int().positive().optional().describe("Default: 10000")
|
|
4106
|
+
sessionInitTimeoutMs: z.number().int().positive().optional().describe("Server init wait timeout in ms; not forwarded to SDK Options. Default: 10000")
|
|
3897
4107
|
}).optional().describe("Default: none");
|
|
3898
4108
|
const diskResumeConfigSchema = z.object({
|
|
3899
4109
|
resumeToken: z.string(),
|
|
3900
4110
|
cwd: z.string(),
|
|
3901
|
-
allowedTools: z.array(z.string()).optional().describe("Default: []"),
|
|
3902
|
-
disallowedTools: z.array(z.string()).optional().describe("Default: []"),
|
|
3903
|
-
strictAllowedTools: z.boolean().optional().describe(
|
|
4111
|
+
allowedTools: z.array(z.string()).optional().describe("Pre-approved tool names for resumed execution. Default: []"),
|
|
4112
|
+
disallowedTools: z.array(z.string()).optional().describe("Always-denied tool names. Default: []"),
|
|
4113
|
+
strictAllowedTools: z.boolean().optional().describe(
|
|
4114
|
+
"Server-side strict allowlist toggle; not forwarded to SDK Options. Default: false"
|
|
4115
|
+
),
|
|
3904
4116
|
maxTurns: z.number().int().positive().optional().describe("Default: SDK"),
|
|
3905
4117
|
model: z.string().optional().describe("Default: SDK"),
|
|
3906
|
-
systemPrompt: systemPromptSchema.optional().describe(
|
|
4118
|
+
systemPrompt: systemPromptSchema.optional().describe(
|
|
4119
|
+
"System prompt config: string, {type:'preset',preset:'claude_code'}, or {type:'preset',preset:'claude_code',append:'...'}. Default: SDK"
|
|
4120
|
+
),
|
|
3907
4121
|
resumeSessionAt: z.string().optional().describe("Default: none"),
|
|
3908
4122
|
...diskResumeOptionFieldsSchemaShape
|
|
3909
4123
|
}).optional().describe("Default: none");
|
|
@@ -3964,17 +4178,29 @@ function createServerContext(serverCwd) {
|
|
|
3964
4178
|
{
|
|
3965
4179
|
description: buildInternalToolsDescription(toolCache.getTools()),
|
|
3966
4180
|
inputSchema: {
|
|
3967
|
-
prompt: z.string().describe(
|
|
4181
|
+
prompt: z.string().describe(
|
|
4182
|
+
"Prompt for a new background run. The final result arrives later via claude_code_check, not this call. Store nextCursor from polls and reuse sessionId with claude_code_reply if you want to continue later."
|
|
4183
|
+
),
|
|
3968
4184
|
cwd: z.string().optional().describe("Working dir. Default: server cwd"),
|
|
3969
|
-
allowedTools: z.array(z.string()).optional().describe(
|
|
3970
|
-
|
|
3971
|
-
|
|
4185
|
+
allowedTools: z.array(z.string()).optional().describe(
|
|
4186
|
+
"Pre-approved tool names. Default: []. This is not a strict allowlist unless strictAllowedTools=true."
|
|
4187
|
+
),
|
|
4188
|
+
disallowedTools: z.array(z.string()).optional().describe("Always-denied tool names. Default: []"),
|
|
4189
|
+
strictAllowedTools: z.boolean().optional().describe("Default: false. When true, tools outside allowedTools are denied."),
|
|
3972
4190
|
maxTurns: z.number().int().positive().optional().describe("Default: SDK"),
|
|
3973
4191
|
model: z.string().optional().describe("Default: SDK"),
|
|
3974
|
-
effort: effortOptionSchema.describe(
|
|
3975
|
-
|
|
3976
|
-
|
|
3977
|
-
|
|
4192
|
+
effort: effortOptionSchema.describe(
|
|
4193
|
+
"Effort string: 'low' | 'medium' | 'high' | 'max'. Default: SDK"
|
|
4194
|
+
),
|
|
4195
|
+
thinking: thinkingOptionSchema.describe(
|
|
4196
|
+
"Thinking config object, not a string. Use {type:'adaptive'} | {type:'enabled', budgetTokens?:N} | {type:'disabled'}. Default: SDK"
|
|
4197
|
+
),
|
|
4198
|
+
systemPrompt: systemPromptSchema.optional().describe(
|
|
4199
|
+
"System prompt config: string, {type:'preset',preset:'claude_code'}, or {type:'preset',preset:'claude_code',append:'...'}. Default: SDK"
|
|
4200
|
+
),
|
|
4201
|
+
permissionRequestTimeoutMs: z.number().int().positive().optional().describe(
|
|
4202
|
+
"Server permission wait timeout in ms; not forwarded to SDK Options. Default: 60000, clamped to 300000"
|
|
4203
|
+
),
|
|
3978
4204
|
advanced: advancedOptionsSchema
|
|
3979
4205
|
},
|
|
3980
4206
|
outputSchema: startResultSchema,
|
|
@@ -4028,16 +4254,26 @@ function createServerContext(serverCwd) {
|
|
|
4028
4254
|
server.registerTool(
|
|
4029
4255
|
"claude_code_reply",
|
|
4030
4256
|
{
|
|
4031
|
-
description: "Send a follow-up to an existing session. Returns immediately;
|
|
4257
|
+
description: "Send a follow-up to an existing session. Reuse the same sessionId instead of starting a new claude_code session when you want to continue. Returns immediately; poll with claude_code_check. Use diskResumeConfig only when the in-memory session is missing and disk resume is enabled.",
|
|
4032
4258
|
inputSchema: {
|
|
4033
|
-
sessionId: z.string().describe(
|
|
4034
|
-
|
|
4259
|
+
sessionId: z.string().describe(
|
|
4260
|
+
"Session ID from claude_code or an earlier claude_code_reply. Prefer this over starting a fresh claude_code session. Reply works only for persistent sessions, or with diskResumeConfig when disk resume fallback is enabled."
|
|
4261
|
+
),
|
|
4262
|
+
prompt: z.string().describe("Follow-up prompt for the existing session."),
|
|
4035
4263
|
forkSession: z.boolean().optional().describe("Default: false"),
|
|
4036
|
-
effort: effortOptionSchema.describe(
|
|
4037
|
-
|
|
4038
|
-
|
|
4039
|
-
|
|
4040
|
-
|
|
4264
|
+
effort: effortOptionSchema.describe(
|
|
4265
|
+
"Effort string: 'low' | 'medium' | 'high' | 'max'. Default: SDK"
|
|
4266
|
+
),
|
|
4267
|
+
thinking: thinkingOptionSchema.describe(
|
|
4268
|
+
"Thinking config object, not a string. Use {type:'adaptive'} | {type:'enabled', budgetTokens?:N} | {type:'disabled'}. Default: SDK"
|
|
4269
|
+
),
|
|
4270
|
+
sessionInitTimeoutMs: z.number().int().positive().optional().describe("Default: 10000. Applies when forkSession=true."),
|
|
4271
|
+
permissionRequestTimeoutMs: z.number().int().positive().optional().describe(
|
|
4272
|
+
"Server permission wait timeout in ms; not forwarded to SDK Options. Default: 60000, clamped to 300000"
|
|
4273
|
+
),
|
|
4274
|
+
diskResumeConfig: diskResumeConfigSchema.describe(
|
|
4275
|
+
"Default: none. Use only when the in-memory session is missing and the server allows disk resume."
|
|
4276
|
+
)
|
|
4041
4277
|
},
|
|
4042
4278
|
outputSchema: startResultSchema,
|
|
4043
4279
|
annotations: {
|
|
@@ -4086,9 +4322,11 @@ function createServerContext(serverCwd) {
|
|
|
4086
4322
|
{
|
|
4087
4323
|
description: "List, inspect, cancel, or interrupt sessions.",
|
|
4088
4324
|
inputSchema: {
|
|
4089
|
-
action: z.enum(SESSION_ACTIONS),
|
|
4090
|
-
sessionId: z.string().optional().describe("Required for get/cancel/interrupt"),
|
|
4091
|
-
includeSensitive: z.boolean().optional().describe(
|
|
4325
|
+
action: z.enum(SESSION_ACTIONS).describe("Session operation: list, get, cancel, or interrupt."),
|
|
4326
|
+
sessionId: z.string().optional().describe("Required for get/cancel/interrupt."),
|
|
4327
|
+
includeSensitive: z.boolean().optional().describe(
|
|
4328
|
+
"Default: false. Exposes more session fields, but some secrets remain redacted."
|
|
4329
|
+
)
|
|
4092
4330
|
},
|
|
4093
4331
|
outputSchema: sessionResultSchema,
|
|
4094
4332
|
annotations: {
|
|
@@ -4134,19 +4372,31 @@ function createServerContext(serverCwd) {
|
|
|
4134
4372
|
server.registerTool(
|
|
4135
4373
|
"claude_code_check",
|
|
4136
4374
|
{
|
|
4137
|
-
description: "Poll session
|
|
4375
|
+
description: "Poll session state or answer a pending permission request. Main loop: call action='poll', persist nextCursor, and use action='respond_permission' for approvals. respond_user_input is not supported.",
|
|
4138
4376
|
inputSchema: {
|
|
4139
|
-
action: z.enum(CHECK_ACTIONS)
|
|
4140
|
-
|
|
4141
|
-
|
|
4142
|
-
|
|
4377
|
+
action: z.enum(CHECK_ACTIONS).describe(
|
|
4378
|
+
"'poll' fetches new events/actions/result; 'respond_permission' answers one pending permission request."
|
|
4379
|
+
),
|
|
4380
|
+
sessionId: z.string().describe("Session ID returned by claude_code or claude_code_reply."),
|
|
4381
|
+
cursor: z.number().int().nonnegative().optional().describe(
|
|
4382
|
+
"Default: 0. Pass the previous nextCursor to avoid replaying old buffered events."
|
|
4383
|
+
),
|
|
4384
|
+
responseMode: z.enum(CHECK_RESPONSE_MODES).optional().describe(
|
|
4385
|
+
"Default: 'minimal'. Use 'delta_compact' for lightweight high-frequency polling; use 'full' mainly for diagnostics."
|
|
4386
|
+
),
|
|
4143
4387
|
maxEvents: z.number().int().positive().optional().describe("Default: 200 (minimal), unlimited (full/delta_compact)"),
|
|
4144
|
-
requestId: z.string().optional().describe("Default: none"),
|
|
4145
|
-
decision: z.enum(["allow", "deny", "allow_for_session"]).optional().describe(
|
|
4146
|
-
|
|
4147
|
-
|
|
4388
|
+
requestId: z.string().optional().describe("Default: none. Required for action='respond_permission'."),
|
|
4389
|
+
decision: z.enum(["allow", "deny", "allow_for_session"]).optional().describe(
|
|
4390
|
+
"Default: none. Required for action='respond_permission'. 'allow_for_session' reduces repeated prompts in the same session."
|
|
4391
|
+
),
|
|
4392
|
+
denyMessage: z.string().optional().describe("Default: 'Permission denied by caller'. Used only with decision='deny'."),
|
|
4393
|
+
interrupt: z.boolean().optional().describe(
|
|
4394
|
+
"Default: false. When true, a deny decision also interrupts the whole session."
|
|
4395
|
+
),
|
|
4148
4396
|
pollOptions: z.object({
|
|
4149
|
-
includeTools: z.boolean().optional().describe(
|
|
4397
|
+
includeTools: z.boolean().optional().describe(
|
|
4398
|
+
"Default: false. When true, include runtime-discovered availableTools; use this when exact tool names matter."
|
|
4399
|
+
),
|
|
4150
4400
|
includeEvents: z.boolean().optional().describe("Default: true"),
|
|
4151
4401
|
includeActions: z.boolean().optional().describe("Default: true"),
|
|
4152
4402
|
includeResult: z.boolean().optional().describe("Default: true"),
|
|
@@ -4156,11 +4406,13 @@ function createServerContext(serverCwd) {
|
|
|
4156
4406
|
includeTerminalEvents: z.boolean().optional().describe("Default: full=true, minimal/delta_compact=false"),
|
|
4157
4407
|
includeProgressEvents: z.boolean().optional().describe("Default: full=true, minimal/delta_compact=false"),
|
|
4158
4408
|
maxBytes: z.number().int().positive().optional().describe("Default: unlimited")
|
|
4159
|
-
}).optional().describe("Default: none"),
|
|
4409
|
+
}).optional().describe("Default: none. Advanced polling payload controls for action='poll'."),
|
|
4160
4410
|
permissionOptions: z.object({
|
|
4161
4411
|
updatedInput: z.record(z.string(), z.unknown()).optional().describe("Default: none"),
|
|
4162
4412
|
updatedPermissions: z.array(z.record(z.string(), z.unknown())).optional().describe("Default: none")
|
|
4163
|
-
}).optional().describe(
|
|
4413
|
+
}).optional().describe(
|
|
4414
|
+
"Default: none. Advanced permission response overrides for action='respond_permission'."
|
|
4415
|
+
)
|
|
4164
4416
|
},
|
|
4165
4417
|
outputSchema: checkResultSchema,
|
|
4166
4418
|
annotations: {
|
|
@@ -4396,10 +4648,11 @@ async function main() {
|
|
|
4396
4648
|
process.stdin.on("error", handleStdinError);
|
|
4397
4649
|
process.stdin.on("end", onStdinEnd);
|
|
4398
4650
|
process.stdin.on("close", onStdinClose);
|
|
4651
|
+
checkWindowsBashAvailability();
|
|
4652
|
+
checkDefaultClaudeExecutableAvailability();
|
|
4399
4653
|
await server.connect(transport);
|
|
4400
4654
|
server.sendToolListChanged();
|
|
4401
4655
|
server.sendResourceListChanged();
|
|
4402
|
-
checkWindowsBashAvailability();
|
|
4403
4656
|
try {
|
|
4404
4657
|
if (transport && server) {
|
|
4405
4658
|
await server.sendLoggingMessage({
|