@leo000001/claude-code-mcp 2.8.1 → 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 +6 -0
- package/README.md +112 -85
- package/dist/index.js +320 -85
- 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,26 +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",
|
|
3439
3601
|
"",
|
|
3440
|
-
"Usage reminders:",
|
|
3441
|
-
"- 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.",
|
|
3442
|
-
"- 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.",
|
|
3443
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.",
|
|
3444
3604
|
"",
|
|
3445
|
-
"
|
|
3446
|
-
"
|
|
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.",
|
|
3447
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`.",
|
|
3448
3617
|
"- Store `nextCursor` and feed it back into the next `claude_code_check(action='poll')`; otherwise you will keep replaying old events.",
|
|
3449
3618
|
"- On Windows, set `CLAUDE_CODE_GIT_BASH_PATH` or Claude Code may fail before the session starts.",
|
|
3450
3619
|
"- If `decision='allow_for_session'` still shows a permission request, inspect `actions[].suggestions` / `blockedPath`; directory access may need a more specific permission update.",
|
|
3451
3620
|
"",
|
|
3452
3621
|
"Notes:",
|
|
3453
|
-
"- `respond_user_input` is not supported
|
|
3454
|
-
"- `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.",
|
|
3455
3623
|
"- OpenCode/Codex-style clients usually work best when they store `sessionId` + `nextCursor` and answer approvals with `decision=allow_for_session`.",
|
|
3456
3624
|
"- Prefer `responseMode='delta_compact'` for high-frequency polling."
|
|
3457
3625
|
].join("\n"),
|
|
@@ -3511,6 +3679,7 @@ function registerResources(server, deps) {
|
|
|
3511
3679
|
const diskResumeEnabled = process.env.CLAUDE_CODE_MCP_ALLOW_DISK_RESUME === "1";
|
|
3512
3680
|
const resumeSecretConfigured = typeof process.env.CLAUDE_CODE_MCP_RESUME_SECRET === "string" && process.env.CLAUDE_CODE_MCP_RESUME_SECRET.trim() !== "";
|
|
3513
3681
|
const runtimeToolStats = deps.sessionManager.getRuntimeToolStats();
|
|
3682
|
+
const defaultClaudeExecutable = resolveDefaultClaudeExecutable();
|
|
3514
3683
|
const toolCatalogCount = deps.toolCache.getTools().length;
|
|
3515
3684
|
const detectedMismatches = [];
|
|
3516
3685
|
if (runtimeToolStats.sessionsWithInitTools > 0 && runtimeToolStats.runtimeDiscoveredUniqueCount < toolCatalogCount) {
|
|
@@ -3539,6 +3708,12 @@ function registerResources(server, deps) {
|
|
|
3539
3708
|
enabled: diskResumeEnabled,
|
|
3540
3709
|
resumeSecretConfigured
|
|
3541
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
|
+
},
|
|
3542
3717
|
features: {
|
|
3543
3718
|
resources: true,
|
|
3544
3719
|
resourceTemplates: true,
|
|
@@ -3565,8 +3740,10 @@ function registerResources(server, deps) {
|
|
|
3565
3740
|
},
|
|
3566
3741
|
guidance: [
|
|
3567
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.",
|
|
3568
3744
|
"Use allowedTools/disallowedTools only with exact runtime tool names.",
|
|
3569
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.",
|
|
3570
3747
|
"This server assumes MCP client and server run on the same machine/platform.",
|
|
3571
3748
|
"For high-frequency status checks, prefer responseMode='delta_compact'.",
|
|
3572
3749
|
"respond_user_input is not supported on this backend; use poll/respond_permission flow."
|
|
@@ -3735,7 +3912,8 @@ function registerResources(server, deps) {
|
|
|
3735
3912
|
detectedMismatches: [],
|
|
3736
3913
|
recommendations: [
|
|
3737
3914
|
"Prefer responseMode='delta_compact' for fast status loops.",
|
|
3738
|
-
"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."
|
|
3739
3917
|
]
|
|
3740
3918
|
};
|
|
3741
3919
|
}
|
|
@@ -3746,7 +3924,8 @@ function registerResources(server, deps) {
|
|
|
3746
3924
|
recommendations: [
|
|
3747
3925
|
"Use resources and resource templates for low-latency diagnostics.",
|
|
3748
3926
|
"Use allowedTools/disallowedTools with exact runtime names.",
|
|
3749
|
-
"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."
|
|
3750
3929
|
]
|
|
3751
3930
|
};
|
|
3752
3931
|
}
|
|
@@ -3767,7 +3946,8 @@ function registerResources(server, deps) {
|
|
|
3767
3946
|
detectedMismatches: [],
|
|
3768
3947
|
recommendations: [
|
|
3769
3948
|
"Persist nextCursor and de-duplicate by event.id.",
|
|
3770
|
-
"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."
|
|
3771
3951
|
]
|
|
3772
3952
|
};
|
|
3773
3953
|
})();
|
|
@@ -3795,7 +3975,7 @@ function registerResources(server, deps) {
|
|
|
3795
3975
|
}
|
|
3796
3976
|
|
|
3797
3977
|
// src/server.ts
|
|
3798
|
-
var SERVER_VERSION = true ? "2.8.
|
|
3978
|
+
var SERVER_VERSION = true ? "2.8.3" : "0.0.0-dev";
|
|
3799
3979
|
function createServerContext(serverCwd) {
|
|
3800
3980
|
const sessionManager = new SessionManager();
|
|
3801
3981
|
const server = new McpServer(
|
|
@@ -3803,7 +3983,7 @@ function createServerContext(serverCwd) {
|
|
|
3803
3983
|
name: "claude-code-mcp",
|
|
3804
3984
|
version: SERVER_VERSION,
|
|
3805
3985
|
title: "Claude Code MCP",
|
|
3806
|
-
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.",
|
|
3807
3987
|
websiteUrl: "https://github.com/xihuai18/claude-code-mcp",
|
|
3808
3988
|
icons: []
|
|
3809
3989
|
},
|
|
@@ -3833,11 +4013,13 @@ function createServerContext(serverCwd) {
|
|
|
3833
4013
|
const agentDefinitionSchema = z.object({
|
|
3834
4014
|
description: z.string(),
|
|
3835
4015
|
prompt: z.string(),
|
|
3836
|
-
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"),
|
|
3837
4017
|
disallowedTools: z.array(z.string()).optional().describe("Default: none"),
|
|
3838
4018
|
model: z.string().optional().describe("Default: inherit"),
|
|
3839
4019
|
maxTurns: z.number().int().positive().optional().describe("Default: none"),
|
|
3840
|
-
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
|
+
),
|
|
3841
4023
|
skills: z.array(z.string()).optional().describe("Default: none"),
|
|
3842
4024
|
criticalSystemReminder_EXPERIMENTAL: z.string().optional().describe("Default: none")
|
|
3843
4025
|
});
|
|
@@ -3860,7 +4042,7 @@ function createServerContext(serverCwd) {
|
|
|
3860
4042
|
z.object({ type: z.literal("adaptive") }),
|
|
3861
4043
|
z.object({
|
|
3862
4044
|
type: z.literal("enabled"),
|
|
3863
|
-
budgetTokens: z.number().int().positive()
|
|
4045
|
+
budgetTokens: z.number().int().positive().optional()
|
|
3864
4046
|
}),
|
|
3865
4047
|
z.object({ type: z.literal("disabled") })
|
|
3866
4048
|
]);
|
|
@@ -3871,51 +4053,71 @@ function createServerContext(serverCwd) {
|
|
|
3871
4053
|
schema: z.record(z.string(), z.unknown())
|
|
3872
4054
|
});
|
|
3873
4055
|
const sharedOptionFieldsSchemaShape = {
|
|
3874
|
-
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
|
+
),
|
|
3875
4059
|
persistSession: z.boolean().optional().describe("Default: true"),
|
|
3876
|
-
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"),
|
|
3877
4061
|
agent: z.string().optional().describe("Default: none"),
|
|
3878
4062
|
maxBudgetUsd: z.number().positive().optional().describe("Default: none"),
|
|
3879
4063
|
betas: z.array(z.string()).optional().describe("Default: none"),
|
|
3880
4064
|
additionalDirectories: z.array(z.string()).optional().describe("Default: none"),
|
|
3881
|
-
outputFormat: outputFormatSchema.optional().describe("Default: none"),
|
|
3882
|
-
pathToClaudeCodeExecutable: z.string().optional().describe(
|
|
3883
|
-
|
|
3884
|
-
|
|
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
|
+
),
|
|
3885
4073
|
fallbackModel: z.string().optional().describe("Default: none"),
|
|
3886
4074
|
enableFileCheckpointing: z.boolean().optional().describe("Default: false"),
|
|
3887
|
-
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
|
+
),
|
|
3888
4078
|
includePartialMessages: z.boolean().optional().describe("Default: false"),
|
|
3889
4079
|
promptSuggestions: z.boolean().optional().describe("Default: false"),
|
|
3890
4080
|
agentProgressSummaries: z.boolean().optional().describe("Default: false"),
|
|
3891
4081
|
strictMcpConfig: z.boolean().optional().describe("Default: false"),
|
|
3892
|
-
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
|
+
),
|
|
3893
4085
|
settingSources: z.array(z.enum(["user", "project", "local"])).optional().describe("Default: ['user','project','local']. []=isolation"),
|
|
3894
4086
|
debug: z.boolean().optional().describe("Default: false"),
|
|
3895
|
-
debugFile: z.string().optional().describe("Default: none"),
|
|
3896
|
-
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
|
+
)
|
|
3897
4091
|
};
|
|
3898
4092
|
const advancedOptionFieldsSchemaShape = {
|
|
3899
4093
|
...sharedOptionFieldsSchemaShape
|
|
3900
4094
|
};
|
|
3901
4095
|
const diskResumeOptionFieldsSchemaShape = {
|
|
3902
4096
|
...sharedOptionFieldsSchemaShape,
|
|
3903
|
-
effort: effortOptionSchema.describe(
|
|
3904
|
-
|
|
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
|
+
)
|
|
3905
4103
|
};
|
|
3906
4104
|
const advancedOptionsSchema = z.object({
|
|
3907
4105
|
...advancedOptionFieldsSchemaShape,
|
|
3908
|
-
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")
|
|
3909
4107
|
}).optional().describe("Default: none");
|
|
3910
4108
|
const diskResumeConfigSchema = z.object({
|
|
3911
4109
|
resumeToken: z.string(),
|
|
3912
4110
|
cwd: z.string(),
|
|
3913
|
-
allowedTools: z.array(z.string()).optional().describe("Default: []"),
|
|
3914
|
-
disallowedTools: z.array(z.string()).optional().describe("Default: []"),
|
|
3915
|
-
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
|
+
),
|
|
3916
4116
|
maxTurns: z.number().int().positive().optional().describe("Default: SDK"),
|
|
3917
4117
|
model: z.string().optional().describe("Default: SDK"),
|
|
3918
|
-
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
|
+
),
|
|
3919
4121
|
resumeSessionAt: z.string().optional().describe("Default: none"),
|
|
3920
4122
|
...diskResumeOptionFieldsSchemaShape
|
|
3921
4123
|
}).optional().describe("Default: none");
|
|
@@ -3977,18 +4179,28 @@ function createServerContext(serverCwd) {
|
|
|
3977
4179
|
description: buildInternalToolsDescription(toolCache.getTools()),
|
|
3978
4180
|
inputSchema: {
|
|
3979
4181
|
prompt: z.string().describe(
|
|
3980
|
-
"Prompt.
|
|
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."
|
|
3981
4183
|
),
|
|
3982
4184
|
cwd: z.string().optional().describe("Working dir. Default: server cwd"),
|
|
3983
|
-
allowedTools: z.array(z.string()).optional().describe(
|
|
3984
|
-
|
|
3985
|
-
|
|
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."),
|
|
3986
4190
|
maxTurns: z.number().int().positive().optional().describe("Default: SDK"),
|
|
3987
4191
|
model: z.string().optional().describe("Default: SDK"),
|
|
3988
|
-
effort: effortOptionSchema.describe(
|
|
3989
|
-
|
|
3990
|
-
|
|
3991
|
-
|
|
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
|
+
),
|
|
3992
4204
|
advanced: advancedOptionsSchema
|
|
3993
4205
|
},
|
|
3994
4206
|
outputSchema: startResultSchema,
|
|
@@ -4042,18 +4254,26 @@ function createServerContext(serverCwd) {
|
|
|
4042
4254
|
server.registerTool(
|
|
4043
4255
|
"claude_code_reply",
|
|
4044
4256
|
{
|
|
4045
|
-
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;
|
|
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.",
|
|
4046
4258
|
inputSchema: {
|
|
4047
4259
|
sessionId: z.string().describe(
|
|
4048
|
-
"Session ID from
|
|
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."
|
|
4049
4261
|
),
|
|
4050
4262
|
prompt: z.string().describe("Follow-up prompt for the existing session."),
|
|
4051
4263
|
forkSession: z.boolean().optional().describe("Default: false"),
|
|
4052
|
-
effort: effortOptionSchema.describe(
|
|
4053
|
-
|
|
4054
|
-
|
|
4055
|
-
|
|
4056
|
-
|
|
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
|
+
)
|
|
4057
4277
|
},
|
|
4058
4278
|
outputSchema: startResultSchema,
|
|
4059
4279
|
annotations: {
|
|
@@ -4102,9 +4322,11 @@ function createServerContext(serverCwd) {
|
|
|
4102
4322
|
{
|
|
4103
4323
|
description: "List, inspect, cancel, or interrupt sessions.",
|
|
4104
4324
|
inputSchema: {
|
|
4105
|
-
action: z.enum(SESSION_ACTIONS),
|
|
4106
|
-
sessionId: z.string().optional().describe("Required for get/cancel/interrupt"),
|
|
4107
|
-
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
|
+
)
|
|
4108
4330
|
},
|
|
4109
4331
|
outputSchema: sessionResultSchema,
|
|
4110
4332
|
annotations: {
|
|
@@ -4150,21 +4372,31 @@ function createServerContext(serverCwd) {
|
|
|
4150
4372
|
server.registerTool(
|
|
4151
4373
|
"claude_code_check",
|
|
4152
4374
|
{
|
|
4153
|
-
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.",
|
|
4154
4376
|
inputSchema: {
|
|
4155
|
-
action: z.enum(CHECK_ACTIONS)
|
|
4156
|
-
|
|
4157
|
-
|
|
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
|
+
),
|
|
4158
4384
|
responseMode: z.enum(CHECK_RESPONSE_MODES).optional().describe(
|
|
4159
|
-
"Default: 'minimal'. Use 'delta_compact' for lightweight polling
|
|
4385
|
+
"Default: 'minimal'. Use 'delta_compact' for lightweight high-frequency polling; use 'full' mainly for diagnostics."
|
|
4160
4386
|
),
|
|
4161
4387
|
maxEvents: z.number().int().positive().optional().describe("Default: 200 (minimal), unlimited (full/delta_compact)"),
|
|
4162
|
-
requestId: z.string().optional().describe("Default: none"),
|
|
4163
|
-
decision: z.enum(["allow", "deny", "allow_for_session"]).optional().describe(
|
|
4164
|
-
|
|
4165
|
-
|
|
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
|
+
),
|
|
4166
4396
|
pollOptions: z.object({
|
|
4167
|
-
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
|
+
),
|
|
4168
4400
|
includeEvents: z.boolean().optional().describe("Default: true"),
|
|
4169
4401
|
includeActions: z.boolean().optional().describe("Default: true"),
|
|
4170
4402
|
includeResult: z.boolean().optional().describe("Default: true"),
|
|
@@ -4174,11 +4406,13 @@ function createServerContext(serverCwd) {
|
|
|
4174
4406
|
includeTerminalEvents: z.boolean().optional().describe("Default: full=true, minimal/delta_compact=false"),
|
|
4175
4407
|
includeProgressEvents: z.boolean().optional().describe("Default: full=true, minimal/delta_compact=false"),
|
|
4176
4408
|
maxBytes: z.number().int().positive().optional().describe("Default: unlimited")
|
|
4177
|
-
}).optional().describe("Default: none"),
|
|
4409
|
+
}).optional().describe("Default: none. Advanced polling payload controls for action='poll'."),
|
|
4178
4410
|
permissionOptions: z.object({
|
|
4179
4411
|
updatedInput: z.record(z.string(), z.unknown()).optional().describe("Default: none"),
|
|
4180
4412
|
updatedPermissions: z.array(z.record(z.string(), z.unknown())).optional().describe("Default: none")
|
|
4181
|
-
}).optional().describe(
|
|
4413
|
+
}).optional().describe(
|
|
4414
|
+
"Default: none. Advanced permission response overrides for action='respond_permission'."
|
|
4415
|
+
)
|
|
4182
4416
|
},
|
|
4183
4417
|
outputSchema: checkResultSchema,
|
|
4184
4418
|
annotations: {
|
|
@@ -4414,10 +4648,11 @@ async function main() {
|
|
|
4414
4648
|
process.stdin.on("error", handleStdinError);
|
|
4415
4649
|
process.stdin.on("end", onStdinEnd);
|
|
4416
4650
|
process.stdin.on("close", onStdinClose);
|
|
4651
|
+
checkWindowsBashAvailability();
|
|
4652
|
+
checkDefaultClaudeExecutableAvailability();
|
|
4417
4653
|
await server.connect(transport);
|
|
4418
4654
|
server.sendToolListChanged();
|
|
4419
4655
|
server.sendResourceListChanged();
|
|
4420
|
-
checkWindowsBashAvailability();
|
|
4421
4656
|
try {
|
|
4422
4657
|
if (transport && server) {
|
|
4423
4658
|
await server.sendLoggingMessage({
|