infinitecampus-mcp 3.1.6 → 3.1.7
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 +312 -74
- package/dist/index.js +1 -1
- package/package.json +4 -4
- 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.7"
|
|
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.7",
|
|
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.7",
|
|
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}`);
|
|
@@ -27996,7 +27996,7 @@ var OAuthTokenRevocationRequestSchema = z.object({
|
|
|
27996
27996
|
token_type_hint: z.string().optional()
|
|
27997
27997
|
}).strip();
|
|
27998
27998
|
|
|
27999
|
-
// node_modules/@modelcontextprotocol/server/dist/src-
|
|
27999
|
+
// node_modules/@modelcontextprotocol/server/dist/src-Cqbh3MYc.mjs
|
|
28000
28000
|
var z2 = __toESM(require_v4(), 1);
|
|
28001
28001
|
var BRANDS = /* @__PURE__ */ Symbol.for("mcp.sdk.errorBrands");
|
|
28002
28002
|
function stampErrorBrands(instance, ctor) {
|
|
@@ -30240,7 +30240,8 @@ function build() {
|
|
|
30240
30240
|
ListResourceTemplatesResultResponseSchema: wireResultResponse(ListResourceTemplatesResultSchema$1),
|
|
30241
30241
|
ReadResourceResultResponseSchema: wireResultResponse(z2.union([ReadResourceResultSchema$1, InputRequiredResultSchema])),
|
|
30242
30242
|
CompleteResultResponseSchema: wireResultResponse(CompleteResultSchema$1),
|
|
30243
|
-
DiscoverResultResponseSchema: wireResultResponse(DiscoverResultSchema$1)
|
|
30243
|
+
DiscoverResultResponseSchema: wireResultResponse(DiscoverResultSchema$1),
|
|
30244
|
+
SubscriptionsListenResultResponseSchema: wireResultResponse(SubscriptionsListenResultSchema$1)
|
|
30244
30245
|
};
|
|
30245
30246
|
}
|
|
30246
30247
|
var memo;
|
|
@@ -30748,6 +30749,9 @@ function isSpecRequestMethod(method) {
|
|
|
30748
30749
|
function isSpecNotificationMethod(method) {
|
|
30749
30750
|
return ALL_CODECS.some((codec2) => codec2.hasNotificationMethod(method));
|
|
30750
30751
|
}
|
|
30752
|
+
function isExtensionReusedRequestMethod(method) {
|
|
30753
|
+
return method === "tasks/get" || method === "tasks/cancel";
|
|
30754
|
+
}
|
|
30751
30755
|
var ALL_CODECS = [rev2025Codec, rev2026Codec];
|
|
30752
30756
|
function isPlainObject$3(value) {
|
|
30753
30757
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
@@ -31725,6 +31729,8 @@ var Protocol = class {
|
|
|
31725
31729
|
_transport;
|
|
31726
31730
|
_requestMessageId = 0;
|
|
31727
31731
|
_requestHandlers = /* @__PURE__ */ new Map();
|
|
31732
|
+
/** Methods registered with an explicit schema; the era gate in `_onrequest` reads it for the Tasks extension names. */
|
|
31733
|
+
_customSchemaRequestMethods = /* @__PURE__ */ new Set();
|
|
31728
31734
|
_requestHandlerAbortControllers = /* @__PURE__ */ new Map();
|
|
31729
31735
|
_notificationHandlers = /* @__PURE__ */ new Map();
|
|
31730
31736
|
_responseHandlers = /* @__PURE__ */ new Map();
|
|
@@ -32008,7 +32014,7 @@ var Protocol = class {
|
|
|
32008
32014
|
return;
|
|
32009
32015
|
}
|
|
32010
32016
|
}
|
|
32011
|
-
if (isSpecRequestMethod(request.method) && !codec2.hasRequestMethod(request.method)) {
|
|
32017
|
+
if (isSpecRequestMethod(request.method) && !codec2.hasRequestMethod(request.method) && !(isExtensionReusedRequestMethod(request.method) && this._customSchemaRequestMethods.has(request.method))) {
|
|
32012
32018
|
sendErrorResponse(ProtocolErrorCode.MethodNotFound, "Method not found");
|
|
32013
32019
|
return;
|
|
32014
32020
|
}
|
|
@@ -32141,8 +32147,11 @@ var Protocol = class {
|
|
|
32141
32147
|
}
|
|
32142
32148
|
request(request, schemaOrOptions, maybeOptions) {
|
|
32143
32149
|
const codec2 = this._resolveOutboundCodec(request.method);
|
|
32150
|
+
if (isStandardSchema(schemaOrOptions)) {
|
|
32151
|
+
if (!isExtensionReusedRequestMethod(request.method)) this._assertOutboundRequestInEra(codec2, request.method);
|
|
32152
|
+
return this._requestWithSchemaViaCodec(codec2, request, schemaOrOptions, maybeOptions);
|
|
32153
|
+
}
|
|
32144
32154
|
this._assertOutboundRequestInEra(codec2, request.method);
|
|
32145
|
-
if (isStandardSchema(schemaOrOptions)) return this._requestWithSchemaViaCodec(codec2, request, schemaOrOptions, maybeOptions);
|
|
32146
32155
|
const validate2 = codecResultValidator(codec2, request.method);
|
|
32147
32156
|
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
32157
|
return this._requestWithSchemaViaCodec(codec2, request, validate2, schemaOrOptions);
|
|
@@ -32386,6 +32395,8 @@ var Protocol = class {
|
|
|
32386
32395
|
return maybeHandler(parsed.data, ctx);
|
|
32387
32396
|
};
|
|
32388
32397
|
else throw new TypeError("setRequestHandler: handler is required");
|
|
32398
|
+
if (typeof schemasOrHandler === "function") this._customSchemaRequestMethods.delete(method);
|
|
32399
|
+
else this._customSchemaRequestMethods.add(method);
|
|
32389
32400
|
this._requestHandlers.set(method, this._wrapHandler(method, stored));
|
|
32390
32401
|
}
|
|
32391
32402
|
/**
|
|
@@ -32415,6 +32426,7 @@ var Protocol = class {
|
|
|
32415
32426
|
*/
|
|
32416
32427
|
removeRequestHandler(method) {
|
|
32417
32428
|
this._requestHandlers.delete(method);
|
|
32429
|
+
this._customSchemaRequestMethods.delete(method);
|
|
32418
32430
|
}
|
|
32419
32431
|
/**
|
|
32420
32432
|
* 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 +39669,7 @@ var Ajv = import_ajv.Ajv;
|
|
|
39657
39669
|
// node_modules/@modelcontextprotocol/server/dist/shimsNode.mjs
|
|
39658
39670
|
import process2 from "node:process";
|
|
39659
39671
|
|
|
39660
|
-
// node_modules/@modelcontextprotocol/server/dist/mcp-
|
|
39672
|
+
// node_modules/@modelcontextprotocol/server/dist/mcp-DIH4cS6P.mjs
|
|
39661
39673
|
var COMPLETABLE_SYMBOL = /* @__PURE__ */ Symbol.for("mcp.completable");
|
|
39662
39674
|
function isCompletable(schema) {
|
|
39663
39675
|
return !!schema && typeof schema === "object" && COMPLETABLE_SYMBOL in schema;
|
|
@@ -39722,7 +39734,7 @@ var StdioListenRouter = class {
|
|
|
39722
39734
|
_serverCapabilities;
|
|
39723
39735
|
/**
|
|
39724
39736
|
* The serving instance's identity, stamped onto the graceful-close
|
|
39725
|
-
* results' `_meta` (the spec's `
|
|
39737
|
+
* results' `_meta` (the spec's `SubscriptionsListenResultMetaObject` extends
|
|
39726
39738
|
* `ResultMetaObject`). Handed over together with the capabilities.
|
|
39727
39739
|
*/
|
|
39728
39740
|
_serverInfo;
|
|
@@ -40054,6 +40066,11 @@ var Server = class extends Protocol {
|
|
|
40054
40066
|
if (modernProtocolVersions(this._supportedProtocolVersions).length > 0) this.setRequestHandler("server/discover", () => this._ondiscover());
|
|
40055
40067
|
if (this._capabilities.logging) this._registerLoggingHandler();
|
|
40056
40068
|
}
|
|
40069
|
+
/** Attaches to the given transport; rejects while this instance is connected to another one. */
|
|
40070
|
+
async connect(transport) {
|
|
40071
|
+
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.");
|
|
40072
|
+
await super.connect(transport);
|
|
40073
|
+
}
|
|
40057
40074
|
/**
|
|
40058
40075
|
* Registers the built-in `logging/setLevel` request handler.
|
|
40059
40076
|
*
|
|
@@ -40607,21 +40624,41 @@ var Server = class extends Protocol {
|
|
|
40607
40624
|
function discoverAdvertisedCapabilities(capabilities) {
|
|
40608
40625
|
return { ...capabilities };
|
|
40609
40626
|
}
|
|
40627
|
+
function toolInputElementCount(value, max) {
|
|
40628
|
+
let count = 0;
|
|
40629
|
+
const stack = [value];
|
|
40630
|
+
while (stack.length > 0) {
|
|
40631
|
+
const node2 = stack.pop();
|
|
40632
|
+
if (node2 === null || typeof node2 !== "object") continue;
|
|
40633
|
+
if (Array.isArray(node2)) for (const child of node2) {
|
|
40634
|
+
if (++count > max) return count;
|
|
40635
|
+
if (child !== null && typeof child === "object") stack.push(child);
|
|
40636
|
+
}
|
|
40637
|
+
else for (const key in node2) {
|
|
40638
|
+
if (!Object.prototype.hasOwnProperty.call(node2, key)) continue;
|
|
40639
|
+
if (++count > max) return count;
|
|
40640
|
+
const child = node2[key];
|
|
40641
|
+
if (child !== null && typeof child === "object") stack.push(child);
|
|
40642
|
+
}
|
|
40643
|
+
}
|
|
40644
|
+
return count;
|
|
40645
|
+
}
|
|
40646
|
+
function resolveMaxToolInputElements(value) {
|
|
40647
|
+
if (value === void 0 || value === Infinity) return void 0;
|
|
40648
|
+
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)}`);
|
|
40649
|
+
return value;
|
|
40650
|
+
}
|
|
40610
40651
|
var McpServer = class {
|
|
40611
40652
|
/**
|
|
40612
40653
|
* The underlying {@linkcode Server} instance, useful for advanced operations like sending notifications.
|
|
40613
40654
|
*/
|
|
40614
40655
|
server;
|
|
40656
|
+
_maxToolInputElements;
|
|
40615
40657
|
_registeredResources = {};
|
|
40616
40658
|
_registeredResourceTemplates = {};
|
|
40617
40659
|
_registeredTools = {};
|
|
40618
40660
|
_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
|
-
*/
|
|
40661
|
+
/** Per-tool JSON-converted `inputSchema`, filled on first use by `toolInputSchemaJson()`. */
|
|
40625
40662
|
_toolInputSchemaJson = {};
|
|
40626
40663
|
/**
|
|
40627
40664
|
* The JSON-serialized `inputSchema` of a registered tool, or `undefined`
|
|
@@ -40646,6 +40683,7 @@ var McpServer = class {
|
|
|
40646
40683
|
}
|
|
40647
40684
|
constructor(serverInfo, options) {
|
|
40648
40685
|
this.server = new Server(serverInfo, options);
|
|
40686
|
+
this._maxToolInputElements = resolveMaxToolInputElements(options?.maxToolInputElements);
|
|
40649
40687
|
if (options?.capabilities?.tools) this.setToolRequestHandlers();
|
|
40650
40688
|
if (options?.capabilities?.resources) this.setResourceRequestHandlers();
|
|
40651
40689
|
if (options?.capabilities?.prompts) this.setPromptRequestHandlers();
|
|
@@ -40718,7 +40756,7 @@ var McpServer = class {
|
|
|
40718
40756
|
name,
|
|
40719
40757
|
title: tool.title,
|
|
40720
40758
|
description: tool.description,
|
|
40721
|
-
inputSchema: tool.inputSchema ?
|
|
40759
|
+
inputSchema: tool.inputSchema ? convertListedInputSchema(name, tool.inputSchema) : EMPTY_OBJECT_JSON_SCHEMA,
|
|
40722
40760
|
annotations: tool.annotations,
|
|
40723
40761
|
icons: tool.icons,
|
|
40724
40762
|
execution: tool.execution,
|
|
@@ -40763,6 +40801,7 @@ var McpServer = class {
|
|
|
40763
40801
|
* Validates tool input arguments against the tool's input schema.
|
|
40764
40802
|
*/
|
|
40765
40803
|
async validateToolInput(tool, args, toolName) {
|
|
40804
|
+
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
40805
|
if (!tool.inputSchema) return;
|
|
40767
40806
|
const parseResult = await validateStandardSchema(tool.inputSchema, args ?? {});
|
|
40768
40807
|
if (!parseResult.success) throw new ProtocolError(ProtocolErrorCode.InvalidParams, `Input validation error: Invalid arguments for tool ${toolName}: ${parseResult.error}`);
|
|
@@ -41037,20 +41076,19 @@ var McpServer = class {
|
|
|
41037
41076
|
}
|
|
41038
41077
|
_createRegisteredTool(name, title, description, inputSchema, outputSchema, annotations, icons, execution, scopeChallenge, _meta, handler) {
|
|
41039
41078
|
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
41079
|
let currentHandler = handler;
|
|
41080
|
+
let outputSchemaJson;
|
|
41048
41081
|
const registeredTool = {
|
|
41049
41082
|
title,
|
|
41050
41083
|
description,
|
|
41051
41084
|
inputSchema,
|
|
41052
41085
|
outputSchema,
|
|
41053
|
-
outputSchemaJson
|
|
41086
|
+
get outputSchemaJson() {
|
|
41087
|
+
return outputSchemaJson ??= convertOutputSchemaJson(registeredTool.outputSchema);
|
|
41088
|
+
},
|
|
41089
|
+
set outputSchemaJson(value) {
|
|
41090
|
+
outputSchemaJson = value;
|
|
41091
|
+
},
|
|
41054
41092
|
annotations,
|
|
41055
41093
|
icons,
|
|
41056
41094
|
execution,
|
|
@@ -41177,6 +41215,12 @@ var EMPTY_OBJECT_JSON_SCHEMA = {
|
|
|
41177
41215
|
type: "object",
|
|
41178
41216
|
properties: {}
|
|
41179
41217
|
};
|
|
41218
|
+
function convertListedInputSchema(name, inputSchema) {
|
|
41219
|
+
const json2 = standardSchemaToJsonSchema(inputSchema, "input");
|
|
41220
|
+
const scan = scanXMcpHeaderDeclarations(json2);
|
|
41221
|
+
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}`);
|
|
41222
|
+
return json2;
|
|
41223
|
+
}
|
|
41180
41224
|
function convertOutputSchemaJson(outputSchema) {
|
|
41181
41225
|
if (outputSchema === void 0) return void 0;
|
|
41182
41226
|
try {
|
|
@@ -41189,7 +41233,7 @@ function createPromptHandler(name, argsSchema15, callback) {
|
|
|
41189
41233
|
if (argsSchema15) {
|
|
41190
41234
|
const typedCallback = callback;
|
|
41191
41235
|
return async (args, ctx) => {
|
|
41192
|
-
const parseResult = await validateStandardSchema(argsSchema15, args);
|
|
41236
|
+
const parseResult = await validateStandardSchema(argsSchema15, args ?? {});
|
|
41193
41237
|
if (!parseResult.success) throw new ProtocolError(ProtocolErrorCode.InvalidParams, `Invalid arguments for prompt ${name}: ${parseResult.error}`);
|
|
41194
41238
|
return typedCallback(parseResult.data, ctx);
|
|
41195
41239
|
};
|
|
@@ -59546,8 +59590,8 @@ function currencyCode2(_params) {
|
|
|
59546
59590
|
return _stringFormat(ZodCustomStringFormat, "currency_code", currencyCode, _params);
|
|
59547
59591
|
}
|
|
59548
59592
|
function hash(alg, params) {
|
|
59549
|
-
const
|
|
59550
|
-
const format = `${alg}_${
|
|
59593
|
+
const enc7 = params?.enc ?? "hex";
|
|
59594
|
+
const format = `${alg}_${enc7}`;
|
|
59551
59595
|
const regex = regexes_exports[format];
|
|
59552
59596
|
if (!regex)
|
|
59553
59597
|
throw new Error(`Unrecognized hash format: ${format}`);
|
|
@@ -61730,7 +61774,10 @@ function surfaceToolHints(server) {
|
|
|
61730
61774
|
));
|
|
61731
61775
|
}
|
|
61732
61776
|
async function createMcpServer(opts) {
|
|
61733
|
-
const server = new McpServer({ name: opts.name, version: opts.version }, {
|
|
61777
|
+
const server = new McpServer({ name: opts.name, version: opts.version }, {
|
|
61778
|
+
supportedProtocolVersions: [...SERVER_PROTOCOL_VERSIONS],
|
|
61779
|
+
...opts.maxToolInputElements !== void 0 ? { maxToolInputElements: opts.maxToolInputElements } : {}
|
|
61780
|
+
});
|
|
61734
61781
|
if (opts.surfaceHints !== false)
|
|
61735
61782
|
surfaceToolHints(server);
|
|
61736
61783
|
if (opts.banner !== void 0) {
|
|
@@ -62313,6 +62360,49 @@ var KNOWN_CAPABILITIES = /* @__PURE__ */ new Set([
|
|
|
62313
62360
|
"graphql",
|
|
62314
62361
|
"write_cookies"
|
|
62315
62362
|
]);
|
|
62363
|
+
var ACCOUNT_KEY_FRAME = "account-key";
|
|
62364
|
+
var ACCOUNT_ATTEST_FRAME = "account-attest";
|
|
62365
|
+
|
|
62366
|
+
// node_modules/@fetchproxy/protocol/dist/mcp-id.js
|
|
62367
|
+
var ID_RE = /^([^:]+):([^:]+):([0-9a-f]{16})$/;
|
|
62368
|
+
function generateMcpId(serverName, version2) {
|
|
62369
|
+
if (serverName.includes(":")) {
|
|
62370
|
+
throw new Error(`serverName cannot contain ':': ${serverName}`);
|
|
62371
|
+
}
|
|
62372
|
+
if (version2.includes(":")) {
|
|
62373
|
+
throw new Error(`version cannot contain ':': ${version2}`);
|
|
62374
|
+
}
|
|
62375
|
+
const rand = randomHex(8);
|
|
62376
|
+
return `${serverName}:${version2}:${rand}`;
|
|
62377
|
+
}
|
|
62378
|
+
function isValidMcpId(id) {
|
|
62379
|
+
return typeof id === "string" && ID_RE.test(id);
|
|
62380
|
+
}
|
|
62381
|
+
function randomHex(bytes) {
|
|
62382
|
+
const arr = new Uint8Array(bytes);
|
|
62383
|
+
globalThis.crypto.getRandomValues(arr);
|
|
62384
|
+
return Array.from(arr, (b) => b.toString(16).padStart(2, "0")).join("");
|
|
62385
|
+
}
|
|
62386
|
+
|
|
62387
|
+
// node_modules/@fetchproxy/protocol/dist/account-attest.js
|
|
62388
|
+
var ACCOUNT_ATTEST_CONSENTS = Object.freeze([
|
|
62389
|
+
"silent",
|
|
62390
|
+
"confirm",
|
|
62391
|
+
"confirm-each"
|
|
62392
|
+
]);
|
|
62393
|
+
var NO_SCOPE_DIGEST = "0".repeat(64);
|
|
62394
|
+
var ACCOUNT_ID_RE = /^[A-Za-z0-9_.\-]{1,128}$/;
|
|
62395
|
+
var HEX64_RE = /^[0-9a-f]{64}$/;
|
|
62396
|
+
var ACCOUNT_KID_RE = /^[0-9a-f]{16}$/;
|
|
62397
|
+
var enc2 = new TextEncoder();
|
|
62398
|
+
|
|
62399
|
+
// node_modules/@fetchproxy/protocol/dist/awaiting-approval.js
|
|
62400
|
+
var AWAITING_APPROVAL_REASON_PREFIX = "awaiting-approval:";
|
|
62401
|
+
function parseAwaitingApprovalReason(reason) {
|
|
62402
|
+
if (!reason.startsWith(AWAITING_APPROVAL_REASON_PREFIX))
|
|
62403
|
+
return null;
|
|
62404
|
+
return reason.slice(AWAITING_APPROVAL_REASON_PREFIX.length).trim();
|
|
62405
|
+
}
|
|
62316
62406
|
|
|
62317
62407
|
// node_modules/@fetchproxy/protocol/dist/capability-availability.js
|
|
62318
62408
|
var CAPABILITY_UNAVAILABLE_CODE = "capability_unavailable";
|
|
@@ -62338,27 +62428,6 @@ function parseUnsupportedCapabilityReason(reason) {
|
|
|
62338
62428
|
return rest.split(",").map((s) => s.trim()).filter((s) => s.length > 0);
|
|
62339
62429
|
}
|
|
62340
62430
|
|
|
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
62431
|
// node_modules/@fetchproxy/protocol/dist/json-pointer.js
|
|
62363
62432
|
function matchesDeclaredKey(requested, declared) {
|
|
62364
62433
|
for (const decl of declared) {
|
|
@@ -62954,6 +63023,10 @@ function validateFrame(raw) {
|
|
|
62954
63023
|
return { type: "extension-disconnected" };
|
|
62955
63024
|
if (t === "peer-gone")
|
|
62956
63025
|
return validatePeerGone(raw);
|
|
63026
|
+
if (t === ACCOUNT_KEY_FRAME)
|
|
63027
|
+
return validateAccountKey(raw);
|
|
63028
|
+
if (t === ACCOUNT_ATTEST_FRAME)
|
|
63029
|
+
return validateAccountAttest(raw);
|
|
62957
63030
|
throw new ProtocolError3(`unknown frame type: ${String(t)}`);
|
|
62958
63031
|
}
|
|
62959
63032
|
function validateHello(raw) {
|
|
@@ -63157,6 +63230,128 @@ function validateHelloRejected(raw) {
|
|
|
63157
63230
|
}
|
|
63158
63231
|
return { type: "hello-rejected", mcpId: raw.mcpId, reason: raw.reason };
|
|
63159
63232
|
}
|
|
63233
|
+
var DISPLAY_FORBIDDEN_RE = /[\u0000-\u001f\u007f-\u009f\u200e\u200f\u202a-\u202e\u2066-\u2069]/;
|
|
63234
|
+
function assertExactFields(raw, allowed, label) {
|
|
63235
|
+
for (const k of Object.keys(raw)) {
|
|
63236
|
+
if (!allowed.includes(k)) {
|
|
63237
|
+
throw new ProtocolError3(`${label}: unexpected field ${JSON.stringify(k)}`);
|
|
63238
|
+
}
|
|
63239
|
+
}
|
|
63240
|
+
}
|
|
63241
|
+
function assertMatch(x, re, label, what) {
|
|
63242
|
+
assertString(x, label);
|
|
63243
|
+
if (!re.test(x))
|
|
63244
|
+
throw new ProtocolError3(`${label}: must be ${what}`);
|
|
63245
|
+
}
|
|
63246
|
+
function assertPositiveSafeInt(x, label) {
|
|
63247
|
+
if (typeof x !== "number" || !Number.isSafeInteger(x) || x <= 0) {
|
|
63248
|
+
throw new ProtocolError3(`${label}: expected positive safe integer`);
|
|
63249
|
+
}
|
|
63250
|
+
}
|
|
63251
|
+
function assertDisplayString(x, label, min, max) {
|
|
63252
|
+
assertString(x, label);
|
|
63253
|
+
if (x.length < min || x.length > max) {
|
|
63254
|
+
throw new ProtocolError3(`${label}: must be ${min}-${max} characters`);
|
|
63255
|
+
}
|
|
63256
|
+
if (DISPLAY_FORBIDDEN_RE.test(x)) {
|
|
63257
|
+
throw new ProtocolError3(`${label}: control or bidi-override character`);
|
|
63258
|
+
}
|
|
63259
|
+
}
|
|
63260
|
+
var ACCOUNT_KEY_FIELDS = [
|
|
63261
|
+
"type",
|
|
63262
|
+
"accountId",
|
|
63263
|
+
"slug",
|
|
63264
|
+
"displayName",
|
|
63265
|
+
"confirmedBy",
|
|
63266
|
+
"tokenId",
|
|
63267
|
+
"kid",
|
|
63268
|
+
"publicKey",
|
|
63269
|
+
"generation",
|
|
63270
|
+
"bridgedRegistrations"
|
|
63271
|
+
];
|
|
63272
|
+
function validateAccountKey(raw) {
|
|
63273
|
+
const L = "account-key";
|
|
63274
|
+
assertMatch(raw.accountId, ACCOUNT_ID_RE, `${L}.accountId`, "an account id");
|
|
63275
|
+
assertMatch(raw.slug, ACCOUNT_ID_RE, `${L}.slug`, "a slug");
|
|
63276
|
+
assertDisplayString(raw.displayName, `${L}.displayName`, 0, 128);
|
|
63277
|
+
assertDisplayString(raw.confirmedBy, `${L}.confirmedBy`, 1, 256);
|
|
63278
|
+
assertMatch(raw.tokenId, ACCOUNT_ID_RE, `${L}.tokenId`, "a token id");
|
|
63279
|
+
assertMatch(raw.kid, ACCOUNT_KID_RE, `${L}.kid`, "16 lowercase hex");
|
|
63280
|
+
assertBase64Bytes(raw.publicKey, `${L}.publicKey`, 32);
|
|
63281
|
+
assertPositiveSafeInt(raw.generation, `${L}.generation`);
|
|
63282
|
+
const n = raw.bridgedRegistrations;
|
|
63283
|
+
if (typeof n !== "number" || !Number.isSafeInteger(n) || n < 0) {
|
|
63284
|
+
throw new ProtocolError3(`${L}.bridgedRegistrations: expected non-negative safe integer`);
|
|
63285
|
+
}
|
|
63286
|
+
assertExactFields(raw, ACCOUNT_KEY_FIELDS, L);
|
|
63287
|
+
return {
|
|
63288
|
+
type: ACCOUNT_KEY_FRAME,
|
|
63289
|
+
accountId: raw.accountId,
|
|
63290
|
+
slug: raw.slug,
|
|
63291
|
+
displayName: raw.displayName,
|
|
63292
|
+
confirmedBy: raw.confirmedBy,
|
|
63293
|
+
tokenId: raw.tokenId,
|
|
63294
|
+
kid: raw.kid,
|
|
63295
|
+
publicKey: raw.publicKey,
|
|
63296
|
+
generation: raw.generation,
|
|
63297
|
+
bridgedRegistrations: n
|
|
63298
|
+
};
|
|
63299
|
+
}
|
|
63300
|
+
var ACCOUNT_ATTEST_FIELDS = [
|
|
63301
|
+
"type",
|
|
63302
|
+
"mcpId",
|
|
63303
|
+
"accountId",
|
|
63304
|
+
"generation",
|
|
63305
|
+
"tokenId",
|
|
63306
|
+
"kid",
|
|
63307
|
+
"registrationId",
|
|
63308
|
+
"slug",
|
|
63309
|
+
"identityHash",
|
|
63310
|
+
"identityEd25519Pub",
|
|
63311
|
+
"scopeDigest",
|
|
63312
|
+
"consent",
|
|
63313
|
+
"notAfter",
|
|
63314
|
+
"sig"
|
|
63315
|
+
];
|
|
63316
|
+
function validateAccountAttest(raw) {
|
|
63317
|
+
const L = "account-attest";
|
|
63318
|
+
if (!isValidMcpId(raw.mcpId))
|
|
63319
|
+
throw new ProtocolError3(`${L}.mcpId: invalid format`);
|
|
63320
|
+
assertMatch(raw.accountId, ACCOUNT_ID_RE, `${L}.accountId`, "an account id");
|
|
63321
|
+
assertPositiveSafeInt(raw.generation, `${L}.generation`);
|
|
63322
|
+
assertMatch(raw.tokenId, ACCOUNT_ID_RE, `${L}.tokenId`, "a token id");
|
|
63323
|
+
assertMatch(raw.kid, ACCOUNT_KID_RE, `${L}.kid`, "16 lowercase hex");
|
|
63324
|
+
assertMatch(raw.registrationId, ACCOUNT_ID_RE, `${L}.registrationId`, "a registration id");
|
|
63325
|
+
assertMatch(raw.slug, ACCOUNT_ID_RE, `${L}.slug`, "a slug");
|
|
63326
|
+
assertMatch(raw.identityHash, HEX64_RE, `${L}.identityHash`, "64 lowercase hex");
|
|
63327
|
+
assertBase64Bytes(raw.identityEd25519Pub, `${L}.identityEd25519Pub`, 32);
|
|
63328
|
+
assertMatch(raw.scopeDigest, HEX64_RE, `${L}.scopeDigest`, "64 lowercase hex");
|
|
63329
|
+
assertString(raw.consent, `${L}.consent`);
|
|
63330
|
+
const consent = raw.consent;
|
|
63331
|
+
const known = ACCOUNT_ATTEST_CONSENTS.find((c) => c === consent);
|
|
63332
|
+
if (known === void 0) {
|
|
63333
|
+
throw new ProtocolError3(`${L}.consent: must be one of ${ACCOUNT_ATTEST_CONSENTS.join(", ")}`);
|
|
63334
|
+
}
|
|
63335
|
+
assertPositiveSafeInt(raw.notAfter, `${L}.notAfter`);
|
|
63336
|
+
assertBase64Bytes(raw.sig, `${L}.sig`, 64);
|
|
63337
|
+
assertExactFields(raw, ACCOUNT_ATTEST_FIELDS, L);
|
|
63338
|
+
return {
|
|
63339
|
+
type: ACCOUNT_ATTEST_FRAME,
|
|
63340
|
+
mcpId: raw.mcpId,
|
|
63341
|
+
accountId: raw.accountId,
|
|
63342
|
+
generation: raw.generation,
|
|
63343
|
+
tokenId: raw.tokenId,
|
|
63344
|
+
kid: raw.kid,
|
|
63345
|
+
registrationId: raw.registrationId,
|
|
63346
|
+
slug: raw.slug,
|
|
63347
|
+
identityHash: raw.identityHash,
|
|
63348
|
+
identityEd25519Pub: raw.identityEd25519Pub,
|
|
63349
|
+
scopeDigest: raw.scopeDigest,
|
|
63350
|
+
consent: known,
|
|
63351
|
+
notAfter: raw.notAfter,
|
|
63352
|
+
sig: raw.sig
|
|
63353
|
+
};
|
|
63354
|
+
}
|
|
63160
63355
|
function validateInnerFrame(raw) {
|
|
63161
63356
|
assertObject(raw, "inner");
|
|
63162
63357
|
const t = raw.type;
|
|
@@ -63624,10 +63819,10 @@ function validateInnerResponse(raw) {
|
|
|
63624
63819
|
}
|
|
63625
63820
|
|
|
63626
63821
|
// node_modules/@fetchproxy/protocol/dist/pair-code.js
|
|
63627
|
-
var
|
|
63822
|
+
var enc3 = new TextEncoder();
|
|
63628
63823
|
var PAIR_LABEL = "fetchproxy/4/pair";
|
|
63629
63824
|
async function pairTranscript(mcpIdentityPub, extIdentityPub, mcpNonce, extNonce, mcpSessionPub) {
|
|
63630
|
-
const label =
|
|
63825
|
+
const label = enc3.encode(PAIR_LABEL);
|
|
63631
63826
|
const parts = [mcpIdentityPub, extIdentityPub, mcpNonce, extNonce, mcpSessionPub];
|
|
63632
63827
|
const out = new Uint8Array(label.length + 1 + parts.reduce((n, p) => n + p.length, 0));
|
|
63633
63828
|
out.set(label, 0);
|
|
@@ -63648,7 +63843,7 @@ function digits(hash2) {
|
|
|
63648
63843
|
}
|
|
63649
63844
|
|
|
63650
63845
|
// node_modules/@fetchproxy/protocol/dist/seal.js
|
|
63651
|
-
var
|
|
63846
|
+
var enc4 = new TextEncoder();
|
|
63652
63847
|
var dec = new TextDecoder();
|
|
63653
63848
|
function randomIv() {
|
|
63654
63849
|
const iv = new Uint8Array(12);
|
|
@@ -63661,14 +63856,14 @@ function base64Length(byteLength) {
|
|
|
63661
63856
|
return Math.ceil(byteLength / 3) * 4;
|
|
63662
63857
|
}
|
|
63663
63858
|
function encodeInnerFrame(inner) {
|
|
63664
|
-
return
|
|
63859
|
+
return enc4.encode(JSON.stringify(inner));
|
|
63665
63860
|
}
|
|
63666
63861
|
function plaintextOf(inner) {
|
|
63667
63862
|
return inner instanceof Uint8Array ? inner : encodeInnerFrame(inner);
|
|
63668
63863
|
}
|
|
63669
63864
|
function sealedFrameWireBytes(mcpId, seq, inner) {
|
|
63670
63865
|
const plaintext = plaintextOf(inner).length;
|
|
63671
|
-
const envelope =
|
|
63866
|
+
const envelope = enc4.encode(JSON.stringify({ type: "frame", mcpId, seq, iv: "", ciphertext: "" })).length;
|
|
63672
63867
|
return envelope + IV_B64_BYTES + base64Length(plaintext + AES_GCM_TAG_BYTES);
|
|
63673
63868
|
}
|
|
63674
63869
|
var MAX_FRAME_BYTES = 42 * 1024 * 1024;
|
|
@@ -64008,14 +64203,23 @@ var FetchproxyHelloRejectedError = class extends Error {
|
|
|
64008
64203
|
platform;
|
|
64009
64204
|
/**
|
|
64010
64205
|
* #418: the remedy, when the reason is one this package knows how to
|
|
64011
|
-
* explain —
|
|
64012
|
-
*
|
|
64206
|
+
* explain — `unsupported-capability`, which blames the browser rather than
|
|
64207
|
+
* the MCP, and (D12) `awaiting-approval`, which says to approve in the
|
|
64208
|
+
* browser. `null` otherwise.
|
|
64013
64209
|
*/
|
|
64014
64210
|
hint;
|
|
64211
|
+
/**
|
|
64212
|
+
* D12: `true` only for an `awaiting-approval:` refusal — the extension has
|
|
64213
|
+
* queued an approval card and nobody is at the browser yet, so the same call
|
|
64214
|
+
* succeeds once the person approves. Every other refusal is the extension's
|
|
64215
|
+
* final answer, and retrying unchanged is refused the same way.
|
|
64216
|
+
*/
|
|
64217
|
+
retryable;
|
|
64015
64218
|
constructor(info) {
|
|
64016
64219
|
const unavailable = parseUnsupportedCapabilityReason(info.reason);
|
|
64220
|
+
const awaiting = parseAwaitingApprovalReason(info.reason);
|
|
64017
64221
|
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;
|
|
64222
|
+
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
64223
|
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
64224
|
this.name = "FetchproxyHelloRejectedError";
|
|
64021
64225
|
this.mcpId = info.mcpId;
|
|
@@ -64023,6 +64227,7 @@ var FetchproxyHelloRejectedError = class extends Error {
|
|
|
64023
64227
|
this.unavailableCapabilities = unavailable ?? [];
|
|
64024
64228
|
this.platform = platform;
|
|
64025
64229
|
this.hint = hint;
|
|
64230
|
+
this.retryable = awaiting !== null;
|
|
64026
64231
|
Object.setPrototypeOf(this, new.target.prototype);
|
|
64027
64232
|
}
|
|
64028
64233
|
};
|
|
@@ -64575,7 +64780,7 @@ function originVerdict(origin, allowLocal) {
|
|
|
64575
64780
|
}
|
|
64576
64781
|
var HANDSHAKE_TIMEOUT_MS = 15e3;
|
|
64577
64782
|
var MAX_PAYLOAD_BYTES = MAX_FRAME_BYTES;
|
|
64578
|
-
var
|
|
64783
|
+
var enc5 = new TextEncoder();
|
|
64579
64784
|
var OWN_DECRYPT_FAILURES_BEFORE_REHANDSHAKE = 3;
|
|
64580
64785
|
async function startHost(opts) {
|
|
64581
64786
|
const allowLocalOrigins = envAllowsLocalOrigins();
|
|
@@ -64646,10 +64851,20 @@ async function startHost(opts) {
|
|
|
64646
64851
|
let resolveOwnSession;
|
|
64647
64852
|
let rejectOwnSession;
|
|
64648
64853
|
let ownSessionReady;
|
|
64854
|
+
let ownRetryableRefusal = false;
|
|
64855
|
+
let ownSessionSettled = false;
|
|
64649
64856
|
function resetSessionPromise() {
|
|
64857
|
+
ownRetryableRefusal = false;
|
|
64858
|
+
ownSessionSettled = false;
|
|
64650
64859
|
ownSessionReady = new Promise((resolve6, reject) => {
|
|
64651
|
-
resolveOwnSession =
|
|
64652
|
-
|
|
64860
|
+
resolveOwnSession = (st) => {
|
|
64861
|
+
ownSessionSettled = true;
|
|
64862
|
+
resolve6(st);
|
|
64863
|
+
};
|
|
64864
|
+
rejectOwnSession = (e) => {
|
|
64865
|
+
ownSessionSettled = true;
|
|
64866
|
+
reject(e);
|
|
64867
|
+
};
|
|
64653
64868
|
});
|
|
64654
64869
|
ownSessionReady.catch(() => {
|
|
64655
64870
|
});
|
|
@@ -64916,13 +65131,15 @@ async function startHost(opts) {
|
|
|
64916
65131
|
const extPub = fromB64(frame.extensionSessionPub);
|
|
64917
65132
|
const shared = await ecdhX25519(held.priv, extPub);
|
|
64918
65133
|
const salt = await transcriptHash(held.nonce, extNonce, held.pub, extPub);
|
|
64919
|
-
const key = await hkdfSha256(shared, salt,
|
|
65134
|
+
const key = await hkdfSha256(shared, salt, enc5.encode(HKDF_SESSION_INFO), 32);
|
|
64920
65135
|
if (extensionWs !== ws)
|
|
64921
65136
|
return;
|
|
64922
65137
|
ownSession = new SessionState(key);
|
|
64923
65138
|
ownSessionInfo = sessionInfoFromHello(verifiedHello);
|
|
64924
65139
|
ownDecryptFailures = 0;
|
|
64925
65140
|
ownPendingPairCode = null;
|
|
65141
|
+
if (ownRetryableRefusal)
|
|
65142
|
+
resetSessionPromise();
|
|
64926
65143
|
resolveOwnSession(ownSession);
|
|
64927
65144
|
} else {
|
|
64928
65145
|
const slot = peers.get(frame.mcpId);
|
|
@@ -64991,11 +65208,17 @@ async function startHost(opts) {
|
|
|
64991
65208
|
}
|
|
64992
65209
|
if (frame.type === "hello-rejected" && identified === "extension") {
|
|
64993
65210
|
if (frame.mcpId === opts.ownMcpId) {
|
|
64994
|
-
|
|
65211
|
+
const refusal = new FetchproxyHelloRejectedError({
|
|
64995
65212
|
mcpId: frame.mcpId,
|
|
64996
65213
|
reason: frame.reason,
|
|
64997
65214
|
platform: extensionHello?.platform ?? null
|
|
64998
|
-
})
|
|
65215
|
+
});
|
|
65216
|
+
if (ownRetryableRefusal)
|
|
65217
|
+
resetSessionPromise();
|
|
65218
|
+
const settlesPending = !ownSessionSettled;
|
|
65219
|
+
rejectOwnSession(refusal);
|
|
65220
|
+
if (refusal.retryable && settlesPending)
|
|
65221
|
+
ownRetryableRefusal = true;
|
|
64999
65222
|
} else {
|
|
65000
65223
|
const slot = peers.get(frame.mcpId);
|
|
65001
65224
|
if (slot?.helloFrame.accepts?.includes("hello-rejected")) {
|
|
@@ -65111,7 +65334,7 @@ async function startHost(opts) {
|
|
|
65111
65334
|
|
|
65112
65335
|
// node_modules/@fetchproxy/server/dist/peer.js
|
|
65113
65336
|
var PEER_DIAL_TIMEOUT_MS = 5e3;
|
|
65114
|
-
var
|
|
65337
|
+
var enc6 = new TextEncoder();
|
|
65115
65338
|
function notSentError() {
|
|
65116
65339
|
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
65340
|
}
|
|
@@ -65211,7 +65434,9 @@ async function startPeer(opts) {
|
|
|
65211
65434
|
let rejectFirstReady;
|
|
65212
65435
|
let sessionPromise;
|
|
65213
65436
|
let sessionPromiseSettled = false;
|
|
65437
|
+
let retryableRefusal = false;
|
|
65214
65438
|
function resetSessionPromise() {
|
|
65439
|
+
retryableRefusal = false;
|
|
65215
65440
|
sessionPromiseSettled = false;
|
|
65216
65441
|
sessionPromise = new Promise((resolve6, reject) => {
|
|
65217
65442
|
resolveFirstReady = (st) => {
|
|
@@ -65308,6 +65533,8 @@ async function startPeer(opts) {
|
|
|
65308
65533
|
raw = JSON.parse(data.toString());
|
|
65309
65534
|
const frame = validateFrame(raw);
|
|
65310
65535
|
if (frame.type === "hello" && frame.role === "extension") {
|
|
65536
|
+
if (retryableRefusal)
|
|
65537
|
+
resetSessionPromise();
|
|
65311
65538
|
extensionHello = frame;
|
|
65312
65539
|
const mintedKeypair = await generateSessionKeypair();
|
|
65313
65540
|
const mintedHello = await buildServerHello({
|
|
@@ -65337,6 +65564,8 @@ async function startPeer(opts) {
|
|
|
65337
65564
|
session = null;
|
|
65338
65565
|
if (sessionPromiseSettled)
|
|
65339
65566
|
resetSessionPromise();
|
|
65567
|
+
} else if (retryableRefusal) {
|
|
65568
|
+
resetSessionPromise();
|
|
65340
65569
|
}
|
|
65341
65570
|
extensionDisconnectListeners.forEach((cb) => cb());
|
|
65342
65571
|
return;
|
|
@@ -65358,7 +65587,7 @@ async function startPeer(opts) {
|
|
|
65358
65587
|
const extNonce = fromB64(authenticated.sessionNonce);
|
|
65359
65588
|
const shared = await ecdhX25519(held.priv, extPub);
|
|
65360
65589
|
const salt = await transcriptHash(held.nonce, extNonce, held.pub, extPub);
|
|
65361
|
-
const sessionKey = await hkdfSha256(shared, salt,
|
|
65590
|
+
const sessionKey = await hkdfSha256(shared, salt, enc6.encode(HKDF_SESSION_INFO), 32);
|
|
65362
65591
|
if (sessionEphemeral !== held) {
|
|
65363
65592
|
console.warn(`[fetchproxy] ${opts.serverName}: dropping a session derived against an ephemeral that was superseded while it was being derived`);
|
|
65364
65593
|
return;
|
|
@@ -65371,16 +65600,24 @@ async function startPeer(opts) {
|
|
|
65371
65600
|
if (isRenegotiation) {
|
|
65372
65601
|
renegotiateListeners.forEach((cb) => cb());
|
|
65373
65602
|
} else {
|
|
65603
|
+
if (retryableRefusal)
|
|
65604
|
+
resetSessionPromise();
|
|
65374
65605
|
resolveFirstReady(session);
|
|
65375
65606
|
}
|
|
65376
65607
|
return;
|
|
65377
65608
|
}
|
|
65378
65609
|
if (frame.type === "hello-rejected" && frame.mcpId === opts.mcpId) {
|
|
65379
|
-
|
|
65610
|
+
const refusal = new FetchproxyHelloRejectedError({
|
|
65380
65611
|
mcpId: frame.mcpId,
|
|
65381
65612
|
reason: frame.reason,
|
|
65382
65613
|
platform: extensionHello?.platform ?? null
|
|
65383
|
-
})
|
|
65614
|
+
});
|
|
65615
|
+
if (retryableRefusal)
|
|
65616
|
+
resetSessionPromise();
|
|
65617
|
+
const settlesPending = !sessionPromiseSettled;
|
|
65618
|
+
rejectFirstReady(refusal);
|
|
65619
|
+
if (refusal.retryable && settlesPending)
|
|
65620
|
+
retryableRefusal = true;
|
|
65384
65621
|
}
|
|
65385
65622
|
if (frame.type === "pair-pending" && frame.mcpId === opts.mcpId) {
|
|
65386
65623
|
const hello2 = extensionHello;
|
|
@@ -65544,8 +65781,9 @@ function classifyFetchError(error62, code) {
|
|
|
65544
65781
|
|
|
65545
65782
|
// node_modules/@fetchproxy/server/dist/classify-bridge-error.js
|
|
65546
65783
|
function classifyBridgeError(err) {
|
|
65547
|
-
if (err instanceof FetchproxyHelloRejectedError)
|
|
65548
|
-
return "hello_rejected";
|
|
65784
|
+
if (err instanceof FetchproxyHelloRejectedError) {
|
|
65785
|
+
return err.retryable ? "awaiting_approval" : "hello_rejected";
|
|
65786
|
+
}
|
|
65549
65787
|
if (err instanceof FetchproxySessionNotReadyError)
|
|
65550
65788
|
return "session_not_ready";
|
|
65551
65789
|
if (err instanceof FetchproxyTimeoutError)
|
|
@@ -68317,7 +68555,7 @@ function resolveDownloadDir(env = process.env) {
|
|
|
68317
68555
|
// package.json
|
|
68318
68556
|
var package_default = {
|
|
68319
68557
|
name: "infinitecampus-mcp",
|
|
68320
|
-
version: "3.1.
|
|
68558
|
+
version: "3.1.7",
|
|
68321
68559
|
mcpName: "io.github.chrischall/infinitecampus-mcp",
|
|
68322
68560
|
description: "Infinite Campus (Campus Parent) MCP server \u2014 multi-district read + message/document write",
|
|
68323
68561
|
author: "Claude Code (AI) <https://www.anthropic.com/claude>",
|
|
@@ -68362,16 +68600,16 @@ var package_default = {
|
|
|
68362
68600
|
typecheck: "tsc -p tsconfig.json --noEmit"
|
|
68363
68601
|
},
|
|
68364
68602
|
dependencies: {
|
|
68365
|
-
"@chrischall/mcp-utils": "^2.
|
|
68603
|
+
"@chrischall/mcp-utils": "^2.14.0",
|
|
68366
68604
|
"@fetchproxy/bootstrap": "^3.4.1",
|
|
68367
68605
|
"@fetchproxy/server": "^3.4.1",
|
|
68368
|
-
"@modelcontextprotocol/server": "^2.
|
|
68606
|
+
"@modelcontextprotocol/server": "^2.3.0",
|
|
68369
68607
|
dotenv: "^18.0.2",
|
|
68370
68608
|
"node-html-parser": "^9.0.0",
|
|
68371
68609
|
zod: "^4.6.5"
|
|
68372
68610
|
},
|
|
68373
68611
|
devDependencies: {
|
|
68374
|
-
"@modelcontextprotocol/client": "^2.
|
|
68612
|
+
"@modelcontextprotocol/client": "^2.3.0",
|
|
68375
68613
|
"@types/node": "^26.0.0",
|
|
68376
68614
|
"@vitest/coverage-v8": "^5.0.0",
|
|
68377
68615
|
esbuild: "^0.28.0",
|
|
@@ -70603,7 +70841,7 @@ try {
|
|
|
70603
70841
|
}
|
|
70604
70842
|
var COMMON = {
|
|
70605
70843
|
name: "infinitecampus",
|
|
70606
|
-
version: "3.1.
|
|
70844
|
+
version: "3.1.7"
|
|
70607
70845
|
// x-release-please-version
|
|
70608
70846
|
};
|
|
70609
70847
|
var healthState = { account, source, configError, client: null };
|
|
@@ -70654,7 +70892,7 @@ ${AI_NOTICE}` });
|
|
|
70654
70892
|
}
|
|
70655
70893
|
/*! Bundled license information:
|
|
70656
70894
|
|
|
70657
|
-
@modelcontextprotocol/server/dist/src-
|
|
70895
|
+
@modelcontextprotocol/server/dist/src-Cqbh3MYc.mjs:
|
|
70658
70896
|
(*!
|
|
70659
70897
|
* content-type
|
|
70660
70898
|
* 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.7', // 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.7",
|
|
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.
|
|
48
|
+
"@chrischall/mcp-utils": "^2.14.0",
|
|
49
49
|
"@fetchproxy/bootstrap": "^3.4.1",
|
|
50
50
|
"@fetchproxy/server": "^3.4.1",
|
|
51
|
-
"@modelcontextprotocol/server": "^2.
|
|
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.7",
|
|
10
10
|
"packages": [
|
|
11
11
|
{
|
|
12
12
|
"registryType": "npm",
|
|
13
13
|
"identifier": "infinitecampus-mcp",
|
|
14
|
-
"version": "3.1.
|
|
14
|
+
"version": "3.1.7",
|
|
15
15
|
"transport": {
|
|
16
16
|
"type": "stdio"
|
|
17
17
|
},
|