@chrischall/gemini-mcp 2.0.0 → 2.1.1
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 +670 -14
- package/dist/tools/shared.js +1 -1
- package/dist/version.js +1 -1
- package/package.json +2 -2
- 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.
|
|
10
|
+
"version": "2.1.1"
|
|
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.
|
|
18
|
+
"version": "2.1.1",
|
|
19
19
|
"author": {
|
|
20
20
|
"name": "Chris Hall"
|
|
21
21
|
},
|
package/dist/bundle.js
CHANGED
|
@@ -26527,6 +26527,25 @@ function isSpecRequestMethod(method) {
|
|
|
26527
26527
|
function isSpecNotificationMethod(method) {
|
|
26528
26528
|
return ALL_CODECS.some((codec2) => codec2.hasNotificationMethod(method));
|
|
26529
26529
|
}
|
|
26530
|
+
function isPlainObject$3(value) {
|
|
26531
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
26532
|
+
}
|
|
26533
|
+
function requestMetaOf(params) {
|
|
26534
|
+
if (!isPlainObject$3(params)) return void 0;
|
|
26535
|
+
const meta3 = params["_meta"];
|
|
26536
|
+
return isPlainObject$3(meta3) ? meta3 : void 0;
|
|
26537
|
+
}
|
|
26538
|
+
function hasEnvelopeClaim(params) {
|
|
26539
|
+
const meta3 = requestMetaOf(params);
|
|
26540
|
+
return meta3 !== void 0 && PROTOCOL_VERSION_META_KEY in meta3;
|
|
26541
|
+
}
|
|
26542
|
+
function envelopeClaimVersion(params) {
|
|
26543
|
+
const value = requestMetaOf(params)?.[PROTOCOL_VERSION_META_KEY];
|
|
26544
|
+
return typeof value === "string" ? value : void 0;
|
|
26545
|
+
}
|
|
26546
|
+
function validateEnvelopeMeta(meta3) {
|
|
26547
|
+
return codecForVersion(MODERN_WIRE_REVISION).validateEnvelopeMeta(meta3);
|
|
26548
|
+
}
|
|
26530
26549
|
function assertCompleteRequestPrompt(request) {
|
|
26531
26550
|
if (request.params.ref.type !== "ref/prompt") throw new TypeError(`Expected CompleteRequestPrompt, but got ${request.params.ref.type}`);
|
|
26532
26551
|
}
|
|
@@ -26583,6 +26602,45 @@ function scanXMcpHeaderDeclarations(inputSchema) {
|
|
|
26583
26602
|
function pathName(path) {
|
|
26584
26603
|
return path.length === 0 ? "<root>" : path.join(".");
|
|
26585
26604
|
}
|
|
26605
|
+
function rejection(rung, cell, httpStatus, error62, settled) {
|
|
26606
|
+
return {
|
|
26607
|
+
kind: "reject",
|
|
26608
|
+
rung,
|
|
26609
|
+
cell,
|
|
26610
|
+
httpStatus,
|
|
26611
|
+
code: error62.code,
|
|
26612
|
+
message: error62.message,
|
|
26613
|
+
...error62.data !== void 0 && { data: error62.data },
|
|
26614
|
+
settled
|
|
26615
|
+
};
|
|
26616
|
+
}
|
|
26617
|
+
function carriesValidModernEnvelopeClaim(params) {
|
|
26618
|
+
if (!hasEnvelopeClaim(params)) return false;
|
|
26619
|
+
const claimedVersion = envelopeClaimVersion(params);
|
|
26620
|
+
if (claimedVersion === void 0 || !isModernProtocolVersion(claimedVersion)) return false;
|
|
26621
|
+
const meta3 = requestMetaOf(params);
|
|
26622
|
+
return meta3 !== void 0 && validateEnvelopeMeta(meta3).length === 0;
|
|
26623
|
+
}
|
|
26624
|
+
function modernOnlyStrictRejection(route, supportedVersions) {
|
|
26625
|
+
switch (route.reason) {
|
|
26626
|
+
case "http-method":
|
|
26627
|
+
return rejection("http-method", "modern-only-method-not-allowed", 405, new ProtocolError(-32e3, "Method not allowed."), true);
|
|
26628
|
+
case "batch":
|
|
26629
|
+
return rejection("jsonrpc-shape", "modern-only-batch-not-supported", 400, new ProtocolError(ProtocolErrorCode.InvalidRequest, "Bad Request: JSON-RPC batches are not supported by this endpoint"), true);
|
|
26630
|
+
case "response":
|
|
26631
|
+
return rejection("jsonrpc-shape", "modern-only-response-post", 400, new ProtocolError(ProtocolErrorCode.InvalidRequest, "Bad Request: JSON-RPC responses cannot be posted to this endpoint"), true);
|
|
26632
|
+
case "notification":
|
|
26633
|
+
return;
|
|
26634
|
+
case "initialize":
|
|
26635
|
+
case "no-claim": {
|
|
26636
|
+
const requested = route.requestedVersion;
|
|
26637
|
+
return rejection("era-classification", "modern-only-missing-envelope", 400, requested === void 0 ? new ProtocolError(ProtocolErrorCode.UnsupportedProtocolVersion, "Unsupported protocol version: the request did not name a protocol version", { supported: [...supportedVersions] }) : new UnsupportedProtocolVersionError({
|
|
26638
|
+
supported: [...supportedVersions],
|
|
26639
|
+
requested
|
|
26640
|
+
}), true);
|
|
26641
|
+
}
|
|
26642
|
+
}
|
|
26643
|
+
}
|
|
26586
26644
|
function parseSchema(schema, data) {
|
|
26587
26645
|
return z2.safeParse(schema, data);
|
|
26588
26646
|
}
|
|
@@ -26894,6 +26952,9 @@ function withRequestStateValue(ctx, value) {
|
|
|
26894
26952
|
}
|
|
26895
26953
|
};
|
|
26896
26954
|
}
|
|
26955
|
+
function setNegotiatedProtocolVersion(instance, version2) {
|
|
26956
|
+
writeNegotiatedProtocolVersion(instance, version2);
|
|
26957
|
+
}
|
|
26897
26958
|
function isPlainObject$1(value) {
|
|
26898
26959
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
26899
26960
|
}
|
|
@@ -27007,7 +27068,7 @@ function normalizeRawShapeSchema(schema) {
|
|
|
27007
27068
|
if (!isStandardSchema(schema)) throw new TypeError("inputSchema/outputSchema/argsSchema must be a Standard Schema (e.g. z.object({...})) or a raw Zod shape ({ field: z.string() }).");
|
|
27008
27069
|
return schema;
|
|
27009
27070
|
}
|
|
27010
|
-
var z2, BRANDS, OAuthError, SdkErrorCode, SdkError, SdkHttpError, FIRST_MODERN_PROTOCOL_VERSION, TOOL_RESULT_FOREIGN_FAMILY_KEYS, memo$1, REF_REWRITE_DATA_POSITION_KEYS, REF_REWRITE_NAME_MAP_KEYS, requestMethodKeys$1, notificationMethodKeys$1, resultMethodKeys, maps$1, rev2025RequestMethods, rev2025NotificationMethods, NOT_IN_ERA$1, rev2025Codec, memo, CACHEABLE_RESULT_METHODS, RESULT_CACHE_HINT_FALLBACK, ProtocolErrorCode, ProtocolError, ResourceNotFoundError, UrlElicitationRequiredError, UnsupportedProtocolVersionError, MissingRequiredClientCapabilityError, DEFAULT_CACHE_TTL_MS, DEFAULT_CACHE_SCOPE, EXTENDED_RESULT_TYPE_METHODS, INPUT_REQUEST_METHODS_2026, maps, requestMethodKeys, notificationMethodKeys, rev2026RequestMethods, rev2026NotificationMethods, NOT_IN_ERA, REQUIRED_ENVELOPE_KEYS, rev2026Codec, wireResultSchemasMemo, MODERN_WIRE_REVISION, ALL_CODECS, schemas_exports, isJSONRPCRequest, isJSONRPCNotification, isJSONRPCResultResponse, isJSONRPCErrorResponse, isInputRequiredResult, X_MCP_HEADER_KEY, RFC9110_TOKEN, PERMITTED_X_MCP_HEADER_TYPES, NON_REACHABLE_SUBSCHEMA_KEYWORDS, OBJECT_VALUED_SUBSCHEMA_KEYWORDS, HEADER_MISMATCH_ERROR_CODE, INBOUND_VALIDATION_LADDER, LADDER_ERROR_HTTP_STATUS, warnedZodFallback, JSON_SCHEMA_CONVERSION_TARGET, DATETIME_FRACTION_DIGITS, ANNOTATION_ONLY_JSON_SCHEMA_KEYWORDS, ROOT_KEYS, PROPERTY_KEYS_BY_TYPE, SUPPORTED_STRING_FORMATS, inputRequired, REQUEST_STATE_ONLY_LEG_PACING_MS, SPEC_SCHEMA_KEYS, authSchemas, _specTypeSchemas, _isSpecType, specTypeSchemas, isSpecType, DEFAULT_REQUEST_TIMEOUT_MSEC, RESERVED_ENVELOPE_META_KEYS, RETRY_PARAMS_KEYS, NO_REQUEST_STATE, writeNegotiatedProtocolVersion, Protocol, require_content_type, import_content_type, STDIO_DEFAULT_MAX_BUFFER_SIZE, ReadBuffer, TOOL_NAME_REGEX;
|
|
27071
|
+
var z2, BRANDS, OAuthError, SdkErrorCode, SdkError, SdkHttpError, FIRST_MODERN_PROTOCOL_VERSION, SUPPORTED_MODERN_PROTOCOL_VERSIONS, TOOL_RESULT_FOREIGN_FAMILY_KEYS, memo$1, REF_REWRITE_DATA_POSITION_KEYS, REF_REWRITE_NAME_MAP_KEYS, requestMethodKeys$1, notificationMethodKeys$1, resultMethodKeys, maps$1, rev2025RequestMethods, rev2025NotificationMethods, NOT_IN_ERA$1, rev2025Codec, memo, CACHEABLE_RESULT_METHODS, RESULT_CACHE_HINT_FALLBACK, ProtocolErrorCode, ProtocolError, ResourceNotFoundError, UrlElicitationRequiredError, UnsupportedProtocolVersionError, MissingRequiredClientCapabilityError, DEFAULT_CACHE_TTL_MS, DEFAULT_CACHE_SCOPE, EXTENDED_RESULT_TYPE_METHODS, INPUT_REQUEST_METHODS_2026, maps, requestMethodKeys, notificationMethodKeys, rev2026RequestMethods, rev2026NotificationMethods, NOT_IN_ERA, REQUIRED_ENVELOPE_KEYS, rev2026Codec, wireResultSchemasMemo, MODERN_WIRE_REVISION, ALL_CODECS, schemas_exports, isJSONRPCRequest, isJSONRPCNotification, isJSONRPCResultResponse, isJSONRPCErrorResponse, isInputRequiredResult, X_MCP_HEADER_KEY, RFC9110_TOKEN, PERMITTED_X_MCP_HEADER_TYPES, NON_REACHABLE_SUBSCHEMA_KEYWORDS, OBJECT_VALUED_SUBSCHEMA_KEYWORDS, HEADER_MISMATCH_ERROR_CODE, INBOUND_VALIDATION_LADDER, LADDER_ERROR_HTTP_STATUS, warnedZodFallback, JSON_SCHEMA_CONVERSION_TARGET, DATETIME_FRACTION_DIGITS, ANNOTATION_ONLY_JSON_SCHEMA_KEYWORDS, ROOT_KEYS, PROPERTY_KEYS_BY_TYPE, SUPPORTED_STRING_FORMATS, inputRequired, REQUEST_STATE_ONLY_LEG_PACING_MS, SPEC_SCHEMA_KEYS, authSchemas, _specTypeSchemas, _isSpecType, specTypeSchemas, isSpecType, DEFAULT_REQUEST_TIMEOUT_MSEC, RESERVED_ENVELOPE_META_KEYS, RETRY_PARAMS_KEYS, NO_REQUEST_STATE, writeNegotiatedProtocolVersion, Protocol, require_content_type, import_content_type, STDIO_DEFAULT_MAX_BUFFER_SIZE, ReadBuffer, TOOL_NAME_REGEX;
|
|
27011
27072
|
var init_src_CX2iR2pK = __esm({
|
|
27012
27073
|
"node_modules/@modelcontextprotocol/server/dist/src-CX2iR2pK.mjs"() {
|
|
27013
27074
|
init_chunk_Br0eD_fh();
|
|
@@ -27126,6 +27187,7 @@ var init_src_CX2iR2pK = __esm({
|
|
|
27126
27187
|
}
|
|
27127
27188
|
};
|
|
27128
27189
|
FIRST_MODERN_PROTOCOL_VERSION = "2026-07-28";
|
|
27190
|
+
SUPPORTED_MODERN_PROTOCOL_VERSIONS = [FIRST_MODERN_PROTOCOL_VERSION];
|
|
27129
27191
|
TOOL_RESULT_FOREIGN_FAMILY_KEYS = [
|
|
27130
27192
|
"task",
|
|
27131
27193
|
"inputRequests",
|
|
@@ -35930,6 +35992,58 @@ function isCompletable(schema) {
|
|
|
35930
35992
|
function getCompleter(schema) {
|
|
35931
35993
|
return schema[COMPLETABLE_SYMBOL]?.complete;
|
|
35932
35994
|
}
|
|
35995
|
+
function listenFilterAccepts(filter, event) {
|
|
35996
|
+
switch (event.kind) {
|
|
35997
|
+
case "tools_list_changed":
|
|
35998
|
+
return filter.toolsListChanged === true;
|
|
35999
|
+
case "prompts_list_changed":
|
|
36000
|
+
return filter.promptsListChanged === true;
|
|
36001
|
+
case "resources_list_changed":
|
|
36002
|
+
return filter.resourcesListChanged === true;
|
|
36003
|
+
case "resource_updated":
|
|
36004
|
+
return filter.resourceSubscriptions !== void 0 && filter.resourceSubscriptions.includes(event.uri);
|
|
36005
|
+
}
|
|
36006
|
+
}
|
|
36007
|
+
function honoredSubset(requested, capabilities) {
|
|
36008
|
+
const honored = {};
|
|
36009
|
+
const allow = (bit) => capabilities === void 0 || bit === true;
|
|
36010
|
+
if (requested.toolsListChanged === true && allow(capabilities?.tools?.listChanged)) honored.toolsListChanged = true;
|
|
36011
|
+
if (requested.promptsListChanged === true && allow(capabilities?.prompts?.listChanged)) honored.promptsListChanged = true;
|
|
36012
|
+
if (requested.resourcesListChanged === true && allow(capabilities?.resources?.listChanged)) honored.resourcesListChanged = true;
|
|
36013
|
+
if (requested.resourceSubscriptions !== void 0 && requested.resourceSubscriptions.length > 0 && allow(capabilities?.resources?.subscribe)) honored.resourceSubscriptions = [...requested.resourceSubscriptions];
|
|
36014
|
+
return honored;
|
|
36015
|
+
}
|
|
36016
|
+
function stampSubscriptionId(notification, subscriptionId) {
|
|
36017
|
+
return {
|
|
36018
|
+
method: notification.method,
|
|
36019
|
+
params: {
|
|
36020
|
+
...notification.params,
|
|
36021
|
+
_meta: {
|
|
36022
|
+
...notification.params?._meta,
|
|
36023
|
+
[SUBSCRIPTION_ID_META_KEY]: subscriptionId
|
|
36024
|
+
}
|
|
36025
|
+
}
|
|
36026
|
+
};
|
|
36027
|
+
}
|
|
36028
|
+
function parseListenFilter(message) {
|
|
36029
|
+
const outcome = codecForVersion(MODERN_WIRE_REVISION).validateRequest("subscriptions/listen", message);
|
|
36030
|
+
return outcome.ok ? outcome.value.params?.notifications : void 0;
|
|
36031
|
+
}
|
|
36032
|
+
function notificationToServerEvent(method, uri) {
|
|
36033
|
+
switch (method) {
|
|
36034
|
+
case "notifications/tools/list_changed":
|
|
36035
|
+
return { kind: "tools_list_changed" };
|
|
36036
|
+
case "notifications/prompts/list_changed":
|
|
36037
|
+
return { kind: "prompts_list_changed" };
|
|
36038
|
+
case "notifications/resources/list_changed":
|
|
36039
|
+
return { kind: "resources_list_changed" };
|
|
36040
|
+
default:
|
|
36041
|
+
return {
|
|
36042
|
+
kind: "resource_updated",
|
|
36043
|
+
uri: uri ?? ""
|
|
36044
|
+
};
|
|
36045
|
+
}
|
|
36046
|
+
}
|
|
35933
36047
|
function resolveLegacyShimOptions(options) {
|
|
35934
36048
|
if (options?.maxRounds !== void 0 && (!Number.isInteger(options.maxRounds) || options.maxRounds < 1)) throw new RangeError(`inputRequired.maxRounds must be a positive integer (got ${options.maxRounds})`);
|
|
35935
36049
|
if (options?.roundTimeoutMs !== void 0 && (!Number.isFinite(options.roundTimeoutMs) || options.roundTimeoutMs <= 0)) throw new RangeError(`inputRequired.roundTimeoutMs must be a positive number (got ${options.roundTimeoutMs})`);
|
|
@@ -35969,6 +36083,12 @@ function legacyShimFailure(method, message) {
|
|
|
35969
36083
|
};
|
|
35970
36084
|
throw new ProtocolError(ProtocolErrorCode.InternalError, message);
|
|
35971
36085
|
}
|
|
36086
|
+
function installModernOnlyHandlers(server, servedModernVersions) {
|
|
36087
|
+
installDiscoverHandler(server, servedModernVersions);
|
|
36088
|
+
}
|
|
36089
|
+
function serverIdentityOf(server) {
|
|
36090
|
+
return readServerIdentity(server);
|
|
36091
|
+
}
|
|
35972
36092
|
function discoverAdvertisedCapabilities(capabilities) {
|
|
35973
36093
|
return { ...capabilities };
|
|
35974
36094
|
}
|
|
@@ -36021,13 +36141,145 @@ function unwrapOptionalSchema(schema) {
|
|
|
36021
36141
|
if (!isOptionalSchema(schema)) return schema;
|
|
36022
36142
|
return schema.def?.innerType ?? schema;
|
|
36023
36143
|
}
|
|
36024
|
-
var COMPLETABLE_SYMBOL, MAX_TIMER_DELAY_MS, DEFAULT_LEGACY_SHIM_MAX_ROUNDS, DEFAULT_LEGACY_SHIM_ROUND_TIMEOUT_MS, LegacyInputRequiredShim, INPUT_REQUIRED_CAPABLE_METHODS, writeClientIdentity, installDiscoverHandler, readServerIdentity, Server, McpServer, EMPTY_OBJECT_JSON_SCHEMA, EMPTY_COMPLETION_RESULT;
|
|
36144
|
+
var COMPLETABLE_SYMBOL, MAX_TIMER_DELAY_MS, DEFAULT_MAX_SUBSCRIPTIONS, CHANGE_NOTIFICATION_METHODS, StdioListenRouter, DEFAULT_LEGACY_SHIM_MAX_ROUNDS, DEFAULT_LEGACY_SHIM_ROUND_TIMEOUT_MS, LegacyInputRequiredShim, INPUT_REQUIRED_CAPABLE_METHODS, writeClientIdentity, installDiscoverHandler, readServerIdentity, Server, McpServer, EMPTY_OBJECT_JSON_SCHEMA, EMPTY_COMPLETION_RESULT;
|
|
36025
36145
|
var init_mcp_DXXb3Vv3 = __esm({
|
|
36026
36146
|
"node_modules/@modelcontextprotocol/server/dist/mcp-DXXb3Vv3.mjs"() {
|
|
36027
36147
|
init_src_CX2iR2pK();
|
|
36028
36148
|
init_shimsNode();
|
|
36029
36149
|
COMPLETABLE_SYMBOL = /* @__PURE__ */ Symbol.for("mcp.completable");
|
|
36030
36150
|
MAX_TIMER_DELAY_MS = 2 ** 31 - 1;
|
|
36151
|
+
DEFAULT_MAX_SUBSCRIPTIONS = 1024;
|
|
36152
|
+
CHANGE_NOTIFICATION_METHODS = /* @__PURE__ */ new Set([
|
|
36153
|
+
"notifications/tools/list_changed",
|
|
36154
|
+
"notifications/prompts/list_changed",
|
|
36155
|
+
"notifications/resources/list_changed",
|
|
36156
|
+
"notifications/resources/updated"
|
|
36157
|
+
]);
|
|
36158
|
+
StdioListenRouter = class {
|
|
36159
|
+
/** Active subscriptions, keyed by the listen request's JSON-RPC id verbatim. */
|
|
36160
|
+
_subs = /* @__PURE__ */ new Map();
|
|
36161
|
+
/**
|
|
36162
|
+
* The serving instance's declared capabilities. Filled in by the entry
|
|
36163
|
+
* once the modern instance is constructed (the router is created before
|
|
36164
|
+
* the instance exists), so the acknowledged filter is narrowed against
|
|
36165
|
+
* what the server can actually deliver.
|
|
36166
|
+
*/
|
|
36167
|
+
_serverCapabilities;
|
|
36168
|
+
/**
|
|
36169
|
+
* The serving instance's identity, stamped onto the graceful-close
|
|
36170
|
+
* results' `_meta` (the spec's `SubscriptionsListenResultMeta` extends
|
|
36171
|
+
* `ResultMetaObject`). Handed over together with the capabilities.
|
|
36172
|
+
*/
|
|
36173
|
+
_serverInfo;
|
|
36174
|
+
constructor(_maxSubscriptions = DEFAULT_MAX_SUBSCRIPTIONS, serverCapabilities, serverInfo) {
|
|
36175
|
+
this._maxSubscriptions = _maxSubscriptions;
|
|
36176
|
+
this._serverCapabilities = serverCapabilities;
|
|
36177
|
+
this._serverInfo = serverInfo;
|
|
36178
|
+
}
|
|
36179
|
+
/**
|
|
36180
|
+
* Record the serving instance's declared capabilities and identity once
|
|
36181
|
+
* it has been constructed. Called by `serveStdio`'s connect path;
|
|
36182
|
+
* subsequent `serve()` calls narrow the honored filter against the
|
|
36183
|
+
* capabilities, and `teardownAll()` stamps the identity.
|
|
36184
|
+
*/
|
|
36185
|
+
setServerCapabilities(capabilities, serverInfo) {
|
|
36186
|
+
this._serverCapabilities = capabilities;
|
|
36187
|
+
if (serverInfo !== void 0) this._serverInfo = serverInfo;
|
|
36188
|
+
}
|
|
36189
|
+
/** Whether `id` is an active listen subscription on this connection. */
|
|
36190
|
+
has(id) {
|
|
36191
|
+
return this._subs.has(id);
|
|
36192
|
+
}
|
|
36193
|
+
/**
|
|
36194
|
+
* Serve one inbound `subscriptions/listen` request: registers the
|
|
36195
|
+
* subscription and returns the stamped acknowledged notification (or, on
|
|
36196
|
+
* capacity / params rejection, the in-band JSON-RPC error response).
|
|
36197
|
+
*
|
|
36198
|
+
* @throws when called before {@linkcode setServerCapabilities} (or the
|
|
36199
|
+
* constructor) has supplied the serving instance's capabilities. Honoring a
|
|
36200
|
+
* filter without knowing the server's advertised capabilities would fail
|
|
36201
|
+
* open (deliver unadvertised types); the entry guarantees capabilities are
|
|
36202
|
+
* set before any listen request is routed here.
|
|
36203
|
+
*/
|
|
36204
|
+
serve(message) {
|
|
36205
|
+
if (this._serverCapabilities === void 0) throw new Error("StdioListenRouter.serve() called before setServerCapabilities(); refusing to honor a filter without capabilities");
|
|
36206
|
+
if (this._subs.size >= this._maxSubscriptions) return {
|
|
36207
|
+
jsonrpc: "2.0",
|
|
36208
|
+
id: message.id,
|
|
36209
|
+
error: {
|
|
36210
|
+
code: -32603,
|
|
36211
|
+
message: "Subscription limit reached"
|
|
36212
|
+
}
|
|
36213
|
+
};
|
|
36214
|
+
const filter = parseListenFilter(message);
|
|
36215
|
+
if (filter === void 0) return {
|
|
36216
|
+
jsonrpc: "2.0",
|
|
36217
|
+
id: message.id,
|
|
36218
|
+
error: {
|
|
36219
|
+
code: -32602,
|
|
36220
|
+
message: "Invalid params: 'notifications' is required and must be a valid SubscriptionFilter"
|
|
36221
|
+
}
|
|
36222
|
+
};
|
|
36223
|
+
const honored = honoredSubset(filter, this._serverCapabilities);
|
|
36224
|
+
this._subs.set(message.id, honored);
|
|
36225
|
+
return stampSubscriptionId({
|
|
36226
|
+
method: "notifications/subscriptions/acknowledged",
|
|
36227
|
+
params: { notifications: honored }
|
|
36228
|
+
}, message.id);
|
|
36229
|
+
}
|
|
36230
|
+
/**
|
|
36231
|
+
* Tear down one subscription (inbound `notifications/cancelled`). Returns
|
|
36232
|
+
* `true` when a subscription was removed. After this call NOTHING further
|
|
36233
|
+
* is delivered for that subscription id (the post-cancel hardening).
|
|
36234
|
+
*/
|
|
36235
|
+
cancel(id) {
|
|
36236
|
+
return this._subs.delete(id);
|
|
36237
|
+
}
|
|
36238
|
+
/**
|
|
36239
|
+
* Route an outbound notification through the active subscriptions.
|
|
36240
|
+
*
|
|
36241
|
+
* - For a subscription-gated change notification, returns one stamped copy
|
|
36242
|
+
* per subscription that opted in to it (an empty array means it is
|
|
36243
|
+
* dropped — the modern era never delivers an un-requested change type).
|
|
36244
|
+
* - For any other outbound message, returns `'passthrough'` (the entry
|
|
36245
|
+
* forwards it as-is).
|
|
36246
|
+
*/
|
|
36247
|
+
routeOutbound(message) {
|
|
36248
|
+
if (!CHANGE_NOTIFICATION_METHODS.has(message.method)) return "passthrough";
|
|
36249
|
+
const uriParam = message.params?.["uri"];
|
|
36250
|
+
const uri = typeof uriParam === "string" ? uriParam : void 0;
|
|
36251
|
+
const event = notificationToServerEvent(message.method, uri);
|
|
36252
|
+
const out = [];
|
|
36253
|
+
for (const [subscriptionId, filter] of this._subs) if (listenFilterAccepts(filter, event)) out.push(stampSubscriptionId({
|
|
36254
|
+
method: message.method,
|
|
36255
|
+
params: message.params ?? {}
|
|
36256
|
+
}, subscriptionId));
|
|
36257
|
+
return out;
|
|
36258
|
+
}
|
|
36259
|
+
/**
|
|
36260
|
+
* Server-side graceful teardown of every active subscription: returns the
|
|
36261
|
+
* empty `subscriptions/listen` JSON-RPC result for each subscription id —
|
|
36262
|
+
* the spec's graceful-close signal, `_meta` carrying the subscription id
|
|
36263
|
+
* and the serving instance's identity — for the entry to emit before
|
|
36264
|
+
* closing the wire. Clears the set so nothing further is delivered.
|
|
36265
|
+
*/
|
|
36266
|
+
teardownAll() {
|
|
36267
|
+
const out = [];
|
|
36268
|
+
for (const id of this._subs.keys()) out.push({
|
|
36269
|
+
jsonrpc: "2.0",
|
|
36270
|
+
id,
|
|
36271
|
+
result: {
|
|
36272
|
+
resultType: "complete",
|
|
36273
|
+
_meta: {
|
|
36274
|
+
[SUBSCRIPTION_ID_META_KEY]: id,
|
|
36275
|
+
...this._serverInfo !== void 0 && { [SERVER_INFO_META_KEY]: this._serverInfo }
|
|
36276
|
+
}
|
|
36277
|
+
}
|
|
36278
|
+
});
|
|
36279
|
+
this._subs.clear();
|
|
36280
|
+
return out;
|
|
36281
|
+
}
|
|
36282
|
+
};
|
|
36031
36283
|
DEFAULT_LEGACY_SHIM_MAX_ROUNDS = 8;
|
|
36032
36284
|
DEFAULT_LEGACY_SHIM_ROUND_TIMEOUT_MS = 6e5;
|
|
36033
36285
|
LegacyInputRequiredShim = class {
|
|
@@ -37259,7 +37511,319 @@ var init_mcp_DXXb3Vv3 = __esm({
|
|
|
37259
37511
|
});
|
|
37260
37512
|
|
|
37261
37513
|
// node_modules/@modelcontextprotocol/server/dist/stdio.mjs
|
|
37262
|
-
|
|
37514
|
+
function classifyOpeningMessage(message) {
|
|
37515
|
+
const params = message.params;
|
|
37516
|
+
if (message.method === "initialize" && !carriesValidModernEnvelopeClaim(params)) {
|
|
37517
|
+
const requestedVersion = params !== null && typeof params === "object" && typeof params.protocolVersion === "string" ? params.protocolVersion : void 0;
|
|
37518
|
+
return {
|
|
37519
|
+
kind: "legacy",
|
|
37520
|
+
reason: "initialize",
|
|
37521
|
+
...requestedVersion !== void 0 && { requestedVersion }
|
|
37522
|
+
};
|
|
37523
|
+
}
|
|
37524
|
+
if (!hasEnvelopeClaim(params)) return {
|
|
37525
|
+
kind: "legacy",
|
|
37526
|
+
reason: "no-claim"
|
|
37527
|
+
};
|
|
37528
|
+
const meta3 = requestMetaOf(params);
|
|
37529
|
+
const firstIssue = (meta3 === void 0 ? [] : validateEnvelopeMeta(meta3))[0];
|
|
37530
|
+
if (firstIssue !== void 0) return {
|
|
37531
|
+
kind: "invalid-envelope",
|
|
37532
|
+
issue: firstIssue
|
|
37533
|
+
};
|
|
37534
|
+
const claimedVersion = envelopeClaimVersion(params);
|
|
37535
|
+
if (claimedVersion === void 0 || !SUPPORTED_MODERN_PROTOCOL_VERSIONS.includes(claimedVersion)) return {
|
|
37536
|
+
kind: "unsupported-revision",
|
|
37537
|
+
requested: claimedVersion ?? "unknown"
|
|
37538
|
+
};
|
|
37539
|
+
return {
|
|
37540
|
+
kind: "modern",
|
|
37541
|
+
revision: claimedVersion,
|
|
37542
|
+
classification: {
|
|
37543
|
+
era: "modern",
|
|
37544
|
+
revision: claimedVersion
|
|
37545
|
+
}
|
|
37546
|
+
};
|
|
37547
|
+
}
|
|
37548
|
+
function serveStdio(factory, options = {}) {
|
|
37549
|
+
const legacyMode = options.legacy ?? "serve";
|
|
37550
|
+
const wire = options.transport ?? new StdioServerTransport();
|
|
37551
|
+
let state = { phase: "opening" };
|
|
37552
|
+
let discarding;
|
|
37553
|
+
let closing = false;
|
|
37554
|
+
const isTornDown = () => closing || state.phase === "closed";
|
|
37555
|
+
const reportError = (error62) => {
|
|
37556
|
+
try {
|
|
37557
|
+
options.onerror?.(error62);
|
|
37558
|
+
} catch {
|
|
37559
|
+
}
|
|
37560
|
+
};
|
|
37561
|
+
const writeErrorResponse = (id, code, message, data) => wire.send({
|
|
37562
|
+
jsonrpc: "2.0",
|
|
37563
|
+
id,
|
|
37564
|
+
error: {
|
|
37565
|
+
code,
|
|
37566
|
+
message,
|
|
37567
|
+
...data !== void 0 && { data }
|
|
37568
|
+
}
|
|
37569
|
+
}).catch((error62) => reportError(toError(error62)));
|
|
37570
|
+
const listenRouter = new StdioListenRouter(options.maxSubscriptions ?? DEFAULT_MAX_SUBSCRIPTIONS);
|
|
37571
|
+
const modernOutboundIntercept = (message) => {
|
|
37572
|
+
if (!isJSONRPCNotification(message)) return void 0;
|
|
37573
|
+
const routed = listenRouter.routeOutbound(message);
|
|
37574
|
+
if (routed === "passthrough") return void 0;
|
|
37575
|
+
for (const stamped of routed) wire.send({
|
|
37576
|
+
jsonrpc: "2.0",
|
|
37577
|
+
...stamped
|
|
37578
|
+
}).catch((error62) => reportError(toError(error62)));
|
|
37579
|
+
return "handled";
|
|
37580
|
+
};
|
|
37581
|
+
const tryServeListen = async (message) => {
|
|
37582
|
+
if (isJSONRPCRequest(message) && message.method === "subscriptions/listen") {
|
|
37583
|
+
const meta3 = requestMetaOf(message.params);
|
|
37584
|
+
const issue2 = hasEnvelopeClaim(message.params) ? (meta3 === void 0 ? [] : validateEnvelopeMeta(meta3))[0] : {
|
|
37585
|
+
key: "_meta",
|
|
37586
|
+
problem: "the per-request envelope is required on protocol revision 2026-07-28"
|
|
37587
|
+
};
|
|
37588
|
+
const claimedVersion = envelopeClaimVersion(message.params);
|
|
37589
|
+
let reply;
|
|
37590
|
+
if (issue2 !== void 0) reply = {
|
|
37591
|
+
jsonrpc: "2.0",
|
|
37592
|
+
id: message.id,
|
|
37593
|
+
error: {
|
|
37594
|
+
code: -32602,
|
|
37595
|
+
message: `Invalid _meta envelope: ${issue2.key}: ${issue2.problem}`
|
|
37596
|
+
}
|
|
37597
|
+
};
|
|
37598
|
+
else if (claimedVersion === void 0 || !SUPPORTED_MODERN_PROTOCOL_VERSIONS.includes(claimedVersion)) {
|
|
37599
|
+
const error62 = new UnsupportedProtocolVersionError({
|
|
37600
|
+
supported: [...SUPPORTED_MODERN_PROTOCOL_VERSIONS],
|
|
37601
|
+
requested: claimedVersion ?? "unknown"
|
|
37602
|
+
});
|
|
37603
|
+
reply = {
|
|
37604
|
+
jsonrpc: "2.0",
|
|
37605
|
+
id: message.id,
|
|
37606
|
+
error: {
|
|
37607
|
+
code: error62.code,
|
|
37608
|
+
message: error62.message,
|
|
37609
|
+
data: error62.data
|
|
37610
|
+
}
|
|
37611
|
+
};
|
|
37612
|
+
} else reply = listenRouter.serve(message);
|
|
37613
|
+
await wire.send("error" in reply ? reply : {
|
|
37614
|
+
jsonrpc: "2.0",
|
|
37615
|
+
method: reply.method,
|
|
37616
|
+
params: reply.params
|
|
37617
|
+
}).catch((error62) => reportError(toError(error62)));
|
|
37618
|
+
return true;
|
|
37619
|
+
}
|
|
37620
|
+
if (isJSONRPCNotification(message) && message.method === "notifications/cancelled") {
|
|
37621
|
+
const cancelledId = message.params?.requestId;
|
|
37622
|
+
if (cancelledId !== void 0 && listenRouter.cancel(cancelledId)) return true;
|
|
37623
|
+
}
|
|
37624
|
+
return false;
|
|
37625
|
+
};
|
|
37626
|
+
const answerLegacyRejection = (request, reason, requestedVersion) => {
|
|
37627
|
+
const rejection2 = modernOnlyStrictRejection({
|
|
37628
|
+
kind: "legacy",
|
|
37629
|
+
reason,
|
|
37630
|
+
...requestedVersion !== void 0 && { requestedVersion }
|
|
37631
|
+
}, SUPPORTED_MODERN_PROTOCOL_VERSIONS);
|
|
37632
|
+
if (rejection2 === void 0) return Promise.resolve();
|
|
37633
|
+
reportError(/* @__PURE__ */ new Error(`Rejected 2025-era request on a modern-only stdio connection (${rejection2.cell}): ${rejection2.message}`));
|
|
37634
|
+
return writeErrorResponse(request.id, rejection2.code, rejection2.message, rejection2.data);
|
|
37635
|
+
};
|
|
37636
|
+
const onInstanceClosed = (channel) => {
|
|
37637
|
+
if (closing || channel === discarding) return;
|
|
37638
|
+
closeAll();
|
|
37639
|
+
};
|
|
37640
|
+
const connectInstance = async (era, revision) => {
|
|
37641
|
+
const product = await factory({ era });
|
|
37642
|
+
const server = product instanceof McpServer ? product.server : product;
|
|
37643
|
+
if (era === "modern") {
|
|
37644
|
+
setNegotiatedProtocolVersion(server, revision);
|
|
37645
|
+
installModernOnlyHandlers(server, SUPPORTED_MODERN_PROTOCOL_VERSIONS);
|
|
37646
|
+
listenRouter.setServerCapabilities(server.getCapabilities(), serverIdentityOf(server));
|
|
37647
|
+
}
|
|
37648
|
+
const channel = new StdioConnectionChannel(wire, () => onInstanceClosed(channel), era === "modern" ? modernOutboundIntercept : void 0);
|
|
37649
|
+
await product.connect(channel);
|
|
37650
|
+
return {
|
|
37651
|
+
product,
|
|
37652
|
+
channel
|
|
37653
|
+
};
|
|
37654
|
+
};
|
|
37655
|
+
const disposeLateInstance = (instance) => instance.product.close().catch((error62) => reportError(toError(error62)));
|
|
37656
|
+
const discardProbeInstance = async (instance) => {
|
|
37657
|
+
discarding = instance.channel;
|
|
37658
|
+
try {
|
|
37659
|
+
if (!await instance.channel.whenRequestsAnswered(DISCARD_ANSWER_TIMEOUT_MS)) reportError(/* @__PURE__ */ new Error(`Discarded the probe instance with requests still unanswered after ${DISCARD_ANSWER_TIMEOUT_MS}ms; continuing with the fallback`));
|
|
37660
|
+
await instance.product.close();
|
|
37661
|
+
} catch (error62) {
|
|
37662
|
+
reportError(toError(error62));
|
|
37663
|
+
} finally {
|
|
37664
|
+
discarding = void 0;
|
|
37665
|
+
}
|
|
37666
|
+
};
|
|
37667
|
+
const processMessage = async (message) => {
|
|
37668
|
+
if (state.phase === "closed") return;
|
|
37669
|
+
if (state.phase === "pinned") {
|
|
37670
|
+
if (state.era === "modern" && isJSONRPCRequest(message) && message.method === "initialize" && !carriesValidModernEnvelopeClaim(message.params)) {
|
|
37671
|
+
await answerLegacyRejection(message, "initialize", message.params !== null && typeof message.params === "object" && typeof message.params.protocolVersion === "string" ? message.params.protocolVersion : void 0);
|
|
37672
|
+
return;
|
|
37673
|
+
}
|
|
37674
|
+
if (state.era === "modern" && await tryServeListen(message)) return;
|
|
37675
|
+
state.instance.channel.deliver(message);
|
|
37676
|
+
return;
|
|
37677
|
+
}
|
|
37678
|
+
if (!isJSONRPCRequest(message) && !isJSONRPCNotification(message)) {
|
|
37679
|
+
reportError(/* @__PURE__ */ new Error("Discarded a JSON-RPC response received before the connection negotiated an era"));
|
|
37680
|
+
return;
|
|
37681
|
+
}
|
|
37682
|
+
const opening = classifyOpeningMessage(message);
|
|
37683
|
+
switch (opening.kind) {
|
|
37684
|
+
case "invalid-envelope": {
|
|
37685
|
+
const detail = `Invalid _meta envelope for protocol revision 2026-07-28: ${opening.issue.key}: ${opening.issue.problem}`;
|
|
37686
|
+
if (isJSONRPCRequest(message)) await writeErrorResponse(message.id, ProtocolErrorCode.InvalidParams, detail, { envelope: opening.issue });
|
|
37687
|
+
else reportError(/* @__PURE__ */ new Error(`Discarded a notification with a malformed envelope: ${detail}`));
|
|
37688
|
+
return;
|
|
37689
|
+
}
|
|
37690
|
+
case "unsupported-revision":
|
|
37691
|
+
if (isJSONRPCRequest(message)) {
|
|
37692
|
+
const error62 = new UnsupportedProtocolVersionError({
|
|
37693
|
+
supported: [...SUPPORTED_MODERN_PROTOCOL_VERSIONS],
|
|
37694
|
+
requested: opening.requested
|
|
37695
|
+
});
|
|
37696
|
+
reportError(error62);
|
|
37697
|
+
await writeErrorResponse(message.id, error62.code, error62.message, error62.data);
|
|
37698
|
+
} else reportError(/* @__PURE__ */ new Error(`Discarded a notification claiming unsupported protocol revision ${opening.requested}`));
|
|
37699
|
+
return;
|
|
37700
|
+
case "modern":
|
|
37701
|
+
if (isJSONRPCRequest(message) && message.method === "server/discover") {
|
|
37702
|
+
if (state.phase === "probe") {
|
|
37703
|
+
state.instance.channel.deliver(message, { classification: opening.classification });
|
|
37704
|
+
return;
|
|
37705
|
+
}
|
|
37706
|
+
const instance = await connectInstance("modern", opening.revision);
|
|
37707
|
+
if (isTornDown()) {
|
|
37708
|
+
await disposeLateInstance(instance);
|
|
37709
|
+
return;
|
|
37710
|
+
}
|
|
37711
|
+
state = {
|
|
37712
|
+
phase: "probe",
|
|
37713
|
+
instance
|
|
37714
|
+
};
|
|
37715
|
+
instance.channel.deliver(message, { classification: opening.classification });
|
|
37716
|
+
return;
|
|
37717
|
+
}
|
|
37718
|
+
if (state.phase === "probe") {
|
|
37719
|
+
if (isJSONRPCNotification(message)) {
|
|
37720
|
+
state.instance.channel.deliver(message, { classification: opening.classification });
|
|
37721
|
+
return;
|
|
37722
|
+
}
|
|
37723
|
+
state = {
|
|
37724
|
+
phase: "pinned",
|
|
37725
|
+
era: "modern",
|
|
37726
|
+
instance: state.instance
|
|
37727
|
+
};
|
|
37728
|
+
} else {
|
|
37729
|
+
const instance = await connectInstance("modern", opening.revision);
|
|
37730
|
+
if (isTornDown()) {
|
|
37731
|
+
await disposeLateInstance(instance);
|
|
37732
|
+
return;
|
|
37733
|
+
}
|
|
37734
|
+
state = {
|
|
37735
|
+
phase: "pinned",
|
|
37736
|
+
era: "modern",
|
|
37737
|
+
instance
|
|
37738
|
+
};
|
|
37739
|
+
}
|
|
37740
|
+
if (await tryServeListen(message)) return;
|
|
37741
|
+
state.instance.channel.deliver(message, { classification: opening.classification });
|
|
37742
|
+
return;
|
|
37743
|
+
case "legacy": {
|
|
37744
|
+
if (legacyMode === "reject") {
|
|
37745
|
+
if (isJSONRPCRequest(message)) await answerLegacyRejection(message, opening.reason, opening.requestedVersion);
|
|
37746
|
+
return;
|
|
37747
|
+
}
|
|
37748
|
+
if (state.phase === "probe") {
|
|
37749
|
+
await discardProbeInstance(state.instance);
|
|
37750
|
+
if (isTornDown()) return;
|
|
37751
|
+
state = { phase: "opening" };
|
|
37752
|
+
}
|
|
37753
|
+
const instance = await connectInstance("legacy");
|
|
37754
|
+
if (isTornDown()) {
|
|
37755
|
+
await disposeLateInstance(instance);
|
|
37756
|
+
return;
|
|
37757
|
+
}
|
|
37758
|
+
state = {
|
|
37759
|
+
phase: "pinned",
|
|
37760
|
+
era: "legacy",
|
|
37761
|
+
instance
|
|
37762
|
+
};
|
|
37763
|
+
state.instance.channel.deliver(message);
|
|
37764
|
+
return;
|
|
37765
|
+
}
|
|
37766
|
+
}
|
|
37767
|
+
};
|
|
37768
|
+
const queue = [];
|
|
37769
|
+
let pumping = false;
|
|
37770
|
+
const pump = async () => {
|
|
37771
|
+
if (pumping) return;
|
|
37772
|
+
pumping = true;
|
|
37773
|
+
try {
|
|
37774
|
+
while (queue.length > 0) {
|
|
37775
|
+
const message = queue.shift();
|
|
37776
|
+
try {
|
|
37777
|
+
await processMessage(message);
|
|
37778
|
+
} catch (error62) {
|
|
37779
|
+
if (isJSONRPCRequest(message)) await writeErrorResponse(message.id, ProtocolErrorCode.InternalError, "Internal server error");
|
|
37780
|
+
reportError(toError(error62));
|
|
37781
|
+
}
|
|
37782
|
+
}
|
|
37783
|
+
} finally {
|
|
37784
|
+
pumping = false;
|
|
37785
|
+
}
|
|
37786
|
+
};
|
|
37787
|
+
const closeAll = async () => {
|
|
37788
|
+
if (closing || state.phase === "closed") return;
|
|
37789
|
+
closing = true;
|
|
37790
|
+
const current = state;
|
|
37791
|
+
state = { phase: "closed" };
|
|
37792
|
+
for (const result of listenRouter.teardownAll()) await wire.send(result).catch((error62) => reportError(toError(error62)));
|
|
37793
|
+
if (current.phase === "probe" || current.phase === "pinned") await current.instance.product.close().catch((error62) => reportError(toError(error62)));
|
|
37794
|
+
await wire.close().catch((error62) => reportError(toError(error62)));
|
|
37795
|
+
};
|
|
37796
|
+
wire.onmessage = (message) => {
|
|
37797
|
+
queue.push(message);
|
|
37798
|
+
pump();
|
|
37799
|
+
};
|
|
37800
|
+
wire.onerror = (error62) => {
|
|
37801
|
+
reportError(error62);
|
|
37802
|
+
if (state.phase === "probe" || state.phase === "pinned") state.instance.channel.onerror?.(error62);
|
|
37803
|
+
};
|
|
37804
|
+
wire.onclose = () => {
|
|
37805
|
+
if (closing || state.phase === "closed") return;
|
|
37806
|
+
closing = true;
|
|
37807
|
+
const current = state;
|
|
37808
|
+
state = { phase: "closed" };
|
|
37809
|
+
if (current.phase === "probe" || current.phase === "pinned") current.instance.product.close().catch((error62) => reportError(toError(error62)));
|
|
37810
|
+
};
|
|
37811
|
+
const started = wire.start().catch((error62) => {
|
|
37812
|
+
reportError(toError(error62));
|
|
37813
|
+
throw error62;
|
|
37814
|
+
});
|
|
37815
|
+
started.catch(() => {
|
|
37816
|
+
});
|
|
37817
|
+
return { close: async () => {
|
|
37818
|
+
await started.catch(() => {
|
|
37819
|
+
});
|
|
37820
|
+
await closeAll();
|
|
37821
|
+
} };
|
|
37822
|
+
}
|
|
37823
|
+
function toError(value) {
|
|
37824
|
+
return value instanceof Error ? value : new Error(String(value));
|
|
37825
|
+
}
|
|
37826
|
+
var StdioServerTransport, DISCARD_ANSWER_TIMEOUT_MS, StdioConnectionChannel;
|
|
37263
37827
|
var init_stdio = __esm({
|
|
37264
37828
|
"node_modules/@modelcontextprotocol/server/dist/stdio.mjs"() {
|
|
37265
37829
|
init_mcp_DXXb3Vv3();
|
|
@@ -37353,6 +37917,88 @@ var init_stdio = __esm({
|
|
|
37353
37917
|
});
|
|
37354
37918
|
}
|
|
37355
37919
|
};
|
|
37920
|
+
DISCARD_ANSWER_TIMEOUT_MS = 3e3;
|
|
37921
|
+
StdioConnectionChannel = class {
|
|
37922
|
+
onclose;
|
|
37923
|
+
onerror;
|
|
37924
|
+
onmessage;
|
|
37925
|
+
_closed = false;
|
|
37926
|
+
/** Request ids the entry delivered to the instance that the instance has not yet answered. */
|
|
37927
|
+
_pendingRequests = /* @__PURE__ */ new Set();
|
|
37928
|
+
_drainWaiters = [];
|
|
37929
|
+
constructor(_wire, _onInstanceClose, _outboundIntercept) {
|
|
37930
|
+
this._wire = _wire;
|
|
37931
|
+
this._onInstanceClose = _onInstanceClose;
|
|
37932
|
+
this._outboundIntercept = _outboundIntercept;
|
|
37933
|
+
}
|
|
37934
|
+
async start() {
|
|
37935
|
+
}
|
|
37936
|
+
async send(message, options) {
|
|
37937
|
+
if (isJSONRPCResultResponse(message) || isJSONRPCErrorResponse(message)) {
|
|
37938
|
+
const { id } = message;
|
|
37939
|
+
if (id !== void 0) this._settle(id);
|
|
37940
|
+
}
|
|
37941
|
+
if (this._closed) return;
|
|
37942
|
+
if (this._outboundIntercept?.(message) === "handled") return;
|
|
37943
|
+
return this._wire.send(message, options);
|
|
37944
|
+
}
|
|
37945
|
+
setProtocolVersion = (version2) => {
|
|
37946
|
+
this._wire.setProtocolVersion?.(version2);
|
|
37947
|
+
};
|
|
37948
|
+
/** Forwards one inbound message to the connected instance. */
|
|
37949
|
+
deliver(message, extra) {
|
|
37950
|
+
if (this._closed) return;
|
|
37951
|
+
if (isJSONRPCRequest(message)) this._pendingRequests.add(message.id);
|
|
37952
|
+
else if (isJSONRPCNotification(message) && message.method === "notifications/cancelled") {
|
|
37953
|
+
const cancelledId = message.params?.requestId;
|
|
37954
|
+
if (cancelledId !== void 0) this._settle(cancelledId);
|
|
37955
|
+
}
|
|
37956
|
+
this.onmessage?.(message, extra);
|
|
37957
|
+
}
|
|
37958
|
+
/**
|
|
37959
|
+
* Resolves once every request delivered to the instance has been answered
|
|
37960
|
+
* through {@linkcode send}, settled by a delivered cancellation, or the
|
|
37961
|
+
* channel has been closed and nothing further can be answered. The wait is
|
|
37962
|
+
* bounded by `timeoutMs` as a backstop so no edge can hold the caller
|
|
37963
|
+
* indefinitely; resolves `false` only when the bound elapsed with requests
|
|
37964
|
+
* still unanswered. Used by the probe-discard path so a probe request the
|
|
37965
|
+
* entry accepted is never silently dropped.
|
|
37966
|
+
*/
|
|
37967
|
+
async whenRequestsAnswered(timeoutMs) {
|
|
37968
|
+
if (this._closed || this._pendingRequests.size === 0) return true;
|
|
37969
|
+
return await new Promise((resolve2) => {
|
|
37970
|
+
const waiter = () => {
|
|
37971
|
+
clearTimeout(timer);
|
|
37972
|
+
resolve2(true);
|
|
37973
|
+
};
|
|
37974
|
+
const timer = setTimeout(() => {
|
|
37975
|
+
this._drainWaiters = this._drainWaiters.filter((pending) => pending !== waiter);
|
|
37976
|
+
resolve2(false);
|
|
37977
|
+
}, timeoutMs);
|
|
37978
|
+
this._drainWaiters.push(waiter);
|
|
37979
|
+
});
|
|
37980
|
+
}
|
|
37981
|
+
async close() {
|
|
37982
|
+
if (this._closed) return;
|
|
37983
|
+
this._closed = true;
|
|
37984
|
+
this._pendingRequests.clear();
|
|
37985
|
+
this._releaseDrainWaiters();
|
|
37986
|
+
try {
|
|
37987
|
+
this._onInstanceClose();
|
|
37988
|
+
} finally {
|
|
37989
|
+
this.onclose?.();
|
|
37990
|
+
}
|
|
37991
|
+
}
|
|
37992
|
+
_settle(id) {
|
|
37993
|
+
this._pendingRequests.delete(id);
|
|
37994
|
+
if (this._pendingRequests.size === 0) this._releaseDrainWaiters();
|
|
37995
|
+
}
|
|
37996
|
+
_releaseDrainWaiters() {
|
|
37997
|
+
const waiters = this._drainWaiters;
|
|
37998
|
+
this._drainWaiters = [];
|
|
37999
|
+
for (const waiter of waiters) waiter();
|
|
38000
|
+
}
|
|
38001
|
+
};
|
|
37356
38002
|
}
|
|
37357
38003
|
});
|
|
37358
38004
|
|
|
@@ -57858,7 +58504,7 @@ async function createMcpServer(opts) {
|
|
|
57858
58504
|
}
|
|
57859
58505
|
return server;
|
|
57860
58506
|
}
|
|
57861
|
-
function withGracefulShutdown(
|
|
58507
|
+
function withGracefulShutdown(target, opts = {}) {
|
|
57862
58508
|
const shouldExit = opts.exit ?? true;
|
|
57863
58509
|
let shuttingDown = false;
|
|
57864
58510
|
const handler = (signal) => {
|
|
@@ -57869,7 +58515,7 @@ function withGracefulShutdown(server, opts = {}) {
|
|
|
57869
58515
|
try {
|
|
57870
58516
|
if (opts.onSignal)
|
|
57871
58517
|
await opts.onSignal(signal);
|
|
57872
|
-
await
|
|
58518
|
+
await target.close();
|
|
57873
58519
|
} catch (err) {
|
|
57874
58520
|
console.error(`[mcp-utils] error during graceful shutdown on ${signal}: ${err instanceof Error ? err.message : String(err)}`);
|
|
57875
58521
|
} finally {
|
|
@@ -57881,16 +58527,26 @@ function withGracefulShutdown(server, opts = {}) {
|
|
|
57881
58527
|
process.on("SIGINT", () => handler("SIGINT"));
|
|
57882
58528
|
process.on("SIGTERM", () => handler("SIGTERM"));
|
|
57883
58529
|
}
|
|
57884
|
-
|
|
57885
|
-
|
|
58530
|
+
function runMcp(opts) {
|
|
58531
|
+
if (opts.banner !== void 0) {
|
|
58532
|
+
console.error(opts.banner);
|
|
58533
|
+
}
|
|
58534
|
+
const spec = opts.transport ?? "stdio";
|
|
58535
|
+
const handle = serveStdio(() => createMcpServer({ ...opts, banner: void 0 }), {
|
|
58536
|
+
legacy: opts.legacy ?? "serve",
|
|
58537
|
+
onerror: opts.onerror ?? ((error62) => {
|
|
58538
|
+
console.error(`[mcp-utils] stdio server error: ${redactSecrets(error62.message)}`);
|
|
58539
|
+
}),
|
|
58540
|
+
// `'stdio'` means "let the entry make its own StdioServerTransport over
|
|
58541
|
+
// this process"; anything else is the caller's transport, which the entry
|
|
58542
|
+
// then owns (it starts it, pumps it, and closes it with the handle).
|
|
58543
|
+
...spec === "stdio" ? {} : { transport: spec }
|
|
58544
|
+
});
|
|
57886
58545
|
const shutdown = opts.shutdown ?? true;
|
|
57887
58546
|
if (shutdown !== false) {
|
|
57888
|
-
withGracefulShutdown(
|
|
58547
|
+
withGracefulShutdown(handle, shutdown === true ? {} : shutdown);
|
|
57889
58548
|
}
|
|
57890
|
-
|
|
57891
|
-
const transport = spec === "stdio" ? new StdioServerTransport() : spec;
|
|
57892
|
-
await server.connect(transport);
|
|
57893
|
-
return server;
|
|
58549
|
+
return handle;
|
|
57894
58550
|
}
|
|
57895
58551
|
var SERVER_PROTOCOL_VERSIONS;
|
|
57896
58552
|
var init_server = __esm({
|
|
@@ -58536,7 +59192,7 @@ async function loadStdioDotenv() {
|
|
|
58536
59192
|
}
|
|
58537
59193
|
|
|
58538
59194
|
// src/version.ts
|
|
58539
|
-
var VERSION = "2.
|
|
59195
|
+
var VERSION = "2.1.1";
|
|
58540
59196
|
|
|
58541
59197
|
// src/errors.ts
|
|
58542
59198
|
init_dist2();
|
|
@@ -59757,7 +60413,7 @@ async function withProgressHeartbeat(extra, message, fn) {
|
|
|
59757
60413
|
if (active) {
|
|
59758
60414
|
console.error(`[gemini-mcp] heartbeat active: progressToken present, interval=${intervalMs}ms \u2014 ${message}`);
|
|
59759
60415
|
} else {
|
|
59760
|
-
const reason = progressToken === void 0 ? "no progressToken from host (host cannot extend its tools/call timeout; long calls will hit it)" : !send ? "
|
|
60416
|
+
const reason = progressToken === void 0 ? "no progressToken from host (host cannot extend its tools/call timeout; long calls will hit it)" : !send ? "no mcpReq.notify on the request extra (SDK v2 renamed v1's sendNotification; without it there is no channel to send progress on)" : "heartbeat disabled (GEMINI_HEARTBEAT_MS=0)";
|
|
59761
60417
|
console.error(`[gemini-mcp] heartbeat inactive: ${reason} \u2014 ${message}`);
|
|
59762
60418
|
}
|
|
59763
60419
|
}
|
package/dist/tools/shared.js
CHANGED
|
@@ -376,7 +376,7 @@ export async function withProgressHeartbeat(extra, message, fn) {
|
|
|
376
376
|
const reason = progressToken === undefined
|
|
377
377
|
? 'no progressToken from host (host cannot extend its tools/call timeout; long calls will hit it)'
|
|
378
378
|
: !send
|
|
379
|
-
? '
|
|
379
|
+
? 'no mcpReq.notify on the request extra (SDK v2 renamed v1\'s sendNotification; without it there is no channel to send progress on)'
|
|
380
380
|
: 'heartbeat disabled (GEMINI_HEARTBEAT_MS=0)';
|
|
381
381
|
console.error(`[gemini-mcp] heartbeat inactive: ${reason} — ${message}`);
|
|
382
382
|
}
|
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.
|
|
2
|
+
export const VERSION = '2.1.1'; // x-release-please-version
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@chrischall/gemini-mcp",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.1.1",
|
|
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,7 +46,7 @@
|
|
|
46
46
|
"typecheck": "tsc -p tsconfig.test.json"
|
|
47
47
|
},
|
|
48
48
|
"dependencies": {
|
|
49
|
-
"@chrischall/mcp-utils": "^0.
|
|
49
|
+
"@chrischall/mcp-utils": "^1.0.0",
|
|
50
50
|
"@modelcontextprotocol/server": "^2.0.0",
|
|
51
51
|
"dotenv": "^17.4.0",
|
|
52
52
|
"zod": "^4.6.2"
|
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.
|
|
9
|
+
"version": "2.1.1",
|
|
10
10
|
"packages": [
|
|
11
11
|
{
|
|
12
12
|
"registryType": "npm",
|
|
13
13
|
"identifier": "@chrischall/gemini-mcp",
|
|
14
|
-
"version": "2.
|
|
14
|
+
"version": "2.1.1",
|
|
15
15
|
"transport": {
|
|
16
16
|
"type": "stdio"
|
|
17
17
|
},
|