@chrischall/gemini-mcp 2.1.1 → 2.1.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/.claude-plugin/marketplace.json +2 -2
- package/.claude-plugin/plugin.json +1 -1
- package/dist/bundle.js +394 -110
- package/dist/version.js +1 -1
- package/package.json +3 -3
- package/server.json +2 -2
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
},
|
|
8
8
|
"metadata": {
|
|
9
9
|
"description": "MCP server for Google Gemini image generation and editing — generate and edit images via the Gemini API",
|
|
10
|
-
"version": "2.1.
|
|
10
|
+
"version": "2.1.3"
|
|
11
11
|
},
|
|
12
12
|
"plugins": [
|
|
13
13
|
{
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
"displayName": "Gemini Images",
|
|
16
16
|
"source": "./",
|
|
17
17
|
"description": "Generate and edit images with Google Gemini image models (Nano Banana / Nano Banana Pro) via natural language prompts",
|
|
18
|
-
"version": "2.1.
|
|
18
|
+
"version": "2.1.3",
|
|
19
19
|
"author": {
|
|
20
20
|
"name": "Chris Hall"
|
|
21
21
|
},
|
package/dist/bundle.js
CHANGED
|
@@ -41,6 +41,41 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
41
41
|
mod
|
|
42
42
|
));
|
|
43
43
|
|
|
44
|
+
// node_modules/@chrischall/mcp-utils/dist/cancel/index.js
|
|
45
|
+
import { AsyncLocalStorage } from "node:async_hooks";
|
|
46
|
+
function withCallSignal(signal, fn, request) {
|
|
47
|
+
return signal ? storage.run({ signal, ...request ? { request } : {} }, fn) : fn();
|
|
48
|
+
}
|
|
49
|
+
function currentCallSignal() {
|
|
50
|
+
return storage.getStore()?.signal;
|
|
51
|
+
}
|
|
52
|
+
function withAmbientCancellation(own2) {
|
|
53
|
+
const ambient = currentCallSignal();
|
|
54
|
+
if (!ambient)
|
|
55
|
+
return own2;
|
|
56
|
+
if (!own2)
|
|
57
|
+
return ambient;
|
|
58
|
+
return AbortSignal.any([own2, ambient]);
|
|
59
|
+
}
|
|
60
|
+
var storage;
|
|
61
|
+
var init_cancel = __esm({
|
|
62
|
+
"node_modules/@chrischall/mcp-utils/dist/cancel/index.js"() {
|
|
63
|
+
storage = new AsyncLocalStorage();
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
// node_modules/@chrischall/mcp-utils/dist/caller/index.js
|
|
68
|
+
import { AsyncLocalStorage as AsyncLocalStorage2 } from "node:async_hooks";
|
|
69
|
+
function withCallerCapabilities(capabilities, fn) {
|
|
70
|
+
return capabilities ? storage2.run(capabilities, fn) : fn();
|
|
71
|
+
}
|
|
72
|
+
var storage2;
|
|
73
|
+
var init_caller = __esm({
|
|
74
|
+
"node_modules/@chrischall/mcp-utils/dist/caller/index.js"() {
|
|
75
|
+
storage2 = new AsyncLocalStorage2();
|
|
76
|
+
}
|
|
77
|
+
});
|
|
78
|
+
|
|
44
79
|
// node_modules/@modelcontextprotocol/server/dist/chunk-Br0eD_fh.mjs
|
|
45
80
|
var __create2, __defProp2, __getOwnPropDesc2, __getOwnPropNames2, __getProtoOf2, __hasOwnProp2, __commonJSMin, __exportAll, __copyProps2, __toESM2;
|
|
46
81
|
var init_chunk_Br0eD_fh = __esm({
|
|
@@ -4926,7 +4961,7 @@ var require_memoizer = __commonJS({
|
|
|
4926
4961
|
var NONE2 = 0;
|
|
4927
4962
|
var ASSUMED2 = 1;
|
|
4928
4963
|
var PROVEN2 = 2;
|
|
4929
|
-
function isRecursive2(inst, stack,
|
|
4964
|
+
function isRecursive2(inst, stack, resolve4) {
|
|
4930
4965
|
const cached2 = recursive2.get(inst);
|
|
4931
4966
|
if (cached2 !== void 0)
|
|
4932
4967
|
return cached2 ? PROVEN2 : NONE2;
|
|
@@ -4936,7 +4971,7 @@ var require_memoizer = __commonJS({
|
|
|
4936
4971
|
let result = NONE2;
|
|
4937
4972
|
const check2 = (child) => {
|
|
4938
4973
|
if (result !== PROVEN2 && child?._zod) {
|
|
4939
|
-
const answer = isRecursive2(child, stack,
|
|
4974
|
+
const answer = isRecursive2(child, stack, resolve4);
|
|
4940
4975
|
if (answer > result)
|
|
4941
4976
|
result = answer;
|
|
4942
4977
|
}
|
|
@@ -4947,7 +4982,7 @@ var require_memoizer = __commonJS({
|
|
|
4947
4982
|
const desc = Object.getOwnPropertyDescriptor(sh, key);
|
|
4948
4983
|
if (spread && !desc.enumerable)
|
|
4949
4984
|
continue;
|
|
4950
|
-
const child = desc.get ? ASSUMED2 : desc.value?._zod ? isRecursive2(desc.value, stack,
|
|
4985
|
+
const child = desc.get ? ASSUMED2 : desc.value?._zod ? isRecursive2(desc.value, stack, resolve4) : NONE2;
|
|
4951
4986
|
if (child > answer)
|
|
4952
4987
|
answer = child;
|
|
4953
4988
|
}
|
|
@@ -5011,7 +5046,7 @@ var require_memoizer = __commonJS({
|
|
|
5011
5046
|
break;
|
|
5012
5047
|
// `$ZodLazy` caches its inner on the def, so a resolved edge is followed exactly
|
|
5013
5048
|
case "lazy": {
|
|
5014
|
-
const inner = def._cachedInner ?? (
|
|
5049
|
+
const inner = def._cachedInner ?? (resolve4 ? inst._zod.innerType : void 0);
|
|
5015
5050
|
merge2(inner ? isRecursive2(inner, stack, false) : ASSUMED2);
|
|
5016
5051
|
break;
|
|
5017
5052
|
}
|
|
@@ -26845,14 +26880,14 @@ function inputRequiredRoundsExceededMessage(method, maxRounds) {
|
|
|
26845
26880
|
return `Multi-round-trip request '${method}' still required input after ${maxRounds} rounds (inputRequired.maxRounds)`;
|
|
26846
26881
|
}
|
|
26847
26882
|
function sleep(ms, signal) {
|
|
26848
|
-
return new Promise((
|
|
26883
|
+
return new Promise((resolve4, reject) => {
|
|
26849
26884
|
if (signal?.aborted) {
|
|
26850
26885
|
reject(signal.reason instanceof SdkError ? signal.reason : new SdkError(SdkErrorCode.RequestTimeout, String(signal.reason)));
|
|
26851
26886
|
return;
|
|
26852
26887
|
}
|
|
26853
26888
|
const timer = setTimeout(() => {
|
|
26854
26889
|
signal?.removeEventListener("abort", onAbort);
|
|
26855
|
-
|
|
26890
|
+
resolve4();
|
|
26856
26891
|
}, ms);
|
|
26857
26892
|
const onAbort = () => {
|
|
26858
26893
|
clearTimeout(timer);
|
|
@@ -28648,7 +28683,7 @@ var init_src_CX2iR2pK = __esm({
|
|
|
28648
28683
|
const flowStartedAt = Date.now();
|
|
28649
28684
|
let onAbort;
|
|
28650
28685
|
let cleanupMessageId;
|
|
28651
|
-
return new Promise((
|
|
28686
|
+
return new Promise((resolve4, reject) => {
|
|
28652
28687
|
const earlyReject = (error62) => {
|
|
28653
28688
|
reject(error62);
|
|
28654
28689
|
};
|
|
@@ -28716,7 +28751,7 @@ var init_src_CX2iR2pK = __esm({
|
|
|
28716
28751
|
}
|
|
28717
28752
|
if (decoded.kind === "invalid") return reject(decoded.error);
|
|
28718
28753
|
if (decoded.kind === "input_required") {
|
|
28719
|
-
if (options?.allowInputRequired === true) return
|
|
28754
|
+
if (options?.allowInputRequired === true) return resolve4(manualInputRequiredValue(decoded));
|
|
28720
28755
|
const flow = {
|
|
28721
28756
|
codec: codec2,
|
|
28722
28757
|
request,
|
|
@@ -28728,11 +28763,11 @@ var init_src_CX2iR2pK = __esm({
|
|
|
28728
28763
|
params
|
|
28729
28764
|
}, resultSchema, legOptions)
|
|
28730
28765
|
};
|
|
28731
|
-
return
|
|
28766
|
+
return resolve4(this._resolveNonCompleteResult(decoded, flow));
|
|
28732
28767
|
}
|
|
28733
28768
|
const result = decoded.result;
|
|
28734
28769
|
validateStandardSchema(resultSchema, result).then((parseResult) => {
|
|
28735
|
-
if (parseResult.success)
|
|
28770
|
+
if (parseResult.success) resolve4(parseResult.data);
|
|
28736
28771
|
else reject(new SdkError(SdkErrorCode.InvalidResult, `Invalid result for ${request.method}: ${parseResult.error}`));
|
|
28737
28772
|
}, reject);
|
|
28738
28773
|
});
|
|
@@ -31548,7 +31583,7 @@ var init_ajvProvider_CEoC_sr = __esm({
|
|
|
31548
31583
|
ref = (0, resolve_1.resolveUrl)(this.opts.uriResolver, baseId, ref);
|
|
31549
31584
|
const schOrFunc = root.refs[ref];
|
|
31550
31585
|
if (schOrFunc) return schOrFunc;
|
|
31551
|
-
let _sch =
|
|
31586
|
+
let _sch = resolve4.call(this, root, ref);
|
|
31552
31587
|
if (_sch === void 0) {
|
|
31553
31588
|
const schema = (_a3 = root.localRefs) === null || _a3 === void 0 ? void 0 : _a3[ref];
|
|
31554
31589
|
const { schemaId } = this.opts;
|
|
@@ -31574,7 +31609,7 @@ var init_ajvProvider_CEoC_sr = __esm({
|
|
|
31574
31609
|
function sameSchemaEnv(s1, s2) {
|
|
31575
31610
|
return s1.schema === s2.schema && s1.root === s2.root && s1.baseId === s2.baseId;
|
|
31576
31611
|
}
|
|
31577
|
-
function
|
|
31612
|
+
function resolve4(root, ref) {
|
|
31578
31613
|
let sch;
|
|
31579
31614
|
while (typeof (sch = this.refs[ref]) == "string") ref = sch;
|
|
31580
31615
|
return sch || this.schemas[ref] || resolveSchema.call(this, root, ref);
|
|
@@ -32024,47 +32059,47 @@ var init_ajvProvider_CEoC_sr = __esm({
|
|
|
32024
32059
|
else if (typeof uri === "object") uri = parse3(serialize(uri, options), options);
|
|
32025
32060
|
return uri;
|
|
32026
32061
|
}
|
|
32027
|
-
function
|
|
32062
|
+
function resolve4(baseURI, relativeURI, options) {
|
|
32028
32063
|
const schemelessOptions = options ? Object.assign({ scheme: "null" }, options) : { scheme: "null" };
|
|
32029
32064
|
const resolved = resolveComponent(parse3(baseURI, schemelessOptions), parse3(relativeURI, schemelessOptions), schemelessOptions, true);
|
|
32030
32065
|
schemelessOptions.skipEscape = true;
|
|
32031
32066
|
return serialize(resolved, schemelessOptions);
|
|
32032
32067
|
}
|
|
32033
|
-
function resolveComponent(base,
|
|
32068
|
+
function resolveComponent(base, relative2, options, skipNormalization) {
|
|
32034
32069
|
const target = {};
|
|
32035
32070
|
if (!skipNormalization) {
|
|
32036
32071
|
base = parse3(serialize(base, options), options);
|
|
32037
|
-
|
|
32072
|
+
relative2 = parse3(serialize(relative2, options), options);
|
|
32038
32073
|
}
|
|
32039
32074
|
options = options || {};
|
|
32040
|
-
if (!options.tolerant &&
|
|
32041
|
-
target.scheme =
|
|
32042
|
-
target.userinfo =
|
|
32043
|
-
target.host =
|
|
32044
|
-
target.port =
|
|
32045
|
-
target.path = removeDotSegments(
|
|
32046
|
-
target.query =
|
|
32075
|
+
if (!options.tolerant && relative2.scheme) {
|
|
32076
|
+
target.scheme = relative2.scheme;
|
|
32077
|
+
target.userinfo = relative2.userinfo;
|
|
32078
|
+
target.host = relative2.host;
|
|
32079
|
+
target.port = relative2.port;
|
|
32080
|
+
target.path = removeDotSegments(relative2.path || "");
|
|
32081
|
+
target.query = relative2.query;
|
|
32047
32082
|
} else {
|
|
32048
|
-
if (
|
|
32049
|
-
target.userinfo =
|
|
32050
|
-
target.host =
|
|
32051
|
-
target.port =
|
|
32052
|
-
target.path = removeDotSegments(
|
|
32053
|
-
target.query =
|
|
32083
|
+
if (relative2.userinfo !== void 0 || relative2.host !== void 0 || relative2.port !== void 0) {
|
|
32084
|
+
target.userinfo = relative2.userinfo;
|
|
32085
|
+
target.host = relative2.host;
|
|
32086
|
+
target.port = relative2.port;
|
|
32087
|
+
target.path = removeDotSegments(relative2.path || "");
|
|
32088
|
+
target.query = relative2.query;
|
|
32054
32089
|
} else {
|
|
32055
|
-
if (!
|
|
32090
|
+
if (!relative2.path) {
|
|
32056
32091
|
target.path = base.path;
|
|
32057
|
-
if (
|
|
32092
|
+
if (relative2.query !== void 0) target.query = relative2.query;
|
|
32058
32093
|
else target.query = base.query;
|
|
32059
32094
|
} else {
|
|
32060
|
-
if (
|
|
32095
|
+
if (relative2.path[0] === "/") target.path = removeDotSegments(relative2.path);
|
|
32061
32096
|
else {
|
|
32062
|
-
if ((base.userinfo !== void 0 || base.host !== void 0 || base.port !== void 0) && !base.path) target.path = "/" +
|
|
32063
|
-
else if (!base.path) target.path =
|
|
32064
|
-
else target.path = base.path.slice(0, base.path.lastIndexOf("/") + 1) +
|
|
32097
|
+
if ((base.userinfo !== void 0 || base.host !== void 0 || base.port !== void 0) && !base.path) target.path = "/" + relative2.path;
|
|
32098
|
+
else if (!base.path) target.path = relative2.path;
|
|
32099
|
+
else target.path = base.path.slice(0, base.path.lastIndexOf("/") + 1) + relative2.path;
|
|
32065
32100
|
target.path = removeDotSegments(target.path);
|
|
32066
32101
|
}
|
|
32067
|
-
target.query =
|
|
32102
|
+
target.query = relative2.query;
|
|
32068
32103
|
}
|
|
32069
32104
|
target.userinfo = base.userinfo;
|
|
32070
32105
|
target.host = base.host;
|
|
@@ -32072,7 +32107,7 @@ var init_ajvProvider_CEoC_sr = __esm({
|
|
|
32072
32107
|
}
|
|
32073
32108
|
target.scheme = base.scheme;
|
|
32074
32109
|
}
|
|
32075
|
-
target.fragment =
|
|
32110
|
+
target.fragment = relative2.fragment;
|
|
32076
32111
|
return target;
|
|
32077
32112
|
}
|
|
32078
32113
|
function equal(uriA, uriB, options) {
|
|
@@ -32198,7 +32233,7 @@ var init_ajvProvider_CEoC_sr = __esm({
|
|
|
32198
32233
|
const fastUri = {
|
|
32199
32234
|
SCHEMES,
|
|
32200
32235
|
normalize,
|
|
32201
|
-
resolve:
|
|
32236
|
+
resolve: resolve4,
|
|
32202
32237
|
resolveComponent,
|
|
32203
32238
|
equal,
|
|
32204
32239
|
serialize,
|
|
@@ -37890,7 +37925,7 @@ var init_stdio = __esm({
|
|
|
37890
37925
|
}
|
|
37891
37926
|
send(message) {
|
|
37892
37927
|
if (this._closed) return Promise.reject(/* @__PURE__ */ new Error("StdioServerTransport is closed"));
|
|
37893
|
-
return new Promise((
|
|
37928
|
+
return new Promise((resolve4, reject) => {
|
|
37894
37929
|
const json2 = serializeMessage(message);
|
|
37895
37930
|
let settled = false;
|
|
37896
37931
|
const onError = (error62) => {
|
|
@@ -37905,14 +37940,14 @@ var init_stdio = __esm({
|
|
|
37905
37940
|
settled = true;
|
|
37906
37941
|
this._stdout.off("error", onError);
|
|
37907
37942
|
this._stdout.off("drain", onDrain);
|
|
37908
|
-
|
|
37943
|
+
resolve4();
|
|
37909
37944
|
};
|
|
37910
37945
|
this._stdout.once("error", onError);
|
|
37911
37946
|
if (this._stdout.write(json2)) {
|
|
37912
37947
|
if (settled) return;
|
|
37913
37948
|
settled = true;
|
|
37914
37949
|
this._stdout.off("error", onError);
|
|
37915
|
-
|
|
37950
|
+
resolve4();
|
|
37916
37951
|
} else if (!settled) this._stdout.once("drain", onDrain);
|
|
37917
37952
|
});
|
|
37918
37953
|
}
|
|
@@ -37966,14 +38001,14 @@ var init_stdio = __esm({
|
|
|
37966
38001
|
*/
|
|
37967
38002
|
async whenRequestsAnswered(timeoutMs) {
|
|
37968
38003
|
if (this._closed || this._pendingRequests.size === 0) return true;
|
|
37969
|
-
return await new Promise((
|
|
38004
|
+
return await new Promise((resolve4) => {
|
|
37970
38005
|
const waiter = () => {
|
|
37971
38006
|
clearTimeout(timer);
|
|
37972
|
-
|
|
38007
|
+
resolve4(true);
|
|
37973
38008
|
};
|
|
37974
38009
|
const timer = setTimeout(() => {
|
|
37975
38010
|
this._drainWaiters = this._drainWaiters.filter((pending) => pending !== waiter);
|
|
37976
|
-
|
|
38011
|
+
resolve4(false);
|
|
37977
38012
|
}, timeoutMs);
|
|
37978
38013
|
this._drainWaiters.push(waiter);
|
|
37979
38014
|
});
|
|
@@ -38013,7 +38048,7 @@ var init_dist = __esm({
|
|
|
38013
38048
|
|
|
38014
38049
|
// node_modules/@chrischall/mcp-utils/dist/errors/index.js
|
|
38015
38050
|
function redactSecrets(text) {
|
|
38016
|
-
return text.replace(BEARER_RE, "$1[REDACTED]").replace(BASIC_AUTH_RE, "$1[REDACTED]").replace(SET_COOKIE_RE, "$1$2=[REDACTED]").replace(COOKIE_HEADER_RE, (_m, prefix, pairs) => `${prefix}${pairs.replace(/=[^;,\s]*/g, "=[REDACTED]")}`).replace(API_KEY_RE, "[REDACTED]").replace(QUERY_SECRET_RE, "$1[REDACTED]").replace(AWS_SIGV4_RE, "$1[REDACTED]").replace(JSON_SECRET_DQ_RE, "$1[REDACTED]$2").replace(JSON_SECRET_SQ_RE, "$1[REDACTED]$2").replace(JWT_RE, "[REDACTED]");
|
|
38051
|
+
return text.replace(BEARER_RE, "$1[REDACTED]").replace(BASIC_AUTH_RE, "$1[REDACTED]").replace(SET_COOKIE_RE, "$1$2=[REDACTED]").replace(COOKIE_HEADER_RE, (_m, prefix, pairs) => `${prefix}${pairs.replace(/=[^;,\s]*/g, "=[REDACTED]")}`).replace(API_KEY_RE, "[REDACTED]").replace(HEADER_SECRET_RE, "$1[REDACTED]").replace(QUERY_SECRET_RE, "$1[REDACTED]").replace(OAUTH_CODE_RE, "$1[REDACTED]").replace(FORM_PASSWORD_RE, "$1[REDACTED]").replace(AWS_SIGV4_RE, "$1[REDACTED]").replace(JSON_SECRET_DQ_RE, "$1[REDACTED]$2").replace(JSON_SECRET_SQ_RE, "$1[REDACTED]$2").replace(JWT_RE, "[REDACTED]");
|
|
38017
38052
|
}
|
|
38018
38053
|
function truncateErrorMessage(text, max = DEFAULT_ERROR_MESSAGE_MAX) {
|
|
38019
38054
|
const str = text === null || text === void 0 ? "" : String(text);
|
|
@@ -38027,7 +38062,7 @@ function messageOf(err) {
|
|
|
38027
38062
|
return err.message;
|
|
38028
38063
|
return String(err);
|
|
38029
38064
|
}
|
|
38030
|
-
var DEFAULT_ERROR_MESSAGE_MAX, McpToolError, BEARER_RE, JWT_RE, BASIC_AUTH_RE, SET_COOKIE_RE, COOKIE_HEADER_RE, API_KEY_RE, QUERY_SECRET_RE, AWS_SIGV4_RE, JSON_SECRET_KEYS, JSON_SECRET_DQ_RE, JSON_SECRET_SQ_RE;
|
|
38065
|
+
var DEFAULT_ERROR_MESSAGE_MAX, McpToolError, BEARER_RE, JWT_RE, BASIC_AUTH_RE, SET_COOKIE_RE, COOKIE_HEADER_RE, API_KEY_RE, QUERY_SECRET_RE, OAUTH_CODE_RE, FORM_PASSWORD_RE, HEADER_SECRET_RE, AWS_SIGV4_RE, JSON_SECRET_KEYS, JSON_SECRET_DQ_RE, JSON_SECRET_SQ_RE;
|
|
38031
38066
|
var init_errors = __esm({
|
|
38032
38067
|
"node_modules/@chrischall/mcp-utils/dist/errors/index.js"() {
|
|
38033
38068
|
DEFAULT_ERROR_MESSAGE_MAX = 500;
|
|
@@ -38061,11 +38096,26 @@ var init_errors = __esm({
|
|
|
38061
38096
|
"whsec_[A-Za-z0-9]{16,}\\b"
|
|
38062
38097
|
// webhook signing secret (Stripe-style)
|
|
38063
38098
|
].map((p) => `\\b${p}`).join("|"), "g");
|
|
38064
|
-
QUERY_SECRET_RE = /([?&](?:
|
|
38099
|
+
QUERY_SECRET_RE = /([?&](?:(?:access|refresh|id|auth|session|csrf|xsrf)[_-]?token|client[_-]?secret|api[_-]?secret|api[_-]?key|password|passwd|signature|token|key|sig)=)[^&#\s"'<>`]+/gi;
|
|
38100
|
+
OAUTH_CODE_RE = /([?&]code=)(?=[^&#\s"'<>`]{16,})[^&#\s"'<>`]+/gi;
|
|
38101
|
+
FORM_PASSWORD_RE = /((?:^|[\s,;:"'(\[{])(?:password|passwd)=)[^&#\s"'<>`]+/gim;
|
|
38102
|
+
HEADER_SECRET_RE = /(\b(?:x[-_][a-z0-9_-]*?(?:api[-_]?key|token|secret|auth)[a-z0-9_-]*|api[-_]?key)\s*:\s*)[^\s,;"'<>`]+/gi;
|
|
38065
38103
|
AWS_SIGV4_RE = /([?&]X-Amz-(?:Signature|Security-Token|Credential)=)[^&#\s"'<>`]+/gi;
|
|
38066
|
-
JSON_SECRET_KEYS =
|
|
38067
|
-
|
|
38068
|
-
|
|
38104
|
+
JSON_SECRET_KEYS = [
|
|
38105
|
+
"(?:access|refresh|id|auth|session|bearer|csrf|xsrf)[_-]?token",
|
|
38106
|
+
"client[_-]?secret",
|
|
38107
|
+
"api[_-]?secret",
|
|
38108
|
+
"(?:x[_-])?api[_-]?key",
|
|
38109
|
+
"private[_-]?key",
|
|
38110
|
+
"x[_-][a-z0-9_-]*?(?:api[_-]?key|token|secret|auth)[a-z0-9_-]*",
|
|
38111
|
+
"(?:proxy-)?authorization",
|
|
38112
|
+
"password",
|
|
38113
|
+
"passwd",
|
|
38114
|
+
"secret",
|
|
38115
|
+
"token"
|
|
38116
|
+
].join("|");
|
|
38117
|
+
JSON_SECRET_DQ_RE = new RegExp(`("(?:${JSON_SECRET_KEYS})"\\s*:\\s*")(?:[^"\\\\]|\\\\.)*(")`, "gi");
|
|
38118
|
+
JSON_SECRET_SQ_RE = new RegExp(`('(?:${JSON_SECRET_KEYS})'\\s*:\\s*')(?:[^'\\\\]|\\\\.)*(')`, "gi");
|
|
38069
38119
|
}
|
|
38070
38120
|
});
|
|
38071
38121
|
|
|
@@ -42565,7 +42615,7 @@ function isRef(value) {
|
|
|
42565
42615
|
function cloneIssues(issues) {
|
|
42566
42616
|
return issues.map((iss) => iss.path ? { ...iss, path: iss.path.slice() } : { ...iss });
|
|
42567
42617
|
}
|
|
42568
|
-
function isRecursive(inst, stack,
|
|
42618
|
+
function isRecursive(inst, stack, resolve4) {
|
|
42569
42619
|
const cached2 = recursive.get(inst);
|
|
42570
42620
|
if (cached2 !== void 0)
|
|
42571
42621
|
return cached2 ? PROVEN : NONE;
|
|
@@ -42575,7 +42625,7 @@ function isRecursive(inst, stack, resolve2) {
|
|
|
42575
42625
|
let result = NONE;
|
|
42576
42626
|
const check2 = (child) => {
|
|
42577
42627
|
if (result !== PROVEN && child?._zod) {
|
|
42578
|
-
const answer = isRecursive(child, stack,
|
|
42628
|
+
const answer = isRecursive(child, stack, resolve4);
|
|
42579
42629
|
if (answer > result)
|
|
42580
42630
|
result = answer;
|
|
42581
42631
|
}
|
|
@@ -42586,7 +42636,7 @@ function isRecursive(inst, stack, resolve2) {
|
|
|
42586
42636
|
const desc = Object.getOwnPropertyDescriptor(sh, key);
|
|
42587
42637
|
if (spread && !desc.enumerable)
|
|
42588
42638
|
continue;
|
|
42589
|
-
const child = desc.get ? ASSUMED : desc.value?._zod ? isRecursive(desc.value, stack,
|
|
42639
|
+
const child = desc.get ? ASSUMED : desc.value?._zod ? isRecursive(desc.value, stack, resolve4) : NONE;
|
|
42590
42640
|
if (child > answer)
|
|
42591
42641
|
answer = child;
|
|
42592
42642
|
}
|
|
@@ -42650,7 +42700,7 @@ function isRecursive(inst, stack, resolve2) {
|
|
|
42650
42700
|
break;
|
|
42651
42701
|
// `$ZodLazy` caches its inner on the def, so a resolved edge is followed exactly
|
|
42652
42702
|
case "lazy": {
|
|
42653
|
-
const inner = def._cachedInner ?? (
|
|
42703
|
+
const inner = def._cachedInner ?? (resolve4 ? inst._zod.innerType : void 0);
|
|
42654
42704
|
merge2(inner ? isRecursive(inner, stack, false) : ASSUMED);
|
|
42655
42705
|
break;
|
|
42656
42706
|
}
|
|
@@ -58466,6 +58516,7 @@ var init_response = __esm({
|
|
|
58466
58516
|
var init_confirmation = __esm({
|
|
58467
58517
|
"node_modules/@chrischall/mcp-utils/dist/server/confirmation.js"() {
|
|
58468
58518
|
init_dist();
|
|
58519
|
+
init_caller();
|
|
58469
58520
|
init_response();
|
|
58470
58521
|
}
|
|
58471
58522
|
});
|
|
@@ -58479,17 +58530,73 @@ Hint: ${err.hint}`);
|
|
|
58479
58530
|
}
|
|
58480
58531
|
throw err;
|
|
58481
58532
|
}
|
|
58533
|
+
function mcpRequestFrom(args) {
|
|
58534
|
+
const ctx = args.at(-1);
|
|
58535
|
+
if (typeof ctx !== "object" || ctx === null)
|
|
58536
|
+
return void 0;
|
|
58537
|
+
const req = ctx.mcpReq;
|
|
58538
|
+
if (typeof req !== "object" || req === null)
|
|
58539
|
+
return void 0;
|
|
58540
|
+
return typeof req.notify === "function" ? req : void 0;
|
|
58541
|
+
}
|
|
58542
|
+
function callSignalFrom(args) {
|
|
58543
|
+
const ctx = args.at(-1);
|
|
58544
|
+
if (typeof ctx !== "object" || ctx === null)
|
|
58545
|
+
return void 0;
|
|
58546
|
+
const req = ctx.mcpReq;
|
|
58547
|
+
if (typeof req !== "object" || req === null)
|
|
58548
|
+
return void 0;
|
|
58549
|
+
const signal = req.signal;
|
|
58550
|
+
return signal instanceof AbortSignal ? signal : void 0;
|
|
58551
|
+
}
|
|
58552
|
+
function declaredCapabilitiesFrom(server) {
|
|
58553
|
+
const inner = server.server;
|
|
58554
|
+
if (typeof inner !== "object" || inner === null)
|
|
58555
|
+
return void 0;
|
|
58556
|
+
const read = inner.getClientCapabilities;
|
|
58557
|
+
if (typeof read !== "function")
|
|
58558
|
+
return void 0;
|
|
58559
|
+
try {
|
|
58560
|
+
const declared = read.call(inner);
|
|
58561
|
+
return typeof declared === "object" && declared !== null ? declared : void 0;
|
|
58562
|
+
} catch {
|
|
58563
|
+
return void 0;
|
|
58564
|
+
}
|
|
58565
|
+
}
|
|
58482
58566
|
function surfaceToolHints(server) {
|
|
58483
58567
|
const register2 = server.registerTool.bind(server);
|
|
58484
|
-
server.registerTool = (name, config2, cb) => register2(name, config2, (...args) =>
|
|
58485
|
-
|
|
58486
|
-
|
|
58487
|
-
|
|
58488
|
-
|
|
58489
|
-
|
|
58490
|
-
|
|
58491
|
-
|
|
58492
|
-
|
|
58568
|
+
server.registerTool = (name, config2, cb) => register2(name, config2, (...args) => (
|
|
58569
|
+
// THE CALLER'S CANCELLATION, made ambient for the whole handler
|
|
58570
|
+
// (`cancel/index.ts`). The SDK delivers it and the fleet ignored it:
|
|
58571
|
+
// measured against @modelcontextprotocol/server 2.0.0, a cancelled
|
|
58572
|
+
// call aborts `ctx.mcpReq.signal` with the caller's reason and the
|
|
58573
|
+
// handler runs to completion regardless — so the HTTP request stays
|
|
58574
|
+
// in flight, the child keeps burning metered CPU, and the upstream
|
|
58575
|
+
// keeps being hit for somebody who has gone. claude.ai sent 101
|
|
58576
|
+
// cancellations in the week to 2026-09-20.
|
|
58577
|
+
//
|
|
58578
|
+
// Here because this is the one wrapper every tool already passes
|
|
58579
|
+
// through: threading the signal by hand would mean editing several
|
|
58580
|
+
// hundred handlers and missing exactly the ones nobody edits.
|
|
58581
|
+
withCallSignal(callSignalFrom(args), () => (
|
|
58582
|
+
// WHAT THE CALLER CAN DO, made ambient for the same reason and in
|
|
58583
|
+
// the same place (`caller/index.ts`). Only the 2025-era half needs
|
|
58584
|
+
// the wrapper — a 2026-07-28 request answers for itself off its own
|
|
58585
|
+
// envelope — but a guarded tool that cannot tell whether the caller
|
|
58586
|
+
// can be shown a prompt returns one the SDK then refuses to deliver,
|
|
58587
|
+
// and that refusal reaches the caller as an unexplained protocol
|
|
58588
|
+
// error it had no chance to catch.
|
|
58589
|
+
withCallerCapabilities(declaredCapabilitiesFrom(server), () => {
|
|
58590
|
+
let result;
|
|
58591
|
+
try {
|
|
58592
|
+
result = cb(...args);
|
|
58593
|
+
} catch (err) {
|
|
58594
|
+
return hintResultOrRethrow(err);
|
|
58595
|
+
}
|
|
58596
|
+
return result instanceof Promise ? result.catch(hintResultOrRethrow) : result;
|
|
58597
|
+
})
|
|
58598
|
+
), mcpRequestFrom(args))
|
|
58599
|
+
));
|
|
58493
58600
|
}
|
|
58494
58601
|
async function createMcpServer(opts) {
|
|
58495
58602
|
const server = new McpServer({ name: opts.name, version: opts.version }, { supportedProtocolVersions: [...SERVER_PROTOCOL_VERSIONS] });
|
|
@@ -58506,11 +58613,43 @@ async function createMcpServer(opts) {
|
|
|
58506
58613
|
}
|
|
58507
58614
|
function withGracefulShutdown(target, opts = {}) {
|
|
58508
58615
|
const shouldExit = opts.exit ?? true;
|
|
58616
|
+
if (opts.timeoutMs !== void 0 && !(Number.isFinite(opts.timeoutMs) && opts.timeoutMs > 0)) {
|
|
58617
|
+
throw new RangeError("withGracefulShutdown: timeoutMs must be a finite number greater than 0.");
|
|
58618
|
+
}
|
|
58619
|
+
const timeoutMs = opts.timeoutMs ?? DEFAULT_SHUTDOWN_TIMEOUT_MS;
|
|
58620
|
+
if (opts.repeatSignalGraceMs !== void 0 && !(Number.isFinite(opts.repeatSignalGraceMs) && opts.repeatSignalGraceMs >= 0)) {
|
|
58621
|
+
throw new RangeError("withGracefulShutdown: repeatSignalGraceMs must be a finite number >= 0.");
|
|
58622
|
+
}
|
|
58623
|
+
const repeatGraceMs = opts.repeatSignalGraceMs ?? DEFAULT_REPEAT_SIGNAL_GRACE_MS;
|
|
58509
58624
|
let shuttingDown = false;
|
|
58625
|
+
let firstSignalAt = 0;
|
|
58626
|
+
let exited = false;
|
|
58627
|
+
const exitOnce = () => {
|
|
58628
|
+
if (exited)
|
|
58629
|
+
return;
|
|
58630
|
+
exited = true;
|
|
58631
|
+
process.exit(0);
|
|
58632
|
+
};
|
|
58510
58633
|
const handler = (signal) => {
|
|
58511
|
-
if (shuttingDown)
|
|
58634
|
+
if (shuttingDown) {
|
|
58635
|
+
if (Date.now() - firstSignalAt < repeatGraceMs)
|
|
58636
|
+
return;
|
|
58637
|
+
if (shouldExit) {
|
|
58638
|
+
console.error(`[mcp-utils] second ${signal} during shutdown \u2014 exiting now`);
|
|
58639
|
+
exitOnce();
|
|
58640
|
+
}
|
|
58512
58641
|
return;
|
|
58642
|
+
}
|
|
58513
58643
|
shuttingDown = true;
|
|
58644
|
+
firstSignalAt = Date.now();
|
|
58645
|
+
let timer;
|
|
58646
|
+
if (shouldExit) {
|
|
58647
|
+
timer = setTimeout(() => {
|
|
58648
|
+
console.error(`[mcp-utils] graceful shutdown on ${signal} did not finish in ${timeoutMs}ms \u2014 exiting`);
|
|
58649
|
+
exitOnce();
|
|
58650
|
+
}, timeoutMs);
|
|
58651
|
+
timer.unref?.();
|
|
58652
|
+
}
|
|
58514
58653
|
void (async () => {
|
|
58515
58654
|
try {
|
|
58516
58655
|
if (opts.onSignal)
|
|
@@ -58519,8 +58658,10 @@ function withGracefulShutdown(target, opts = {}) {
|
|
|
58519
58658
|
} catch (err) {
|
|
58520
58659
|
console.error(`[mcp-utils] error during graceful shutdown on ${signal}: ${err instanceof Error ? err.message : String(err)}`);
|
|
58521
58660
|
} finally {
|
|
58661
|
+
if (timer !== void 0)
|
|
58662
|
+
clearTimeout(timer);
|
|
58522
58663
|
if (shouldExit)
|
|
58523
|
-
|
|
58664
|
+
exitOnce();
|
|
58524
58665
|
}
|
|
58525
58666
|
})();
|
|
58526
58667
|
};
|
|
@@ -58548,7 +58689,7 @@ function runMcp(opts) {
|
|
|
58548
58689
|
}
|
|
58549
58690
|
return handle;
|
|
58550
58691
|
}
|
|
58551
|
-
var SERVER_PROTOCOL_VERSIONS;
|
|
58692
|
+
var SERVER_PROTOCOL_VERSIONS, DEFAULT_SHUTDOWN_TIMEOUT_MS, DEFAULT_REPEAT_SIGNAL_GRACE_MS;
|
|
58552
58693
|
var init_server = __esm({
|
|
58553
58694
|
"node_modules/@chrischall/mcp-utils/dist/server/index.js"() {
|
|
58554
58695
|
init_stdio();
|
|
@@ -58556,14 +58697,20 @@ var init_server = __esm({
|
|
|
58556
58697
|
init_errors();
|
|
58557
58698
|
init_response();
|
|
58558
58699
|
init_confirmation();
|
|
58700
|
+
init_cancel();
|
|
58701
|
+
init_caller();
|
|
58559
58702
|
SERVER_PROTOCOL_VERSIONS = Object.freeze([
|
|
58560
58703
|
"2026-07-28",
|
|
58561
58704
|
...SUPPORTED_PROTOCOL_VERSIONS
|
|
58562
58705
|
]);
|
|
58706
|
+
DEFAULT_SHUTDOWN_TIMEOUT_MS = 5e3;
|
|
58707
|
+
DEFAULT_REPEAT_SIGNAL_GRACE_MS = 500;
|
|
58563
58708
|
}
|
|
58564
58709
|
});
|
|
58565
58710
|
|
|
58566
58711
|
// node_modules/@chrischall/mcp-utils/dist/config/index.js
|
|
58712
|
+
import { homedir } from "node:os";
|
|
58713
|
+
import { isAbsolute, join, resolve } from "node:path";
|
|
58567
58714
|
function readEnvVar(key, opts = {}) {
|
|
58568
58715
|
const env = opts.env ?? process.env;
|
|
58569
58716
|
const raw = env[key];
|
|
@@ -58575,6 +58722,15 @@ function readEnvVar(key, opts = {}) {
|
|
|
58575
58722
|
}
|
|
58576
58723
|
return opts.default;
|
|
58577
58724
|
}
|
|
58725
|
+
function expandPath(p) {
|
|
58726
|
+
let expanded = p;
|
|
58727
|
+
if (p === "~") {
|
|
58728
|
+
expanded = homedir();
|
|
58729
|
+
} else if (p.startsWith("~/")) {
|
|
58730
|
+
expanded = join(homedir(), p.slice(2));
|
|
58731
|
+
}
|
|
58732
|
+
return isAbsolute(expanded) ? expanded : resolve(expanded);
|
|
58733
|
+
}
|
|
58578
58734
|
async function loadDotenvSafely(opts = {}) {
|
|
58579
58735
|
try {
|
|
58580
58736
|
const mod = await import(
|
|
@@ -58598,19 +58754,61 @@ var init_config = __esm({
|
|
|
58598
58754
|
}
|
|
58599
58755
|
});
|
|
58600
58756
|
|
|
58757
|
+
// node_modules/@chrischall/mcp-utils/dist/fs/confine.js
|
|
58758
|
+
import { existsSync, realpathSync } from "node:fs";
|
|
58759
|
+
import { dirname, isAbsolute as isAbsolute2, relative, resolve as resolve2, sep } from "node:path";
|
|
58760
|
+
function isInside(root, target) {
|
|
58761
|
+
const rel = relative(root, target);
|
|
58762
|
+
return rel === "" || !rel.startsWith(`..${sep}`) && rel !== ".." && !isAbsolute2(rel);
|
|
58763
|
+
}
|
|
58764
|
+
function realPathAllowingMissing(p) {
|
|
58765
|
+
const abs = resolve2(p);
|
|
58766
|
+
let existing = abs;
|
|
58767
|
+
const tail = [];
|
|
58768
|
+
while (!existsSync(existing)) {
|
|
58769
|
+
const parent = dirname(existing);
|
|
58770
|
+
if (parent === existing)
|
|
58771
|
+
break;
|
|
58772
|
+
tail.unshift(existing.slice(parent.length).replace(/^[/\\]+/, ""));
|
|
58773
|
+
existing = parent;
|
|
58774
|
+
}
|
|
58775
|
+
let real;
|
|
58776
|
+
try {
|
|
58777
|
+
real = realpathSync(existing);
|
|
58778
|
+
} catch {
|
|
58779
|
+
real = existing;
|
|
58780
|
+
}
|
|
58781
|
+
return tail.length > 0 ? resolve2(real, ...tail) : real;
|
|
58782
|
+
}
|
|
58783
|
+
function assertPathWithinRoots(path, roots) {
|
|
58784
|
+
const target = realPathAllowingMissing(expandPath(path));
|
|
58785
|
+
for (const root of roots) {
|
|
58786
|
+
if (isInside(realPathAllowingMissing(expandPath(root)), target))
|
|
58787
|
+
return target;
|
|
58788
|
+
}
|
|
58789
|
+
throw new Error(`Path is outside the allowed directories: ${path}`);
|
|
58790
|
+
}
|
|
58791
|
+
var init_confine = __esm({
|
|
58792
|
+
"node_modules/@chrischall/mcp-utils/dist/fs/confine.js"() {
|
|
58793
|
+
init_config();
|
|
58794
|
+
}
|
|
58795
|
+
});
|
|
58796
|
+
|
|
58601
58797
|
// node_modules/@chrischall/mcp-utils/dist/fs/output.js
|
|
58602
58798
|
var init_output = __esm({
|
|
58603
58799
|
"node_modules/@chrischall/mcp-utils/dist/fs/output.js"() {
|
|
58604
58800
|
init_config();
|
|
58801
|
+
init_confine();
|
|
58605
58802
|
}
|
|
58606
58803
|
});
|
|
58607
58804
|
|
|
58608
58805
|
// node_modules/@chrischall/mcp-utils/dist/fs/index.js
|
|
58609
58806
|
import { openAsBlob } from "node:fs";
|
|
58610
58807
|
async function fileBlob(path, opts = {}) {
|
|
58808
|
+
const target = opts.allowedRoots ? assertPathWithinRoots(path, opts.allowedRoots) : path;
|
|
58611
58809
|
let blob;
|
|
58612
58810
|
try {
|
|
58613
|
-
blob = await openAsBlob(
|
|
58811
|
+
blob = await openAsBlob(target, opts.type !== void 0 ? { type: opts.type } : void 0);
|
|
58614
58812
|
} catch {
|
|
58615
58813
|
throw new Error(`Cannot read file for upload: ${path}`);
|
|
58616
58814
|
}
|
|
@@ -58621,7 +58819,9 @@ async function fileBlob(path, opts = {}) {
|
|
|
58621
58819
|
}
|
|
58622
58820
|
var init_fs = __esm({
|
|
58623
58821
|
"node_modules/@chrischall/mcp-utils/dist/fs/index.js"() {
|
|
58822
|
+
init_confine();
|
|
58624
58823
|
init_output();
|
|
58824
|
+
init_confine();
|
|
58625
58825
|
}
|
|
58626
58826
|
});
|
|
58627
58827
|
|
|
@@ -58672,23 +58872,78 @@ function createApiClient(opts) {
|
|
|
58672
58872
|
const retryStatuses = retry.statuses ?? [429];
|
|
58673
58873
|
const timeoutMs = opts.timeout;
|
|
58674
58874
|
const authHeader = (token) => !token ? {} : opts.tokenHeader ? { [opts.tokenHeader]: token } : { Authorization: `Bearer ${token}` };
|
|
58675
|
-
function withTimeout(run) {
|
|
58676
|
-
if (timeoutMs == null || timeoutMs <= 0)
|
|
58677
|
-
|
|
58875
|
+
async function withTimeout(run) {
|
|
58876
|
+
if (timeoutMs == null || timeoutMs <= 0) {
|
|
58877
|
+
const res2 = await run(withAmbientCancellation(void 0));
|
|
58878
|
+
return { res: res2, done: () => {
|
|
58879
|
+
}, expired: void 0 };
|
|
58880
|
+
}
|
|
58678
58881
|
const controller = new AbortController();
|
|
58679
58882
|
const timer = setTimeout(() => controller.abort(), timeoutMs);
|
|
58680
|
-
|
|
58681
|
-
|
|
58883
|
+
let res;
|
|
58884
|
+
try {
|
|
58885
|
+
res = await run(withAmbientCancellation(controller.signal));
|
|
58886
|
+
} catch (err) {
|
|
58887
|
+
clearTimeout(timer);
|
|
58888
|
+
if (err instanceof Error && err.name === "AbortError" && controller.signal.aborted) {
|
|
58682
58889
|
throw new RequestTimeoutError(service, timeoutMs);
|
|
58890
|
+
}
|
|
58683
58891
|
throw err;
|
|
58684
|
-
}
|
|
58892
|
+
}
|
|
58893
|
+
const expired = new Promise((_resolve, reject) => {
|
|
58894
|
+
controller.signal.addEventListener("abort", () => reject(new RequestTimeoutError(service, timeoutMs)), {
|
|
58895
|
+
once: true
|
|
58896
|
+
});
|
|
58897
|
+
});
|
|
58898
|
+
expired.catch(() => {
|
|
58899
|
+
});
|
|
58900
|
+
return { res, done: () => clearTimeout(timer), expired };
|
|
58901
|
+
}
|
|
58902
|
+
async function readBody(attempt, read) {
|
|
58903
|
+
try {
|
|
58904
|
+
if (!attempt.expired)
|
|
58905
|
+
return await read(attempt.res);
|
|
58906
|
+
return await Promise.race([read(attempt.res), attempt.expired]);
|
|
58907
|
+
} catch (err) {
|
|
58908
|
+
if (err instanceof RequestTimeoutError) {
|
|
58909
|
+
attempt.res.body?.cancel().catch(() => {
|
|
58910
|
+
});
|
|
58911
|
+
}
|
|
58912
|
+
throw err;
|
|
58913
|
+
} finally {
|
|
58914
|
+
attempt.done();
|
|
58915
|
+
}
|
|
58916
|
+
}
|
|
58917
|
+
const baseParts = (() => {
|
|
58918
|
+
try {
|
|
58919
|
+
const u = new URL(base);
|
|
58920
|
+
return { origin: u.origin, username: u.username, password: u.password };
|
|
58921
|
+
} catch {
|
|
58922
|
+
return void 0;
|
|
58923
|
+
}
|
|
58924
|
+
})();
|
|
58925
|
+
const baseOrigin = baseParts?.origin;
|
|
58926
|
+
function resolveUrl2(path, query) {
|
|
58927
|
+
const url4 = `${base}${path}${query}`;
|
|
58928
|
+
if (baseOrigin === void 0)
|
|
58929
|
+
return url4;
|
|
58930
|
+
let parsed;
|
|
58931
|
+
try {
|
|
58932
|
+
parsed = new URL(url4);
|
|
58933
|
+
} catch {
|
|
58934
|
+
throw new Error(`Refusing request to ${service}: path ${JSON.stringify(path)} does not form a valid URL.`);
|
|
58935
|
+
}
|
|
58936
|
+
if (parsed.origin !== baseOrigin || parsed.username !== baseParts?.username || parsed.password !== baseParts?.password) {
|
|
58937
|
+
throw new Error(`Refusing request to ${service}: path ${JSON.stringify(path)} resolves outside the base origin ${baseOrigin}. Paths must be relative to baseUrl (start them with "/").`);
|
|
58938
|
+
}
|
|
58939
|
+
return url4;
|
|
58685
58940
|
}
|
|
58686
58941
|
async function send(method, path, opt) {
|
|
58687
58942
|
const isMultipart = opt.formData !== void 0;
|
|
58688
58943
|
const hasJsonBody = !isMultipart && opt.body !== void 0;
|
|
58689
58944
|
const reqBody = isMultipart ? opt.formData : hasJsonBody ? JSON.stringify(opt.body) : void 0;
|
|
58690
58945
|
const query = opt.query ? buildQueryString(opt.query) : "";
|
|
58691
|
-
const url4 =
|
|
58946
|
+
const url4 = resolveUrl2(path, query);
|
|
58692
58947
|
const bodyInit = reqBody !== void 0 ? { body: reqBody } : {};
|
|
58693
58948
|
const fetchWith = (token, signal) => doFetch(url4, {
|
|
58694
58949
|
method,
|
|
@@ -58705,8 +58960,10 @@ function createApiClient(opts) {
|
|
|
58705
58960
|
const once = () => withTimeout((signal) => opts.tokenManager ? opts.tokenManager.withAuth((token) => fetchWith(token, signal)) : (async () => fetchWith(await opts.getToken?.() || void 0, signal))());
|
|
58706
58961
|
let attempt = 0;
|
|
58707
58962
|
for (; ; ) {
|
|
58708
|
-
const
|
|
58963
|
+
const current = await once();
|
|
58964
|
+
const res = current.res;
|
|
58709
58965
|
if (retryStatuses.includes(res.status) && attempt < retry.count) {
|
|
58966
|
+
current.done();
|
|
58710
58967
|
attempt += 1;
|
|
58711
58968
|
const delay = retry.honorRetryAfter ? parseRetryAfterMs(res.headers.get("retry-after"), {
|
|
58712
58969
|
defaultMs: retry.delayMs,
|
|
@@ -58715,18 +58972,21 @@ function createApiClient(opts) {
|
|
|
58715
58972
|
await sleep2(delay);
|
|
58716
58973
|
continue;
|
|
58717
58974
|
}
|
|
58718
|
-
return
|
|
58975
|
+
return current;
|
|
58719
58976
|
}
|
|
58720
58977
|
}
|
|
58721
58978
|
async function fetchJson(method, path, opt = {}) {
|
|
58722
|
-
const
|
|
58979
|
+
const attempt = await send(method, path, opt);
|
|
58980
|
+
const res = attempt.res;
|
|
58981
|
+
if (res.status === 401 || res.status === 429 || res.status === 204)
|
|
58982
|
+
attempt.done();
|
|
58723
58983
|
if (res.status === 401)
|
|
58724
58984
|
throw unauthorized();
|
|
58725
58985
|
if (res.status === 429)
|
|
58726
58986
|
throw rateLimited();
|
|
58727
58987
|
if (res.status === 204)
|
|
58728
58988
|
return void 0;
|
|
58729
|
-
const text = await
|
|
58989
|
+
const text = await readBody(attempt, (r) => r.text());
|
|
58730
58990
|
if (!res.ok) {
|
|
58731
58991
|
throw new ApiError(res.status, formatApiError(res.status, method, path, text, { service }));
|
|
58732
58992
|
}
|
|
@@ -58736,12 +58996,15 @@ function createApiClient(opts) {
|
|
|
58736
58996
|
}
|
|
58737
58997
|
async function fetchHtml(method, path, opt = {}) {
|
|
58738
58998
|
const headers = { Accept: "text/html,*/*", ...opt.headers };
|
|
58739
|
-
const
|
|
58999
|
+
const attempt = await send(method, path, { ...opt, headers });
|
|
59000
|
+
const res = attempt.res;
|
|
59001
|
+
if (res.status === 401 || res.status === 429)
|
|
59002
|
+
attempt.done();
|
|
58740
59003
|
if (res.status === 401)
|
|
58741
59004
|
throw unauthorized();
|
|
58742
59005
|
if (res.status === 429)
|
|
58743
59006
|
throw rateLimited();
|
|
58744
|
-
const text = await
|
|
59007
|
+
const text = await readBody(attempt, (r) => r.text());
|
|
58745
59008
|
if (!res.ok) {
|
|
58746
59009
|
throw new ApiError(res.status, formatApiError(res.status, method, path, text, { service }));
|
|
58747
59010
|
}
|
|
@@ -58749,16 +59012,23 @@ function createApiClient(opts) {
|
|
|
58749
59012
|
}
|
|
58750
59013
|
async function fetchRaw(method, path, opt = {}) {
|
|
58751
59014
|
const headers = { Accept: "*/*", ...opt.headers };
|
|
58752
|
-
const
|
|
59015
|
+
const attempt = await send(method, path, { ...opt, headers });
|
|
59016
|
+
const res = attempt.res;
|
|
59017
|
+
if (res.status === 401 || res.status === 429)
|
|
59018
|
+
attempt.done();
|
|
58753
59019
|
if (res.status === 401)
|
|
58754
59020
|
throw unauthorized();
|
|
58755
59021
|
if (res.status === 429)
|
|
58756
59022
|
throw rateLimited();
|
|
58757
59023
|
if (!res.ok) {
|
|
58758
|
-
const text = await
|
|
59024
|
+
const text = await readBody(attempt, (r) => r.text()).catch((err) => {
|
|
59025
|
+
if (err instanceof RequestTimeoutError)
|
|
59026
|
+
throw err;
|
|
59027
|
+
return "";
|
|
59028
|
+
});
|
|
58759
59029
|
throw new ApiError(res.status, formatApiError(res.status, method, path, text, { service }));
|
|
58760
59030
|
}
|
|
58761
|
-
const bytes = new Uint8Array(await
|
|
59031
|
+
const bytes = new Uint8Array(await readBody(attempt, (r) => r.arrayBuffer()));
|
|
58762
59032
|
return {
|
|
58763
59033
|
status: res.status,
|
|
58764
59034
|
contentType: res.headers.get("content-type"),
|
|
@@ -58794,6 +59064,7 @@ function formatApiError(status, method, path, errorText, opts = {}) {
|
|
|
58794
59064
|
var DEFAULT_RETRY, defaultSleep, UnauthorizedError, RateLimitedError, RequestTimeoutError, ApiError;
|
|
58795
59065
|
var init_http = __esm({
|
|
58796
59066
|
"node_modules/@chrischall/mcp-utils/dist/http/index.js"() {
|
|
59067
|
+
init_cancel();
|
|
58797
59068
|
init_errors();
|
|
58798
59069
|
init_throttle();
|
|
58799
59070
|
init_response_cache();
|
|
@@ -58866,10 +59137,14 @@ var init_parse_lenient = __esm({
|
|
|
58866
59137
|
|
|
58867
59138
|
// node_modules/@chrischall/mcp-utils/dist/zod/index.js
|
|
58868
59139
|
function toolAnnotations(opts = {}) {
|
|
59140
|
+
if (opts.readOnly === true && opts.destructive === true) {
|
|
59141
|
+
throw new Error("toolAnnotations: readOnly: true contradicts destructive: true \u2014 a destructive tool is not read-only.");
|
|
59142
|
+
}
|
|
58869
59143
|
return {
|
|
58870
59144
|
...opts.title !== void 0 ? { title: opts.title } : {},
|
|
58871
|
-
readOnlyHint: opts.readOnly ??
|
|
59145
|
+
readOnlyHint: opts.readOnly ?? opts.destructive === void 0,
|
|
58872
59146
|
...opts.idempotent !== void 0 ? { idempotentHint: opts.idempotent } : {},
|
|
59147
|
+
...opts.destructive !== void 0 ? { destructiveHint: opts.destructive } : {},
|
|
58873
59148
|
...opts.openWorld !== void 0 ? { openWorldHint: opts.openWorld } : {}
|
|
58874
59149
|
};
|
|
58875
59150
|
}
|
|
@@ -58921,15 +59196,24 @@ var init_auth = __esm({
|
|
|
58921
59196
|
}
|
|
58922
59197
|
});
|
|
58923
59198
|
|
|
59199
|
+
// node_modules/@chrischall/mcp-utils/dist/internal/ascii.js
|
|
59200
|
+
var init_ascii = __esm({
|
|
59201
|
+
"node_modules/@chrischall/mcp-utils/dist/internal/ascii.js"() {
|
|
59202
|
+
}
|
|
59203
|
+
});
|
|
59204
|
+
|
|
58924
59205
|
// node_modules/@chrischall/mcp-utils/dist/scrape/index.js
|
|
58925
59206
|
var init_scrape = __esm({
|
|
58926
59207
|
"node_modules/@chrischall/mcp-utils/dist/scrape/index.js"() {
|
|
59208
|
+
init_ascii();
|
|
58927
59209
|
}
|
|
58928
59210
|
});
|
|
58929
59211
|
|
|
58930
59212
|
// node_modules/@chrischall/mcp-utils/dist/index.js
|
|
58931
59213
|
var init_dist2 = __esm({
|
|
58932
59214
|
"node_modules/@chrischall/mcp-utils/dist/index.js"() {
|
|
59215
|
+
init_cancel();
|
|
59216
|
+
init_caller();
|
|
58933
59217
|
init_server();
|
|
58934
59218
|
init_response();
|
|
58935
59219
|
init_errors();
|
|
@@ -58964,8 +59248,8 @@ __export(images_exports, {
|
|
|
58964
59248
|
writeSidecar: () => writeSidecar
|
|
58965
59249
|
});
|
|
58966
59250
|
import { mkdir, readFile, writeFile, access, stat, open as open2 } from "node:fs/promises";
|
|
58967
|
-
import { existsSync } from "node:fs";
|
|
58968
|
-
import { join as
|
|
59251
|
+
import { existsSync as existsSync2 } from "node:fs";
|
|
59252
|
+
import { join as join3, resolve as resolve3, isAbsolute as isAbsolute3 } from "node:path";
|
|
58969
59253
|
function slugify2(text, max = 40) {
|
|
58970
59254
|
const s = text.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "").slice(0, max).replace(/-+$/g, "");
|
|
58971
59255
|
return s || "image";
|
|
@@ -58979,10 +59263,10 @@ async function exists(p) {
|
|
|
58979
59263
|
}
|
|
58980
59264
|
}
|
|
58981
59265
|
async function uniquePath(dir, base, ext) {
|
|
58982
|
-
let candidate =
|
|
59266
|
+
let candidate = join3(dir, `${base}.${ext}`);
|
|
58983
59267
|
let n = 2;
|
|
58984
59268
|
while (await exists(candidate)) {
|
|
58985
|
-
candidate =
|
|
59269
|
+
candidate = join3(dir, `${base}-${n}.${ext}`);
|
|
58986
59270
|
n++;
|
|
58987
59271
|
}
|
|
58988
59272
|
return candidate;
|
|
@@ -59016,7 +59300,7 @@ async function writeMedia(dir, base, base643, mimeType) {
|
|
|
59016
59300
|
await mkdir(dir, { recursive: true });
|
|
59017
59301
|
const path = await uniquePath(dir, base, mediaExt(mimeType));
|
|
59018
59302
|
await writeFile(path, Buffer.from(base643, "base64"));
|
|
59019
|
-
return
|
|
59303
|
+
return resolve3(path);
|
|
59020
59304
|
}
|
|
59021
59305
|
async function writeImage(dir, base, base643, mimeType) {
|
|
59022
59306
|
return writeMedia(dir, base, base643, mimeType);
|
|
@@ -59025,14 +59309,14 @@ async function writeSidecar(imagePath, data) {
|
|
|
59025
59309
|
await writeFile(`${imagePath}.json`, JSON.stringify(data, null, 2));
|
|
59026
59310
|
}
|
|
59027
59311
|
function resolveInputPath(p, kind) {
|
|
59028
|
-
if (
|
|
59312
|
+
if (isAbsolute3(p) && existsSync2(p)) return p;
|
|
59029
59313
|
const inputDir = readEnvVar("GEMINI_INPUT_DIR");
|
|
59030
59314
|
if (inputDir) {
|
|
59031
|
-
const candidate =
|
|
59032
|
-
if (
|
|
59315
|
+
const candidate = join3(inputDir, p);
|
|
59316
|
+
if (existsSync2(candidate)) return resolve3(candidate);
|
|
59033
59317
|
}
|
|
59034
|
-
const cwd =
|
|
59035
|
-
if (
|
|
59318
|
+
const cwd = resolve3(p);
|
|
59319
|
+
if (existsSync2(cwd)) return cwd;
|
|
59036
59320
|
const hint = `Set GEMINI_INPUT_DIR to a directory containing your ${kind.toLowerCase()}s, or pass an absolute path.`;
|
|
59037
59321
|
throw new McpToolError(
|
|
59038
59322
|
`${kind} not found: ${p}` + (inputDir ? ` (also searched GEMINI_INPUT_DIR=${inputDir})` : ""),
|
|
@@ -59128,7 +59412,7 @@ import { execFile } from "node:child_process";
|
|
|
59128
59412
|
import { promisify } from "node:util";
|
|
59129
59413
|
import { readFile as readFile2, unlink } from "node:fs/promises";
|
|
59130
59414
|
import { tmpdir } from "node:os";
|
|
59131
|
-
import { join as
|
|
59415
|
+
import { join as join4 } from "node:path";
|
|
59132
59416
|
async function readClipboardImage(run = defaultRun) {
|
|
59133
59417
|
if (process.platform !== "darwin") {
|
|
59134
59418
|
throw new McpToolError("from_clipboard is only supported on macOS", {
|
|
@@ -59136,8 +59420,8 @@ async function readClipboardImage(run = defaultRun) {
|
|
|
59136
59420
|
});
|
|
59137
59421
|
}
|
|
59138
59422
|
const id = `${Date.now()}-${Math.random().toString(36).slice(2)}`;
|
|
59139
|
-
const png =
|
|
59140
|
-
const jpg =
|
|
59423
|
+
const png = join4(tmpdir(), `gemini-clip-${id}.png`);
|
|
59424
|
+
const jpg = join4(tmpdir(), `gemini-clip-${id}.jpg`);
|
|
59141
59425
|
try {
|
|
59142
59426
|
try {
|
|
59143
59427
|
await run("osascript", [
|
|
@@ -59184,15 +59468,15 @@ init_dist2();
|
|
|
59184
59468
|
|
|
59185
59469
|
// src/dotenv.ts
|
|
59186
59470
|
init_dist2();
|
|
59187
|
-
import { dirname, join } from "node:path";
|
|
59471
|
+
import { dirname as dirname2, join as join2 } from "node:path";
|
|
59188
59472
|
import { fileURLToPath } from "node:url";
|
|
59189
59473
|
async function loadStdioDotenv() {
|
|
59190
|
-
const here =
|
|
59191
|
-
await loadDotenvSafely({ path:
|
|
59474
|
+
const here = dirname2(fileURLToPath(import.meta.url));
|
|
59475
|
+
await loadDotenvSafely({ path: join2(here, "..", ".env"), override: false });
|
|
59192
59476
|
}
|
|
59193
59477
|
|
|
59194
59478
|
// src/version.ts
|
|
59195
|
-
var VERSION = "2.1.
|
|
59479
|
+
var VERSION = "2.1.3";
|
|
59196
59480
|
|
|
59197
59481
|
// src/errors.ts
|
|
59198
59482
|
init_dist2();
|
|
@@ -60510,8 +60794,8 @@ async function emitMedia(named, kind, opts, meta3, onWritten) {
|
|
|
60510
60794
|
...p.key ? { curl_hint: `curl -sS -o ${downloadFilename(p.key)} "${p.ref}"` } : {}
|
|
60511
60795
|
}))
|
|
60512
60796
|
} : {};
|
|
60513
|
-
const
|
|
60514
|
-
return minifiedResult({ [`${kind}s`]: refs, ...media, ...unavailable, ...note, ...
|
|
60797
|
+
const storage3 = sink.persistsFiles ? {} : { storage: sink.kind, storage_note: storageNote };
|
|
60798
|
+
return minifiedResult({ [`${kind}s`]: refs, ...media, ...unavailable, ...note, ...storage3, ...meta3 });
|
|
60515
60799
|
}
|
|
60516
60800
|
async function emit(named, opts, meta3, onWritten) {
|
|
60517
60801
|
return emitMedia(named.map((n) => ({ media: n.image, base: n.base })), "image", opts, meta3, onWritten);
|
|
@@ -60827,13 +61111,13 @@ function persistableResult(result) {
|
|
|
60827
61111
|
return { result };
|
|
60828
61112
|
}
|
|
60829
61113
|
function awaitWithBudget(promise2, waitMs) {
|
|
60830
|
-
return new Promise((
|
|
60831
|
-
const timer = setTimeout(() =>
|
|
61114
|
+
return new Promise((resolve4, reject) => {
|
|
61115
|
+
const timer = setTimeout(() => resolve4(void 0), waitMs);
|
|
60832
61116
|
timer.unref?.();
|
|
60833
61117
|
promise2.then(
|
|
60834
61118
|
(result) => {
|
|
60835
61119
|
clearTimeout(timer);
|
|
60836
|
-
|
|
61120
|
+
resolve4(result);
|
|
60837
61121
|
},
|
|
60838
61122
|
(err) => {
|
|
60839
61123
|
clearTimeout(timer);
|
|
@@ -60901,7 +61185,7 @@ var JobRegistry = class {
|
|
|
60901
61185
|
/** Await outstanding durable writes. Tests only — handlers never need it. */
|
|
60902
61186
|
async drain() {
|
|
60903
61187
|
for (let round = 0; round < 50; round++) {
|
|
60904
|
-
await new Promise((
|
|
61188
|
+
await new Promise((resolve4) => setTimeout(resolve4, 0));
|
|
60905
61189
|
if (!this.pending.size) return;
|
|
60906
61190
|
await Promise.allSettled([...this.pending]);
|
|
60907
61191
|
}
|
|
@@ -62967,8 +63251,8 @@ init_images();
|
|
|
62967
63251
|
|
|
62968
63252
|
// src/sidecar.ts
|
|
62969
63253
|
import { readdir, readFile as readFile3, stat as stat2 } from "node:fs/promises";
|
|
62970
|
-
import { existsSync as
|
|
62971
|
-
import { join as
|
|
63254
|
+
import { existsSync as existsSync3 } from "node:fs";
|
|
63255
|
+
import { join as join5 } from "node:path";
|
|
62972
63256
|
var SIDECAR_SUFFIX2 = ".json";
|
|
62973
63257
|
async function readSidecars(dir) {
|
|
62974
63258
|
let entries;
|
|
@@ -62980,7 +63264,7 @@ async function readSidecars(dir) {
|
|
|
62980
63264
|
const records = [];
|
|
62981
63265
|
for (const entry of entries) {
|
|
62982
63266
|
if (!entry.endsWith(SIDECAR_SUFFIX2)) continue;
|
|
62983
|
-
const sidecarPath =
|
|
63267
|
+
const sidecarPath = join5(dir, entry);
|
|
62984
63268
|
try {
|
|
62985
63269
|
const parsed = JSON.parse(await readFile3(sidecarPath, "utf8"));
|
|
62986
63270
|
if (typeof parsed !== "object" || parsed === null) continue;
|
|
@@ -62990,7 +63274,7 @@ async function readSidecars(dir) {
|
|
|
62990
63274
|
records.push({
|
|
62991
63275
|
sidecarPath,
|
|
62992
63276
|
interactionId,
|
|
62993
|
-
images: paths.filter((p) =>
|
|
63277
|
+
images: paths.filter((p) => existsSync3(p)),
|
|
62994
63278
|
mtimeMs: (await stat2(sidecarPath)).mtimeMs
|
|
62995
63279
|
});
|
|
62996
63280
|
} catch {
|
package/dist/version.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
/** Single source of the server version. release-please bumps the literal below. */
|
|
2
|
-
export const VERSION = '2.1.
|
|
2
|
+
export const VERSION = '2.1.3'; // x-release-please-version
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@chrischall/gemini-mcp",
|
|
3
|
-
"version": "2.1.
|
|
3
|
+
"version": "2.1.3",
|
|
4
4
|
"mcpName": "io.github.chrischall/gemini-mcp",
|
|
5
5
|
"description": "Gemini image-generation MCP server for Claude — developed and maintained by AI (Claude Code)",
|
|
6
6
|
"author": "Claude Code (AI) <https://www.anthropic.com/claude>",
|
|
@@ -46,10 +46,10 @@
|
|
|
46
46
|
"typecheck": "tsc -p tsconfig.test.json"
|
|
47
47
|
},
|
|
48
48
|
"dependencies": {
|
|
49
|
-
"@chrischall/mcp-utils": "^
|
|
49
|
+
"@chrischall/mcp-utils": "^2.4.0",
|
|
50
50
|
"@modelcontextprotocol/server": "^2.0.0",
|
|
51
51
|
"dotenv": "^17.4.0",
|
|
52
|
-
"zod": "^4.6.
|
|
52
|
+
"zod": "^4.6.5"
|
|
53
53
|
},
|
|
54
54
|
"devDependencies": {
|
|
55
55
|
"@modelcontextprotocol/client": "^2.0.0",
|
package/server.json
CHANGED
|
@@ -6,12 +6,12 @@
|
|
|
6
6
|
"url": "https://github.com/chrischall/gemini-mcp",
|
|
7
7
|
"source": "github"
|
|
8
8
|
},
|
|
9
|
-
"version": "2.1.
|
|
9
|
+
"version": "2.1.3",
|
|
10
10
|
"packages": [
|
|
11
11
|
{
|
|
12
12
|
"registryType": "npm",
|
|
13
13
|
"identifier": "@chrischall/gemini-mcp",
|
|
14
|
-
"version": "2.1.
|
|
14
|
+
"version": "2.1.3",
|
|
15
15
|
"transport": {
|
|
16
16
|
"type": "stdio"
|
|
17
17
|
},
|