infinitecampus-mcp 3.1.6 → 3.1.8
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 +384 -79
- 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": "MCP server for Infinite Campus (Campus Parent) — grades, attendance, assignments, messages, documents",
|
|
10
|
-
"version": "3.1.
|
|
10
|
+
"version": "3.1.8"
|
|
11
11
|
},
|
|
12
12
|
"plugins": [
|
|
13
13
|
{
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
"displayName": "Infinite Campus",
|
|
16
16
|
"source": "./",
|
|
17
17
|
"description": "Infinite Campus (Campus Parent) MCP server for Claude — grades, attendance, assignments, messages, and documents via natural language",
|
|
18
|
-
"version": "3.1.
|
|
18
|
+
"version": "3.1.8",
|
|
19
19
|
"author": {
|
|
20
20
|
"name": "Chris Hall"
|
|
21
21
|
},
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "infinitecampus-mcp",
|
|
3
3
|
"displayName": "Infinite Campus",
|
|
4
|
-
"version": "3.1.
|
|
4
|
+
"version": "3.1.8",
|
|
5
5
|
"description": "Infinite Campus (Campus Parent) MCP server for Claude — grades, attendance, assignments, messages, and documents",
|
|
6
6
|
"author": {
|
|
7
7
|
"name": "Chris Hall",
|
package/dist/bundle.js
CHANGED
|
@@ -20693,8 +20693,8 @@ var require_schemas2 = __commonJS({
|
|
|
20693
20693
|
return core._stringFormat(exports.ZodCustomStringFormat, "currency_code", regexes.currencyCode, _params);
|
|
20694
20694
|
}
|
|
20695
20695
|
function hash2(alg, params) {
|
|
20696
|
-
const
|
|
20697
|
-
const format = `${alg}_${
|
|
20696
|
+
const enc7 = params?.enc ?? "hex";
|
|
20697
|
+
const format = `${alg}_${enc7}`;
|
|
20698
20698
|
const regex = core.regexes[format];
|
|
20699
20699
|
if (!regex)
|
|
20700
20700
|
throw new Error(`Unrecognized hash format: ${format}`);
|
|
@@ -25604,11 +25604,23 @@ var require_websocket = __commonJS({
|
|
|
25604
25604
|
this._isServer = false;
|
|
25605
25605
|
this._redirects = 0;
|
|
25606
25606
|
if (protocols === void 0) {
|
|
25607
|
-
protocols
|
|
25607
|
+
if (!options || options.protocols === void 0) {
|
|
25608
|
+
protocols = [];
|
|
25609
|
+
} else if (Array.isArray(options.protocols)) {
|
|
25610
|
+
protocols = options.protocols;
|
|
25611
|
+
} else {
|
|
25612
|
+
protocols = [options.protocols];
|
|
25613
|
+
}
|
|
25608
25614
|
} else if (!Array.isArray(protocols)) {
|
|
25609
25615
|
if (typeof protocols === "object" && protocols !== null) {
|
|
25610
25616
|
options = protocols;
|
|
25611
|
-
protocols
|
|
25617
|
+
if (options.protocols === void 0) {
|
|
25618
|
+
protocols = [];
|
|
25619
|
+
} else if (Array.isArray(options.protocols)) {
|
|
25620
|
+
protocols = options.protocols;
|
|
25621
|
+
} else {
|
|
25622
|
+
protocols = [options.protocols];
|
|
25623
|
+
}
|
|
25612
25624
|
} else {
|
|
25613
25625
|
protocols = [protocols];
|
|
25614
25626
|
}
|
|
@@ -25805,7 +25817,6 @@ var require_websocket = __commonJS({
|
|
|
25805
25817
|
}
|
|
25806
25818
|
return;
|
|
25807
25819
|
}
|
|
25808
|
-
this._readyState = _WebSocket.CLOSING;
|
|
25809
25820
|
this._sender.close(code, data, !this._isServer, (err) => {
|
|
25810
25821
|
if (err) return;
|
|
25811
25822
|
this._closeFrameSent = true;
|
|
@@ -25813,6 +25824,7 @@ var require_websocket = __commonJS({
|
|
|
25813
25824
|
this._socket.end();
|
|
25814
25825
|
}
|
|
25815
25826
|
});
|
|
25827
|
+
this._readyState = _WebSocket.CLOSING;
|
|
25816
25828
|
setCloseTimer(this);
|
|
25817
25829
|
}
|
|
25818
25830
|
/**
|
|
@@ -26037,6 +26049,7 @@ var require_websocket = __commonJS({
|
|
|
26037
26049
|
socketPath: void 0,
|
|
26038
26050
|
hostname: void 0,
|
|
26039
26051
|
protocol: void 0,
|
|
26052
|
+
protocols: void 0,
|
|
26040
26053
|
timeout: void 0,
|
|
26041
26054
|
method: "GET",
|
|
26042
26055
|
host: void 0,
|
|
@@ -27996,7 +28009,7 @@ var OAuthTokenRevocationRequestSchema = z.object({
|
|
|
27996
28009
|
token_type_hint: z.string().optional()
|
|
27997
28010
|
}).strip();
|
|
27998
28011
|
|
|
27999
|
-
// node_modules/@modelcontextprotocol/server/dist/src-
|
|
28012
|
+
// node_modules/@modelcontextprotocol/server/dist/src-Cqbh3MYc.mjs
|
|
28000
28013
|
var z2 = __toESM(require_v4(), 1);
|
|
28001
28014
|
var BRANDS = /* @__PURE__ */ Symbol.for("mcp.sdk.errorBrands");
|
|
28002
28015
|
function stampErrorBrands(instance, ctor) {
|
|
@@ -30240,7 +30253,8 @@ function build() {
|
|
|
30240
30253
|
ListResourceTemplatesResultResponseSchema: wireResultResponse(ListResourceTemplatesResultSchema$1),
|
|
30241
30254
|
ReadResourceResultResponseSchema: wireResultResponse(z2.union([ReadResourceResultSchema$1, InputRequiredResultSchema])),
|
|
30242
30255
|
CompleteResultResponseSchema: wireResultResponse(CompleteResultSchema$1),
|
|
30243
|
-
DiscoverResultResponseSchema: wireResultResponse(DiscoverResultSchema$1)
|
|
30256
|
+
DiscoverResultResponseSchema: wireResultResponse(DiscoverResultSchema$1),
|
|
30257
|
+
SubscriptionsListenResultResponseSchema: wireResultResponse(SubscriptionsListenResultSchema$1)
|
|
30244
30258
|
};
|
|
30245
30259
|
}
|
|
30246
30260
|
var memo;
|
|
@@ -30748,6 +30762,9 @@ function isSpecRequestMethod(method) {
|
|
|
30748
30762
|
function isSpecNotificationMethod(method) {
|
|
30749
30763
|
return ALL_CODECS.some((codec2) => codec2.hasNotificationMethod(method));
|
|
30750
30764
|
}
|
|
30765
|
+
function isExtensionReusedRequestMethod(method) {
|
|
30766
|
+
return method === "tasks/get" || method === "tasks/cancel";
|
|
30767
|
+
}
|
|
30751
30768
|
var ALL_CODECS = [rev2025Codec, rev2026Codec];
|
|
30752
30769
|
function isPlainObject$3(value) {
|
|
30753
30770
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
@@ -31725,6 +31742,8 @@ var Protocol = class {
|
|
|
31725
31742
|
_transport;
|
|
31726
31743
|
_requestMessageId = 0;
|
|
31727
31744
|
_requestHandlers = /* @__PURE__ */ new Map();
|
|
31745
|
+
/** Methods registered with an explicit schema; the era gate in `_onrequest` reads it for the Tasks extension names. */
|
|
31746
|
+
_customSchemaRequestMethods = /* @__PURE__ */ new Set();
|
|
31728
31747
|
_requestHandlerAbortControllers = /* @__PURE__ */ new Map();
|
|
31729
31748
|
_notificationHandlers = /* @__PURE__ */ new Map();
|
|
31730
31749
|
_responseHandlers = /* @__PURE__ */ new Map();
|
|
@@ -32008,7 +32027,7 @@ var Protocol = class {
|
|
|
32008
32027
|
return;
|
|
32009
32028
|
}
|
|
32010
32029
|
}
|
|
32011
|
-
if (isSpecRequestMethod(request.method) && !codec2.hasRequestMethod(request.method)) {
|
|
32030
|
+
if (isSpecRequestMethod(request.method) && !codec2.hasRequestMethod(request.method) && !(isExtensionReusedRequestMethod(request.method) && this._customSchemaRequestMethods.has(request.method))) {
|
|
32012
32031
|
sendErrorResponse(ProtocolErrorCode.MethodNotFound, "Method not found");
|
|
32013
32032
|
return;
|
|
32014
32033
|
}
|
|
@@ -32141,8 +32160,11 @@ var Protocol = class {
|
|
|
32141
32160
|
}
|
|
32142
32161
|
request(request, schemaOrOptions, maybeOptions) {
|
|
32143
32162
|
const codec2 = this._resolveOutboundCodec(request.method);
|
|
32163
|
+
if (isStandardSchema(schemaOrOptions)) {
|
|
32164
|
+
if (!isExtensionReusedRequestMethod(request.method)) this._assertOutboundRequestInEra(codec2, request.method);
|
|
32165
|
+
return this._requestWithSchemaViaCodec(codec2, request, schemaOrOptions, maybeOptions);
|
|
32166
|
+
}
|
|
32144
32167
|
this._assertOutboundRequestInEra(codec2, request.method);
|
|
32145
|
-
if (isStandardSchema(schemaOrOptions)) return this._requestWithSchemaViaCodec(codec2, request, schemaOrOptions, maybeOptions);
|
|
32146
32168
|
const validate2 = codecResultValidator(codec2, request.method);
|
|
32147
32169
|
if (validate2 === void 0) throw new TypeError(`'${request.method}' is not a spec method; pass a result schema as the second argument to request().`);
|
|
32148
32170
|
return this._requestWithSchemaViaCodec(codec2, request, validate2, schemaOrOptions);
|
|
@@ -32386,6 +32408,8 @@ var Protocol = class {
|
|
|
32386
32408
|
return maybeHandler(parsed.data, ctx);
|
|
32387
32409
|
};
|
|
32388
32410
|
else throw new TypeError("setRequestHandler: handler is required");
|
|
32411
|
+
if (typeof schemasOrHandler === "function") this._customSchemaRequestMethods.delete(method);
|
|
32412
|
+
else this._customSchemaRequestMethods.add(method);
|
|
32389
32413
|
this._requestHandlers.set(method, this._wrapHandler(method, stored));
|
|
32390
32414
|
}
|
|
32391
32415
|
/**
|
|
@@ -32415,6 +32439,7 @@ var Protocol = class {
|
|
|
32415
32439
|
*/
|
|
32416
32440
|
removeRequestHandler(method) {
|
|
32417
32441
|
this._requestHandlers.delete(method);
|
|
32442
|
+
this._customSchemaRequestMethods.delete(method);
|
|
32418
32443
|
}
|
|
32419
32444
|
/**
|
|
32420
32445
|
* Asserts that a request handler has not already been set for the given method, in preparation for a new one being automatically installed.
|
|
@@ -39657,7 +39682,7 @@ var Ajv = import_ajv.Ajv;
|
|
|
39657
39682
|
// node_modules/@modelcontextprotocol/server/dist/shimsNode.mjs
|
|
39658
39683
|
import process2 from "node:process";
|
|
39659
39684
|
|
|
39660
|
-
// node_modules/@modelcontextprotocol/server/dist/mcp-
|
|
39685
|
+
// node_modules/@modelcontextprotocol/server/dist/mcp-DIH4cS6P.mjs
|
|
39661
39686
|
var COMPLETABLE_SYMBOL = /* @__PURE__ */ Symbol.for("mcp.completable");
|
|
39662
39687
|
function isCompletable(schema) {
|
|
39663
39688
|
return !!schema && typeof schema === "object" && COMPLETABLE_SYMBOL in schema;
|
|
@@ -39722,7 +39747,7 @@ var StdioListenRouter = class {
|
|
|
39722
39747
|
_serverCapabilities;
|
|
39723
39748
|
/**
|
|
39724
39749
|
* The serving instance's identity, stamped onto the graceful-close
|
|
39725
|
-
* results' `_meta` (the spec's `
|
|
39750
|
+
* results' `_meta` (the spec's `SubscriptionsListenResultMetaObject` extends
|
|
39726
39751
|
* `ResultMetaObject`). Handed over together with the capabilities.
|
|
39727
39752
|
*/
|
|
39728
39753
|
_serverInfo;
|
|
@@ -40054,6 +40079,11 @@ var Server = class extends Protocol {
|
|
|
40054
40079
|
if (modernProtocolVersions(this._supportedProtocolVersions).length > 0) this.setRequestHandler("server/discover", () => this._ondiscover());
|
|
40055
40080
|
if (this._capabilities.logging) this._registerLoggingHandler();
|
|
40056
40081
|
}
|
|
40082
|
+
/** Attaches to the given transport; rejects while this instance is connected to another one. */
|
|
40083
|
+
async connect(transport) {
|
|
40084
|
+
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.");
|
|
40085
|
+
await super.connect(transport);
|
|
40086
|
+
}
|
|
40057
40087
|
/**
|
|
40058
40088
|
* Registers the built-in `logging/setLevel` request handler.
|
|
40059
40089
|
*
|
|
@@ -40607,21 +40637,41 @@ var Server = class extends Protocol {
|
|
|
40607
40637
|
function discoverAdvertisedCapabilities(capabilities) {
|
|
40608
40638
|
return { ...capabilities };
|
|
40609
40639
|
}
|
|
40640
|
+
function toolInputElementCount(value, max) {
|
|
40641
|
+
let count = 0;
|
|
40642
|
+
const stack = [value];
|
|
40643
|
+
while (stack.length > 0) {
|
|
40644
|
+
const node2 = stack.pop();
|
|
40645
|
+
if (node2 === null || typeof node2 !== "object") continue;
|
|
40646
|
+
if (Array.isArray(node2)) for (const child of node2) {
|
|
40647
|
+
if (++count > max) return count;
|
|
40648
|
+
if (child !== null && typeof child === "object") stack.push(child);
|
|
40649
|
+
}
|
|
40650
|
+
else for (const key in node2) {
|
|
40651
|
+
if (!Object.prototype.hasOwnProperty.call(node2, key)) continue;
|
|
40652
|
+
if (++count > max) return count;
|
|
40653
|
+
const child = node2[key];
|
|
40654
|
+
if (child !== null && typeof child === "object") stack.push(child);
|
|
40655
|
+
}
|
|
40656
|
+
}
|
|
40657
|
+
return count;
|
|
40658
|
+
}
|
|
40659
|
+
function resolveMaxToolInputElements(value) {
|
|
40660
|
+
if (value === void 0 || value === Infinity) return void 0;
|
|
40661
|
+
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)}`);
|
|
40662
|
+
return value;
|
|
40663
|
+
}
|
|
40610
40664
|
var McpServer = class {
|
|
40611
40665
|
/**
|
|
40612
40666
|
* The underlying {@linkcode Server} instance, useful for advanced operations like sending notifications.
|
|
40613
40667
|
*/
|
|
40614
40668
|
server;
|
|
40669
|
+
_maxToolInputElements;
|
|
40615
40670
|
_registeredResources = {};
|
|
40616
40671
|
_registeredResourceTemplates = {};
|
|
40617
40672
|
_registeredTools = {};
|
|
40618
40673
|
_registeredPrompts = {};
|
|
40619
|
-
/**
|
|
40620
|
-
* Per-tool JSON-converted `inputSchema`, memoized so the SEP-2243
|
|
40621
|
-
* registration-time scan and the pre-dispatch validation step share one
|
|
40622
|
-
* conversion instead of paying it twice per request under the
|
|
40623
|
-
* per-request-factory `createMcpHandler` model.
|
|
40624
|
-
*/
|
|
40674
|
+
/** Per-tool JSON-converted `inputSchema`, filled on first use by `toolInputSchemaJson()`. */
|
|
40625
40675
|
_toolInputSchemaJson = {};
|
|
40626
40676
|
/**
|
|
40627
40677
|
* The JSON-serialized `inputSchema` of a registered tool, or `undefined`
|
|
@@ -40646,6 +40696,7 @@ var McpServer = class {
|
|
|
40646
40696
|
}
|
|
40647
40697
|
constructor(serverInfo, options) {
|
|
40648
40698
|
this.server = new Server(serverInfo, options);
|
|
40699
|
+
this._maxToolInputElements = resolveMaxToolInputElements(options?.maxToolInputElements);
|
|
40649
40700
|
if (options?.capabilities?.tools) this.setToolRequestHandlers();
|
|
40650
40701
|
if (options?.capabilities?.resources) this.setResourceRequestHandlers();
|
|
40651
40702
|
if (options?.capabilities?.prompts) this.setPromptRequestHandlers();
|
|
@@ -40718,7 +40769,7 @@ var McpServer = class {
|
|
|
40718
40769
|
name,
|
|
40719
40770
|
title: tool.title,
|
|
40720
40771
|
description: tool.description,
|
|
40721
|
-
inputSchema: tool.inputSchema ?
|
|
40772
|
+
inputSchema: tool.inputSchema ? convertListedInputSchema(name, tool.inputSchema) : EMPTY_OBJECT_JSON_SCHEMA,
|
|
40722
40773
|
annotations: tool.annotations,
|
|
40723
40774
|
icons: tool.icons,
|
|
40724
40775
|
execution: tool.execution,
|
|
@@ -40763,6 +40814,7 @@ var McpServer = class {
|
|
|
40763
40814
|
* Validates tool input arguments against the tool's input schema.
|
|
40764
40815
|
*/
|
|
40765
40816
|
async validateToolInput(tool, args, toolName) {
|
|
40817
|
+
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`);
|
|
40766
40818
|
if (!tool.inputSchema) return;
|
|
40767
40819
|
const parseResult = await validateStandardSchema(tool.inputSchema, args ?? {});
|
|
40768
40820
|
if (!parseResult.success) throw new ProtocolError(ProtocolErrorCode.InvalidParams, `Input validation error: Invalid arguments for tool ${toolName}: ${parseResult.error}`);
|
|
@@ -41037,20 +41089,19 @@ var McpServer = class {
|
|
|
41037
41089
|
}
|
|
41038
41090
|
_createRegisteredTool(name, title, description, inputSchema, outputSchema, annotations, icons, execution, scopeChallenge, _meta, handler) {
|
|
41039
41091
|
validateAndWarnToolName(name);
|
|
41040
|
-
if (inputSchema !== void 0) try {
|
|
41041
|
-
const json2 = standardSchemaToJsonSchema(inputSchema, "input");
|
|
41042
|
-
this._toolInputSchemaJson[name] = json2;
|
|
41043
|
-
const scan = scanXMcpHeaderDeclarations(json2);
|
|
41044
|
-
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}`);
|
|
41045
|
-
} catch {
|
|
41046
|
-
}
|
|
41047
41092
|
let currentHandler = handler;
|
|
41093
|
+
let outputSchemaJson;
|
|
41048
41094
|
const registeredTool = {
|
|
41049
41095
|
title,
|
|
41050
41096
|
description,
|
|
41051
41097
|
inputSchema,
|
|
41052
41098
|
outputSchema,
|
|
41053
|
-
outputSchemaJson
|
|
41099
|
+
get outputSchemaJson() {
|
|
41100
|
+
return outputSchemaJson ??= convertOutputSchemaJson(registeredTool.outputSchema);
|
|
41101
|
+
},
|
|
41102
|
+
set outputSchemaJson(value) {
|
|
41103
|
+
outputSchemaJson = value;
|
|
41104
|
+
},
|
|
41054
41105
|
annotations,
|
|
41055
41106
|
icons,
|
|
41056
41107
|
execution,
|
|
@@ -41177,6 +41228,12 @@ var EMPTY_OBJECT_JSON_SCHEMA = {
|
|
|
41177
41228
|
type: "object",
|
|
41178
41229
|
properties: {}
|
|
41179
41230
|
};
|
|
41231
|
+
function convertListedInputSchema(name, inputSchema) {
|
|
41232
|
+
const json2 = standardSchemaToJsonSchema(inputSchema, "input");
|
|
41233
|
+
const scan = scanXMcpHeaderDeclarations(json2);
|
|
41234
|
+
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}`);
|
|
41235
|
+
return json2;
|
|
41236
|
+
}
|
|
41180
41237
|
function convertOutputSchemaJson(outputSchema) {
|
|
41181
41238
|
if (outputSchema === void 0) return void 0;
|
|
41182
41239
|
try {
|
|
@@ -41189,7 +41246,7 @@ function createPromptHandler(name, argsSchema15, callback) {
|
|
|
41189
41246
|
if (argsSchema15) {
|
|
41190
41247
|
const typedCallback = callback;
|
|
41191
41248
|
return async (args, ctx) => {
|
|
41192
|
-
const parseResult = await validateStandardSchema(argsSchema15, args);
|
|
41249
|
+
const parseResult = await validateStandardSchema(argsSchema15, args ?? {});
|
|
41193
41250
|
if (!parseResult.success) throw new ProtocolError(ProtocolErrorCode.InvalidParams, `Invalid arguments for prompt ${name}: ${parseResult.error}`);
|
|
41194
41251
|
return typedCallback(parseResult.data, ctx);
|
|
41195
41252
|
};
|
|
@@ -59546,8 +59603,8 @@ function currencyCode2(_params) {
|
|
|
59546
59603
|
return _stringFormat(ZodCustomStringFormat, "currency_code", currencyCode, _params);
|
|
59547
59604
|
}
|
|
59548
59605
|
function hash(alg, params) {
|
|
59549
|
-
const
|
|
59550
|
-
const format = `${alg}_${
|
|
59606
|
+
const enc7 = params?.enc ?? "hex";
|
|
59607
|
+
const format = `${alg}_${enc7}`;
|
|
59551
59608
|
const regex = regexes_exports[format];
|
|
59552
59609
|
if (!regex)
|
|
59553
59610
|
throw new Error(`Unrecognized hash format: ${format}`);
|
|
@@ -61730,7 +61787,10 @@ function surfaceToolHints(server) {
|
|
|
61730
61787
|
));
|
|
61731
61788
|
}
|
|
61732
61789
|
async function createMcpServer(opts) {
|
|
61733
|
-
const server = new McpServer({ name: opts.name, version: opts.version }, {
|
|
61790
|
+
const server = new McpServer({ name: opts.name, version: opts.version }, {
|
|
61791
|
+
supportedProtocolVersions: [...SERVER_PROTOCOL_VERSIONS],
|
|
61792
|
+
...opts.maxToolInputElements !== void 0 ? { maxToolInputElements: opts.maxToolInputElements } : {}
|
|
61793
|
+
});
|
|
61734
61794
|
if (opts.surfaceHints !== false)
|
|
61735
61795
|
surfaceToolHints(server);
|
|
61736
61796
|
if (opts.banner !== void 0) {
|
|
@@ -62313,6 +62373,60 @@ var KNOWN_CAPABILITIES = /* @__PURE__ */ new Set([
|
|
|
62313
62373
|
"graphql",
|
|
62314
62374
|
"write_cookies"
|
|
62315
62375
|
]);
|
|
62376
|
+
var ACCOUNT_KEY_FRAME = "account-key";
|
|
62377
|
+
var ACCOUNT_ATTEST_FRAME = "account-attest";
|
|
62378
|
+
var BRIDGE_ROLE_FRAME = "bridge-role";
|
|
62379
|
+
var BRIDGE_SERVE_FRAME = "bridge-serve";
|
|
62380
|
+
var ROOM_PING_FRAME = "room-ping";
|
|
62381
|
+
var ROOM_PONG_FRAME = "room-pong";
|
|
62382
|
+
var BRIDGE_ROLE_LABEL_MAX = 64;
|
|
62383
|
+
var ROOM_FRAME_ACCEPTS = Object.freeze({
|
|
62384
|
+
[BRIDGE_ROLE_FRAME]: BRIDGE_ROLE_FRAME,
|
|
62385
|
+
[BRIDGE_SERVE_FRAME]: BRIDGE_SERVE_FRAME,
|
|
62386
|
+
[ROOM_PING_FRAME]: ROOM_PING_FRAME,
|
|
62387
|
+
[ROOM_PONG_FRAME]: ROOM_PING_FRAME
|
|
62388
|
+
});
|
|
62389
|
+
|
|
62390
|
+
// node_modules/@fetchproxy/protocol/dist/mcp-id.js
|
|
62391
|
+
var ID_RE = /^([^:]+):([^:]+):([0-9a-f]{16})$/;
|
|
62392
|
+
function generateMcpId(serverName, version2) {
|
|
62393
|
+
if (serverName.includes(":")) {
|
|
62394
|
+
throw new Error(`serverName cannot contain ':': ${serverName}`);
|
|
62395
|
+
}
|
|
62396
|
+
if (version2.includes(":")) {
|
|
62397
|
+
throw new Error(`version cannot contain ':': ${version2}`);
|
|
62398
|
+
}
|
|
62399
|
+
const rand = randomHex(8);
|
|
62400
|
+
return `${serverName}:${version2}:${rand}`;
|
|
62401
|
+
}
|
|
62402
|
+
function isValidMcpId(id) {
|
|
62403
|
+
return typeof id === "string" && ID_RE.test(id);
|
|
62404
|
+
}
|
|
62405
|
+
function randomHex(bytes) {
|
|
62406
|
+
const arr = new Uint8Array(bytes);
|
|
62407
|
+
globalThis.crypto.getRandomValues(arr);
|
|
62408
|
+
return Array.from(arr, (b) => b.toString(16).padStart(2, "0")).join("");
|
|
62409
|
+
}
|
|
62410
|
+
|
|
62411
|
+
// node_modules/@fetchproxy/protocol/dist/account-attest.js
|
|
62412
|
+
var ACCOUNT_ATTEST_CONSENTS = Object.freeze([
|
|
62413
|
+
"silent",
|
|
62414
|
+
"confirm",
|
|
62415
|
+
"confirm-each"
|
|
62416
|
+
]);
|
|
62417
|
+
var NO_SCOPE_DIGEST = "0".repeat(64);
|
|
62418
|
+
var ACCOUNT_ID_RE = /^[A-Za-z0-9_.\-]{1,128}$/;
|
|
62419
|
+
var HEX64_RE = /^[0-9a-f]{64}$/;
|
|
62420
|
+
var ACCOUNT_KID_RE = /^[0-9a-f]{16}$/;
|
|
62421
|
+
var enc2 = new TextEncoder();
|
|
62422
|
+
|
|
62423
|
+
// node_modules/@fetchproxy/protocol/dist/awaiting-approval.js
|
|
62424
|
+
var AWAITING_APPROVAL_REASON_PREFIX = "awaiting-approval:";
|
|
62425
|
+
function parseAwaitingApprovalReason(reason) {
|
|
62426
|
+
if (!reason.startsWith(AWAITING_APPROVAL_REASON_PREFIX))
|
|
62427
|
+
return null;
|
|
62428
|
+
return reason.slice(AWAITING_APPROVAL_REASON_PREFIX.length).trim();
|
|
62429
|
+
}
|
|
62316
62430
|
|
|
62317
62431
|
// node_modules/@fetchproxy/protocol/dist/capability-availability.js
|
|
62318
62432
|
var CAPABILITY_UNAVAILABLE_CODE = "capability_unavailable";
|
|
@@ -62338,27 +62452,6 @@ function parseUnsupportedCapabilityReason(reason) {
|
|
|
62338
62452
|
return rest.split(",").map((s) => s.trim()).filter((s) => s.length > 0);
|
|
62339
62453
|
}
|
|
62340
62454
|
|
|
62341
|
-
// node_modules/@fetchproxy/protocol/dist/mcp-id.js
|
|
62342
|
-
var ID_RE = /^([^:]+):([^:]+):([0-9a-f]{16})$/;
|
|
62343
|
-
function generateMcpId(serverName, version2) {
|
|
62344
|
-
if (serverName.includes(":")) {
|
|
62345
|
-
throw new Error(`serverName cannot contain ':': ${serverName}`);
|
|
62346
|
-
}
|
|
62347
|
-
if (version2.includes(":")) {
|
|
62348
|
-
throw new Error(`version cannot contain ':': ${version2}`);
|
|
62349
|
-
}
|
|
62350
|
-
const rand = randomHex(8);
|
|
62351
|
-
return `${serverName}:${version2}:${rand}`;
|
|
62352
|
-
}
|
|
62353
|
-
function isValidMcpId(id) {
|
|
62354
|
-
return typeof id === "string" && ID_RE.test(id);
|
|
62355
|
-
}
|
|
62356
|
-
function randomHex(bytes) {
|
|
62357
|
-
const arr = new Uint8Array(bytes);
|
|
62358
|
-
globalThis.crypto.getRandomValues(arr);
|
|
62359
|
-
return Array.from(arr, (b) => b.toString(16).padStart(2, "0")).join("");
|
|
62360
|
-
}
|
|
62361
|
-
|
|
62362
62455
|
// node_modules/@fetchproxy/protocol/dist/json-pointer.js
|
|
62363
62456
|
function matchesDeclaredKey(requested, declared) {
|
|
62364
62457
|
for (const decl of declared) {
|
|
@@ -62954,6 +63047,16 @@ function validateFrame(raw) {
|
|
|
62954
63047
|
return { type: "extension-disconnected" };
|
|
62955
63048
|
if (t === "peer-gone")
|
|
62956
63049
|
return validatePeerGone(raw);
|
|
63050
|
+
if (t === ACCOUNT_KEY_FRAME)
|
|
63051
|
+
return validateAccountKey(raw);
|
|
63052
|
+
if (t === ACCOUNT_ATTEST_FRAME)
|
|
63053
|
+
return validateAccountAttest(raw);
|
|
63054
|
+
if (t === BRIDGE_ROLE_FRAME)
|
|
63055
|
+
return validateBridgeRole(raw);
|
|
63056
|
+
if (t === BRIDGE_SERVE_FRAME || t === ROOM_PING_FRAME || t === ROOM_PONG_FRAME) {
|
|
63057
|
+
assertExactFields(raw, TYPE_ONLY_FIELDS, t);
|
|
63058
|
+
return { type: t };
|
|
63059
|
+
}
|
|
62957
63060
|
throw new ProtocolError3(`unknown frame type: ${String(t)}`);
|
|
62958
63061
|
}
|
|
62959
63062
|
function validateHello(raw) {
|
|
@@ -63157,6 +63260,165 @@ function validateHelloRejected(raw) {
|
|
|
63157
63260
|
}
|
|
63158
63261
|
return { type: "hello-rejected", mcpId: raw.mcpId, reason: raw.reason };
|
|
63159
63262
|
}
|
|
63263
|
+
var DISPLAY_FORBIDDEN_RE = /[\u0000-\u001f\u007f-\u009f\u200e\u200f\u202a-\u202e\u2066-\u2069]/;
|
|
63264
|
+
function assertExactFields(raw, allowed, label) {
|
|
63265
|
+
for (const k of Object.keys(raw)) {
|
|
63266
|
+
if (!allowed.includes(k)) {
|
|
63267
|
+
throw new ProtocolError3(`${label}: unexpected field ${JSON.stringify(k)}`);
|
|
63268
|
+
}
|
|
63269
|
+
}
|
|
63270
|
+
}
|
|
63271
|
+
function assertMatch(x, re, label, what) {
|
|
63272
|
+
assertString(x, label);
|
|
63273
|
+
if (!re.test(x))
|
|
63274
|
+
throw new ProtocolError3(`${label}: must be ${what}`);
|
|
63275
|
+
}
|
|
63276
|
+
function assertPositiveSafeInt(x, label) {
|
|
63277
|
+
if (typeof x !== "number" || !Number.isSafeInteger(x) || x <= 0) {
|
|
63278
|
+
throw new ProtocolError3(`${label}: expected positive safe integer`);
|
|
63279
|
+
}
|
|
63280
|
+
}
|
|
63281
|
+
function assertDisplayString(x, label, min, max) {
|
|
63282
|
+
assertString(x, label);
|
|
63283
|
+
if (x.length < min || x.length > max) {
|
|
63284
|
+
throw new ProtocolError3(`${label}: must be ${min}-${max} characters`);
|
|
63285
|
+
}
|
|
63286
|
+
if (DISPLAY_FORBIDDEN_RE.test(x)) {
|
|
63287
|
+
throw new ProtocolError3(`${label}: control or bidi-override character`);
|
|
63288
|
+
}
|
|
63289
|
+
}
|
|
63290
|
+
var ACCOUNT_KEY_FIELDS = [
|
|
63291
|
+
"type",
|
|
63292
|
+
"accountId",
|
|
63293
|
+
"slug",
|
|
63294
|
+
"displayName",
|
|
63295
|
+
"confirmedBy",
|
|
63296
|
+
"tokenId",
|
|
63297
|
+
"kid",
|
|
63298
|
+
"publicKey",
|
|
63299
|
+
"generation",
|
|
63300
|
+
"bridgedRegistrations"
|
|
63301
|
+
];
|
|
63302
|
+
function validateAccountKey(raw) {
|
|
63303
|
+
const L = "account-key";
|
|
63304
|
+
assertMatch(raw.accountId, ACCOUNT_ID_RE, `${L}.accountId`, "an account id");
|
|
63305
|
+
assertMatch(raw.slug, ACCOUNT_ID_RE, `${L}.slug`, "a slug");
|
|
63306
|
+
assertDisplayString(raw.displayName, `${L}.displayName`, 0, 128);
|
|
63307
|
+
assertDisplayString(raw.confirmedBy, `${L}.confirmedBy`, 1, 256);
|
|
63308
|
+
assertMatch(raw.tokenId, ACCOUNT_ID_RE, `${L}.tokenId`, "a token id");
|
|
63309
|
+
assertMatch(raw.kid, ACCOUNT_KID_RE, `${L}.kid`, "16 lowercase hex");
|
|
63310
|
+
assertBase64Bytes(raw.publicKey, `${L}.publicKey`, 32);
|
|
63311
|
+
assertPositiveSafeInt(raw.generation, `${L}.generation`);
|
|
63312
|
+
const n = raw.bridgedRegistrations;
|
|
63313
|
+
if (typeof n !== "number" || !Number.isSafeInteger(n) || n < 0) {
|
|
63314
|
+
throw new ProtocolError3(`${L}.bridgedRegistrations: expected non-negative safe integer`);
|
|
63315
|
+
}
|
|
63316
|
+
assertExactFields(raw, ACCOUNT_KEY_FIELDS, L);
|
|
63317
|
+
return {
|
|
63318
|
+
type: ACCOUNT_KEY_FRAME,
|
|
63319
|
+
accountId: raw.accountId,
|
|
63320
|
+
slug: raw.slug,
|
|
63321
|
+
displayName: raw.displayName,
|
|
63322
|
+
confirmedBy: raw.confirmedBy,
|
|
63323
|
+
tokenId: raw.tokenId,
|
|
63324
|
+
kid: raw.kid,
|
|
63325
|
+
publicKey: raw.publicKey,
|
|
63326
|
+
generation: raw.generation,
|
|
63327
|
+
bridgedRegistrations: n
|
|
63328
|
+
};
|
|
63329
|
+
}
|
|
63330
|
+
var ACCOUNT_ATTEST_FIELDS = [
|
|
63331
|
+
"type",
|
|
63332
|
+
"mcpId",
|
|
63333
|
+
"accountId",
|
|
63334
|
+
"generation",
|
|
63335
|
+
"tokenId",
|
|
63336
|
+
"kid",
|
|
63337
|
+
"registrationId",
|
|
63338
|
+
"slug",
|
|
63339
|
+
"identityHash",
|
|
63340
|
+
"identityEd25519Pub",
|
|
63341
|
+
"scopeDigest",
|
|
63342
|
+
"consent",
|
|
63343
|
+
"notAfter",
|
|
63344
|
+
"sig"
|
|
63345
|
+
];
|
|
63346
|
+
function validateAccountAttest(raw) {
|
|
63347
|
+
const L = "account-attest";
|
|
63348
|
+
if (!isValidMcpId(raw.mcpId))
|
|
63349
|
+
throw new ProtocolError3(`${L}.mcpId: invalid format`);
|
|
63350
|
+
assertMatch(raw.accountId, ACCOUNT_ID_RE, `${L}.accountId`, "an account id");
|
|
63351
|
+
assertPositiveSafeInt(raw.generation, `${L}.generation`);
|
|
63352
|
+
assertMatch(raw.tokenId, ACCOUNT_ID_RE, `${L}.tokenId`, "a token id");
|
|
63353
|
+
assertMatch(raw.kid, ACCOUNT_KID_RE, `${L}.kid`, "16 lowercase hex");
|
|
63354
|
+
assertMatch(raw.registrationId, ACCOUNT_ID_RE, `${L}.registrationId`, "a registration id");
|
|
63355
|
+
assertMatch(raw.slug, ACCOUNT_ID_RE, `${L}.slug`, "a slug");
|
|
63356
|
+
assertMatch(raw.identityHash, HEX64_RE, `${L}.identityHash`, "64 lowercase hex");
|
|
63357
|
+
assertBase64Bytes(raw.identityEd25519Pub, `${L}.identityEd25519Pub`, 32);
|
|
63358
|
+
assertMatch(raw.scopeDigest, HEX64_RE, `${L}.scopeDigest`, "64 lowercase hex");
|
|
63359
|
+
assertString(raw.consent, `${L}.consent`);
|
|
63360
|
+
const consent = raw.consent;
|
|
63361
|
+
const known = ACCOUNT_ATTEST_CONSENTS.find((c) => c === consent);
|
|
63362
|
+
if (known === void 0) {
|
|
63363
|
+
throw new ProtocolError3(`${L}.consent: must be one of ${ACCOUNT_ATTEST_CONSENTS.join(", ")}`);
|
|
63364
|
+
}
|
|
63365
|
+
assertPositiveSafeInt(raw.notAfter, `${L}.notAfter`);
|
|
63366
|
+
assertBase64Bytes(raw.sig, `${L}.sig`, 64);
|
|
63367
|
+
assertExactFields(raw, ACCOUNT_ATTEST_FIELDS, L);
|
|
63368
|
+
return {
|
|
63369
|
+
type: ACCOUNT_ATTEST_FRAME,
|
|
63370
|
+
mcpId: raw.mcpId,
|
|
63371
|
+
accountId: raw.accountId,
|
|
63372
|
+
generation: raw.generation,
|
|
63373
|
+
tokenId: raw.tokenId,
|
|
63374
|
+
kid: raw.kid,
|
|
63375
|
+
registrationId: raw.registrationId,
|
|
63376
|
+
slug: raw.slug,
|
|
63377
|
+
identityHash: raw.identityHash,
|
|
63378
|
+
identityEd25519Pub: raw.identityEd25519Pub,
|
|
63379
|
+
scopeDigest: raw.scopeDigest,
|
|
63380
|
+
consent: known,
|
|
63381
|
+
notAfter: raw.notAfter,
|
|
63382
|
+
sig: raw.sig
|
|
63383
|
+
};
|
|
63384
|
+
}
|
|
63385
|
+
var TYPE_ONLY_FIELDS = ["type"];
|
|
63386
|
+
var BRIDGE_ROLE_FIELDS = ["type", "role", "canServe", "serving"];
|
|
63387
|
+
var BRIDGE_ROLE_SERVING_FIELDS = ["label", "since"];
|
|
63388
|
+
function validateBridgeRole(raw) {
|
|
63389
|
+
const L = BRIDGE_ROLE_FRAME;
|
|
63390
|
+
const role = raw.role;
|
|
63391
|
+
if (role !== "serving" && role !== "standby") {
|
|
63392
|
+
throw new ProtocolError3(`${L}.role: must be one of serving, standby`);
|
|
63393
|
+
}
|
|
63394
|
+
const canServe = raw.canServe;
|
|
63395
|
+
assertBoolean(canServe, `${L}.canServe`);
|
|
63396
|
+
assertExactFields(raw, BRIDGE_ROLE_FIELDS, L);
|
|
63397
|
+
const serving = raw.serving;
|
|
63398
|
+
if (role === "serving") {
|
|
63399
|
+
if (serving !== void 0) {
|
|
63400
|
+
throw new ProtocolError3(`${L}.serving: must be absent when role is serving`);
|
|
63401
|
+
}
|
|
63402
|
+
return { type: BRIDGE_ROLE_FRAME, role, canServe };
|
|
63403
|
+
}
|
|
63404
|
+
if (serving === void 0) {
|
|
63405
|
+
throw new ProtocolError3(`${L}.serving: required when role is standby`);
|
|
63406
|
+
}
|
|
63407
|
+
assertObject(serving, `${L}.serving`);
|
|
63408
|
+
const label = serving.label;
|
|
63409
|
+
assertDisplayString(label, `${L}.serving.label`, 1, BRIDGE_ROLE_LABEL_MAX);
|
|
63410
|
+
const since = serving.since;
|
|
63411
|
+
if (typeof since !== "number" || !Number.isSafeInteger(since) || since < 0) {
|
|
63412
|
+
throw new ProtocolError3(`${L}.serving.since: expected non-negative safe integer (Unix ms)`);
|
|
63413
|
+
}
|
|
63414
|
+
assertExactFields(serving, BRIDGE_ROLE_SERVING_FIELDS, `${L}.serving`);
|
|
63415
|
+
return {
|
|
63416
|
+
type: BRIDGE_ROLE_FRAME,
|
|
63417
|
+
role,
|
|
63418
|
+
canServe,
|
|
63419
|
+
serving: { label, since }
|
|
63420
|
+
};
|
|
63421
|
+
}
|
|
63160
63422
|
function validateInnerFrame(raw) {
|
|
63161
63423
|
assertObject(raw, "inner");
|
|
63162
63424
|
const t = raw.type;
|
|
@@ -63624,10 +63886,10 @@ function validateInnerResponse(raw) {
|
|
|
63624
63886
|
}
|
|
63625
63887
|
|
|
63626
63888
|
// node_modules/@fetchproxy/protocol/dist/pair-code.js
|
|
63627
|
-
var
|
|
63889
|
+
var enc3 = new TextEncoder();
|
|
63628
63890
|
var PAIR_LABEL = "fetchproxy/4/pair";
|
|
63629
63891
|
async function pairTranscript(mcpIdentityPub, extIdentityPub, mcpNonce, extNonce, mcpSessionPub) {
|
|
63630
|
-
const label =
|
|
63892
|
+
const label = enc3.encode(PAIR_LABEL);
|
|
63631
63893
|
const parts = [mcpIdentityPub, extIdentityPub, mcpNonce, extNonce, mcpSessionPub];
|
|
63632
63894
|
const out = new Uint8Array(label.length + 1 + parts.reduce((n, p) => n + p.length, 0));
|
|
63633
63895
|
out.set(label, 0);
|
|
@@ -63648,7 +63910,7 @@ function digits(hash2) {
|
|
|
63648
63910
|
}
|
|
63649
63911
|
|
|
63650
63912
|
// node_modules/@fetchproxy/protocol/dist/seal.js
|
|
63651
|
-
var
|
|
63913
|
+
var enc4 = new TextEncoder();
|
|
63652
63914
|
var dec = new TextDecoder();
|
|
63653
63915
|
function randomIv() {
|
|
63654
63916
|
const iv = new Uint8Array(12);
|
|
@@ -63661,14 +63923,14 @@ function base64Length(byteLength) {
|
|
|
63661
63923
|
return Math.ceil(byteLength / 3) * 4;
|
|
63662
63924
|
}
|
|
63663
63925
|
function encodeInnerFrame(inner) {
|
|
63664
|
-
return
|
|
63926
|
+
return enc4.encode(JSON.stringify(inner));
|
|
63665
63927
|
}
|
|
63666
63928
|
function plaintextOf(inner) {
|
|
63667
63929
|
return inner instanceof Uint8Array ? inner : encodeInnerFrame(inner);
|
|
63668
63930
|
}
|
|
63669
63931
|
function sealedFrameWireBytes(mcpId, seq, inner) {
|
|
63670
63932
|
const plaintext = plaintextOf(inner).length;
|
|
63671
|
-
const envelope =
|
|
63933
|
+
const envelope = enc4.encode(JSON.stringify({ type: "frame", mcpId, seq, iv: "", ciphertext: "" })).length;
|
|
63672
63934
|
return envelope + IV_B64_BYTES + base64Length(plaintext + AES_GCM_TAG_BYTES);
|
|
63673
63935
|
}
|
|
63674
63936
|
var MAX_FRAME_BYTES = 42 * 1024 * 1024;
|
|
@@ -64008,14 +64270,23 @@ var FetchproxyHelloRejectedError = class extends Error {
|
|
|
64008
64270
|
platform;
|
|
64009
64271
|
/**
|
|
64010
64272
|
* #418: the remedy, when the reason is one this package knows how to
|
|
64011
|
-
* explain —
|
|
64012
|
-
*
|
|
64273
|
+
* explain — `unsupported-capability`, which blames the browser rather than
|
|
64274
|
+
* the MCP, and (D12) `awaiting-approval`, which says to approve in the
|
|
64275
|
+
* browser. `null` otherwise.
|
|
64013
64276
|
*/
|
|
64014
64277
|
hint;
|
|
64278
|
+
/**
|
|
64279
|
+
* D12: `true` only for an `awaiting-approval:` refusal — the extension has
|
|
64280
|
+
* queued an approval card and nobody is at the browser yet, so the same call
|
|
64281
|
+
* succeeds once the person approves. Every other refusal is the extension's
|
|
64282
|
+
* final answer, and retrying unchanged is refused the same way.
|
|
64283
|
+
*/
|
|
64284
|
+
retryable;
|
|
64015
64285
|
constructor(info) {
|
|
64016
64286
|
const unavailable = parseUnsupportedCapabilityReason(info.reason);
|
|
64287
|
+
const awaiting = parseAwaitingApprovalReason(info.reason);
|
|
64017
64288
|
const platform = info.platform ?? null;
|
|
64018
|
-
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;
|
|
64289
|
+
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;
|
|
64019
64290
|
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.`));
|
|
64020
64291
|
this.name = "FetchproxyHelloRejectedError";
|
|
64021
64292
|
this.mcpId = info.mcpId;
|
|
@@ -64023,6 +64294,7 @@ var FetchproxyHelloRejectedError = class extends Error {
|
|
|
64023
64294
|
this.unavailableCapabilities = unavailable ?? [];
|
|
64024
64295
|
this.platform = platform;
|
|
64025
64296
|
this.hint = hint;
|
|
64297
|
+
this.retryable = awaiting !== null;
|
|
64026
64298
|
Object.setPrototypeOf(this, new.target.prototype);
|
|
64027
64299
|
}
|
|
64028
64300
|
};
|
|
@@ -64575,7 +64847,7 @@ function originVerdict(origin, allowLocal) {
|
|
|
64575
64847
|
}
|
|
64576
64848
|
var HANDSHAKE_TIMEOUT_MS = 15e3;
|
|
64577
64849
|
var MAX_PAYLOAD_BYTES = MAX_FRAME_BYTES;
|
|
64578
|
-
var
|
|
64850
|
+
var enc5 = new TextEncoder();
|
|
64579
64851
|
var OWN_DECRYPT_FAILURES_BEFORE_REHANDSHAKE = 3;
|
|
64580
64852
|
async function startHost(opts) {
|
|
64581
64853
|
const allowLocalOrigins = envAllowsLocalOrigins();
|
|
@@ -64646,10 +64918,20 @@ async function startHost(opts) {
|
|
|
64646
64918
|
let resolveOwnSession;
|
|
64647
64919
|
let rejectOwnSession;
|
|
64648
64920
|
let ownSessionReady;
|
|
64921
|
+
let ownRetryableRefusal = false;
|
|
64922
|
+
let ownSessionSettled = false;
|
|
64649
64923
|
function resetSessionPromise() {
|
|
64924
|
+
ownRetryableRefusal = false;
|
|
64925
|
+
ownSessionSettled = false;
|
|
64650
64926
|
ownSessionReady = new Promise((resolve6, reject) => {
|
|
64651
|
-
resolveOwnSession =
|
|
64652
|
-
|
|
64927
|
+
resolveOwnSession = (st) => {
|
|
64928
|
+
ownSessionSettled = true;
|
|
64929
|
+
resolve6(st);
|
|
64930
|
+
};
|
|
64931
|
+
rejectOwnSession = (e) => {
|
|
64932
|
+
ownSessionSettled = true;
|
|
64933
|
+
reject(e);
|
|
64934
|
+
};
|
|
64653
64935
|
});
|
|
64654
64936
|
ownSessionReady.catch(() => {
|
|
64655
64937
|
});
|
|
@@ -64916,13 +65198,15 @@ async function startHost(opts) {
|
|
|
64916
65198
|
const extPub = fromB64(frame.extensionSessionPub);
|
|
64917
65199
|
const shared = await ecdhX25519(held.priv, extPub);
|
|
64918
65200
|
const salt = await transcriptHash(held.nonce, extNonce, held.pub, extPub);
|
|
64919
|
-
const key = await hkdfSha256(shared, salt,
|
|
65201
|
+
const key = await hkdfSha256(shared, salt, enc5.encode(HKDF_SESSION_INFO), 32);
|
|
64920
65202
|
if (extensionWs !== ws)
|
|
64921
65203
|
return;
|
|
64922
65204
|
ownSession = new SessionState(key);
|
|
64923
65205
|
ownSessionInfo = sessionInfoFromHello(verifiedHello);
|
|
64924
65206
|
ownDecryptFailures = 0;
|
|
64925
65207
|
ownPendingPairCode = null;
|
|
65208
|
+
if (ownRetryableRefusal)
|
|
65209
|
+
resetSessionPromise();
|
|
64926
65210
|
resolveOwnSession(ownSession);
|
|
64927
65211
|
} else {
|
|
64928
65212
|
const slot = peers.get(frame.mcpId);
|
|
@@ -64991,11 +65275,17 @@ async function startHost(opts) {
|
|
|
64991
65275
|
}
|
|
64992
65276
|
if (frame.type === "hello-rejected" && identified === "extension") {
|
|
64993
65277
|
if (frame.mcpId === opts.ownMcpId) {
|
|
64994
|
-
|
|
65278
|
+
const refusal = new FetchproxyHelloRejectedError({
|
|
64995
65279
|
mcpId: frame.mcpId,
|
|
64996
65280
|
reason: frame.reason,
|
|
64997
65281
|
platform: extensionHello?.platform ?? null
|
|
64998
|
-
})
|
|
65282
|
+
});
|
|
65283
|
+
if (ownRetryableRefusal)
|
|
65284
|
+
resetSessionPromise();
|
|
65285
|
+
const settlesPending = !ownSessionSettled;
|
|
65286
|
+
rejectOwnSession(refusal);
|
|
65287
|
+
if (refusal.retryable && settlesPending)
|
|
65288
|
+
ownRetryableRefusal = true;
|
|
64999
65289
|
} else {
|
|
65000
65290
|
const slot = peers.get(frame.mcpId);
|
|
65001
65291
|
if (slot?.helloFrame.accepts?.includes("hello-rejected")) {
|
|
@@ -65111,7 +65401,7 @@ async function startHost(opts) {
|
|
|
65111
65401
|
|
|
65112
65402
|
// node_modules/@fetchproxy/server/dist/peer.js
|
|
65113
65403
|
var PEER_DIAL_TIMEOUT_MS = 5e3;
|
|
65114
|
-
var
|
|
65404
|
+
var enc6 = new TextEncoder();
|
|
65115
65405
|
function notSentError() {
|
|
65116
65406
|
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.");
|
|
65117
65407
|
}
|
|
@@ -65211,7 +65501,9 @@ async function startPeer(opts) {
|
|
|
65211
65501
|
let rejectFirstReady;
|
|
65212
65502
|
let sessionPromise;
|
|
65213
65503
|
let sessionPromiseSettled = false;
|
|
65504
|
+
let retryableRefusal = false;
|
|
65214
65505
|
function resetSessionPromise() {
|
|
65506
|
+
retryableRefusal = false;
|
|
65215
65507
|
sessionPromiseSettled = false;
|
|
65216
65508
|
sessionPromise = new Promise((resolve6, reject) => {
|
|
65217
65509
|
resolveFirstReady = (st) => {
|
|
@@ -65308,6 +65600,8 @@ async function startPeer(opts) {
|
|
|
65308
65600
|
raw = JSON.parse(data.toString());
|
|
65309
65601
|
const frame = validateFrame(raw);
|
|
65310
65602
|
if (frame.type === "hello" && frame.role === "extension") {
|
|
65603
|
+
if (retryableRefusal)
|
|
65604
|
+
resetSessionPromise();
|
|
65311
65605
|
extensionHello = frame;
|
|
65312
65606
|
const mintedKeypair = await generateSessionKeypair();
|
|
65313
65607
|
const mintedHello = await buildServerHello({
|
|
@@ -65337,6 +65631,8 @@ async function startPeer(opts) {
|
|
|
65337
65631
|
session = null;
|
|
65338
65632
|
if (sessionPromiseSettled)
|
|
65339
65633
|
resetSessionPromise();
|
|
65634
|
+
} else if (retryableRefusal) {
|
|
65635
|
+
resetSessionPromise();
|
|
65340
65636
|
}
|
|
65341
65637
|
extensionDisconnectListeners.forEach((cb) => cb());
|
|
65342
65638
|
return;
|
|
@@ -65358,7 +65654,7 @@ async function startPeer(opts) {
|
|
|
65358
65654
|
const extNonce = fromB64(authenticated.sessionNonce);
|
|
65359
65655
|
const shared = await ecdhX25519(held.priv, extPub);
|
|
65360
65656
|
const salt = await transcriptHash(held.nonce, extNonce, held.pub, extPub);
|
|
65361
|
-
const sessionKey = await hkdfSha256(shared, salt,
|
|
65657
|
+
const sessionKey = await hkdfSha256(shared, salt, enc6.encode(HKDF_SESSION_INFO), 32);
|
|
65362
65658
|
if (sessionEphemeral !== held) {
|
|
65363
65659
|
console.warn(`[fetchproxy] ${opts.serverName}: dropping a session derived against an ephemeral that was superseded while it was being derived`);
|
|
65364
65660
|
return;
|
|
@@ -65371,16 +65667,24 @@ async function startPeer(opts) {
|
|
|
65371
65667
|
if (isRenegotiation) {
|
|
65372
65668
|
renegotiateListeners.forEach((cb) => cb());
|
|
65373
65669
|
} else {
|
|
65670
|
+
if (retryableRefusal)
|
|
65671
|
+
resetSessionPromise();
|
|
65374
65672
|
resolveFirstReady(session);
|
|
65375
65673
|
}
|
|
65376
65674
|
return;
|
|
65377
65675
|
}
|
|
65378
65676
|
if (frame.type === "hello-rejected" && frame.mcpId === opts.mcpId) {
|
|
65379
|
-
|
|
65677
|
+
const refusal = new FetchproxyHelloRejectedError({
|
|
65380
65678
|
mcpId: frame.mcpId,
|
|
65381
65679
|
reason: frame.reason,
|
|
65382
65680
|
platform: extensionHello?.platform ?? null
|
|
65383
|
-
})
|
|
65681
|
+
});
|
|
65682
|
+
if (retryableRefusal)
|
|
65683
|
+
resetSessionPromise();
|
|
65684
|
+
const settlesPending = !sessionPromiseSettled;
|
|
65685
|
+
rejectFirstReady(refusal);
|
|
65686
|
+
if (refusal.retryable && settlesPending)
|
|
65687
|
+
retryableRefusal = true;
|
|
65384
65688
|
}
|
|
65385
65689
|
if (frame.type === "pair-pending" && frame.mcpId === opts.mcpId) {
|
|
65386
65690
|
const hello2 = extensionHello;
|
|
@@ -65544,8 +65848,9 @@ function classifyFetchError(error62, code) {
|
|
|
65544
65848
|
|
|
65545
65849
|
// node_modules/@fetchproxy/server/dist/classify-bridge-error.js
|
|
65546
65850
|
function classifyBridgeError(err) {
|
|
65547
|
-
if (err instanceof FetchproxyHelloRejectedError)
|
|
65548
|
-
return "hello_rejected";
|
|
65851
|
+
if (err instanceof FetchproxyHelloRejectedError) {
|
|
65852
|
+
return err.retryable ? "awaiting_approval" : "hello_rejected";
|
|
65853
|
+
}
|
|
65549
65854
|
if (err instanceof FetchproxySessionNotReadyError)
|
|
65550
65855
|
return "session_not_ready";
|
|
65551
65856
|
if (err instanceof FetchproxyTimeoutError)
|
|
@@ -68317,7 +68622,7 @@ function resolveDownloadDir(env = process.env) {
|
|
|
68317
68622
|
// package.json
|
|
68318
68623
|
var package_default = {
|
|
68319
68624
|
name: "infinitecampus-mcp",
|
|
68320
|
-
version: "3.1.
|
|
68625
|
+
version: "3.1.8",
|
|
68321
68626
|
mcpName: "io.github.chrischall/infinitecampus-mcp",
|
|
68322
68627
|
description: "Infinite Campus (Campus Parent) MCP server \u2014 multi-district read + message/document write",
|
|
68323
68628
|
author: "Claude Code (AI) <https://www.anthropic.com/claude>",
|
|
@@ -68362,16 +68667,16 @@ var package_default = {
|
|
|
68362
68667
|
typecheck: "tsc -p tsconfig.json --noEmit"
|
|
68363
68668
|
},
|
|
68364
68669
|
dependencies: {
|
|
68365
|
-
"@chrischall/mcp-utils": "^2.
|
|
68366
|
-
"@fetchproxy/bootstrap": "^3.
|
|
68367
|
-
"@fetchproxy/server": "^3.
|
|
68368
|
-
"@modelcontextprotocol/server": "^2.
|
|
68670
|
+
"@chrischall/mcp-utils": "^2.15.0",
|
|
68671
|
+
"@fetchproxy/bootstrap": "^3.6.0",
|
|
68672
|
+
"@fetchproxy/server": "^3.6.0",
|
|
68673
|
+
"@modelcontextprotocol/server": "^2.3.0",
|
|
68369
68674
|
dotenv: "^18.0.2",
|
|
68370
68675
|
"node-html-parser": "^9.0.0",
|
|
68371
68676
|
zod: "^4.6.5"
|
|
68372
68677
|
},
|
|
68373
68678
|
devDependencies: {
|
|
68374
|
-
"@modelcontextprotocol/client": "^2.
|
|
68679
|
+
"@modelcontextprotocol/client": "^2.3.0",
|
|
68375
68680
|
"@types/node": "^26.0.0",
|
|
68376
68681
|
"@vitest/coverage-v8": "^5.0.0",
|
|
68377
68682
|
esbuild: "^0.28.0",
|
|
@@ -70603,7 +70908,7 @@ try {
|
|
|
70603
70908
|
}
|
|
70604
70909
|
var COMMON = {
|
|
70605
70910
|
name: "infinitecampus",
|
|
70606
|
-
version: "3.1.
|
|
70911
|
+
version: "3.1.8"
|
|
70607
70912
|
// x-release-please-version
|
|
70608
70913
|
};
|
|
70609
70914
|
var healthState = { account, source, configError, client: null };
|
|
@@ -70654,7 +70959,7 @@ ${AI_NOTICE}` });
|
|
|
70654
70959
|
}
|
|
70655
70960
|
/*! Bundled license information:
|
|
70656
70961
|
|
|
70657
|
-
@modelcontextprotocol/server/dist/src-
|
|
70962
|
+
@modelcontextprotocol/server/dist/src-Cqbh3MYc.mjs:
|
|
70658
70963
|
(*!
|
|
70659
70964
|
* content-type
|
|
70660
70965
|
* Copyright(c) 2015 Douglas Christopher Wilson
|
package/dist/index.js
CHANGED
|
@@ -56,7 +56,7 @@ catch (e) {
|
|
|
56
56
|
// avoids — see `unconfiguredClient`.
|
|
57
57
|
const COMMON = {
|
|
58
58
|
name: 'infinitecampus',
|
|
59
|
-
version: '3.1.
|
|
59
|
+
version: '3.1.8', // x-release-please-version
|
|
60
60
|
};
|
|
61
61
|
// Shared with the healthcheck so it can report the SAME state the tools see,
|
|
62
62
|
// including on the unconfigured path where there are no tools at all.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "infinitecampus-mcp",
|
|
3
|
-
"version": "3.1.
|
|
3
|
+
"version": "3.1.8",
|
|
4
4
|
"mcpName": "io.github.chrischall/infinitecampus-mcp",
|
|
5
5
|
"description": "Infinite Campus (Campus Parent) MCP server — multi-district read + message/document write",
|
|
6
6
|
"author": "Claude Code (AI) <https://www.anthropic.com/claude>",
|
|
@@ -45,16 +45,16 @@
|
|
|
45
45
|
"typecheck": "tsc -p tsconfig.json --noEmit"
|
|
46
46
|
},
|
|
47
47
|
"dependencies": {
|
|
48
|
-
"@chrischall/mcp-utils": "^2.
|
|
49
|
-
"@fetchproxy/bootstrap": "^3.
|
|
50
|
-
"@fetchproxy/server": "^3.
|
|
51
|
-
"@modelcontextprotocol/server": "^2.
|
|
48
|
+
"@chrischall/mcp-utils": "^2.15.0",
|
|
49
|
+
"@fetchproxy/bootstrap": "^3.6.0",
|
|
50
|
+
"@fetchproxy/server": "^3.6.0",
|
|
51
|
+
"@modelcontextprotocol/server": "^2.3.0",
|
|
52
52
|
"dotenv": "^18.0.2",
|
|
53
53
|
"node-html-parser": "^9.0.0",
|
|
54
54
|
"zod": "^4.6.5"
|
|
55
55
|
},
|
|
56
56
|
"devDependencies": {
|
|
57
|
-
"@modelcontextprotocol/client": "^2.
|
|
57
|
+
"@modelcontextprotocol/client": "^2.3.0",
|
|
58
58
|
"@types/node": "^26.0.0",
|
|
59
59
|
"@vitest/coverage-v8": "^5.0.0",
|
|
60
60
|
"esbuild": "^0.28.0",
|
package/server.json
CHANGED
|
@@ -6,12 +6,12 @@
|
|
|
6
6
|
"url": "https://github.com/chrischall/infinitecampus-mcp",
|
|
7
7
|
"source": "github"
|
|
8
8
|
},
|
|
9
|
-
"version": "3.1.
|
|
9
|
+
"version": "3.1.8",
|
|
10
10
|
"packages": [
|
|
11
11
|
{
|
|
12
12
|
"registryType": "npm",
|
|
13
13
|
"identifier": "infinitecampus-mcp",
|
|
14
|
-
"version": "3.1.
|
|
14
|
+
"version": "3.1.8",
|
|
15
15
|
"transport": {
|
|
16
16
|
"type": "stdio"
|
|
17
17
|
},
|