honeybook-mcp 1.2.3 → 1.2.5
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/README.md +2 -1
- package/dist/bundle.js +415 -82
- package/dist/index.js +1 -1
- package/package.json +6 -6
- package/server.json +2 -2
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
},
|
|
8
8
|
"metadata": {
|
|
9
9
|
"description": "HoneyBook client-portal tools for Claude Code",
|
|
10
|
-
"version": "1.2.
|
|
10
|
+
"version": "1.2.5"
|
|
11
11
|
},
|
|
12
12
|
"plugins": [
|
|
13
13
|
{
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
"displayName": "HoneyBook",
|
|
16
16
|
"source": "./",
|
|
17
17
|
"description": "HoneyBook client-portal MCP for Claude — view wedding-vendor contracts and invoices via MCP",
|
|
18
|
-
"version": "1.2.
|
|
18
|
+
"version": "1.2.5",
|
|
19
19
|
"author": {
|
|
20
20
|
"name": "Chris Chall"
|
|
21
21
|
},
|
package/README.md
CHANGED
|
@@ -160,7 +160,8 @@ Until you confirm it only previews the recipients, subject and body — see [Con
|
|
|
160
160
|
|
|
161
161
|
| variable | default | |
|
|
162
162
|
|---|---|---|
|
|
163
|
-
| `MCP_CONFIRM_MODE` | `ask-user` | What a write does on a client that cannot show a confirmation prompt (claude.ai, Claude Desktop). `ask-user`: two steps — the first call does nothing and returns a preview plus a token, and the model must get your approval in chat before calling again with it. `auto`: the same two steps, but the model may use the token after reviewing the preview itself. `refuse`: writes are refused on such clients. A client that can show prompts (Claude Code) always gets the real prompt
|
|
163
|
+
| `MCP_CONFIRM_MODE` | `ask-user` | What a write does on a client that cannot show a confirmation prompt (claude.ai, Claude Desktop). `ask-user`: two steps — the first call does nothing and returns a preview plus a token, and the model must get your approval in chat before calling again with it. `auto`: the same two steps, but the model may use the token after reviewing the preview itself. `refuse`: writes are refused on such clients. A client that can show prompts (Claude Code) always gets the real prompt, unless `MCP_CONFIRM_ELICITATION=off`. An unrecognised value is treated as `refuse`. |
|
|
164
|
+
| `MCP_CONFIRM_ELICITATION` | `on` | `off` never sends a confirmation prompt, so every client gets the `MCP_CONFIRM_MODE` path. Set it for a client that declares it can show prompts but never does (the gated call hangs — opencode 2.0.x). Any other value stays `on`, with a stderr warning. |
|
|
164
165
|
| `MCP_CONFIRM_TTL_SECONDS` | `600` | How long a token stays valid. |
|
|
165
166
|
| `MCP_CONFIRM_SECRET` | random per process | Signing key; set it only if tokens must survive a server restart. |
|
|
166
167
|
|
package/dist/bundle.js
CHANGED
|
@@ -20692,8 +20692,8 @@ var require_schemas2 = __commonJS({
|
|
|
20692
20692
|
return core._stringFormat(exports.ZodCustomStringFormat, "currency_code", regexes.currencyCode, _params);
|
|
20693
20693
|
}
|
|
20694
20694
|
function hash2(alg, params) {
|
|
20695
|
-
const
|
|
20696
|
-
const format = `${alg}_${
|
|
20695
|
+
const enc7 = params?.enc ?? "hex";
|
|
20696
|
+
const format = `${alg}_${enc7}`;
|
|
20697
20697
|
const regex = core.regexes[format];
|
|
20698
20698
|
if (!regex)
|
|
20699
20699
|
throw new Error(`Unrecognized hash format: ${format}`);
|
|
@@ -25603,11 +25603,23 @@ var require_websocket = __commonJS({
|
|
|
25603
25603
|
this._isServer = false;
|
|
25604
25604
|
this._redirects = 0;
|
|
25605
25605
|
if (protocols === void 0) {
|
|
25606
|
-
protocols
|
|
25606
|
+
if (!options || options.protocols === void 0) {
|
|
25607
|
+
protocols = [];
|
|
25608
|
+
} else if (Array.isArray(options.protocols)) {
|
|
25609
|
+
protocols = options.protocols;
|
|
25610
|
+
} else {
|
|
25611
|
+
protocols = [options.protocols];
|
|
25612
|
+
}
|
|
25607
25613
|
} else if (!Array.isArray(protocols)) {
|
|
25608
25614
|
if (typeof protocols === "object" && protocols !== null) {
|
|
25609
25615
|
options = protocols;
|
|
25610
|
-
protocols
|
|
25616
|
+
if (options.protocols === void 0) {
|
|
25617
|
+
protocols = [];
|
|
25618
|
+
} else if (Array.isArray(options.protocols)) {
|
|
25619
|
+
protocols = options.protocols;
|
|
25620
|
+
} else {
|
|
25621
|
+
protocols = [options.protocols];
|
|
25622
|
+
}
|
|
25611
25623
|
} else {
|
|
25612
25624
|
protocols = [protocols];
|
|
25613
25625
|
}
|
|
@@ -25804,7 +25816,6 @@ var require_websocket = __commonJS({
|
|
|
25804
25816
|
}
|
|
25805
25817
|
return;
|
|
25806
25818
|
}
|
|
25807
|
-
this._readyState = _WebSocket.CLOSING;
|
|
25808
25819
|
this._sender.close(code2, data, !this._isServer, (err) => {
|
|
25809
25820
|
if (err) return;
|
|
25810
25821
|
this._closeFrameSent = true;
|
|
@@ -25812,6 +25823,7 @@ var require_websocket = __commonJS({
|
|
|
25812
25823
|
this._socket.end();
|
|
25813
25824
|
}
|
|
25814
25825
|
});
|
|
25826
|
+
this._readyState = _WebSocket.CLOSING;
|
|
25815
25827
|
setCloseTimer(this);
|
|
25816
25828
|
}
|
|
25817
25829
|
/**
|
|
@@ -26036,6 +26048,7 @@ var require_websocket = __commonJS({
|
|
|
26036
26048
|
socketPath: void 0,
|
|
26037
26049
|
hostname: void 0,
|
|
26038
26050
|
protocol: void 0,
|
|
26051
|
+
protocols: void 0,
|
|
26039
26052
|
timeout: void 0,
|
|
26040
26053
|
method: "GET",
|
|
26041
26054
|
host: void 0,
|
|
@@ -28038,7 +28051,7 @@ var OAuthTokenRevocationRequestSchema = z.object({
|
|
|
28038
28051
|
token_type_hint: z.string().optional()
|
|
28039
28052
|
}).strip();
|
|
28040
28053
|
|
|
28041
|
-
// node_modules/@modelcontextprotocol/server/dist/src-
|
|
28054
|
+
// node_modules/@modelcontextprotocol/server/dist/src-Cqbh3MYc.mjs
|
|
28042
28055
|
var z2 = __toESM(require_v4(), 1);
|
|
28043
28056
|
var BRANDS = /* @__PURE__ */ Symbol.for("mcp.sdk.errorBrands");
|
|
28044
28057
|
function stampErrorBrands(instance, ctor) {
|
|
@@ -30282,7 +30295,8 @@ function build() {
|
|
|
30282
30295
|
ListResourceTemplatesResultResponseSchema: wireResultResponse(ListResourceTemplatesResultSchema$1),
|
|
30283
30296
|
ReadResourceResultResponseSchema: wireResultResponse(z2.union([ReadResourceResultSchema$1, InputRequiredResultSchema])),
|
|
30284
30297
|
CompleteResultResponseSchema: wireResultResponse(CompleteResultSchema$1),
|
|
30285
|
-
DiscoverResultResponseSchema: wireResultResponse(DiscoverResultSchema$1)
|
|
30298
|
+
DiscoverResultResponseSchema: wireResultResponse(DiscoverResultSchema$1),
|
|
30299
|
+
SubscriptionsListenResultResponseSchema: wireResultResponse(SubscriptionsListenResultSchema$1)
|
|
30286
30300
|
};
|
|
30287
30301
|
}
|
|
30288
30302
|
var memo;
|
|
@@ -30790,6 +30804,9 @@ function isSpecRequestMethod(method) {
|
|
|
30790
30804
|
function isSpecNotificationMethod(method) {
|
|
30791
30805
|
return ALL_CODECS.some((codec2) => codec2.hasNotificationMethod(method));
|
|
30792
30806
|
}
|
|
30807
|
+
function isExtensionReusedRequestMethod(method) {
|
|
30808
|
+
return method === "tasks/get" || method === "tasks/cancel";
|
|
30809
|
+
}
|
|
30793
30810
|
var ALL_CODECS = [rev2025Codec, rev2026Codec];
|
|
30794
30811
|
function isPlainObject$3(value) {
|
|
30795
30812
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
@@ -31798,6 +31815,8 @@ var Protocol = class {
|
|
|
31798
31815
|
_transport;
|
|
31799
31816
|
_requestMessageId = 0;
|
|
31800
31817
|
_requestHandlers = /* @__PURE__ */ new Map();
|
|
31818
|
+
/** Methods registered with an explicit schema; the era gate in `_onrequest` reads it for the Tasks extension names. */
|
|
31819
|
+
_customSchemaRequestMethods = /* @__PURE__ */ new Set();
|
|
31801
31820
|
_requestHandlerAbortControllers = /* @__PURE__ */ new Map();
|
|
31802
31821
|
_notificationHandlers = /* @__PURE__ */ new Map();
|
|
31803
31822
|
_responseHandlers = /* @__PURE__ */ new Map();
|
|
@@ -32081,7 +32100,7 @@ var Protocol = class {
|
|
|
32081
32100
|
return;
|
|
32082
32101
|
}
|
|
32083
32102
|
}
|
|
32084
|
-
if (isSpecRequestMethod(request.method) && !codec2.hasRequestMethod(request.method)) {
|
|
32103
|
+
if (isSpecRequestMethod(request.method) && !codec2.hasRequestMethod(request.method) && !(isExtensionReusedRequestMethod(request.method) && this._customSchemaRequestMethods.has(request.method))) {
|
|
32085
32104
|
sendErrorResponse(ProtocolErrorCode.MethodNotFound, "Method not found");
|
|
32086
32105
|
return;
|
|
32087
32106
|
}
|
|
@@ -32214,8 +32233,11 @@ var Protocol = class {
|
|
|
32214
32233
|
}
|
|
32215
32234
|
request(request, schemaOrOptions, maybeOptions) {
|
|
32216
32235
|
const codec2 = this._resolveOutboundCodec(request.method);
|
|
32236
|
+
if (isStandardSchema(schemaOrOptions)) {
|
|
32237
|
+
if (!isExtensionReusedRequestMethod(request.method)) this._assertOutboundRequestInEra(codec2, request.method);
|
|
32238
|
+
return this._requestWithSchemaViaCodec(codec2, request, schemaOrOptions, maybeOptions);
|
|
32239
|
+
}
|
|
32217
32240
|
this._assertOutboundRequestInEra(codec2, request.method);
|
|
32218
|
-
if (isStandardSchema(schemaOrOptions)) return this._requestWithSchemaViaCodec(codec2, request, schemaOrOptions, maybeOptions);
|
|
32219
32241
|
const validate2 = codecResultValidator(codec2, request.method);
|
|
32220
32242
|
if (validate2 === void 0) throw new TypeError(`'${request.method}' is not a spec method; pass a result schema as the second argument to request().`);
|
|
32221
32243
|
return this._requestWithSchemaViaCodec(codec2, request, validate2, schemaOrOptions);
|
|
@@ -32459,6 +32481,8 @@ var Protocol = class {
|
|
|
32459
32481
|
return maybeHandler(parsed.data, ctx);
|
|
32460
32482
|
};
|
|
32461
32483
|
else throw new TypeError("setRequestHandler: handler is required");
|
|
32484
|
+
if (typeof schemasOrHandler === "function") this._customSchemaRequestMethods.delete(method);
|
|
32485
|
+
else this._customSchemaRequestMethods.add(method);
|
|
32462
32486
|
this._requestHandlers.set(method, this._wrapHandler(method, stored));
|
|
32463
32487
|
}
|
|
32464
32488
|
/**
|
|
@@ -32488,6 +32512,7 @@ var Protocol = class {
|
|
|
32488
32512
|
*/
|
|
32489
32513
|
removeRequestHandler(method) {
|
|
32490
32514
|
this._requestHandlers.delete(method);
|
|
32515
|
+
this._customSchemaRequestMethods.delete(method);
|
|
32491
32516
|
}
|
|
32492
32517
|
/**
|
|
32493
32518
|
* Asserts that a request handler has not already been set for the given method, in preparation for a new one being automatically installed.
|
|
@@ -39730,7 +39755,7 @@ var Ajv = import_ajv.Ajv;
|
|
|
39730
39755
|
// node_modules/@modelcontextprotocol/server/dist/shimsNode.mjs
|
|
39731
39756
|
import process2 from "node:process";
|
|
39732
39757
|
|
|
39733
|
-
// node_modules/@modelcontextprotocol/server/dist/mcp-
|
|
39758
|
+
// node_modules/@modelcontextprotocol/server/dist/mcp-DIH4cS6P.mjs
|
|
39734
39759
|
var COMPLETABLE_SYMBOL = /* @__PURE__ */ Symbol.for("mcp.completable");
|
|
39735
39760
|
function isCompletable(schema) {
|
|
39736
39761
|
return !!schema && typeof schema === "object" && COMPLETABLE_SYMBOL in schema;
|
|
@@ -39795,7 +39820,7 @@ var StdioListenRouter = class {
|
|
|
39795
39820
|
_serverCapabilities;
|
|
39796
39821
|
/**
|
|
39797
39822
|
* The serving instance's identity, stamped onto the graceful-close
|
|
39798
|
-
* results' `_meta` (the spec's `
|
|
39823
|
+
* results' `_meta` (the spec's `SubscriptionsListenResultMetaObject` extends
|
|
39799
39824
|
* `ResultMetaObject`). Handed over together with the capabilities.
|
|
39800
39825
|
*/
|
|
39801
39826
|
_serverInfo;
|
|
@@ -40127,6 +40152,11 @@ var Server = class extends Protocol {
|
|
|
40127
40152
|
if (modernProtocolVersions(this._supportedProtocolVersions).length > 0) this.setRequestHandler("server/discover", () => this._ondiscover());
|
|
40128
40153
|
if (this._capabilities.logging) this._registerLoggingHandler();
|
|
40129
40154
|
}
|
|
40155
|
+
/** Attaches to the given transport; rejects while this instance is connected to another one. */
|
|
40156
|
+
async connect(transport) {
|
|
40157
|
+
if (this.transport !== void 0) throw new SdkError(SdkErrorCode.AlreadyConnected, "Use a separate Server instance per connection: this instance is already connected to a transport. To connect it to a new transport, call close() first.");
|
|
40158
|
+
await super.connect(transport);
|
|
40159
|
+
}
|
|
40130
40160
|
/**
|
|
40131
40161
|
* Registers the built-in `logging/setLevel` request handler.
|
|
40132
40162
|
*
|
|
@@ -40680,21 +40710,41 @@ var Server = class extends Protocol {
|
|
|
40680
40710
|
function discoverAdvertisedCapabilities(capabilities) {
|
|
40681
40711
|
return { ...capabilities };
|
|
40682
40712
|
}
|
|
40713
|
+
function toolInputElementCount(value, max) {
|
|
40714
|
+
let count = 0;
|
|
40715
|
+
const stack = [value];
|
|
40716
|
+
while (stack.length > 0) {
|
|
40717
|
+
const node2 = stack.pop();
|
|
40718
|
+
if (node2 === null || typeof node2 !== "object") continue;
|
|
40719
|
+
if (Array.isArray(node2)) for (const child of node2) {
|
|
40720
|
+
if (++count > max) return count;
|
|
40721
|
+
if (child !== null && typeof child === "object") stack.push(child);
|
|
40722
|
+
}
|
|
40723
|
+
else for (const key in node2) {
|
|
40724
|
+
if (!Object.prototype.hasOwnProperty.call(node2, key)) continue;
|
|
40725
|
+
if (++count > max) return count;
|
|
40726
|
+
const child = node2[key];
|
|
40727
|
+
if (child !== null && typeof child === "object") stack.push(child);
|
|
40728
|
+
}
|
|
40729
|
+
}
|
|
40730
|
+
return count;
|
|
40731
|
+
}
|
|
40732
|
+
function resolveMaxToolInputElements(value) {
|
|
40733
|
+
if (value === void 0 || value === Infinity) return void 0;
|
|
40734
|
+
if (typeof value !== "number" || Number.isNaN(value) || value < 1) throw new RangeError(`maxToolInputElements must be a number of at least 1, or Infinity, got ${String(value)}`);
|
|
40735
|
+
return value;
|
|
40736
|
+
}
|
|
40683
40737
|
var McpServer = class {
|
|
40684
40738
|
/**
|
|
40685
40739
|
* The underlying {@linkcode Server} instance, useful for advanced operations like sending notifications.
|
|
40686
40740
|
*/
|
|
40687
40741
|
server;
|
|
40742
|
+
_maxToolInputElements;
|
|
40688
40743
|
_registeredResources = {};
|
|
40689
40744
|
_registeredResourceTemplates = {};
|
|
40690
40745
|
_registeredTools = {};
|
|
40691
40746
|
_registeredPrompts = {};
|
|
40692
|
-
/**
|
|
40693
|
-
* Per-tool JSON-converted `inputSchema`, memoized so the SEP-2243
|
|
40694
|
-
* registration-time scan and the pre-dispatch validation step share one
|
|
40695
|
-
* conversion instead of paying it twice per request under the
|
|
40696
|
-
* per-request-factory `createMcpHandler` model.
|
|
40697
|
-
*/
|
|
40747
|
+
/** Per-tool JSON-converted `inputSchema`, filled on first use by `toolInputSchemaJson()`. */
|
|
40698
40748
|
_toolInputSchemaJson = {};
|
|
40699
40749
|
/**
|
|
40700
40750
|
* The JSON-serialized `inputSchema` of a registered tool, or `undefined`
|
|
@@ -40719,6 +40769,7 @@ var McpServer = class {
|
|
|
40719
40769
|
}
|
|
40720
40770
|
constructor(serverInfo, options) {
|
|
40721
40771
|
this.server = new Server(serverInfo, options);
|
|
40772
|
+
this._maxToolInputElements = resolveMaxToolInputElements(options?.maxToolInputElements);
|
|
40722
40773
|
if (options?.capabilities?.tools) this.setToolRequestHandlers();
|
|
40723
40774
|
if (options?.capabilities?.resources) this.setResourceRequestHandlers();
|
|
40724
40775
|
if (options?.capabilities?.prompts) this.setPromptRequestHandlers();
|
|
@@ -40791,7 +40842,7 @@ var McpServer = class {
|
|
|
40791
40842
|
name,
|
|
40792
40843
|
title: tool.title,
|
|
40793
40844
|
description: tool.description,
|
|
40794
|
-
inputSchema: tool.inputSchema ?
|
|
40845
|
+
inputSchema: tool.inputSchema ? convertListedInputSchema(name, tool.inputSchema) : EMPTY_OBJECT_JSON_SCHEMA,
|
|
40795
40846
|
annotations: tool.annotations,
|
|
40796
40847
|
icons: tool.icons,
|
|
40797
40848
|
execution: tool.execution,
|
|
@@ -40836,6 +40887,7 @@ var McpServer = class {
|
|
|
40836
40887
|
* Validates tool input arguments against the tool's input schema.
|
|
40837
40888
|
*/
|
|
40838
40889
|
async validateToolInput(tool, args, toolName) {
|
|
40890
|
+
if (this._maxToolInputElements !== void 0 && toolInputElementCount(args, this._maxToolInputElements) > this._maxToolInputElements) throw new ProtocolError(ProtocolErrorCode.InvalidParams, `Invalid arguments for tool ${toolName}: arguments contain more than the maximum of ${this._maxToolInputElements} elements`);
|
|
40839
40891
|
if (!tool.inputSchema) return;
|
|
40840
40892
|
const parseResult = await validateStandardSchema(tool.inputSchema, args ?? {});
|
|
40841
40893
|
if (!parseResult.success) throw new ProtocolError(ProtocolErrorCode.InvalidParams, `Input validation error: Invalid arguments for tool ${toolName}: ${parseResult.error}`);
|
|
@@ -41110,20 +41162,19 @@ var McpServer = class {
|
|
|
41110
41162
|
}
|
|
41111
41163
|
_createRegisteredTool(name, title, description, inputSchema, outputSchema, annotations, icons, execution, scopeChallenge, _meta, handler) {
|
|
41112
41164
|
validateAndWarnToolName(name);
|
|
41113
|
-
if (inputSchema !== void 0) try {
|
|
41114
|
-
const json2 = standardSchemaToJsonSchema(inputSchema, "input");
|
|
41115
|
-
this._toolInputSchemaJson[name] = json2;
|
|
41116
|
-
const scan = scanXMcpHeaderDeclarations(json2);
|
|
41117
|
-
if (!scan.valid) console.warn(`[mcp-sdk] tool '${name}' carries an invalid x-mcp-header declaration and will be excluded by conforming Streamable HTTP clients: ${scan.reason}`);
|
|
41118
|
-
} catch {
|
|
41119
|
-
}
|
|
41120
41165
|
let currentHandler = handler;
|
|
41166
|
+
let outputSchemaJson;
|
|
41121
41167
|
const registeredTool = {
|
|
41122
41168
|
title,
|
|
41123
41169
|
description,
|
|
41124
41170
|
inputSchema,
|
|
41125
41171
|
outputSchema,
|
|
41126
|
-
outputSchemaJson
|
|
41172
|
+
get outputSchemaJson() {
|
|
41173
|
+
return outputSchemaJson ??= convertOutputSchemaJson(registeredTool.outputSchema);
|
|
41174
|
+
},
|
|
41175
|
+
set outputSchemaJson(value) {
|
|
41176
|
+
outputSchemaJson = value;
|
|
41177
|
+
},
|
|
41127
41178
|
annotations,
|
|
41128
41179
|
icons,
|
|
41129
41180
|
execution,
|
|
@@ -41250,6 +41301,12 @@ var EMPTY_OBJECT_JSON_SCHEMA = {
|
|
|
41250
41301
|
type: "object",
|
|
41251
41302
|
properties: {}
|
|
41252
41303
|
};
|
|
41304
|
+
function convertListedInputSchema(name, inputSchema) {
|
|
41305
|
+
const json2 = standardSchemaToJsonSchema(inputSchema, "input");
|
|
41306
|
+
const scan = scanXMcpHeaderDeclarations(json2);
|
|
41307
|
+
if (!scan.valid) console.warn(`[mcp-sdk] tool '${name}' carries an invalid x-mcp-header declaration and will be excluded by conforming Streamable HTTP clients: ${scan.reason}`);
|
|
41308
|
+
return json2;
|
|
41309
|
+
}
|
|
41253
41310
|
function convertOutputSchemaJson(outputSchema) {
|
|
41254
41311
|
if (outputSchema === void 0) return void 0;
|
|
41255
41312
|
try {
|
|
@@ -41262,7 +41319,7 @@ function createPromptHandler(name, argsSchema, callback) {
|
|
|
41262
41319
|
if (argsSchema) {
|
|
41263
41320
|
const typedCallback = callback;
|
|
41264
41321
|
return async (args, ctx) => {
|
|
41265
|
-
const parseResult = await validateStandardSchema(argsSchema, args);
|
|
41322
|
+
const parseResult = await validateStandardSchema(argsSchema, args ?? {});
|
|
41266
41323
|
if (!parseResult.success) throw new ProtocolError(ProtocolErrorCode.InvalidParams, `Invalid arguments for prompt ${name}: ${parseResult.error}`);
|
|
41267
41324
|
return typedCallback(parseResult.data, ctx);
|
|
41268
41325
|
};
|
|
@@ -59619,8 +59676,8 @@ function currencyCode2(_params) {
|
|
|
59619
59676
|
return _stringFormat(ZodCustomStringFormat, "currency_code", currencyCode, _params);
|
|
59620
59677
|
}
|
|
59621
59678
|
function hash(alg, params) {
|
|
59622
|
-
const
|
|
59623
|
-
const format = `${alg}_${
|
|
59679
|
+
const enc7 = params?.enc ?? "hex";
|
|
59680
|
+
const format = `${alg}_${enc7}`;
|
|
59624
59681
|
const regex = regexes_exports[format];
|
|
59625
59682
|
if (!regex)
|
|
59626
59683
|
throw new Error(`Unrecognized hash format: ${format}`);
|
|
@@ -61657,6 +61714,7 @@ function escapeKey(key) {
|
|
|
61657
61714
|
var DEFAULT_REQUEST_KEY = "confirmation";
|
|
61658
61715
|
var DEFAULT_CONFIRMATION_LABEL = "Confirm this action should proceed.";
|
|
61659
61716
|
var UNSUPPORTED_NOTE = "Nothing was done because this client cannot show a confirmation prompt (it declares no MCP elicitation capability), and this action is never taken without one";
|
|
61717
|
+
var DISABLED_NOTE = "Nothing was done because confirmation prompts are turned off for this server, and this action is never taken without one";
|
|
61660
61718
|
var STATE_PREFIX = "mcpu.confirm.v1.";
|
|
61661
61719
|
function bindingKey(binding) {
|
|
61662
61720
|
if (binding.ttlSeconds !== void 0 && !(Number.isFinite(binding.ttlSeconds) && binding.ttlSeconds > 0)) {
|
|
@@ -61729,6 +61787,15 @@ ${JSON.stringify(preview, null, 2)}`,
|
|
|
61729
61787
|
};
|
|
61730
61788
|
const response = inputResponse(ctx.mcpReq.inputResponses, requestKey);
|
|
61731
61789
|
const accepted = acceptedContent(ctx.mcpReq.inputResponses, requestKey, confirmationSchema);
|
|
61790
|
+
if (options.elicitation === false) {
|
|
61791
|
+
return textResult({
|
|
61792
|
+
confirmed: false,
|
|
61793
|
+
dispatched: false,
|
|
61794
|
+
action: options.action,
|
|
61795
|
+
reason: "confirmation-unsupported",
|
|
61796
|
+
note: options.unsupportedNote ? `${DISABLED_NOTE}. ${options.unsupportedNote}` : `${DISABLED_NOTE}.`
|
|
61797
|
+
});
|
|
61798
|
+
}
|
|
61732
61799
|
if (response.kind === "missing") {
|
|
61733
61800
|
if (callerAcceptsFormElicitation(ctx) === false) {
|
|
61734
61801
|
return textResult({
|
|
@@ -61923,7 +61990,7 @@ async function tokenConfirmation(action, fb) {
|
|
|
61923
61990
|
}
|
|
61924
61991
|
async function requireConfirmationWithFallback(ctx, options) {
|
|
61925
61992
|
const { tokenFallback, ...confirmation } = options;
|
|
61926
|
-
if (tokenFallback && callerAcceptsFormElicitation(ctx) === false) {
|
|
61993
|
+
if (tokenFallback && (options.elicitation === false || callerAcceptsFormElicitation(ctx) === false)) {
|
|
61927
61994
|
return tokenConfirmation(options.action, tokenFallback);
|
|
61928
61995
|
}
|
|
61929
61996
|
return requireConfirmation(ctx, confirmation);
|
|
@@ -62074,6 +62141,20 @@ function readConfirmMode(env = process.env) {
|
|
|
62074
62141
|
}
|
|
62075
62142
|
return "refuse";
|
|
62076
62143
|
}
|
|
62144
|
+
function readConfirmElicitation(env = process.env) {
|
|
62145
|
+
const raw = readEnvVar("MCP_CONFIRM_ELICITATION", { env })?.trim().toLowerCase();
|
|
62146
|
+
if (!raw || raw === "on")
|
|
62147
|
+
return "on";
|
|
62148
|
+
if (raw === "off")
|
|
62149
|
+
return "off";
|
|
62150
|
+
const key = `elicitation:${raw}`;
|
|
62151
|
+
if (!warned.has(key)) {
|
|
62152
|
+
warned.add(key);
|
|
62153
|
+
process.stderr.write(`MCP_CONFIRM_ELICITATION="${raw}" is not one of on, off; treating it as on.
|
|
62154
|
+
`);
|
|
62155
|
+
}
|
|
62156
|
+
return "on";
|
|
62157
|
+
}
|
|
62077
62158
|
function readConfirmTtl(env) {
|
|
62078
62159
|
const raw = readEnvVar("MCP_CONFIRM_TTL_SECONDS", { env })?.trim();
|
|
62079
62160
|
if (!raw)
|
|
@@ -62118,6 +62199,7 @@ function spentTokenStoreFromEnv(env = process.env) {
|
|
|
62118
62199
|
}
|
|
62119
62200
|
var CONFIRM_TOKEN_AUTO_INSTRUCTION = "Nothing has been done yet. Review this preview; if it is what was intended, call again with the same arguments plus confirmToken. (This server runs with MCP_CONFIRM_MODE=auto, so the user's approval in chat is not required.)";
|
|
62120
62201
|
var REFUSE_HINT = "Set MCP_CONFIRM_MODE=ask-user on the server to allow two-step confirmation instead.";
|
|
62202
|
+
var ELICITATION_OFF_HINT = "MCP_CONFIRM_ELICITATION=off on the server turns confirmation prompts off.";
|
|
62121
62203
|
var BAD_TTL_HINT = "MCP_CONFIRM_TTL_SECONDS on the server is not a positive whole number of seconds; fix it to allow two-step confirmation.";
|
|
62122
62204
|
function boundArgs(args) {
|
|
62123
62205
|
if (args === null || typeof args !== "object" || Array.isArray(args) || !("confirmToken" in args))
|
|
@@ -62131,10 +62213,13 @@ function confirmationFromEnv(options) {
|
|
|
62131
62213
|
const spent = callerSpent ?? spentTokenStoreFromEnv(env);
|
|
62132
62214
|
const mode = readConfirmMode(env);
|
|
62133
62215
|
const ttlSeconds = readConfirmTtl(env);
|
|
62216
|
+
const elicitationOff = readConfirmElicitation(env) === "off";
|
|
62134
62217
|
const bound = args === void 0 ? void 0 : boundArgs(args);
|
|
62135
|
-
const
|
|
62218
|
+
const bindingAdded = bound === void 0 || rest.binding ? rest : { ...rest, binding: { key: confirmKeyFromEnv(env), args: bound, ttlSeconds: ttlSeconds ?? DEFAULT_TTL_SECONDS2 } };
|
|
62219
|
+
const confirmation = elicitationOff ? { ...bindingAdded, elicitation: false } : bindingAdded;
|
|
62136
62220
|
if (mode === "refuse" || ttlSeconds === void 0) {
|
|
62137
|
-
const
|
|
62221
|
+
const reason = mode === "refuse" ? REFUSE_HINT : BAD_TTL_HINT;
|
|
62222
|
+
const hint = elicitationOff ? `${ELICITATION_OFF_HINT} ${reason}` : reason;
|
|
62138
62223
|
return {
|
|
62139
62224
|
...confirmation,
|
|
62140
62225
|
unsupportedNote: confirmation.unsupportedNote ? `${confirmation.unsupportedNote} ${hint}` : hint
|
|
@@ -62243,7 +62328,10 @@ function surfaceToolHints(server) {
|
|
|
62243
62328
|
));
|
|
62244
62329
|
}
|
|
62245
62330
|
async function createMcpServer(opts) {
|
|
62246
|
-
const server = new McpServer({ name: opts.name, version: opts.version }, {
|
|
62331
|
+
const server = new McpServer({ name: opts.name, version: opts.version }, {
|
|
62332
|
+
supportedProtocolVersions: [...SERVER_PROTOCOL_VERSIONS],
|
|
62333
|
+
...opts.maxToolInputElements !== void 0 ? { maxToolInputElements: opts.maxToolInputElements } : {}
|
|
62334
|
+
});
|
|
62247
62335
|
if (opts.surfaceHints !== false)
|
|
62248
62336
|
surfaceToolHints(server);
|
|
62249
62337
|
if (opts.banner !== void 0) {
|
|
@@ -63313,6 +63401,60 @@ var KNOWN_CAPABILITIES = /* @__PURE__ */ new Set([
|
|
|
63313
63401
|
"graphql",
|
|
63314
63402
|
"write_cookies"
|
|
63315
63403
|
]);
|
|
63404
|
+
var ACCOUNT_KEY_FRAME = "account-key";
|
|
63405
|
+
var ACCOUNT_ATTEST_FRAME = "account-attest";
|
|
63406
|
+
var BRIDGE_ROLE_FRAME = "bridge-role";
|
|
63407
|
+
var BRIDGE_SERVE_FRAME = "bridge-serve";
|
|
63408
|
+
var ROOM_PING_FRAME = "room-ping";
|
|
63409
|
+
var ROOM_PONG_FRAME = "room-pong";
|
|
63410
|
+
var BRIDGE_ROLE_LABEL_MAX = 64;
|
|
63411
|
+
var ROOM_FRAME_ACCEPTS = Object.freeze({
|
|
63412
|
+
[BRIDGE_ROLE_FRAME]: BRIDGE_ROLE_FRAME,
|
|
63413
|
+
[BRIDGE_SERVE_FRAME]: BRIDGE_SERVE_FRAME,
|
|
63414
|
+
[ROOM_PING_FRAME]: ROOM_PING_FRAME,
|
|
63415
|
+
[ROOM_PONG_FRAME]: ROOM_PING_FRAME
|
|
63416
|
+
});
|
|
63417
|
+
|
|
63418
|
+
// node_modules/@fetchproxy/protocol/dist/mcp-id.js
|
|
63419
|
+
var ID_RE = /^([^:]+):([^:]+):([0-9a-f]{16})$/;
|
|
63420
|
+
function generateMcpId(serverName, version2) {
|
|
63421
|
+
if (serverName.includes(":")) {
|
|
63422
|
+
throw new Error(`serverName cannot contain ':': ${serverName}`);
|
|
63423
|
+
}
|
|
63424
|
+
if (version2.includes(":")) {
|
|
63425
|
+
throw new Error(`version cannot contain ':': ${version2}`);
|
|
63426
|
+
}
|
|
63427
|
+
const rand = randomHex(8);
|
|
63428
|
+
return `${serverName}:${version2}:${rand}`;
|
|
63429
|
+
}
|
|
63430
|
+
function isValidMcpId(id) {
|
|
63431
|
+
return typeof id === "string" && ID_RE.test(id);
|
|
63432
|
+
}
|
|
63433
|
+
function randomHex(bytes) {
|
|
63434
|
+
const arr2 = new Uint8Array(bytes);
|
|
63435
|
+
globalThis.crypto.getRandomValues(arr2);
|
|
63436
|
+
return Array.from(arr2, (b) => b.toString(16).padStart(2, "0")).join("");
|
|
63437
|
+
}
|
|
63438
|
+
|
|
63439
|
+
// node_modules/@fetchproxy/protocol/dist/account-attest.js
|
|
63440
|
+
var ACCOUNT_ATTEST_CONSENTS = Object.freeze([
|
|
63441
|
+
"silent",
|
|
63442
|
+
"confirm",
|
|
63443
|
+
"confirm-each"
|
|
63444
|
+
]);
|
|
63445
|
+
var NO_SCOPE_DIGEST = "0".repeat(64);
|
|
63446
|
+
var ACCOUNT_ID_RE = /^[A-Za-z0-9_.\-]{1,128}$/;
|
|
63447
|
+
var HEX64_RE = /^[0-9a-f]{64}$/;
|
|
63448
|
+
var ACCOUNT_KID_RE = /^[0-9a-f]{16}$/;
|
|
63449
|
+
var enc2 = new TextEncoder();
|
|
63450
|
+
|
|
63451
|
+
// node_modules/@fetchproxy/protocol/dist/awaiting-approval.js
|
|
63452
|
+
var AWAITING_APPROVAL_REASON_PREFIX = "awaiting-approval:";
|
|
63453
|
+
function parseAwaitingApprovalReason(reason) {
|
|
63454
|
+
if (!reason.startsWith(AWAITING_APPROVAL_REASON_PREFIX))
|
|
63455
|
+
return null;
|
|
63456
|
+
return reason.slice(AWAITING_APPROVAL_REASON_PREFIX.length).trim();
|
|
63457
|
+
}
|
|
63316
63458
|
|
|
63317
63459
|
// node_modules/@fetchproxy/protocol/dist/capability-availability.js
|
|
63318
63460
|
var CAPABILITY_UNAVAILABLE_CODE = "capability_unavailable";
|
|
@@ -63338,27 +63480,6 @@ function parseUnsupportedCapabilityReason(reason) {
|
|
|
63338
63480
|
return rest.split(",").map((s) => s.trim()).filter((s) => s.length > 0);
|
|
63339
63481
|
}
|
|
63340
63482
|
|
|
63341
|
-
// node_modules/@fetchproxy/protocol/dist/mcp-id.js
|
|
63342
|
-
var ID_RE = /^([^:]+):([^:]+):([0-9a-f]{16})$/;
|
|
63343
|
-
function generateMcpId(serverName, version2) {
|
|
63344
|
-
if (serverName.includes(":")) {
|
|
63345
|
-
throw new Error(`serverName cannot contain ':': ${serverName}`);
|
|
63346
|
-
}
|
|
63347
|
-
if (version2.includes(":")) {
|
|
63348
|
-
throw new Error(`version cannot contain ':': ${version2}`);
|
|
63349
|
-
}
|
|
63350
|
-
const rand = randomHex(8);
|
|
63351
|
-
return `${serverName}:${version2}:${rand}`;
|
|
63352
|
-
}
|
|
63353
|
-
function isValidMcpId(id) {
|
|
63354
|
-
return typeof id === "string" && ID_RE.test(id);
|
|
63355
|
-
}
|
|
63356
|
-
function randomHex(bytes) {
|
|
63357
|
-
const arr2 = new Uint8Array(bytes);
|
|
63358
|
-
globalThis.crypto.getRandomValues(arr2);
|
|
63359
|
-
return Array.from(arr2, (b) => b.toString(16).padStart(2, "0")).join("");
|
|
63360
|
-
}
|
|
63361
|
-
|
|
63362
63483
|
// node_modules/@fetchproxy/protocol/dist/json-pointer.js
|
|
63363
63484
|
function matchesDeclaredKey(requested, declared) {
|
|
63364
63485
|
for (const decl of declared) {
|
|
@@ -63954,6 +64075,16 @@ function validateFrame(raw) {
|
|
|
63954
64075
|
return { type: "extension-disconnected" };
|
|
63955
64076
|
if (t === "peer-gone")
|
|
63956
64077
|
return validatePeerGone(raw);
|
|
64078
|
+
if (t === ACCOUNT_KEY_FRAME)
|
|
64079
|
+
return validateAccountKey(raw);
|
|
64080
|
+
if (t === ACCOUNT_ATTEST_FRAME)
|
|
64081
|
+
return validateAccountAttest(raw);
|
|
64082
|
+
if (t === BRIDGE_ROLE_FRAME)
|
|
64083
|
+
return validateBridgeRole(raw);
|
|
64084
|
+
if (t === BRIDGE_SERVE_FRAME || t === ROOM_PING_FRAME || t === ROOM_PONG_FRAME) {
|
|
64085
|
+
assertExactFields(raw, TYPE_ONLY_FIELDS, t);
|
|
64086
|
+
return { type: t };
|
|
64087
|
+
}
|
|
63957
64088
|
throw new ProtocolError3(`unknown frame type: ${String(t)}`);
|
|
63958
64089
|
}
|
|
63959
64090
|
function validateHello(raw) {
|
|
@@ -64157,6 +64288,165 @@ function validateHelloRejected(raw) {
|
|
|
64157
64288
|
}
|
|
64158
64289
|
return { type: "hello-rejected", mcpId: raw.mcpId, reason: raw.reason };
|
|
64159
64290
|
}
|
|
64291
|
+
var DISPLAY_FORBIDDEN_RE = /[\u0000-\u001f\u007f-\u009f\u200e\u200f\u202a-\u202e\u2066-\u2069]/;
|
|
64292
|
+
function assertExactFields(raw, allowed, label) {
|
|
64293
|
+
for (const k of Object.keys(raw)) {
|
|
64294
|
+
if (!allowed.includes(k)) {
|
|
64295
|
+
throw new ProtocolError3(`${label}: unexpected field ${JSON.stringify(k)}`);
|
|
64296
|
+
}
|
|
64297
|
+
}
|
|
64298
|
+
}
|
|
64299
|
+
function assertMatch(x, re, label, what) {
|
|
64300
|
+
assertString(x, label);
|
|
64301
|
+
if (!re.test(x))
|
|
64302
|
+
throw new ProtocolError3(`${label}: must be ${what}`);
|
|
64303
|
+
}
|
|
64304
|
+
function assertPositiveSafeInt(x, label) {
|
|
64305
|
+
if (typeof x !== "number" || !Number.isSafeInteger(x) || x <= 0) {
|
|
64306
|
+
throw new ProtocolError3(`${label}: expected positive safe integer`);
|
|
64307
|
+
}
|
|
64308
|
+
}
|
|
64309
|
+
function assertDisplayString(x, label, min, max) {
|
|
64310
|
+
assertString(x, label);
|
|
64311
|
+
if (x.length < min || x.length > max) {
|
|
64312
|
+
throw new ProtocolError3(`${label}: must be ${min}-${max} characters`);
|
|
64313
|
+
}
|
|
64314
|
+
if (DISPLAY_FORBIDDEN_RE.test(x)) {
|
|
64315
|
+
throw new ProtocolError3(`${label}: control or bidi-override character`);
|
|
64316
|
+
}
|
|
64317
|
+
}
|
|
64318
|
+
var ACCOUNT_KEY_FIELDS = [
|
|
64319
|
+
"type",
|
|
64320
|
+
"accountId",
|
|
64321
|
+
"slug",
|
|
64322
|
+
"displayName",
|
|
64323
|
+
"confirmedBy",
|
|
64324
|
+
"tokenId",
|
|
64325
|
+
"kid",
|
|
64326
|
+
"publicKey",
|
|
64327
|
+
"generation",
|
|
64328
|
+
"bridgedRegistrations"
|
|
64329
|
+
];
|
|
64330
|
+
function validateAccountKey(raw) {
|
|
64331
|
+
const L = "account-key";
|
|
64332
|
+
assertMatch(raw.accountId, ACCOUNT_ID_RE, `${L}.accountId`, "an account id");
|
|
64333
|
+
assertMatch(raw.slug, ACCOUNT_ID_RE, `${L}.slug`, "a slug");
|
|
64334
|
+
assertDisplayString(raw.displayName, `${L}.displayName`, 0, 128);
|
|
64335
|
+
assertDisplayString(raw.confirmedBy, `${L}.confirmedBy`, 1, 256);
|
|
64336
|
+
assertMatch(raw.tokenId, ACCOUNT_ID_RE, `${L}.tokenId`, "a token id");
|
|
64337
|
+
assertMatch(raw.kid, ACCOUNT_KID_RE, `${L}.kid`, "16 lowercase hex");
|
|
64338
|
+
assertBase64Bytes(raw.publicKey, `${L}.publicKey`, 32);
|
|
64339
|
+
assertPositiveSafeInt(raw.generation, `${L}.generation`);
|
|
64340
|
+
const n = raw.bridgedRegistrations;
|
|
64341
|
+
if (typeof n !== "number" || !Number.isSafeInteger(n) || n < 0) {
|
|
64342
|
+
throw new ProtocolError3(`${L}.bridgedRegistrations: expected non-negative safe integer`);
|
|
64343
|
+
}
|
|
64344
|
+
assertExactFields(raw, ACCOUNT_KEY_FIELDS, L);
|
|
64345
|
+
return {
|
|
64346
|
+
type: ACCOUNT_KEY_FRAME,
|
|
64347
|
+
accountId: raw.accountId,
|
|
64348
|
+
slug: raw.slug,
|
|
64349
|
+
displayName: raw.displayName,
|
|
64350
|
+
confirmedBy: raw.confirmedBy,
|
|
64351
|
+
tokenId: raw.tokenId,
|
|
64352
|
+
kid: raw.kid,
|
|
64353
|
+
publicKey: raw.publicKey,
|
|
64354
|
+
generation: raw.generation,
|
|
64355
|
+
bridgedRegistrations: n
|
|
64356
|
+
};
|
|
64357
|
+
}
|
|
64358
|
+
var ACCOUNT_ATTEST_FIELDS = [
|
|
64359
|
+
"type",
|
|
64360
|
+
"mcpId",
|
|
64361
|
+
"accountId",
|
|
64362
|
+
"generation",
|
|
64363
|
+
"tokenId",
|
|
64364
|
+
"kid",
|
|
64365
|
+
"registrationId",
|
|
64366
|
+
"slug",
|
|
64367
|
+
"identityHash",
|
|
64368
|
+
"identityEd25519Pub",
|
|
64369
|
+
"scopeDigest",
|
|
64370
|
+
"consent",
|
|
64371
|
+
"notAfter",
|
|
64372
|
+
"sig"
|
|
64373
|
+
];
|
|
64374
|
+
function validateAccountAttest(raw) {
|
|
64375
|
+
const L = "account-attest";
|
|
64376
|
+
if (!isValidMcpId(raw.mcpId))
|
|
64377
|
+
throw new ProtocolError3(`${L}.mcpId: invalid format`);
|
|
64378
|
+
assertMatch(raw.accountId, ACCOUNT_ID_RE, `${L}.accountId`, "an account id");
|
|
64379
|
+
assertPositiveSafeInt(raw.generation, `${L}.generation`);
|
|
64380
|
+
assertMatch(raw.tokenId, ACCOUNT_ID_RE, `${L}.tokenId`, "a token id");
|
|
64381
|
+
assertMatch(raw.kid, ACCOUNT_KID_RE, `${L}.kid`, "16 lowercase hex");
|
|
64382
|
+
assertMatch(raw.registrationId, ACCOUNT_ID_RE, `${L}.registrationId`, "a registration id");
|
|
64383
|
+
assertMatch(raw.slug, ACCOUNT_ID_RE, `${L}.slug`, "a slug");
|
|
64384
|
+
assertMatch(raw.identityHash, HEX64_RE, `${L}.identityHash`, "64 lowercase hex");
|
|
64385
|
+
assertBase64Bytes(raw.identityEd25519Pub, `${L}.identityEd25519Pub`, 32);
|
|
64386
|
+
assertMatch(raw.scopeDigest, HEX64_RE, `${L}.scopeDigest`, "64 lowercase hex");
|
|
64387
|
+
assertString(raw.consent, `${L}.consent`);
|
|
64388
|
+
const consent = raw.consent;
|
|
64389
|
+
const known = ACCOUNT_ATTEST_CONSENTS.find((c) => c === consent);
|
|
64390
|
+
if (known === void 0) {
|
|
64391
|
+
throw new ProtocolError3(`${L}.consent: must be one of ${ACCOUNT_ATTEST_CONSENTS.join(", ")}`);
|
|
64392
|
+
}
|
|
64393
|
+
assertPositiveSafeInt(raw.notAfter, `${L}.notAfter`);
|
|
64394
|
+
assertBase64Bytes(raw.sig, `${L}.sig`, 64);
|
|
64395
|
+
assertExactFields(raw, ACCOUNT_ATTEST_FIELDS, L);
|
|
64396
|
+
return {
|
|
64397
|
+
type: ACCOUNT_ATTEST_FRAME,
|
|
64398
|
+
mcpId: raw.mcpId,
|
|
64399
|
+
accountId: raw.accountId,
|
|
64400
|
+
generation: raw.generation,
|
|
64401
|
+
tokenId: raw.tokenId,
|
|
64402
|
+
kid: raw.kid,
|
|
64403
|
+
registrationId: raw.registrationId,
|
|
64404
|
+
slug: raw.slug,
|
|
64405
|
+
identityHash: raw.identityHash,
|
|
64406
|
+
identityEd25519Pub: raw.identityEd25519Pub,
|
|
64407
|
+
scopeDigest: raw.scopeDigest,
|
|
64408
|
+
consent: known,
|
|
64409
|
+
notAfter: raw.notAfter,
|
|
64410
|
+
sig: raw.sig
|
|
64411
|
+
};
|
|
64412
|
+
}
|
|
64413
|
+
var TYPE_ONLY_FIELDS = ["type"];
|
|
64414
|
+
var BRIDGE_ROLE_FIELDS = ["type", "role", "canServe", "serving"];
|
|
64415
|
+
var BRIDGE_ROLE_SERVING_FIELDS = ["label", "since"];
|
|
64416
|
+
function validateBridgeRole(raw) {
|
|
64417
|
+
const L = BRIDGE_ROLE_FRAME;
|
|
64418
|
+
const role = raw.role;
|
|
64419
|
+
if (role !== "serving" && role !== "standby") {
|
|
64420
|
+
throw new ProtocolError3(`${L}.role: must be one of serving, standby`);
|
|
64421
|
+
}
|
|
64422
|
+
const canServe = raw.canServe;
|
|
64423
|
+
assertBoolean(canServe, `${L}.canServe`);
|
|
64424
|
+
assertExactFields(raw, BRIDGE_ROLE_FIELDS, L);
|
|
64425
|
+
const serving = raw.serving;
|
|
64426
|
+
if (role === "serving") {
|
|
64427
|
+
if (serving !== void 0) {
|
|
64428
|
+
throw new ProtocolError3(`${L}.serving: must be absent when role is serving`);
|
|
64429
|
+
}
|
|
64430
|
+
return { type: BRIDGE_ROLE_FRAME, role, canServe };
|
|
64431
|
+
}
|
|
64432
|
+
if (serving === void 0) {
|
|
64433
|
+
throw new ProtocolError3(`${L}.serving: required when role is standby`);
|
|
64434
|
+
}
|
|
64435
|
+
assertObject(serving, `${L}.serving`);
|
|
64436
|
+
const label = serving.label;
|
|
64437
|
+
assertDisplayString(label, `${L}.serving.label`, 1, BRIDGE_ROLE_LABEL_MAX);
|
|
64438
|
+
const since = serving.since;
|
|
64439
|
+
if (typeof since !== "number" || !Number.isSafeInteger(since) || since < 0) {
|
|
64440
|
+
throw new ProtocolError3(`${L}.serving.since: expected non-negative safe integer (Unix ms)`);
|
|
64441
|
+
}
|
|
64442
|
+
assertExactFields(serving, BRIDGE_ROLE_SERVING_FIELDS, `${L}.serving`);
|
|
64443
|
+
return {
|
|
64444
|
+
type: BRIDGE_ROLE_FRAME,
|
|
64445
|
+
role,
|
|
64446
|
+
canServe,
|
|
64447
|
+
serving: { label, since }
|
|
64448
|
+
};
|
|
64449
|
+
}
|
|
64160
64450
|
function validateInnerFrame(raw) {
|
|
64161
64451
|
assertObject(raw, "inner");
|
|
64162
64452
|
const t = raw.type;
|
|
@@ -64624,10 +64914,10 @@ function validateInnerResponse(raw) {
|
|
|
64624
64914
|
}
|
|
64625
64915
|
|
|
64626
64916
|
// node_modules/@fetchproxy/protocol/dist/pair-code.js
|
|
64627
|
-
var
|
|
64917
|
+
var enc3 = new TextEncoder();
|
|
64628
64918
|
var PAIR_LABEL = "fetchproxy/4/pair";
|
|
64629
64919
|
async function pairTranscript(mcpIdentityPub, extIdentityPub, mcpNonce, extNonce, mcpSessionPub) {
|
|
64630
|
-
const label =
|
|
64920
|
+
const label = enc3.encode(PAIR_LABEL);
|
|
64631
64921
|
const parts = [mcpIdentityPub, extIdentityPub, mcpNonce, extNonce, mcpSessionPub];
|
|
64632
64922
|
const out = new Uint8Array(label.length + 1 + parts.reduce((n, p) => n + p.length, 0));
|
|
64633
64923
|
out.set(label, 0);
|
|
@@ -64648,7 +64938,7 @@ function digits(hash2) {
|
|
|
64648
64938
|
}
|
|
64649
64939
|
|
|
64650
64940
|
// node_modules/@fetchproxy/protocol/dist/seal.js
|
|
64651
|
-
var
|
|
64941
|
+
var enc4 = new TextEncoder();
|
|
64652
64942
|
var dec = new TextDecoder();
|
|
64653
64943
|
function randomIv() {
|
|
64654
64944
|
const iv = new Uint8Array(12);
|
|
@@ -64661,14 +64951,14 @@ function base64Length(byteLength) {
|
|
|
64661
64951
|
return Math.ceil(byteLength / 3) * 4;
|
|
64662
64952
|
}
|
|
64663
64953
|
function encodeInnerFrame(inner) {
|
|
64664
|
-
return
|
|
64954
|
+
return enc4.encode(JSON.stringify(inner));
|
|
64665
64955
|
}
|
|
64666
64956
|
function plaintextOf(inner) {
|
|
64667
64957
|
return inner instanceof Uint8Array ? inner : encodeInnerFrame(inner);
|
|
64668
64958
|
}
|
|
64669
64959
|
function sealedFrameWireBytes(mcpId, seq, inner) {
|
|
64670
64960
|
const plaintext = plaintextOf(inner).length;
|
|
64671
|
-
const envelope =
|
|
64961
|
+
const envelope = enc4.encode(JSON.stringify({ type: "frame", mcpId, seq, iv: "", ciphertext: "" })).length;
|
|
64672
64962
|
return envelope + IV_B64_BYTES + base64Length(plaintext + AES_GCM_TAG_BYTES);
|
|
64673
64963
|
}
|
|
64674
64964
|
var MAX_FRAME_BYTES = 42 * 1024 * 1024;
|
|
@@ -65008,14 +65298,23 @@ var FetchproxyHelloRejectedError = class extends Error {
|
|
|
65008
65298
|
platform;
|
|
65009
65299
|
/**
|
|
65010
65300
|
* #418: the remedy, when the reason is one this package knows how to
|
|
65011
|
-
* explain —
|
|
65012
|
-
*
|
|
65301
|
+
* explain — `unsupported-capability`, which blames the browser rather than
|
|
65302
|
+
* the MCP, and (D12) `awaiting-approval`, which says to approve in the
|
|
65303
|
+
* browser. `null` otherwise.
|
|
65013
65304
|
*/
|
|
65014
65305
|
hint;
|
|
65306
|
+
/**
|
|
65307
|
+
* D12: `true` only for an `awaiting-approval:` refusal — the extension has
|
|
65308
|
+
* queued an approval card and nobody is at the browser yet, so the same call
|
|
65309
|
+
* succeeds once the person approves. Every other refusal is the extension's
|
|
65310
|
+
* final answer, and retrying unchanged is refused the same way.
|
|
65311
|
+
*/
|
|
65312
|
+
retryable;
|
|
65015
65313
|
constructor(info) {
|
|
65016
65314
|
const unavailable = parseUnsupportedCapabilityReason(info.reason);
|
|
65315
|
+
const awaiting = parseAwaitingApprovalReason(info.reason);
|
|
65017
65316
|
const platform = info.platform ?? null;
|
|
65018
|
-
const hint = unavailable !== null ? `${platform ? `this browser (${platform})` : "this browser"} cannot serve any of the capabilities this MCP needs (${unavailable.join(", ")}) \u2014 ContextMint Bridge checked for the browser APIs and they are missing. Nothing is wrong with the MCP or your pairing, and updating will not change it: use this MCP from a browser that provides them (for example Chrome).` : null;
|
|
65317
|
+
const hint = awaiting !== null ? `The extension is waiting for you to approve this MCP` + (awaiting !== "" ? ` (${awaiting})` : "") + ` \u2014 open ContextMint Bridge in your browser, approve it there, then retry. Nothing is wrong with the MCP or your sign-in.` : unavailable !== null ? `${platform ? `this browser (${platform})` : "this browser"} cannot serve any of the capabilities this MCP needs (${unavailable.join(", ")}) \u2014 ContextMint Bridge checked for the browser APIs and they are missing. Nothing is wrong with the MCP or your pairing, and updating will not change it: use this MCP from a browser that provides them (for example Chrome).` : null;
|
|
65019
65318
|
super(`fetchproxy: the extension refused the connection for "${info.mcpId}": ${info.reason}. ` + (hint !== null ? hint : `This is the extension's own reason \u2014 it is not a timeout, and retrying unchanged will be refused the same way.`));
|
|
65020
65319
|
this.name = "FetchproxyHelloRejectedError";
|
|
65021
65320
|
this.mcpId = info.mcpId;
|
|
@@ -65023,6 +65322,7 @@ var FetchproxyHelloRejectedError = class extends Error {
|
|
|
65023
65322
|
this.unavailableCapabilities = unavailable ?? [];
|
|
65024
65323
|
this.platform = platform;
|
|
65025
65324
|
this.hint = hint;
|
|
65325
|
+
this.retryable = awaiting !== null;
|
|
65026
65326
|
Object.setPrototypeOf(this, new.target.prototype);
|
|
65027
65327
|
}
|
|
65028
65328
|
};
|
|
@@ -65575,7 +65875,7 @@ function originVerdict(origin, allowLocal) {
|
|
|
65575
65875
|
}
|
|
65576
65876
|
var HANDSHAKE_TIMEOUT_MS = 15e3;
|
|
65577
65877
|
var MAX_PAYLOAD_BYTES = MAX_FRAME_BYTES;
|
|
65578
|
-
var
|
|
65878
|
+
var enc5 = new TextEncoder();
|
|
65579
65879
|
var OWN_DECRYPT_FAILURES_BEFORE_REHANDSHAKE = 3;
|
|
65580
65880
|
async function startHost(opts) {
|
|
65581
65881
|
const allowLocalOrigins = envAllowsLocalOrigins();
|
|
@@ -65646,10 +65946,20 @@ async function startHost(opts) {
|
|
|
65646
65946
|
let resolveOwnSession;
|
|
65647
65947
|
let rejectOwnSession;
|
|
65648
65948
|
let ownSessionReady;
|
|
65949
|
+
let ownRetryableRefusal = false;
|
|
65950
|
+
let ownSessionSettled = false;
|
|
65649
65951
|
function resetSessionPromise() {
|
|
65952
|
+
ownRetryableRefusal = false;
|
|
65953
|
+
ownSessionSettled = false;
|
|
65650
65954
|
ownSessionReady = new Promise((resolve2, reject) => {
|
|
65651
|
-
resolveOwnSession =
|
|
65652
|
-
|
|
65955
|
+
resolveOwnSession = (st) => {
|
|
65956
|
+
ownSessionSettled = true;
|
|
65957
|
+
resolve2(st);
|
|
65958
|
+
};
|
|
65959
|
+
rejectOwnSession = (e) => {
|
|
65960
|
+
ownSessionSettled = true;
|
|
65961
|
+
reject(e);
|
|
65962
|
+
};
|
|
65653
65963
|
});
|
|
65654
65964
|
ownSessionReady.catch(() => {
|
|
65655
65965
|
});
|
|
@@ -65916,13 +66226,15 @@ async function startHost(opts) {
|
|
|
65916
66226
|
const extPub = fromB64(frame.extensionSessionPub);
|
|
65917
66227
|
const shared = await ecdhX25519(held.priv, extPub);
|
|
65918
66228
|
const salt = await transcriptHash(held.nonce, extNonce, held.pub, extPub);
|
|
65919
|
-
const key = await hkdfSha256(shared, salt,
|
|
66229
|
+
const key = await hkdfSha256(shared, salt, enc5.encode(HKDF_SESSION_INFO), 32);
|
|
65920
66230
|
if (extensionWs !== ws)
|
|
65921
66231
|
return;
|
|
65922
66232
|
ownSession = new SessionState(key);
|
|
65923
66233
|
ownSessionInfo = sessionInfoFromHello(verifiedHello);
|
|
65924
66234
|
ownDecryptFailures = 0;
|
|
65925
66235
|
ownPendingPairCode = null;
|
|
66236
|
+
if (ownRetryableRefusal)
|
|
66237
|
+
resetSessionPromise();
|
|
65926
66238
|
resolveOwnSession(ownSession);
|
|
65927
66239
|
} else {
|
|
65928
66240
|
const slot = peers.get(frame.mcpId);
|
|
@@ -65991,11 +66303,17 @@ async function startHost(opts) {
|
|
|
65991
66303
|
}
|
|
65992
66304
|
if (frame.type === "hello-rejected" && identified === "extension") {
|
|
65993
66305
|
if (frame.mcpId === opts.ownMcpId) {
|
|
65994
|
-
|
|
66306
|
+
const refusal = new FetchproxyHelloRejectedError({
|
|
65995
66307
|
mcpId: frame.mcpId,
|
|
65996
66308
|
reason: frame.reason,
|
|
65997
66309
|
platform: extensionHello?.platform ?? null
|
|
65998
|
-
})
|
|
66310
|
+
});
|
|
66311
|
+
if (ownRetryableRefusal)
|
|
66312
|
+
resetSessionPromise();
|
|
66313
|
+
const settlesPending = !ownSessionSettled;
|
|
66314
|
+
rejectOwnSession(refusal);
|
|
66315
|
+
if (refusal.retryable && settlesPending)
|
|
66316
|
+
ownRetryableRefusal = true;
|
|
65999
66317
|
} else {
|
|
66000
66318
|
const slot = peers.get(frame.mcpId);
|
|
66001
66319
|
if (slot?.helloFrame.accepts?.includes("hello-rejected")) {
|
|
@@ -66111,7 +66429,7 @@ async function startHost(opts) {
|
|
|
66111
66429
|
|
|
66112
66430
|
// node_modules/@fetchproxy/server/dist/peer.js
|
|
66113
66431
|
var PEER_DIAL_TIMEOUT_MS = 5e3;
|
|
66114
|
-
var
|
|
66432
|
+
var enc6 = new TextEncoder();
|
|
66115
66433
|
function notSentError() {
|
|
66116
66434
|
return new Error("fetchproxy: request not sent \u2014 the connection to the bridge host closed before it went out, so nothing reached the browser. It is safe to retry.");
|
|
66117
66435
|
}
|
|
@@ -66211,7 +66529,9 @@ async function startPeer(opts) {
|
|
|
66211
66529
|
let rejectFirstReady;
|
|
66212
66530
|
let sessionPromise;
|
|
66213
66531
|
let sessionPromiseSettled = false;
|
|
66532
|
+
let retryableRefusal = false;
|
|
66214
66533
|
function resetSessionPromise() {
|
|
66534
|
+
retryableRefusal = false;
|
|
66215
66535
|
sessionPromiseSettled = false;
|
|
66216
66536
|
sessionPromise = new Promise((resolve2, reject) => {
|
|
66217
66537
|
resolveFirstReady = (st) => {
|
|
@@ -66308,6 +66628,8 @@ async function startPeer(opts) {
|
|
|
66308
66628
|
raw = JSON.parse(data.toString());
|
|
66309
66629
|
const frame = validateFrame(raw);
|
|
66310
66630
|
if (frame.type === "hello" && frame.role === "extension") {
|
|
66631
|
+
if (retryableRefusal)
|
|
66632
|
+
resetSessionPromise();
|
|
66311
66633
|
extensionHello = frame;
|
|
66312
66634
|
const mintedKeypair = await generateSessionKeypair();
|
|
66313
66635
|
const mintedHello = await buildServerHello({
|
|
@@ -66337,6 +66659,8 @@ async function startPeer(opts) {
|
|
|
66337
66659
|
session = null;
|
|
66338
66660
|
if (sessionPromiseSettled)
|
|
66339
66661
|
resetSessionPromise();
|
|
66662
|
+
} else if (retryableRefusal) {
|
|
66663
|
+
resetSessionPromise();
|
|
66340
66664
|
}
|
|
66341
66665
|
extensionDisconnectListeners.forEach((cb) => cb());
|
|
66342
66666
|
return;
|
|
@@ -66358,7 +66682,7 @@ async function startPeer(opts) {
|
|
|
66358
66682
|
const extNonce = fromB64(authenticated.sessionNonce);
|
|
66359
66683
|
const shared = await ecdhX25519(held.priv, extPub);
|
|
66360
66684
|
const salt = await transcriptHash(held.nonce, extNonce, held.pub, extPub);
|
|
66361
|
-
const sessionKey = await hkdfSha256(shared, salt,
|
|
66685
|
+
const sessionKey = await hkdfSha256(shared, salt, enc6.encode(HKDF_SESSION_INFO), 32);
|
|
66362
66686
|
if (sessionEphemeral !== held) {
|
|
66363
66687
|
console.warn(`[fetchproxy] ${opts.serverName}: dropping a session derived against an ephemeral that was superseded while it was being derived`);
|
|
66364
66688
|
return;
|
|
@@ -66371,16 +66695,24 @@ async function startPeer(opts) {
|
|
|
66371
66695
|
if (isRenegotiation) {
|
|
66372
66696
|
renegotiateListeners.forEach((cb) => cb());
|
|
66373
66697
|
} else {
|
|
66698
|
+
if (retryableRefusal)
|
|
66699
|
+
resetSessionPromise();
|
|
66374
66700
|
resolveFirstReady(session);
|
|
66375
66701
|
}
|
|
66376
66702
|
return;
|
|
66377
66703
|
}
|
|
66378
66704
|
if (frame.type === "hello-rejected" && frame.mcpId === opts.mcpId) {
|
|
66379
|
-
|
|
66705
|
+
const refusal = new FetchproxyHelloRejectedError({
|
|
66380
66706
|
mcpId: frame.mcpId,
|
|
66381
66707
|
reason: frame.reason,
|
|
66382
66708
|
platform: extensionHello?.platform ?? null
|
|
66383
|
-
})
|
|
66709
|
+
});
|
|
66710
|
+
if (retryableRefusal)
|
|
66711
|
+
resetSessionPromise();
|
|
66712
|
+
const settlesPending = !sessionPromiseSettled;
|
|
66713
|
+
rejectFirstReady(refusal);
|
|
66714
|
+
if (refusal.retryable && settlesPending)
|
|
66715
|
+
retryableRefusal = true;
|
|
66384
66716
|
}
|
|
66385
66717
|
if (frame.type === "pair-pending" && frame.mcpId === opts.mcpId) {
|
|
66386
66718
|
const hello2 = extensionHello;
|
|
@@ -66544,8 +66876,9 @@ function classifyFetchError(error62, code2) {
|
|
|
66544
66876
|
|
|
66545
66877
|
// node_modules/@fetchproxy/server/dist/classify-bridge-error.js
|
|
66546
66878
|
function classifyBridgeError(err) {
|
|
66547
|
-
if (err instanceof FetchproxyHelloRejectedError)
|
|
66548
|
-
return "hello_rejected";
|
|
66879
|
+
if (err instanceof FetchproxyHelloRejectedError) {
|
|
66880
|
+
return err.retryable ? "awaiting_approval" : "hello_rejected";
|
|
66881
|
+
}
|
|
66549
66882
|
if (err instanceof FetchproxySessionNotReadyError)
|
|
66550
66883
|
return "session_not_ready";
|
|
66551
66884
|
if (err instanceof FetchproxyTimeoutError)
|
|
@@ -69330,7 +69663,7 @@ function isBrowserCapabilityGap(e) {
|
|
|
69330
69663
|
// package.json
|
|
69331
69664
|
var package_default = {
|
|
69332
69665
|
name: "honeybook-mcp",
|
|
69333
|
-
version: "1.2.
|
|
69666
|
+
version: "1.2.5",
|
|
69334
69667
|
mcpName: "io.github.chrischall/honeybook-mcp",
|
|
69335
69668
|
description: "HoneyBook client-portal MCP server for Claude",
|
|
69336
69669
|
author: "Claude Code (AI) <https://www.anthropic.com/claude>",
|
|
@@ -69374,15 +69707,15 @@ var package_default = {
|
|
|
69374
69707
|
typecheck: "tsc -p tsconfig.json --noEmit"
|
|
69375
69708
|
},
|
|
69376
69709
|
dependencies: {
|
|
69377
|
-
"@chrischall/mcp-utils": "^2.
|
|
69378
|
-
"@fetchproxy/bootstrap": "^3.
|
|
69379
|
-
"@fetchproxy/server": "^3.
|
|
69380
|
-
"@modelcontextprotocol/server": "^2.
|
|
69710
|
+
"@chrischall/mcp-utils": "^2.15.0",
|
|
69711
|
+
"@fetchproxy/bootstrap": "^3.6.0",
|
|
69712
|
+
"@fetchproxy/server": "^3.6.0",
|
|
69713
|
+
"@modelcontextprotocol/server": "^2.3.0",
|
|
69381
69714
|
dotenv: "^18.0.2",
|
|
69382
69715
|
zod: "^4.6.5"
|
|
69383
69716
|
},
|
|
69384
69717
|
devDependencies: {
|
|
69385
|
-
"@modelcontextprotocol/client": "^2.
|
|
69718
|
+
"@modelcontextprotocol/client": "^2.3.0",
|
|
69386
69719
|
"@types/node": "^26.0.0",
|
|
69387
69720
|
"@vitest/coverage-v8": "^5.0.0",
|
|
69388
69721
|
esbuild: "^0.28.0",
|
|
@@ -71261,7 +71594,7 @@ var __dirname = dirname3(fileURLToPath(import.meta.url));
|
|
|
71261
71594
|
await loadDotenvSafely({ path: join9(__dirname, "..", ".env"), override: false });
|
|
71262
71595
|
await runMcp({
|
|
71263
71596
|
name: "honeybook-mcp",
|
|
71264
|
-
version: "1.2.
|
|
71597
|
+
version: "1.2.5",
|
|
71265
71598
|
// x-release-please-version
|
|
71266
71599
|
tools: [
|
|
71267
71600
|
registerSessionTools,
|
|
@@ -71283,7 +71616,7 @@ await runMcp({
|
|
|
71283
71616
|
});
|
|
71284
71617
|
/*! Bundled license information:
|
|
71285
71618
|
|
|
71286
|
-
@modelcontextprotocol/server/dist/src-
|
|
71619
|
+
@modelcontextprotocol/server/dist/src-Cqbh3MYc.mjs:
|
|
71287
71620
|
(*!
|
|
71288
71621
|
* content-type
|
|
71289
71622
|
* Copyright(c) 2015 Douglas Christopher Wilson
|
package/dist/index.js
CHANGED
|
@@ -20,7 +20,7 @@ import { registerAttachmentTools } from './tools/attachments.js';
|
|
|
20
20
|
import { registerPaymentTools } from './tools/payments.js';
|
|
21
21
|
await runMcp({
|
|
22
22
|
name: 'honeybook-mcp',
|
|
23
|
-
version: '1.2.
|
|
23
|
+
version: '1.2.5', // x-release-please-version
|
|
24
24
|
tools: [
|
|
25
25
|
registerSessionTools,
|
|
26
26
|
registerFlowTools,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "honeybook-mcp",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.5",
|
|
4
4
|
"mcpName": "io.github.chrischall/honeybook-mcp",
|
|
5
5
|
"description": "HoneyBook client-portal MCP server for Claude",
|
|
6
6
|
"author": "Claude Code (AI) <https://www.anthropic.com/claude>",
|
|
@@ -44,15 +44,15 @@
|
|
|
44
44
|
"typecheck": "tsc -p tsconfig.json --noEmit"
|
|
45
45
|
},
|
|
46
46
|
"dependencies": {
|
|
47
|
-
"@chrischall/mcp-utils": "^2.
|
|
48
|
-
"@fetchproxy/bootstrap": "^3.
|
|
49
|
-
"@fetchproxy/server": "^3.
|
|
50
|
-
"@modelcontextprotocol/server": "^2.
|
|
47
|
+
"@chrischall/mcp-utils": "^2.15.0",
|
|
48
|
+
"@fetchproxy/bootstrap": "^3.6.0",
|
|
49
|
+
"@fetchproxy/server": "^3.6.0",
|
|
50
|
+
"@modelcontextprotocol/server": "^2.3.0",
|
|
51
51
|
"dotenv": "^18.0.2",
|
|
52
52
|
"zod": "^4.6.5"
|
|
53
53
|
},
|
|
54
54
|
"devDependencies": {
|
|
55
|
-
"@modelcontextprotocol/client": "^2.
|
|
55
|
+
"@modelcontextprotocol/client": "^2.3.0",
|
|
56
56
|
"@types/node": "^26.0.0",
|
|
57
57
|
"@vitest/coverage-v8": "^5.0.0",
|
|
58
58
|
"esbuild": "^0.28.0",
|
package/server.json
CHANGED
|
@@ -6,12 +6,12 @@
|
|
|
6
6
|
"url": "https://github.com/chrischall/honeybook-mcp",
|
|
7
7
|
"source": "github"
|
|
8
8
|
},
|
|
9
|
-
"version": "1.2.
|
|
9
|
+
"version": "1.2.5",
|
|
10
10
|
"packages": [
|
|
11
11
|
{
|
|
12
12
|
"registryType": "npm",
|
|
13
13
|
"identifier": "honeybook-mcp",
|
|
14
|
-
"version": "1.2.
|
|
14
|
+
"version": "1.2.5",
|
|
15
15
|
"transport": {
|
|
16
16
|
"type": "stdio"
|
|
17
17
|
},
|