gogcli-mcp-classroom 4.5.0 → 4.5.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/marketplace.json +2 -2
- package/.claude-plugin/plugin.json +1 -1
- package/README.md +2 -0
- package/dist/index.js +571 -135
- package/manifest.json +9 -9
- package/package.json +2 -2
- package/server.json +2 -2
- package/src/tools/classroom-extra.ts +247 -19
- package/tests/tools/classroom-extra-gates.test.ts +211 -0
- package/tests/tools/classroom-extra.test.ts +233 -0
package/dist/index.js
CHANGED
|
@@ -956,14 +956,14 @@ function promiseAllObject(promisesObj) {
|
|
|
956
956
|
}
|
|
957
957
|
function randomString(length = 10) {
|
|
958
958
|
const chars = "abcdefghijklmnopqrstuvwxyz";
|
|
959
|
-
let
|
|
959
|
+
let str2 = "";
|
|
960
960
|
for (let i = 0; i < length; i++) {
|
|
961
|
-
|
|
961
|
+
str2 += chars[Math.floor(Math.random() * chars.length)];
|
|
962
962
|
}
|
|
963
|
-
return
|
|
963
|
+
return str2;
|
|
964
964
|
}
|
|
965
|
-
function esc(
|
|
966
|
-
return JSON.stringify(
|
|
965
|
+
function esc(str2) {
|
|
966
|
+
return JSON.stringify(str2);
|
|
967
967
|
}
|
|
968
968
|
function slugify(input2) {
|
|
969
969
|
return input2.toLowerCase().trim().replace(/[^\w\s-]/g, "").replace(/[\s_-]+/g, "-").replace(/^-+|-+$/g, "");
|
|
@@ -1077,8 +1077,8 @@ var primitiveTypes = /* @__PURE__ */ new Set([
|
|
|
1077
1077
|
"symbol",
|
|
1078
1078
|
"undefined"
|
|
1079
1079
|
]);
|
|
1080
|
-
function escapeRegex(
|
|
1081
|
-
return
|
|
1080
|
+
function escapeRegex(str2) {
|
|
1081
|
+
return str2.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
1082
1082
|
}
|
|
1083
1083
|
function clone(inst, def, params) {
|
|
1084
1084
|
const cl = new inst._zod.constr(def ?? inst._zod.def);
|
|
@@ -1332,13 +1332,13 @@ function getSizableOrigin(input2) {
|
|
|
1332
1332
|
return "unknown";
|
|
1333
1333
|
}
|
|
1334
1334
|
var highSurrogate = /[\uD800-\uDBFF]/;
|
|
1335
|
-
function codePointLength(
|
|
1336
|
-
const units =
|
|
1337
|
-
if (!highSurrogate.test(
|
|
1335
|
+
function codePointLength(str2) {
|
|
1336
|
+
const units = str2.length;
|
|
1337
|
+
if (!highSurrogate.test(str2))
|
|
1338
1338
|
return units;
|
|
1339
1339
|
let count = units;
|
|
1340
1340
|
for (let i = 0; i < units - 1; i++) {
|
|
1341
|
-
if ((
|
|
1341
|
+
if ((str2.charCodeAt(i) & 64512) === 55296 && (str2.charCodeAt(i + 1) & 64512) === 56320) {
|
|
1342
1342
|
count--;
|
|
1343
1343
|
i++;
|
|
1344
1344
|
}
|
|
@@ -19790,7 +19790,7 @@ function date4(params) {
|
|
|
19790
19790
|
return _coercedDate(ZodDate, params);
|
|
19791
19791
|
}
|
|
19792
19792
|
|
|
19793
|
-
// ../../node_modules/@modelcontextprotocol/core/dist/auth-
|
|
19793
|
+
// ../../node_modules/@modelcontextprotocol/server/node_modules/@modelcontextprotocol/core/dist/auth-CGP0BDVq.mjs
|
|
19794
19794
|
var LATEST_PROTOCOL_VERSION = "2025-11-25";
|
|
19795
19795
|
var SUPPORTED_PROTOCOL_VERSIONS = [
|
|
19796
19796
|
LATEST_PROTOCOL_VERSION,
|
|
@@ -20627,7 +20627,8 @@ var OAuthMetadataSchema = looseObject({
|
|
|
20627
20627
|
introspection_endpoint_auth_signing_alg_values_supported: array(string2()).optional(),
|
|
20628
20628
|
code_challenge_methods_supported: array(string2()).optional(),
|
|
20629
20629
|
client_id_metadata_document_supported: boolean2().optional(),
|
|
20630
|
-
authorization_response_iss_parameter_supported: boolean2().optional().catch(void 0)
|
|
20630
|
+
authorization_response_iss_parameter_supported: boolean2().optional().catch(void 0),
|
|
20631
|
+
dpop_signing_alg_values_supported: array(string2()).optional()
|
|
20631
20632
|
});
|
|
20632
20633
|
var OpenIdProviderMetadataSchema = looseObject({
|
|
20633
20634
|
issuer: string2(),
|
|
@@ -20728,7 +20729,7 @@ var OAuthTokenRevocationRequestSchema = object({
|
|
|
20728
20729
|
token_type_hint: string2().optional()
|
|
20729
20730
|
}).strip();
|
|
20730
20731
|
|
|
20731
|
-
// ../../node_modules/@modelcontextprotocol/server/dist/src-
|
|
20732
|
+
// ../../node_modules/@modelcontextprotocol/server/dist/src-D-y6h4N7.mjs
|
|
20732
20733
|
var BRANDS = /* @__PURE__ */ Symbol.for("mcp.sdk.errorBrands");
|
|
20733
20734
|
function stampErrorBrands(instance, ctor) {
|
|
20734
20735
|
const brands = /* @__PURE__ */ new Set();
|
|
@@ -20842,8 +20843,18 @@ var SdkError = class extends Error {
|
|
|
20842
20843
|
if (typeof this !== "function") throw new TypeError("isInstance must be called on the class (e.g. `SdkError.isInstance(value)`); for callbacks use `v => SdkError.isInstance(v)`");
|
|
20843
20844
|
return brandedHasInstance(this, value);
|
|
20844
20845
|
}
|
|
20845
|
-
|
|
20846
|
-
|
|
20846
|
+
/**
|
|
20847
|
+
* @param code - Stable string code identifying the failure ({@linkcode SdkErrorCode}).
|
|
20848
|
+
* @param message - Human-readable description.
|
|
20849
|
+
* @param data - Optional structured payload (for example the HTTP status carried by
|
|
20850
|
+
* {@linkcode SdkHttpError}). Opaque to the SDK: a `cause` key inside `data` is not
|
|
20851
|
+
* promoted to `Error.cause`.
|
|
20852
|
+
* @param options - Standard `ErrorOptions`, forwarded to `Error`. Pass the underlying
|
|
20853
|
+
* failure as `{ cause }` so it is reachable through the `Error.cause` chain that
|
|
20854
|
+
* loggers and error trackers walk.
|
|
20855
|
+
*/
|
|
20856
|
+
constructor(code, message, data, options) {
|
|
20857
|
+
super(message, options);
|
|
20847
20858
|
this.code = code;
|
|
20848
20859
|
this.data = data;
|
|
20849
20860
|
this.name = "SdkError";
|
|
@@ -20854,8 +20865,11 @@ var SdkHttpError = class extends SdkError {
|
|
|
20854
20865
|
static {
|
|
20855
20866
|
Object.defineProperty(this, "mcpBrand", { value: "mcp.SdkHttpError" });
|
|
20856
20867
|
}
|
|
20857
|
-
|
|
20858
|
-
|
|
20868
|
+
/**
|
|
20869
|
+
* @param options - Standard `ErrorOptions`, forwarded to `Error` (see {@linkcode SdkError}).
|
|
20870
|
+
*/
|
|
20871
|
+
constructor(code, message, data, options) {
|
|
20872
|
+
super(code, message, data, options);
|
|
20859
20873
|
this.name = "SdkHttpError";
|
|
20860
20874
|
}
|
|
20861
20875
|
get status() {
|
|
@@ -23806,7 +23820,7 @@ var INBOUND_VALIDATION_LADDER = [
|
|
|
23806
23820
|
evaluatedAt: "pre-dispatch",
|
|
23807
23821
|
codes: [HEADER_MISMATCH_ERROR_CODE],
|
|
23808
23822
|
conformance: ["http-header-validation"],
|
|
23809
|
-
rationale: "SEP-2243 standard `Mcp-Method` / `Mcp-Name` headers \u2014 presence, sentinel decoding, and `Mcp-Name` \u2194 body cross-check \u2014 are validated by the HTTP entry on a modern-classified request after the supported-revision gate and before dispatch. The classifier\u2019s own header-mismatch cells (protocol-version, `Mcp-Method` mismatch) stay on the edge `era-classification` rung; this rung carries the entry-layer presence/`Mcp-Name` half. Evaluated before the capability gate, the factory call, and the `Mcp-Param-*` rung so a request that fails several rungs is answered by the standard-header rung first. The documented order (after method-registry 5 and request-params 6) is NOT the observed precedence: serveModern evaluates this rung immediately after the supported-revision gate, so a request that also fails a dispatch rung is answered here before the dispatch rungs (5\u20136) are consulted."
|
|
23823
|
+
rationale: "SEP-2243 standard `MCP-Protocol-Version` / `Mcp-Method` / `Mcp-Name` headers \u2014 presence, sentinel decoding, and `Mcp-Name` \u2194 body cross-check \u2014 are validated by the HTTP entry on a modern-classified request after the supported-revision gate and before dispatch. The spec requires `MCP-Protocol-Version` and `Mcp-Method` on every modern *request* POST (`Mcp-Name` only for the methods that mirror `params.name` / `params.uri` / `params.taskId`, see `MCP_NAME_HEADER_SOURCE`) and names them in that order, so a request missing several is answered by the earliest. Notification POSTs are exempt: the presence half runs on requests only, so a modern-enveloped notification is dispatched even with no standard headers at all. The classifier\u2019s own header-mismatch cells (protocol-version, `Mcp-Method` mismatch) stay on the edge `era-classification` rung; this rung carries the entry-layer presence/`Mcp-Name` half \u2014 including the missing `MCP-Protocol-Version` cell, which cannot live on the edge rung without breaking body-primary classification. Evaluated before the capability gate, the factory call, and the `Mcp-Param-*` rung so a request that fails several rungs is answered by the standard-header rung first. The documented order (after method-registry 5 and request-params 6) is NOT the observed precedence: serveModern evaluates this rung immediately after the supported-revision gate, so a request that also fails a dispatch rung is answered here before the dispatch rungs (5\u20136) are consulted."
|
|
23810
23824
|
},
|
|
23811
23825
|
{
|
|
23812
23826
|
rung: "client-capabilities",
|
|
@@ -24607,7 +24621,7 @@ var Protocol = class {
|
|
|
24607
24621
|
return this._requestHandlers.get(method);
|
|
24608
24622
|
}
|
|
24609
24623
|
async _oncancel(notification) {
|
|
24610
|
-
if (
|
|
24624
|
+
if (notification.params.requestId === void 0) return;
|
|
24611
24625
|
this._requestHandlerAbortControllers.get(notification.params.requestId)?.abort(notification.params.reason);
|
|
24612
24626
|
}
|
|
24613
24627
|
_setupTimeout(messageId, timeout, maxTotalTimeout, onTimeout, resetTimeoutOnProgress = false) {
|
|
@@ -25006,19 +25020,20 @@ var Protocol = class {
|
|
|
25006
25020
|
const cancel = (reason) => {
|
|
25007
25021
|
if (responseReceived) return;
|
|
25008
25022
|
this._progressHandlers.delete(messageId);
|
|
25009
|
-
if (requestAbort === void 0)
|
|
25010
|
-
|
|
25011
|
-
|
|
25012
|
-
|
|
25013
|
-
|
|
25014
|
-
|
|
25015
|
-
|
|
25016
|
-
|
|
25017
|
-
|
|
25018
|
-
|
|
25019
|
-
|
|
25020
|
-
|
|
25021
|
-
|
|
25023
|
+
if (requestAbort === void 0) {
|
|
25024
|
+
if (request.method !== "initialize") this._transport?.send(this._envelopeOutbound({
|
|
25025
|
+
jsonrpc: "2.0",
|
|
25026
|
+
method: "notifications/cancelled",
|
|
25027
|
+
params: {
|
|
25028
|
+
requestId: messageId,
|
|
25029
|
+
reason: String(reason)
|
|
25030
|
+
}
|
|
25031
|
+
}), {
|
|
25032
|
+
relatedRequestId,
|
|
25033
|
+
resumptionToken,
|
|
25034
|
+
onresumptiontoken
|
|
25035
|
+
}).catch((error62) => this._onerror(/* @__PURE__ */ new Error(`Failed to send cancellation: ${error62}`)));
|
|
25036
|
+
} else requestAbort.abort();
|
|
25022
25037
|
reject(reason instanceof SdkError ? reason : new SdkError(SdkErrorCode.RequestTimeout, String(reason)));
|
|
25023
25038
|
};
|
|
25024
25039
|
this._responseHandlers.set(messageId, (response) => {
|
|
@@ -25098,7 +25113,7 @@ var Protocol = class {
|
|
|
25098
25113
|
jsonrpc: "2.0",
|
|
25099
25114
|
...notification
|
|
25100
25115
|
});
|
|
25101
|
-
if ((this._options?.debouncedNotificationMethods ?? []).includes(notification.method) && !notification.params &&
|
|
25116
|
+
if ((this._options?.debouncedNotificationMethods ?? []).includes(notification.method) && !notification.params && options?.relatedRequestId === void 0) {
|
|
25102
25117
|
if (this._pendingDebouncedNotifications.has(notification.method)) return;
|
|
25103
25118
|
this._pendingDebouncedNotifications.add(notification.method);
|
|
25104
25119
|
Promise.resolve().then(() => {
|
|
@@ -25451,7 +25466,7 @@ var require_code$1 = /* @__PURE__ */ __commonJSMin(((exports) => {
|
|
|
25451
25466
|
}
|
|
25452
25467
|
exports._ = _;
|
|
25453
25468
|
const plus = new _Code("+");
|
|
25454
|
-
function
|
|
25469
|
+
function str2(strs, ...args) {
|
|
25455
25470
|
const expr = [safeStringify(strs[0])];
|
|
25456
25471
|
let i = 0;
|
|
25457
25472
|
while (i < args.length) {
|
|
@@ -25462,7 +25477,7 @@ var require_code$1 = /* @__PURE__ */ __commonJSMin(((exports) => {
|
|
|
25462
25477
|
optimize(expr);
|
|
25463
25478
|
return new _Code(expr);
|
|
25464
25479
|
}
|
|
25465
|
-
exports.str =
|
|
25480
|
+
exports.str = str2;
|
|
25466
25481
|
function addCodeArg(code, arg) {
|
|
25467
25482
|
if (arg instanceof _Code) code.push(...arg._items);
|
|
25468
25483
|
else if (arg instanceof Name) code.push(arg);
|
|
@@ -25495,7 +25510,7 @@ var require_code$1 = /* @__PURE__ */ __commonJSMin(((exports) => {
|
|
|
25495
25510
|
if (typeof b == "string" && b[0] === '"' && !(a instanceof Name)) return `"${a}${b.slice(1)}`;
|
|
25496
25511
|
}
|
|
25497
25512
|
function strConcat(c1, c2) {
|
|
25498
|
-
return c2.emptyStr() ? c1 : c1.emptyStr() ? c2 :
|
|
25513
|
+
return c2.emptyStr() ? c1 : c1.emptyStr() ? c2 : str2`${c1}${c2}`;
|
|
25499
25514
|
}
|
|
25500
25515
|
exports.strConcat = strConcat;
|
|
25501
25516
|
function interpolate(x) {
|
|
@@ -26374,21 +26389,21 @@ var require_util = /* @__PURE__ */ __commonJSMin(((exports) => {
|
|
|
26374
26389
|
return (0, codegen_1._)`${topSchemaRef}${schemaPath}${(0, codegen_1.getProperty)(keyword)}`;
|
|
26375
26390
|
}
|
|
26376
26391
|
exports.schemaRefOrVal = schemaRefOrVal;
|
|
26377
|
-
function unescapeFragment(
|
|
26378
|
-
return unescapeJsonPointer(decodeURIComponent(
|
|
26392
|
+
function unescapeFragment(str2) {
|
|
26393
|
+
return unescapeJsonPointer(decodeURIComponent(str2));
|
|
26379
26394
|
}
|
|
26380
26395
|
exports.unescapeFragment = unescapeFragment;
|
|
26381
|
-
function escapeFragment(
|
|
26382
|
-
return encodeURIComponent(escapeJsonPointer(
|
|
26396
|
+
function escapeFragment(str2) {
|
|
26397
|
+
return encodeURIComponent(escapeJsonPointer(str2));
|
|
26383
26398
|
}
|
|
26384
26399
|
exports.escapeFragment = escapeFragment;
|
|
26385
|
-
function escapeJsonPointer(
|
|
26386
|
-
if (typeof
|
|
26387
|
-
return
|
|
26400
|
+
function escapeJsonPointer(str2) {
|
|
26401
|
+
if (typeof str2 == "number") return `${str2}`;
|
|
26402
|
+
return str2.replace(/~/g, "~0").replace(/\//g, "~1");
|
|
26388
26403
|
}
|
|
26389
26404
|
exports.escapeJsonPointer = escapeJsonPointer;
|
|
26390
|
-
function unescapeJsonPointer(
|
|
26391
|
-
return
|
|
26405
|
+
function unescapeJsonPointer(str2) {
|
|
26406
|
+
return str2.replace(/~1/g, "/").replace(/~0/g, "~");
|
|
26392
26407
|
}
|
|
26393
26408
|
exports.unescapeJsonPointer = unescapeJsonPointer;
|
|
26394
26409
|
function eachItem(xs, f) {
|
|
@@ -27274,8 +27289,8 @@ var require_json_schema_traverse = /* @__PURE__ */ __commonJSMin(((exports, modu
|
|
|
27274
27289
|
post(schema, jsonPtr, rootSchema, parentJsonPtr, parentKeyword, parentSchema, keyIndex);
|
|
27275
27290
|
}
|
|
27276
27291
|
}
|
|
27277
|
-
function escapeJsonPtr(
|
|
27278
|
-
return
|
|
27292
|
+
function escapeJsonPtr(str2) {
|
|
27293
|
+
return str2.replace(/~/g, "~0").replace(/\//g, "~1");
|
|
27279
27294
|
}
|
|
27280
27295
|
}));
|
|
27281
27296
|
var require_resolve = /* @__PURE__ */ __commonJSMin(((exports) => {
|
|
@@ -28167,9 +28182,9 @@ var require_utils = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
|
28167
28182
|
isIPV6: false
|
|
28168
28183
|
};
|
|
28169
28184
|
}
|
|
28170
|
-
function findToken(
|
|
28185
|
+
function findToken(str2, token) {
|
|
28171
28186
|
let ind = 0;
|
|
28172
|
-
for (let i = 0; i <
|
|
28187
|
+
for (let i = 0; i < str2.length; i++) if (str2[i] === token) ind++;
|
|
28173
28188
|
return ind;
|
|
28174
28189
|
}
|
|
28175
28190
|
function removeDotSegments(path) {
|
|
@@ -28684,7 +28699,7 @@ var require_core$3 = /* @__PURE__ */ __commonJSMin(((exports) => {
|
|
|
28684
28699
|
const util_1 = require_util();
|
|
28685
28700
|
const $dataRefSchema = require_data();
|
|
28686
28701
|
const uri_1 = require_uri();
|
|
28687
|
-
const defaultRegExp = (
|
|
28702
|
+
const defaultRegExp = (str2, flags) => new RegExp(str2, flags);
|
|
28688
28703
|
defaultRegExp.code = "new RegExp";
|
|
28689
28704
|
const META_IGNORE_OPTIONS = [
|
|
28690
28705
|
"removeAdditional",
|
|
@@ -29390,16 +29405,16 @@ var require_multipleOf = /* @__PURE__ */ __commonJSMin(((exports) => {
|
|
|
29390
29405
|
}));
|
|
29391
29406
|
var require_ucs2length = /* @__PURE__ */ __commonJSMin(((exports) => {
|
|
29392
29407
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
29393
|
-
function ucs2length(
|
|
29394
|
-
const len =
|
|
29408
|
+
function ucs2length(str2) {
|
|
29409
|
+
const len = str2.length;
|
|
29395
29410
|
let length = 0;
|
|
29396
29411
|
let pos2 = 0;
|
|
29397
29412
|
let value;
|
|
29398
29413
|
while (pos2 < len) {
|
|
29399
29414
|
length++;
|
|
29400
|
-
value =
|
|
29415
|
+
value = str2.charCodeAt(pos2++);
|
|
29401
29416
|
if (value >= 55296 && value <= 56319 && pos2 < len) {
|
|
29402
|
-
value =
|
|
29417
|
+
value = str2.charCodeAt(pos2);
|
|
29403
29418
|
if ((value & 64512) === 56320) pos2++;
|
|
29404
29419
|
}
|
|
29405
29420
|
}
|
|
@@ -32110,8 +32125,8 @@ var require_formats = /* @__PURE__ */ __commonJSMin(((exports) => {
|
|
|
32110
32125
|
30,
|
|
32111
32126
|
31
|
|
32112
32127
|
];
|
|
32113
|
-
function date5(
|
|
32114
|
-
const matches = DATE.exec(
|
|
32128
|
+
function date5(str2) {
|
|
32129
|
+
const matches = DATE.exec(str2);
|
|
32115
32130
|
if (!matches) return false;
|
|
32116
32131
|
const year = +matches[1];
|
|
32117
32132
|
const month = +matches[2];
|
|
@@ -32126,8 +32141,8 @@ var require_formats = /* @__PURE__ */ __commonJSMin(((exports) => {
|
|
|
32126
32141
|
}
|
|
32127
32142
|
const TIME = /^(\d\d):(\d\d):(\d\d(?:\.\d+)?)(z|([+-])(\d\d)(?::?(\d\d))?)?$/i;
|
|
32128
32143
|
function getTime(strictTimeZone) {
|
|
32129
|
-
return function time3(
|
|
32130
|
-
const matches = TIME.exec(
|
|
32144
|
+
return function time3(str2) {
|
|
32145
|
+
const matches = TIME.exec(str2);
|
|
32131
32146
|
if (!matches) return false;
|
|
32132
32147
|
const hr = +matches[1];
|
|
32133
32148
|
const min = +matches[2];
|
|
@@ -32164,8 +32179,8 @@ var require_formats = /* @__PURE__ */ __commonJSMin(((exports) => {
|
|
|
32164
32179
|
const DATE_TIME_SEPARATOR = /t|\s/i;
|
|
32165
32180
|
function getDateTime(strictTimeZone) {
|
|
32166
32181
|
const time3 = getTime(strictTimeZone);
|
|
32167
|
-
return function date_time(
|
|
32168
|
-
const dateTime =
|
|
32182
|
+
return function date_time(str2) {
|
|
32183
|
+
const dateTime = str2.split(DATE_TIME_SEPARATOR);
|
|
32169
32184
|
return dateTime.length === 2 && date5(dateTime[0]) && time3(dateTime[1]);
|
|
32170
32185
|
};
|
|
32171
32186
|
}
|
|
@@ -32186,13 +32201,13 @@ var require_formats = /* @__PURE__ */ __commonJSMin(((exports) => {
|
|
|
32186
32201
|
}
|
|
32187
32202
|
const NOT_URI_FRAGMENT = /\/|:/;
|
|
32188
32203
|
const URI = /^(?:[a-z][a-z0-9+\-.]*:)(?:\/?\/(?:(?:[a-z0-9\-._~!$&'()*+,;=:]|%[0-9a-f]{2})*@)?(?:\[(?:(?:(?:(?:[0-9a-f]{1,4}:){6}|::(?:[0-9a-f]{1,4}:){5}|(?:[0-9a-f]{1,4})?::(?:[0-9a-f]{1,4}:){4}|(?:(?:[0-9a-f]{1,4}:){0,1}[0-9a-f]{1,4})?::(?:[0-9a-f]{1,4}:){3}|(?:(?:[0-9a-f]{1,4}:){0,2}[0-9a-f]{1,4})?::(?:[0-9a-f]{1,4}:){2}|(?:(?:[0-9a-f]{1,4}:){0,3}[0-9a-f]{1,4})?::[0-9a-f]{1,4}:|(?:(?:[0-9a-f]{1,4}:){0,4}[0-9a-f]{1,4})?::)(?:[0-9a-f]{1,4}:[0-9a-f]{1,4}|(?:(?:25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(?:25[0-5]|2[0-4]\d|[01]?\d\d?))|(?:(?:[0-9a-f]{1,4}:){0,5}[0-9a-f]{1,4})?::[0-9a-f]{1,4}|(?:(?:[0-9a-f]{1,4}:){0,6}[0-9a-f]{1,4})?::)|[Vv][0-9a-f]+\.[a-z0-9\-._~!$&'()*+,;=:]+)\]|(?:(?:25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(?:25[0-5]|2[0-4]\d|[01]?\d\d?)|(?:[a-z0-9\-._~!$&'()*+,;=]|%[0-9a-f]{2})*)(?::\d*)?(?:\/(?:[a-z0-9\-._~!$&'()*+,;=:@]|%[0-9a-f]{2})*)*|\/(?:(?:[a-z0-9\-._~!$&'()*+,;=:@]|%[0-9a-f]{2})+(?:\/(?:[a-z0-9\-._~!$&'()*+,;=:@]|%[0-9a-f]{2})*)*)?|(?:[a-z0-9\-._~!$&'()*+,;=:@]|%[0-9a-f]{2})+(?:\/(?:[a-z0-9\-._~!$&'()*+,;=:@]|%[0-9a-f]{2})*)*)(?:\?(?:[a-z0-9\-._~!$&'()*+,;=:@/?]|%[0-9a-f]{2})*)?(?:#(?:[a-z0-9\-._~!$&'()*+,;=:@/?]|%[0-9a-f]{2})*)?$/i;
|
|
32189
|
-
function uri(
|
|
32190
|
-
return NOT_URI_FRAGMENT.test(
|
|
32204
|
+
function uri(str2) {
|
|
32205
|
+
return NOT_URI_FRAGMENT.test(str2) && URI.test(str2);
|
|
32191
32206
|
}
|
|
32192
32207
|
const BYTE = /^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/gm;
|
|
32193
|
-
function byte(
|
|
32208
|
+
function byte(str2) {
|
|
32194
32209
|
BYTE.lastIndex = 0;
|
|
32195
|
-
return BYTE.test(
|
|
32210
|
+
return BYTE.test(str2);
|
|
32196
32211
|
}
|
|
32197
32212
|
const MIN_INT32 = -(2 ** 31);
|
|
32198
32213
|
const MAX_INT32 = 2 ** 31 - 1;
|
|
@@ -32206,10 +32221,10 @@ var require_formats = /* @__PURE__ */ __commonJSMin(((exports) => {
|
|
|
32206
32221
|
return true;
|
|
32207
32222
|
}
|
|
32208
32223
|
const Z_ANCHOR = /[^\\]\\Z/;
|
|
32209
|
-
function regex(
|
|
32210
|
-
if (Z_ANCHOR.test(
|
|
32224
|
+
function regex(str2) {
|
|
32225
|
+
if (Z_ANCHOR.test(str2)) return false;
|
|
32211
32226
|
try {
|
|
32212
|
-
new RegExp(
|
|
32227
|
+
new RegExp(str2);
|
|
32213
32228
|
return true;
|
|
32214
32229
|
} catch (e) {
|
|
32215
32230
|
return false;
|
|
@@ -32401,7 +32416,7 @@ var Ajv = import_ajv.Ajv;
|
|
|
32401
32416
|
// ../../node_modules/@modelcontextprotocol/server/dist/shimsNode.mjs
|
|
32402
32417
|
import process2 from "node:process";
|
|
32403
32418
|
|
|
32404
|
-
// ../../node_modules/@modelcontextprotocol/server/dist/mcp-
|
|
32419
|
+
// ../../node_modules/@modelcontextprotocol/server/dist/mcp-Dw2OlZ1f.mjs
|
|
32405
32420
|
var COMPLETABLE_SYMBOL = /* @__PURE__ */ Symbol.for("mcp.completable");
|
|
32406
32421
|
function isCompletable(schema) {
|
|
32407
32422
|
return !!schema && typeof schema === "object" && COMPLETABLE_SYMBOL in schema;
|
|
@@ -32594,6 +32609,9 @@ function notificationToServerEvent(method, uri) {
|
|
|
32594
32609
|
};
|
|
32595
32610
|
}
|
|
32596
32611
|
}
|
|
32612
|
+
function supportsScopeChallengeResolver(transport) {
|
|
32613
|
+
return typeof transport === "object" && transport !== null && "setScopeChallengeResolver" in transport && typeof transport.setScopeChallengeResolver === "function";
|
|
32614
|
+
}
|
|
32597
32615
|
var DEFAULT_LEGACY_SHIM_MAX_ROUNDS = 8;
|
|
32598
32616
|
var DEFAULT_LEGACY_SHIM_ROUND_TIMEOUT_MS = 6e5;
|
|
32599
32617
|
function resolveLegacyShimOptions(options) {
|
|
@@ -33404,6 +33422,7 @@ var McpServer = class {
|
|
|
33404
33422
|
* ```
|
|
33405
33423
|
*/
|
|
33406
33424
|
async connect(transport) {
|
|
33425
|
+
if (supportsScopeChallengeResolver(transport)) transport.setScopeChallengeResolver((context) => this.resolveScopeChallenge(context));
|
|
33407
33426
|
return await this.server.connect(transport);
|
|
33408
33427
|
}
|
|
33409
33428
|
/**
|
|
@@ -33412,6 +33431,41 @@ var McpServer = class {
|
|
|
33412
33431
|
async close() {
|
|
33413
33432
|
await this.server.close();
|
|
33414
33433
|
}
|
|
33434
|
+
/** @internal */
|
|
33435
|
+
resolveScopeChallenge = (context) => {
|
|
33436
|
+
switch (context.request.method) {
|
|
33437
|
+
case "tools/call": {
|
|
33438
|
+
const toolName = context.request.params?.name;
|
|
33439
|
+
if (typeof toolName !== "string") return;
|
|
33440
|
+
const tool = this._registeredTools[toolName];
|
|
33441
|
+
if (tool === void 0 || !tool.enabled) return;
|
|
33442
|
+
return tool.scopeChallenge?.(context);
|
|
33443
|
+
}
|
|
33444
|
+
case "resources/read": {
|
|
33445
|
+
const resourceUri = context.request.params?.uri;
|
|
33446
|
+
if (typeof resourceUri !== "string") return;
|
|
33447
|
+
let uri;
|
|
33448
|
+
try {
|
|
33449
|
+
uri = new URL(resourceUri);
|
|
33450
|
+
} catch {
|
|
33451
|
+
return;
|
|
33452
|
+
}
|
|
33453
|
+
const resource = this._registeredResources[uri.toString()];
|
|
33454
|
+
if (resource !== void 0) return resource.enabled ? resource.scopeChallenge?.(context) : void 0;
|
|
33455
|
+
for (const template of Object.values(this._registeredResourceTemplates)) if (template.resourceTemplate.uriTemplate.match(uri.toString())) return template.enabled ? template.scopeChallenge?.(context) : void 0;
|
|
33456
|
+
return;
|
|
33457
|
+
}
|
|
33458
|
+
case "prompts/get": {
|
|
33459
|
+
const promptName = context.request.params?.name;
|
|
33460
|
+
if (typeof promptName !== "string") return;
|
|
33461
|
+
const prompt = this._registeredPrompts[promptName];
|
|
33462
|
+
if (prompt === void 0 || !prompt.enabled) return;
|
|
33463
|
+
return prompt.scopeChallenge?.(context);
|
|
33464
|
+
}
|
|
33465
|
+
default:
|
|
33466
|
+
return;
|
|
33467
|
+
}
|
|
33468
|
+
};
|
|
33415
33469
|
_toolHandlersInitialized = false;
|
|
33416
33470
|
setToolRequestHandlers() {
|
|
33417
33471
|
if (this._toolHandlersInitialized) return;
|
|
@@ -33578,7 +33632,10 @@ var McpServer = class {
|
|
|
33578
33632
|
}
|
|
33579
33633
|
for (const template of Object.values(this._registeredResourceTemplates)) {
|
|
33580
33634
|
const variables = template.resourceTemplate.uriTemplate.match(uri.toString());
|
|
33581
|
-
if (variables)
|
|
33635
|
+
if (variables) {
|
|
33636
|
+
if (!template.enabled) throw new ProtocolError(ProtocolErrorCode.InvalidParams, `Resource template ${template.resourceTemplate.uriTemplate} disabled`);
|
|
33637
|
+
return attachCacheHintFallback(await template.readCallback(uri, variables, ctx), template.cacheHint);
|
|
33638
|
+
}
|
|
33582
33639
|
}
|
|
33583
33640
|
throw new ResourceNotFoundError(request.params.uri);
|
|
33584
33641
|
});
|
|
@@ -33609,36 +33666,32 @@ var McpServer = class {
|
|
|
33609
33666
|
this._promptHandlersInitialized = true;
|
|
33610
33667
|
}
|
|
33611
33668
|
registerResource(name, uriOrTemplate, config2, readCallback) {
|
|
33612
|
-
const cacheHint = config2
|
|
33613
|
-
|
|
33614
|
-
if (cacheHint !== void 0) {
|
|
33615
|
-
assertValidCacheHint(cacheHint, `resource ${name}`);
|
|
33616
|
-
const rest = { ...config2 };
|
|
33617
|
-
delete rest.cacheHint;
|
|
33618
|
-
metadata = rest;
|
|
33619
|
-
}
|
|
33669
|
+
const { cacheHint, scopeChallenge, ...resourceMetadata } = config2;
|
|
33670
|
+
const metadata = resourceMetadata;
|
|
33671
|
+
if (cacheHint !== void 0) assertValidCacheHint(cacheHint, `resource ${name}`);
|
|
33620
33672
|
if (typeof uriOrTemplate === "string") {
|
|
33621
33673
|
if (this._registeredResources[uriOrTemplate]) throw new Error(`Resource ${uriOrTemplate} is already registered`);
|
|
33622
|
-
const registeredResource = this._createRegisteredResource(name, config2.title, uriOrTemplate, metadata, readCallback);
|
|
33674
|
+
const registeredResource = this._createRegisteredResource(name, config2.title, uriOrTemplate, metadata, scopeChallenge, readCallback);
|
|
33623
33675
|
if (cacheHint !== void 0) registeredResource.cacheHint = cacheHint;
|
|
33624
33676
|
this.setResourceRequestHandlers();
|
|
33625
33677
|
this.sendResourceListChanged();
|
|
33626
33678
|
return registeredResource;
|
|
33627
33679
|
} else {
|
|
33628
33680
|
if (this._registeredResourceTemplates[name]) throw new Error(`Resource template ${name} is already registered`);
|
|
33629
|
-
const registeredResourceTemplate = this._createRegisteredResourceTemplate(name, config2.title, uriOrTemplate, metadata, readCallback);
|
|
33681
|
+
const registeredResourceTemplate = this._createRegisteredResourceTemplate(name, config2.title, uriOrTemplate, metadata, scopeChallenge, readCallback);
|
|
33630
33682
|
if (cacheHint !== void 0) registeredResourceTemplate.cacheHint = cacheHint;
|
|
33631
33683
|
this.setResourceRequestHandlers();
|
|
33632
33684
|
this.sendResourceListChanged();
|
|
33633
33685
|
return registeredResourceTemplate;
|
|
33634
33686
|
}
|
|
33635
33687
|
}
|
|
33636
|
-
_createRegisteredResource(name, title, uri, metadata, readCallback) {
|
|
33688
|
+
_createRegisteredResource(name, title, uri, metadata, scopeChallenge, readCallback) {
|
|
33637
33689
|
const registeredResource = {
|
|
33638
33690
|
name,
|
|
33639
33691
|
title,
|
|
33640
33692
|
metadata,
|
|
33641
33693
|
readCallback,
|
|
33694
|
+
scopeChallenge,
|
|
33642
33695
|
enabled: true,
|
|
33643
33696
|
disable: () => registeredResource.update({ enabled: false }),
|
|
33644
33697
|
enable: () => registeredResource.update({ enabled: true }),
|
|
@@ -33652,6 +33705,7 @@ var McpServer = class {
|
|
|
33652
33705
|
if (updates.title !== void 0) registeredResource.title = updates.title;
|
|
33653
33706
|
if (updates.metadata !== void 0) registeredResource.metadata = updates.metadata;
|
|
33654
33707
|
if (updates.callback !== void 0) registeredResource.readCallback = updates.callback;
|
|
33708
|
+
if (updates.scopeChallenge !== void 0) registeredResource.scopeChallenge = updates.scopeChallenge === null ? void 0 : updates.scopeChallenge;
|
|
33655
33709
|
if (updates.enabled !== void 0) registeredResource.enabled = updates.enabled;
|
|
33656
33710
|
this.sendResourceListChanged();
|
|
33657
33711
|
}
|
|
@@ -33659,12 +33713,13 @@ var McpServer = class {
|
|
|
33659
33713
|
this._registeredResources[uri] = registeredResource;
|
|
33660
33714
|
return registeredResource;
|
|
33661
33715
|
}
|
|
33662
|
-
_createRegisteredResourceTemplate(name, title, template, metadata, readCallback) {
|
|
33716
|
+
_createRegisteredResourceTemplate(name, title, template, metadata, scopeChallenge, readCallback) {
|
|
33663
33717
|
const registeredResourceTemplate = {
|
|
33664
33718
|
resourceTemplate: template,
|
|
33665
33719
|
title,
|
|
33666
33720
|
metadata,
|
|
33667
33721
|
readCallback,
|
|
33722
|
+
scopeChallenge,
|
|
33668
33723
|
enabled: true,
|
|
33669
33724
|
disable: () => registeredResourceTemplate.update({ enabled: false }),
|
|
33670
33725
|
enable: () => registeredResourceTemplate.update({ enabled: true }),
|
|
@@ -33678,6 +33733,7 @@ var McpServer = class {
|
|
|
33678
33733
|
if (updates.template !== void 0) registeredResourceTemplate.resourceTemplate = updates.template;
|
|
33679
33734
|
if (updates.metadata !== void 0) registeredResourceTemplate.metadata = updates.metadata;
|
|
33680
33735
|
if (updates.callback !== void 0) registeredResourceTemplate.readCallback = updates.callback;
|
|
33736
|
+
if (updates.scopeChallenge !== void 0) registeredResourceTemplate.scopeChallenge = updates.scopeChallenge === null ? void 0 : updates.scopeChallenge;
|
|
33681
33737
|
if (updates.enabled !== void 0) registeredResourceTemplate.enabled = updates.enabled;
|
|
33682
33738
|
this.sendResourceListChanged();
|
|
33683
33739
|
}
|
|
@@ -33687,7 +33743,7 @@ var McpServer = class {
|
|
|
33687
33743
|
if (Array.isArray(variableNames) && variableNames.some((v) => !!template.completeCallback(v))) this.setCompletionRequestHandler();
|
|
33688
33744
|
return registeredResourceTemplate;
|
|
33689
33745
|
}
|
|
33690
|
-
_createRegisteredPrompt(name, title, description, argsSchema, callback, icons, _meta) {
|
|
33746
|
+
_createRegisteredPrompt(name, title, description, argsSchema, callback, icons, scopeChallenge, _meta) {
|
|
33691
33747
|
let currentArgsSchema = argsSchema;
|
|
33692
33748
|
let currentCallback = callback;
|
|
33693
33749
|
const registeredPrompt = {
|
|
@@ -33695,6 +33751,7 @@ var McpServer = class {
|
|
|
33695
33751
|
description,
|
|
33696
33752
|
argsSchema,
|
|
33697
33753
|
icons,
|
|
33754
|
+
scopeChallenge,
|
|
33698
33755
|
_meta,
|
|
33699
33756
|
handler: createPromptHandler(name, argsSchema, callback),
|
|
33700
33757
|
enabled: true,
|
|
@@ -33709,6 +33766,7 @@ var McpServer = class {
|
|
|
33709
33766
|
if (updates.title !== void 0) registeredPrompt.title = updates.title;
|
|
33710
33767
|
if (updates.description !== void 0) registeredPrompt.description = updates.description;
|
|
33711
33768
|
if (updates.icons !== void 0) registeredPrompt.icons = updates.icons;
|
|
33769
|
+
if (updates.scopeChallenge !== void 0) registeredPrompt.scopeChallenge = updates.scopeChallenge === null ? void 0 : updates.scopeChallenge;
|
|
33712
33770
|
if (updates._meta !== void 0) registeredPrompt._meta = updates._meta;
|
|
33713
33771
|
let needsHandlerRegen = false;
|
|
33714
33772
|
if (updates.argsSchema !== void 0) {
|
|
@@ -33736,7 +33794,7 @@ var McpServer = class {
|
|
|
33736
33794
|
}
|
|
33737
33795
|
return registeredPrompt;
|
|
33738
33796
|
}
|
|
33739
|
-
_createRegisteredTool(name, title, description, inputSchema, outputSchema, annotations, icons, execution, _meta, handler) {
|
|
33797
|
+
_createRegisteredTool(name, title, description, inputSchema, outputSchema, annotations, icons, execution, scopeChallenge, _meta, handler) {
|
|
33740
33798
|
validateAndWarnToolName(name);
|
|
33741
33799
|
if (inputSchema !== void 0) try {
|
|
33742
33800
|
const json2 = standardSchemaToJsonSchema(inputSchema, "input");
|
|
@@ -33755,6 +33813,7 @@ var McpServer = class {
|
|
|
33755
33813
|
annotations,
|
|
33756
33814
|
icons,
|
|
33757
33815
|
execution,
|
|
33816
|
+
scopeChallenge,
|
|
33758
33817
|
_meta,
|
|
33759
33818
|
handler,
|
|
33760
33819
|
executor: createToolExecutor(inputSchema, handler),
|
|
@@ -33793,6 +33852,7 @@ var McpServer = class {
|
|
|
33793
33852
|
}
|
|
33794
33853
|
if (updates.annotations !== void 0) registeredTool.annotations = updates.annotations;
|
|
33795
33854
|
if (updates.icons !== void 0) registeredTool.icons = updates.icons;
|
|
33855
|
+
if (updates.scopeChallenge !== void 0) registeredTool.scopeChallenge = updates.scopeChallenge === null ? void 0 : updates.scopeChallenge;
|
|
33796
33856
|
if (updates._meta !== void 0) registeredTool._meta = updates._meta;
|
|
33797
33857
|
if (updates.enabled !== void 0) registeredTool.enabled = updates.enabled;
|
|
33798
33858
|
this.sendToolListChanged();
|
|
@@ -33805,13 +33865,13 @@ var McpServer = class {
|
|
|
33805
33865
|
}
|
|
33806
33866
|
registerTool(name, config2, cb) {
|
|
33807
33867
|
if (this._registeredTools[name]) throw new Error(`Tool ${name} is already registered`);
|
|
33808
|
-
const { title, description, inputSchema, outputSchema, annotations, icons, _meta } = config2;
|
|
33809
|
-
return this._createRegisteredTool(name, title, description, normalizeRawShapeSchema(inputSchema), normalizeRawShapeSchema(outputSchema), annotations, icons, void 0, _meta, cb);
|
|
33868
|
+
const { title, description, inputSchema, outputSchema, annotations, icons, scopeChallenge, _meta } = config2;
|
|
33869
|
+
return this._createRegisteredTool(name, title, description, normalizeRawShapeSchema(inputSchema), normalizeRawShapeSchema(outputSchema), annotations, icons, void 0, scopeChallenge, _meta, cb);
|
|
33810
33870
|
}
|
|
33811
33871
|
registerPrompt(name, config2, cb) {
|
|
33812
33872
|
if (this._registeredPrompts[name]) throw new Error(`Prompt ${name} is already registered`);
|
|
33813
|
-
const { title, description, argsSchema, icons, _meta } = config2;
|
|
33814
|
-
const registeredPrompt = this._createRegisteredPrompt(name, title, description, normalizeRawShapeSchema(argsSchema), cb, icons, _meta);
|
|
33873
|
+
const { title, description, argsSchema, icons, scopeChallenge, _meta } = config2;
|
|
33874
|
+
const registeredPrompt = this._createRegisteredPrompt(name, title, description, normalizeRawShapeSchema(argsSchema), cb, icons, scopeChallenge, _meta);
|
|
33815
33875
|
this.setPromptRequestHandlers();
|
|
33816
33876
|
this.sendPromptListChanged();
|
|
33817
33877
|
return registeredPrompt;
|
|
@@ -33923,6 +33983,7 @@ function unwrapOptionalSchema(schema) {
|
|
|
33923
33983
|
}
|
|
33924
33984
|
|
|
33925
33985
|
// ../../node_modules/@modelcontextprotocol/server/dist/stdio.mjs
|
|
33986
|
+
var swallowsErrorsAfterClose = /* @__PURE__ */ Symbol("swallowsErrorsAfterClose");
|
|
33926
33987
|
var StdioServerTransport = class {
|
|
33927
33988
|
_readBuffer;
|
|
33928
33989
|
_started = false;
|
|
@@ -33949,18 +34010,27 @@ var StdioServerTransport = class {
|
|
|
33949
34010
|
this.onerror?.(error62);
|
|
33950
34011
|
};
|
|
33951
34012
|
_onstdouterror = (error62) => {
|
|
34013
|
+
if (this._closed) return;
|
|
33952
34014
|
this.onerror?.(error62);
|
|
33953
34015
|
this.close().catch(() => {
|
|
33954
34016
|
});
|
|
33955
34017
|
};
|
|
34018
|
+
_onstdinclose = () => {
|
|
34019
|
+
this.close().catch(() => {
|
|
34020
|
+
});
|
|
34021
|
+
};
|
|
33956
34022
|
/**
|
|
33957
34023
|
* Starts listening for messages on `stdin`.
|
|
33958
34024
|
*/
|
|
33959
34025
|
async start() {
|
|
33960
34026
|
if (this._started) throw new Error("StdioServerTransport already started! If using Server class, note that connect() calls start() automatically.");
|
|
33961
34027
|
this._started = true;
|
|
34028
|
+
for (const listener of this._stdout.listeners("error")) if (listener[swallowsErrorsAfterClose]) this._stdout.off("error", listener);
|
|
34029
|
+
if (this._stdin.readableEnded || this._stdin.destroyed) setImmediate(this._onstdinclose);
|
|
33962
34030
|
this._stdin.on("data", this._ondata);
|
|
33963
34031
|
this._stdin.on("error", this._onerror);
|
|
34032
|
+
this._stdin.on("end", this._onstdinclose);
|
|
34033
|
+
this._stdin.on("close", this._onstdinclose);
|
|
33964
34034
|
this._stdout.on("error", this._onstdouterror);
|
|
33965
34035
|
}
|
|
33966
34036
|
processReadBuffer() {
|
|
@@ -33977,7 +34047,9 @@ var StdioServerTransport = class {
|
|
|
33977
34047
|
this._closed = true;
|
|
33978
34048
|
this._stdin.off("data", this._ondata);
|
|
33979
34049
|
this._stdin.off("error", this._onerror);
|
|
33980
|
-
this.
|
|
34050
|
+
this._stdin.off("end", this._onstdinclose);
|
|
34051
|
+
this._stdin.off("close", this._onstdinclose);
|
|
34052
|
+
this._onstdouterror[swallowsErrorsAfterClose] = true;
|
|
33981
34053
|
if (this._stdin.listenerCount("data") === 0) this._stdin.pause();
|
|
33982
34054
|
this._readBuffer.clear();
|
|
33983
34055
|
this.onclose?.();
|
|
@@ -34254,6 +34326,7 @@ function serveStdio(factory, options = {}) {
|
|
|
34254
34326
|
return;
|
|
34255
34327
|
}
|
|
34256
34328
|
if (state.era === "modern" && await tryServeListen(message)) return;
|
|
34329
|
+
if (isTornDown()) return;
|
|
34257
34330
|
state.instance.channel.deliver(message);
|
|
34258
34331
|
return;
|
|
34259
34332
|
}
|
|
@@ -34320,6 +34393,7 @@ function serveStdio(factory, options = {}) {
|
|
|
34320
34393
|
};
|
|
34321
34394
|
}
|
|
34322
34395
|
if (await tryServeListen(message)) return;
|
|
34396
|
+
if (isTornDown()) return;
|
|
34323
34397
|
state.instance.channel.deliver(message, { classification: opening.classification });
|
|
34324
34398
|
return;
|
|
34325
34399
|
case "legacy": {
|
|
@@ -34406,6 +34480,9 @@ function toError(value) {
|
|
|
34406
34480
|
return value instanceof Error ? value : new Error(String(value));
|
|
34407
34481
|
}
|
|
34408
34482
|
|
|
34483
|
+
// ../../node_modules/@modelcontextprotocol/server/dist/index.mjs
|
|
34484
|
+
var DEFAULT_MAX_REQUEST_BODY_SIZE = 4 * 1024 * 1024;
|
|
34485
|
+
|
|
34409
34486
|
// ../../node_modules/@chrischall/mcp-utils/dist/errors/index.js
|
|
34410
34487
|
var McpToolError = class extends Error {
|
|
34411
34488
|
/** Actionable remediation text, when one applies. */
|
|
@@ -35896,6 +35973,7 @@ async function diagnose(err) {
|
|
|
35896
35973
|
const isAuthError = !isTransientError && AUTH_ERROR_PATTERN.test(errText);
|
|
35897
35974
|
const isGridLimitError = GRID_LIMIT_ERROR_PATTERN.test(errText);
|
|
35898
35975
|
const hint = isInvalidGrant ? INVALID_GRANT_HINT : isAuthError ? AUTH_HINT : isTransientError ? TRANSIENT_HINT : isGridLimitError ? GRID_LIMIT_HINT : "";
|
|
35976
|
+
if (!isAuthError && !isInvalidGrant) return errorResult(`${errText}${hint}`);
|
|
35899
35977
|
try {
|
|
35900
35978
|
const accounts = formatAccountList(await run(["auth", "list"]));
|
|
35901
35979
|
return errorResult(`${errText}
|
|
@@ -35999,12 +36077,24 @@ function bodyPreview(text) {
|
|
|
35999
36077
|
}
|
|
36000
36078
|
var CONFIRM_ACTION_INSTRUCTION = CONFIRM_TOKEN_INSTRUCTION;
|
|
36001
36079
|
var CONFIRM_FALLBACK_DESCRIPTION = ' If the client cannot show that prompt (no MCP elicitation, e.g. claude.ai), a two-step flow applies instead: call WITHOUT confirmToken and nothing is sent or changed \u2014 the result has status "confirmation-required", the full preview and a confirmToken. Follow its instruction (by default: show the preview to the user verbatim and only after they explicitly approve it in chat, call again with the SAME arguments plus confirmToken). The tool re-reads what it would act on and refuses (DRAFT_CHANGED, with a fresh preview and token) if it changed; TOKEN_EXPIRED / TOKEN_REUSED / TOKEN_INVALID also do nothing. A server set to MCP_CONFIRM_MODE=refuse refuses instead.';
|
|
36080
|
+
function refusedInRun(what, via, does, instead) {
|
|
36081
|
+
return `${what} ${does} and is not available through ${via}. ${instead}`;
|
|
36082
|
+
}
|
|
36002
36083
|
function gatedElsewhere(what, via, does, tool) {
|
|
36003
|
-
return
|
|
36084
|
+
return refusedInRun(what, via, does, `Use ${tool}, which asks the user to confirm.`);
|
|
36004
36085
|
}
|
|
36005
36086
|
function hasCommandWord(args, words) {
|
|
36006
36087
|
return args.find((a) => words.has(a.toLowerCase()));
|
|
36007
36088
|
}
|
|
36089
|
+
function flagValue(args, name) {
|
|
36090
|
+
const flag = `--${name}`;
|
|
36091
|
+
for (let i = 0; i < args.length; i++) {
|
|
36092
|
+
const a = args[i];
|
|
36093
|
+
if (a === flag) return args[i + 1] ?? "";
|
|
36094
|
+
if (a.startsWith(`${flag}=`)) return a.slice(flag.length + 1);
|
|
36095
|
+
}
|
|
36096
|
+
return void 0;
|
|
36097
|
+
}
|
|
36008
36098
|
async function requireDispatchConfirmation(ctx, options) {
|
|
36009
36099
|
const { action, fallback } = options;
|
|
36010
36100
|
const confirmation = {
|
|
@@ -36165,6 +36255,27 @@ function authToolsFor(defaultServices) {
|
|
|
36165
36255
|
}
|
|
36166
36256
|
|
|
36167
36257
|
// ../gogcli-mcp/src/tools/calendar.ts
|
|
36258
|
+
var ASKS = (tool) => `Use ${tool}, which asks the user to confirm.`;
|
|
36259
|
+
var CALENDAR_REFUSED = {
|
|
36260
|
+
create: { does: "can change what guests see", instead: ASKS("gog_calendar_create") },
|
|
36261
|
+
add: { does: "can change what guests see", instead: ASKS("gog_calendar_create") },
|
|
36262
|
+
new: { does: "can change what guests see", instead: ASKS("gog_calendar_create") },
|
|
36263
|
+
update: { does: "can change what guests see", instead: ASKS("gog_calendar_update") },
|
|
36264
|
+
edit: { does: "can change what guests see", instead: ASKS("gog_calendar_update") },
|
|
36265
|
+
set: { does: "can change what guests see", instead: ASKS("gog_calendar_update") },
|
|
36266
|
+
respond: { does: "can change what guests see", instead: ASKS("gog_calendar_respond") },
|
|
36267
|
+
rsvp: { does: "can change what guests see", instead: ASKS("gog_calendar_respond") },
|
|
36268
|
+
reply: { does: "can change what guests see", instead: ASKS("gog_calendar_respond") },
|
|
36269
|
+
move: { does: "moves an event off guests' calendars (and can email them)", instead: ASKS("gog_calendar_move") },
|
|
36270
|
+
transfer: { does: "moves an event off guests' calendars (and can email them)", instead: ASKS("gog_calendar_move") },
|
|
36271
|
+
delete: { does: "removes an event from every guest's calendar (the whole series by default)", instead: ASKS("gog_calendar_delete") },
|
|
36272
|
+
del: { does: "removes an event from every guest's calendar (the whole series by default)", instead: ASKS("gog_calendar_delete") },
|
|
36273
|
+
rm: { does: "removes an event from every guest's calendar (the whole series by default)", instead: ASKS("gog_calendar_delete") },
|
|
36274
|
+
remove: { does: "removes an event from every guest's calendar (the whole series by default)", instead: ASKS("gog_calendar_delete") },
|
|
36275
|
+
"delete-calendar": { does: "deletes a calendar and every event on it", instead: ASKS("gog_calendar_delete_calendar") },
|
|
36276
|
+
"out-of-office": { does: "auto-declines invitations and notifies their organizers", instead: ASKS("gog_calendar_out_of_office") },
|
|
36277
|
+
ooo: { does: "auto-declines invitations and notifies their organizers", instead: ASKS("gog_calendar_out_of_office") }
|
|
36278
|
+
};
|
|
36168
36279
|
var reminderParams = {
|
|
36169
36280
|
reminders: external_exports.array(external_exports.string()).max(5).optional().describe(
|
|
36170
36281
|
`Reminders as method:duration, e.g. ["popup:30m", "email:1d"]. Method is popup or email; duration accepts m/h/d (max 40320 minutes = 4 weeks). Google allows at most 5. These REPLACE the event's reminders \u2014 on update, pass an EMPTY array to drop custom reminders and go back to the calendar's defaults. Cannot be combined with noReminders.`
|
|
@@ -36196,20 +36307,85 @@ var attachInlineParam = external_exports.array(inlineAttachmentSchema).optional(
|
|
|
36196
36307
|
|
|
36197
36308
|
// ../gogcli-mcp/src/tools/classroom.ts
|
|
36198
36309
|
var CLASSROOM_CREATE_WORDS = /* @__PURE__ */ new Set(["create", "add", "new"]);
|
|
36199
|
-
var
|
|
36200
|
-
|
|
36201
|
-
|
|
36202
|
-
|
|
36203
|
-
|
|
36204
|
-
|
|
36205
|
-
|
|
36310
|
+
var CLASSROOM_DELETE_WORDS = /* @__PURE__ */ new Set(["delete", "rm", "del", "remove"]);
|
|
36311
|
+
var CLASSROOM_UPDATE_WORDS = /* @__PURE__ */ new Set(["update", "edit", "set"]);
|
|
36312
|
+
var CLASSROOM_RETURN_WORDS = /* @__PURE__ */ new Set(["return", "send"]);
|
|
36313
|
+
var CLASSROOM_ASSIGNEE_WORDS = /* @__PURE__ */ new Set(["assignees", "assign"]);
|
|
36314
|
+
var CLASSROOM_GROUPS = {
|
|
36315
|
+
courses: "courses",
|
|
36316
|
+
course: "courses",
|
|
36317
|
+
announcements: "announcements",
|
|
36318
|
+
announcement: "announcements",
|
|
36319
|
+
ann: "announcements",
|
|
36320
|
+
invitations: "invitations",
|
|
36321
|
+
invitation: "invitations",
|
|
36322
|
+
invites: "invitations",
|
|
36323
|
+
coursework: "coursework",
|
|
36324
|
+
work: "coursework",
|
|
36325
|
+
materials: "materials",
|
|
36326
|
+
material: "materials",
|
|
36327
|
+
students: "students",
|
|
36328
|
+
student: "students",
|
|
36329
|
+
teachers: "teachers",
|
|
36330
|
+
teacher: "teachers",
|
|
36331
|
+
submissions: "submissions",
|
|
36332
|
+
submission: "submissions",
|
|
36333
|
+
"guardian-invitations": "guardian-invitations",
|
|
36334
|
+
"guardian-invites": "guardian-invitations"
|
|
36206
36335
|
};
|
|
36336
|
+
function publishesToStudents(args) {
|
|
36337
|
+
return flagValue(args, "state")?.toUpperCase() === "PUBLISHED" || flagValue(args, "scheduled") !== void 0;
|
|
36338
|
+
}
|
|
36339
|
+
function createsVisibleWork(args) {
|
|
36340
|
+
return flagValue(args, "state")?.toUpperCase() !== "DRAFT" || flagValue(args, "scheduled") !== void 0;
|
|
36341
|
+
}
|
|
36342
|
+
function widensAssignees(args) {
|
|
36343
|
+
return flagValue(args, "mode")?.toUpperCase() === "ALL_STUDENTS" || flagValue(args, "add-student") !== void 0;
|
|
36344
|
+
}
|
|
36207
36345
|
function vetClassroomRun(subcommand, args) {
|
|
36208
36346
|
const sub = subcommand.toLowerCase();
|
|
36209
|
-
|
|
36210
|
-
|
|
36211
|
-
const
|
|
36212
|
-
|
|
36347
|
+
if (!Object.hasOwn(CLASSROOM_GROUPS, sub)) return void 0;
|
|
36348
|
+
const group = CLASSROOM_GROUPS[sub];
|
|
36349
|
+
const via = "gog_classroom_run";
|
|
36350
|
+
const what = (word) => `gog classroom ${sub} ${word.toLowerCase()}`;
|
|
36351
|
+
const create = hasCommandWord(args, CLASSROOM_CREATE_WORDS);
|
|
36352
|
+
const update = hasCommandWord(args, CLASSROOM_UPDATE_WORDS);
|
|
36353
|
+
const remove = hasCommandWord(args, CLASSROOM_DELETE_WORDS);
|
|
36354
|
+
const widenedAssignees = () => {
|
|
36355
|
+
const word = hasCommandWord(args, CLASSROOM_ASSIGNEE_WORDS);
|
|
36356
|
+
return word && widensAssignees(args) ? refusedInRun(what(word), via, "shows it to more students", "Ask the user to change who it is assigned to from Classroom.") : void 0;
|
|
36357
|
+
};
|
|
36358
|
+
switch (group) {
|
|
36359
|
+
case "courses":
|
|
36360
|
+
return remove ? gatedElsewhere(what(remove), via, "deletes a course", "gog_classroom_courses_delete") : void 0;
|
|
36361
|
+
case "announcements":
|
|
36362
|
+
if (create) return gatedElsewhere(what(create), via, "posts to a class", "gog_classroom_announcements_create");
|
|
36363
|
+
if (update && publishesToStudents(args)) return gatedElsewhere(what(update), via, "publishes an announcement to a class", "gog_classroom_announcements_update");
|
|
36364
|
+
return widenedAssignees();
|
|
36365
|
+
case "invitations":
|
|
36366
|
+
return create ? gatedElsewhere(what(create), via, "invites someone to a class", "gog_classroom_invitations_create") : void 0;
|
|
36367
|
+
case "coursework":
|
|
36368
|
+
if (create && createsVisibleWork(args)) return gatedElsewhere(what(create), via, "posts coursework to a class", "gog_classroom_coursework_create");
|
|
36369
|
+
if (remove) return gatedElsewhere(what(remove), via, "deletes coursework and every submission to it", "gog_classroom_coursework_delete");
|
|
36370
|
+
if (update && publishesToStudents(args)) return gatedElsewhere(what(update), via, "publishes work to students", "gog_classroom_coursework_update");
|
|
36371
|
+
return widenedAssignees();
|
|
36372
|
+
case "materials":
|
|
36373
|
+
if (create && createsVisibleWork(args)) {
|
|
36374
|
+
return refusedInRun(what(create), via, "publishes material to students", "Create it with --state=DRAFT and no --scheduled; ask the user to publish it from Classroom.");
|
|
36375
|
+
}
|
|
36376
|
+
if (update && publishesToStudents(args)) return refusedInRun(what(update), via, "publishes material to students", "Ask the user to publish it from Classroom.");
|
|
36377
|
+
return void 0;
|
|
36378
|
+
case "students":
|
|
36379
|
+
return create ? gatedElsewhere(what(create), via, "enrols someone in a class", "gog_classroom_students_add") : void 0;
|
|
36380
|
+
case "teachers":
|
|
36381
|
+
return create ? gatedElsewhere(what(create), via, "gives someone a teacher's access to a class and its roster", "gog_classroom_teachers_add") : void 0;
|
|
36382
|
+
case "submissions": {
|
|
36383
|
+
const word = hasCommandWord(args, CLASSROOM_RETURN_WORDS);
|
|
36384
|
+
return word ? gatedElsewhere(what(word), via, "returns work to a student, who is notified", "gog_classroom_submissions_return") : void 0;
|
|
36385
|
+
}
|
|
36386
|
+
case "guardian-invitations":
|
|
36387
|
+
return create ? refusedInRun(what(create), via, "emails a guardian invitation", "Ask the user to invite the guardian from Classroom.") : void 0;
|
|
36388
|
+
}
|
|
36213
36389
|
}
|
|
36214
36390
|
async function readCourse(courseId, account, runner = runOrDiagnose) {
|
|
36215
36391
|
const got = await runner(["classroom", "courses", "get", pos(courseId)], { account });
|
|
@@ -36228,6 +36404,63 @@ async function readCourse(courseId, account, runner = runOrDiagnose) {
|
|
|
36228
36404
|
}
|
|
36229
36405
|
};
|
|
36230
36406
|
}
|
|
36407
|
+
function nested(raw, key) {
|
|
36408
|
+
try {
|
|
36409
|
+
const parsed = JSON.parse(raw);
|
|
36410
|
+
const inner = parsed?.[key];
|
|
36411
|
+
return inner && typeof inner === "object" ? inner : void 0;
|
|
36412
|
+
} catch {
|
|
36413
|
+
return void 0;
|
|
36414
|
+
}
|
|
36415
|
+
}
|
|
36416
|
+
var str = (v) => typeof v === "string" ? v : void 0;
|
|
36417
|
+
var num = (v) => typeof v === "number" ? v : void 0;
|
|
36418
|
+
async function readCoursework(courseId, courseworkId, account, runner = runOrDiagnose) {
|
|
36419
|
+
const got = await runner(["classroom", "coursework", "get", pos(courseId), pos(courseworkId)], { account });
|
|
36420
|
+
if (got.isError) return { error: got };
|
|
36421
|
+
const work = nested(resultText(got), "coursework");
|
|
36422
|
+
const title = str(work?.title);
|
|
36423
|
+
return { coursework: { id: courseworkId, ...title !== void 0 ? { title } : {} } };
|
|
36424
|
+
}
|
|
36425
|
+
async function readClassroomWork(kind, courseId, itemId, account, runner = runOrDiagnose) {
|
|
36426
|
+
const got = await runner(["classroom", kind, "get", pos(courseId), pos(itemId)], { account });
|
|
36427
|
+
if (got.isError) return { error: got };
|
|
36428
|
+
const item = nested(resultText(got), kind === "announcements" ? "announcement" : "coursework");
|
|
36429
|
+
const work = { id: itemId };
|
|
36430
|
+
for (const key of ["text", "title", "description", "state", "updateTime"]) {
|
|
36431
|
+
const value = str(item?.[key]);
|
|
36432
|
+
if (value !== void 0) work[key] = value;
|
|
36433
|
+
}
|
|
36434
|
+
return { work };
|
|
36435
|
+
}
|
|
36436
|
+
async function readSubmission(courseId, courseworkId, submissionId, account, runner = runOrDiagnose) {
|
|
36437
|
+
const got = await runner(["classroom", "submissions", "get", pos(courseId), pos(courseworkId), pos(submissionId)], { account });
|
|
36438
|
+
if (got.isError) return { error: got };
|
|
36439
|
+
const sub = nested(resultText(got), "submission");
|
|
36440
|
+
const fields = {
|
|
36441
|
+
student: str(sub?.userId),
|
|
36442
|
+
state: str(sub?.state),
|
|
36443
|
+
draftGrade: num(sub?.draftGrade),
|
|
36444
|
+
assignedGrade: num(sub?.assignedGrade)
|
|
36445
|
+
};
|
|
36446
|
+
const updateTime = str(sub?.updateTime);
|
|
36447
|
+
return {
|
|
36448
|
+
submission: {
|
|
36449
|
+
id: submissionId,
|
|
36450
|
+
...Object.fromEntries(Object.entries(fields).filter(([, v]) => v !== void 0))
|
|
36451
|
+
},
|
|
36452
|
+
...updateTime !== void 0 ? { updateTime } : {}
|
|
36453
|
+
};
|
|
36454
|
+
}
|
|
36455
|
+
async function studentLabel(courseId, userId, account, runner = runOrDiagnose) {
|
|
36456
|
+
const got = await runner(["classroom", "students", "get", pos(courseId), pos(userId)], { account });
|
|
36457
|
+
if (got.isError) return userId;
|
|
36458
|
+
const profile = nested(resultText(got), "student")?.profile;
|
|
36459
|
+
const name = str(profile?.name?.fullName);
|
|
36460
|
+
const email3 = str(profile?.emailAddress);
|
|
36461
|
+
if (name && email3) return `${name} <${email3}>`;
|
|
36462
|
+
return name ?? email3 ?? userId;
|
|
36463
|
+
}
|
|
36231
36464
|
function registerClassroomTools(server) {
|
|
36232
36465
|
server.registerTool("gog_classroom_courses_list", {
|
|
36233
36466
|
description: "List Google Classroom courses.",
|
|
@@ -36440,15 +36673,38 @@ function registerClassroomTools(server) {
|
|
|
36440
36673
|
return runOrDiagnose(args, { account });
|
|
36441
36674
|
});
|
|
36442
36675
|
server.registerTool("gog_classroom_submissions_return", {
|
|
36443
|
-
description: "Return a graded submission to the student.",
|
|
36676
|
+
description: "Return a graded submission to the student, who is notified and sees the grade. Reads the course, the coursework and the submission and asks the MCP host to show the user a confirmation prompt with the class, the assignment, the student and the grade being returned; nothing is returned unless they accept." + CONFIRM_FALLBACK_DESCRIPTION,
|
|
36444
36677
|
annotations: { destructiveHint: true },
|
|
36445
36678
|
inputSchema: external_exports.object({
|
|
36446
36679
|
courseId: external_exports.string().describe("Course ID"),
|
|
36447
36680
|
courseworkId: external_exports.string().describe("Coursework ID"),
|
|
36448
36681
|
submissionId: external_exports.string().describe("Submission ID"),
|
|
36449
|
-
account: accountParam
|
|
36682
|
+
account: accountParam,
|
|
36683
|
+
confirmToken: confirmTokenParam
|
|
36450
36684
|
})
|
|
36451
|
-
}, async ({ courseId, courseworkId, submissionId, account }) => {
|
|
36685
|
+
}, async ({ courseId, courseworkId, submissionId, account, confirmToken }, ctx) => {
|
|
36686
|
+
const course = await readCourse(courseId, account);
|
|
36687
|
+
if (course.error) return course.error;
|
|
36688
|
+
const work = await readCoursework(courseId, courseworkId, account);
|
|
36689
|
+
if (work.error) return work.error;
|
|
36690
|
+
const sub = await readSubmission(courseId, courseworkId, submissionId, account);
|
|
36691
|
+
if (sub.error) return sub.error;
|
|
36692
|
+
const submission = sub.submission.student ? { ...sub.submission, student: await studentLabel(courseId, sub.submission.student, account) } : sub.submission;
|
|
36693
|
+
const view = { course: course.course, coursework: work.coursework, submission };
|
|
36694
|
+
const confirmation = await requireDispatchConfirmation(ctx, {
|
|
36695
|
+
action: "classroom.submission-return",
|
|
36696
|
+
message: "Review and confirm returning this work \u2014 the student is notified and sees the grade:",
|
|
36697
|
+
confirmationLabel: "Confirm that this submission should be returned to the student now.",
|
|
36698
|
+
details: view,
|
|
36699
|
+
unsupportedNote: "Ask the user to return it from Classroom.",
|
|
36700
|
+
fallback: {
|
|
36701
|
+
tool: "gog_classroom_submissions_return",
|
|
36702
|
+
account,
|
|
36703
|
+
confirmToken,
|
|
36704
|
+
subject: () => ({ target: `${courseId}/${courseworkId}/${submissionId}`, revision: sub.updateTime, payload: view, preview: view })
|
|
36705
|
+
}
|
|
36706
|
+
});
|
|
36707
|
+
if (confirmation) return confirmation;
|
|
36452
36708
|
return runOrDiagnose(["classroom", "submissions", "return", pos(courseId), pos(courseworkId), pos(submissionId)], { account });
|
|
36453
36709
|
});
|
|
36454
36710
|
server.registerTool("gog_classroom_submissions_turn_in", {
|
|
@@ -36510,13 +36766,13 @@ function registerClassroomTools(server) {
|
|
|
36510
36766
|
return runOrDiagnose(["classroom", "announcements", "get", pos(courseId), pos(announcementId)], { account });
|
|
36511
36767
|
});
|
|
36512
36768
|
server.registerTool("gog_classroom_announcements_create", {
|
|
36513
|
-
description: "Create an announcement in a Google Classroom course. Unless state is DRAFT (which students cannot see), this reads the course and asks the MCP host to show the user a confirmation prompt with the class, the full text and when it publishes; nothing is posted unless they accept. To stage one without asking, pass state DRAFT." + CONFIRM_FALLBACK_DESCRIPTION,
|
|
36769
|
+
description: "Create an announcement in a Google Classroom course. Unless state is DRAFT with no scheduled time (which students cannot see; a scheduled draft publishes itself), this reads the course and asks the MCP host to show the user a confirmation prompt with the class, the full text and when it publishes; nothing is posted unless they accept. To stage one without asking, pass state DRAFT and no scheduled time." + CONFIRM_FALLBACK_DESCRIPTION,
|
|
36514
36770
|
annotations: { destructiveHint: true },
|
|
36515
36771
|
inputSchema: external_exports.object({
|
|
36516
36772
|
courseId: external_exports.string().describe("Course ID"),
|
|
36517
36773
|
text: external_exports.string().describe("Announcement text"),
|
|
36518
|
-
state: external_exports.enum(["PUBLISHED", "DRAFT"]).optional().describe("State (DRAFT is visible only to teachers and needs no confirmation)"),
|
|
36519
|
-
scheduled: external_exports.string().optional().describe("Scheduled publish time"),
|
|
36774
|
+
state: external_exports.enum(["PUBLISHED", "DRAFT"]).optional().describe("State (an unscheduled DRAFT is visible only to teachers and needs no confirmation)"),
|
|
36775
|
+
scheduled: external_exports.string().optional().describe("Scheduled publish time (asks the user to confirm, even for a DRAFT)"),
|
|
36520
36776
|
account: accountParam,
|
|
36521
36777
|
confirmToken: confirmTokenParam
|
|
36522
36778
|
})
|
|
@@ -36524,7 +36780,7 @@ function registerClassroomTools(server) {
|
|
|
36524
36780
|
const args = ["classroom", "announcements", "create", pos(courseId), `--text=${text}`];
|
|
36525
36781
|
if (state) args.push(`--state=${state}`);
|
|
36526
36782
|
if (scheduled) args.push(`--scheduled=${scheduled}`);
|
|
36527
|
-
if (state !== "DRAFT") {
|
|
36783
|
+
if (state !== "DRAFT" || scheduled) {
|
|
36528
36784
|
const read = await readCourse(courseId, account);
|
|
36529
36785
|
if (read.error) return read.error;
|
|
36530
36786
|
const publishes = scheduled ? `at ${scheduled}` : "immediately";
|
|
@@ -36673,7 +36929,7 @@ var failIfNotEmptyParam = external_exports.boolean().optional().describe(
|
|
|
36673
36929
|
);
|
|
36674
36930
|
|
|
36675
36931
|
// ../gogcli-mcp/src/server.ts
|
|
36676
|
-
var VERSION = true ? "4.5.
|
|
36932
|
+
var VERSION = true ? "4.5.2" : "0.0.0";
|
|
36677
36933
|
|
|
36678
36934
|
// ../gogcli-mcp/src/bootstrap-auth.ts
|
|
36679
36935
|
import { join as join5 } from "node:path";
|
|
@@ -36751,6 +37007,11 @@ var MAX_BLOB_UPLOAD_BYTES = 100 * 1024 * 1024;
|
|
|
36751
37007
|
var courseState = external_exports.enum(["ACTIVE", "ARCHIVED", "PROVISIONED", "DECLINED", "SUSPENDED"]);
|
|
36752
37008
|
var workState = external_exports.enum(["PUBLISHED", "DRAFT"]);
|
|
36753
37009
|
var workType = external_exports.enum(["ASSIGNMENT", "SHORT_ANSWER_QUESTION", "MULTIPLE_CHOICE_QUESTION"]);
|
|
37010
|
+
function publishesWhen(state, scheduled) {
|
|
37011
|
+
if (scheduled) return `at ${scheduled}`;
|
|
37012
|
+
return state === "PUBLISHED" ? "immediately" : void 0;
|
|
37013
|
+
}
|
|
37014
|
+
var PUBLISH_DESCRIPTION = " Publishing it (state PUBLISHED, or a scheduled time) reads the course and the item and asks the MCP host to show the user a confirmation prompt with the class and what students will see; nothing is published unless they accept. Other edits, and a return to DRAFT, need no confirmation." + CONFIRM_FALLBACK_DESCRIPTION;
|
|
36754
37015
|
var courseSharedFields = {
|
|
36755
37016
|
owner: external_exports.string().optional().describe('Owner user ID (default "me" on create)'),
|
|
36756
37017
|
section: external_exports.string().optional().describe("Section"),
|
|
@@ -36810,13 +37071,31 @@ function registerExtraClassroomTools(server) {
|
|
|
36810
37071
|
return runOrDiagnose(args, { account });
|
|
36811
37072
|
});
|
|
36812
37073
|
server.registerTool("gog_classroom_courses_delete", {
|
|
36813
|
-
description: "Delete a Google Classroom course.",
|
|
37074
|
+
description: "Delete a Google Classroom course \u2014 its coursework, submissions and grades go with it, for good. Reads the course and asks the MCP host to show the user a confirmation prompt naming it first; nothing is deleted unless they accept. gog_classroom_courses_archive is the reversible alternative." + CONFIRM_FALLBACK_DESCRIPTION,
|
|
36814
37075
|
annotations: { destructiveHint: true },
|
|
36815
37076
|
inputSchema: external_exports.object({
|
|
36816
37077
|
courseId: external_exports.string().describe("Course ID"),
|
|
36817
|
-
account: accountParam
|
|
37078
|
+
account: accountParam,
|
|
37079
|
+
confirmToken: confirmTokenParam
|
|
36818
37080
|
})
|
|
36819
|
-
}, async ({ courseId, account }) => {
|
|
37081
|
+
}, async ({ courseId, account, confirmToken }, ctx) => {
|
|
37082
|
+
const read = await readCourse(courseId, account, runOrDiagnose);
|
|
37083
|
+
if (read.error) return read.error;
|
|
37084
|
+
const view = { course: read.course, deletes: "the course with all of its coursework, submissions and grades, for good" };
|
|
37085
|
+
const confirmation = await requireDispatchConfirmation(ctx, {
|
|
37086
|
+
action: "classroom.course-delete",
|
|
37087
|
+
message: "Review and confirm PERMANENTLY deleting this course:",
|
|
37088
|
+
confirmationLabel: "Confirm that this course should be deleted now.",
|
|
37089
|
+
details: view,
|
|
37090
|
+
unsupportedNote: "Archive it with gog_classroom_courses_archive instead, or ask the user to delete it from Classroom.",
|
|
37091
|
+
fallback: {
|
|
37092
|
+
tool: "gog_classroom_courses_delete",
|
|
37093
|
+
account,
|
|
37094
|
+
confirmToken,
|
|
37095
|
+
subject: () => ({ target: courseId, payload: view, preview: view })
|
|
37096
|
+
}
|
|
37097
|
+
});
|
|
37098
|
+
if (confirmation) return confirmation;
|
|
36820
37099
|
return runOrDiagnose(["classroom", "courses", "delete", pos(courseId), "--force"], { account });
|
|
36821
37100
|
});
|
|
36822
37101
|
server.registerTool("gog_classroom_courses_archive", {
|
|
@@ -36840,17 +37119,37 @@ function registerExtraClassroomTools(server) {
|
|
|
36840
37119
|
return runOrDiagnose(["classroom", "courses", "unarchive", pos(courseId)], { account });
|
|
36841
37120
|
});
|
|
36842
37121
|
server.registerTool("gog_classroom_students_add", {
|
|
36843
|
-
description:
|
|
37122
|
+
description: 'Add a student to a Google Classroom course. Adding someone else gives them the class stream and materials, so this reads the course and asks the MCP host to show the user a confirmation prompt with the class and the student first; enrolling yourself ("me") does not ask.' + CONFIRM_FALLBACK_DESCRIPTION,
|
|
36844
37123
|
annotations: { destructiveHint: true },
|
|
36845
37124
|
inputSchema: external_exports.object({
|
|
36846
37125
|
courseId: external_exports.string().describe("Course ID"),
|
|
36847
|
-
userId: external_exports.string().describe('Student user ID (or "me")'),
|
|
37126
|
+
userId: external_exports.string().describe('Student user ID or email (or "me")'),
|
|
36848
37127
|
enrollmentCode: external_exports.string().optional().describe("Enrollment code (required if adding self via code)"),
|
|
36849
|
-
account: accountParam
|
|
37128
|
+
account: accountParam,
|
|
37129
|
+
confirmToken: confirmTokenParam
|
|
36850
37130
|
})
|
|
36851
|
-
}, async ({ courseId, userId, enrollmentCode, account }) => {
|
|
37131
|
+
}, async ({ courseId, userId, enrollmentCode, account, confirmToken }, ctx) => {
|
|
36852
37132
|
const args = ["classroom", "students", "add", pos(courseId), pos(userId)];
|
|
36853
37133
|
if (enrollmentCode) args.push(`--enrollment-code=${enrollmentCode}`);
|
|
37134
|
+
if (userId.toLowerCase() !== "me") {
|
|
37135
|
+
const read = await readCourse(courseId, account, runOrDiagnose);
|
|
37136
|
+
if (read.error) return read.error;
|
|
37137
|
+
const view = { course: read.course, student: userId };
|
|
37138
|
+
const confirmation = await requireDispatchConfirmation(ctx, {
|
|
37139
|
+
action: "classroom.student-add",
|
|
37140
|
+
message: "Review and confirm adding this student to the class:",
|
|
37141
|
+
confirmationLabel: "Confirm that this person should be added to the class now.",
|
|
37142
|
+
details: view,
|
|
37143
|
+
unsupportedNote: "Ask the user to add them from Classroom, or invite them with gog_classroom_invitations_create.",
|
|
37144
|
+
fallback: {
|
|
37145
|
+
tool: "gog_classroom_students_add",
|
|
37146
|
+
account,
|
|
37147
|
+
confirmToken,
|
|
37148
|
+
subject: () => ({ target: `${courseId}/${userId}`, payload: view, preview: view })
|
|
37149
|
+
}
|
|
37150
|
+
});
|
|
37151
|
+
if (confirmation) return confirmation;
|
|
37152
|
+
}
|
|
36854
37153
|
return runOrDiagnose(args, { account });
|
|
36855
37154
|
});
|
|
36856
37155
|
server.registerTool("gog_classroom_students_remove", {
|
|
@@ -36865,14 +37164,32 @@ function registerExtraClassroomTools(server) {
|
|
|
36865
37164
|
return runOrDiagnose(["classroom", "students", "remove", pos(courseId), pos(userId), "--force"], { account });
|
|
36866
37165
|
});
|
|
36867
37166
|
server.registerTool("gog_classroom_teachers_add", {
|
|
36868
|
-
description: "Add a teacher to a Google Classroom course.",
|
|
37167
|
+
description: "Add a teacher to a Google Classroom course. A co-teacher sees every student's work and grades, so this reads the course and asks the MCP host to show the user a confirmation prompt with the class and the teacher first; nothing changes unless they accept." + CONFIRM_FALLBACK_DESCRIPTION,
|
|
36869
37168
|
annotations: { destructiveHint: true },
|
|
36870
37169
|
inputSchema: external_exports.object({
|
|
36871
37170
|
courseId: external_exports.string().describe("Course ID"),
|
|
36872
|
-
userId: external_exports.string().describe("Teacher user ID"),
|
|
36873
|
-
account: accountParam
|
|
37171
|
+
userId: external_exports.string().describe("Teacher user ID or email"),
|
|
37172
|
+
account: accountParam,
|
|
37173
|
+
confirmToken: confirmTokenParam
|
|
36874
37174
|
})
|
|
36875
|
-
}, async ({ courseId, userId, account }) => {
|
|
37175
|
+
}, async ({ courseId, userId, account, confirmToken }, ctx) => {
|
|
37176
|
+
const read = await readCourse(courseId, account, runOrDiagnose);
|
|
37177
|
+
if (read.error) return read.error;
|
|
37178
|
+
const view = { course: read.course, teacher: userId, grants: "teacher access: every student's work, grades and roster" };
|
|
37179
|
+
const confirmation = await requireDispatchConfirmation(ctx, {
|
|
37180
|
+
action: "classroom.teacher-add",
|
|
37181
|
+
message: "Review and confirm giving this person teacher access to the class:",
|
|
37182
|
+
confirmationLabel: "Confirm that this person should become a teacher of the class now.",
|
|
37183
|
+
details: view,
|
|
37184
|
+
unsupportedNote: "Ask the user to add them from Classroom, or invite them with gog_classroom_invitations_create.",
|
|
37185
|
+
fallback: {
|
|
37186
|
+
tool: "gog_classroom_teachers_add",
|
|
37187
|
+
account,
|
|
37188
|
+
confirmToken,
|
|
37189
|
+
subject: () => ({ target: `${courseId}/${userId}`, payload: view, preview: view })
|
|
37190
|
+
}
|
|
37191
|
+
});
|
|
37192
|
+
if (confirmation) return confirmation;
|
|
36876
37193
|
return runOrDiagnose(["classroom", "teachers", "add", pos(courseId), pos(userId)], { account });
|
|
36877
37194
|
});
|
|
36878
37195
|
server.registerTool("gog_classroom_teachers_remove", {
|
|
@@ -36887,15 +37204,16 @@ function registerExtraClassroomTools(server) {
|
|
|
36887
37204
|
return runOrDiagnose(["classroom", "teachers", "remove", pos(courseId), pos(userId), "--force"], { account });
|
|
36888
37205
|
});
|
|
36889
37206
|
server.registerTool("gog_classroom_coursework_create", {
|
|
36890
|
-
description: "Create a new coursework item (assignment, question, etc.) in a course.",
|
|
37207
|
+
description: "Create a new coursework item (assignment, question, etc.) in a course. Unless state is DRAFT with no scheduled time (which students cannot see; a scheduled draft publishes itself), the class is notified, so this reads the course and asks the MCP host to show the user a confirmation prompt with the class, the title, the text, the due date and when it publishes; nothing is posted unless they accept. To stage one without asking, pass state DRAFT and no scheduled time." + CONFIRM_FALLBACK_DESCRIPTION,
|
|
36891
37208
|
annotations: { destructiveHint: true },
|
|
36892
37209
|
inputSchema: external_exports.object({
|
|
36893
37210
|
courseId: external_exports.string().describe("Course ID"),
|
|
36894
37211
|
title: external_exports.string().describe("Coursework title"),
|
|
36895
37212
|
...courseworkSharedFields,
|
|
36896
|
-
account: accountParam
|
|
37213
|
+
account: accountParam,
|
|
37214
|
+
confirmToken: confirmTokenParam
|
|
36897
37215
|
})
|
|
36898
|
-
}, async ({ courseId, title, description, type, state, maxPoints, due, dueDate, dueTime, scheduled, topic, account }) => {
|
|
37216
|
+
}, async ({ courseId, title, description, type, state, maxPoints, due, dueDate, dueTime, scheduled, topic, account, confirmToken }, ctx) => {
|
|
36899
37217
|
const args = ["classroom", "coursework", "create", pos(courseId), `--title=${title}`];
|
|
36900
37218
|
if (description) args.push(`--description=${description}`);
|
|
36901
37219
|
if (type) args.push(`--type=${type}`);
|
|
@@ -36906,19 +37224,49 @@ function registerExtraClassroomTools(server) {
|
|
|
36906
37224
|
if (dueTime) args.push(`--due-time=${dueTime}`);
|
|
36907
37225
|
if (scheduled) args.push(`--scheduled=${scheduled}`);
|
|
36908
37226
|
if (topic) args.push(`--topic=${topic}`);
|
|
37227
|
+
if (state !== "DRAFT" || scheduled) {
|
|
37228
|
+
const read = await readCourse(courseId, account, runOrDiagnose);
|
|
37229
|
+
if (read.error) return read.error;
|
|
37230
|
+
const work = {
|
|
37231
|
+
course: read.course,
|
|
37232
|
+
title,
|
|
37233
|
+
type: type ?? "ASSIGNMENT",
|
|
37234
|
+
publishes: scheduled ? `at ${scheduled}` : "immediately",
|
|
37235
|
+
due: due ?? ([dueDate, dueTime].filter(Boolean).join(" ") || void 0),
|
|
37236
|
+
maxPoints
|
|
37237
|
+
};
|
|
37238
|
+
const confirmation = await requireDispatchConfirmation(ctx, {
|
|
37239
|
+
action: "classroom.coursework-create",
|
|
37240
|
+
message: "Review and confirm posting this coursework to the class:",
|
|
37241
|
+
confirmationLabel: "Confirm that this coursework should be posted to the class.",
|
|
37242
|
+
details: { ...work, descriptionPreview: bodyPreview(description) },
|
|
37243
|
+
unsupportedNote: "Create it with state DRAFT instead; the user can review and post it from Classroom.",
|
|
37244
|
+
fallback: {
|
|
37245
|
+
tool: "gog_classroom_coursework_create",
|
|
37246
|
+
account,
|
|
37247
|
+
confirmToken,
|
|
37248
|
+
subject: () => {
|
|
37249
|
+
const view = { ...work, description };
|
|
37250
|
+
return { target: courseId, payload: view, preview: view };
|
|
37251
|
+
}
|
|
37252
|
+
}
|
|
37253
|
+
});
|
|
37254
|
+
if (confirmation) return confirmation;
|
|
37255
|
+
}
|
|
36909
37256
|
return runOrDiagnose(args, { account });
|
|
36910
37257
|
});
|
|
36911
37258
|
server.registerTool("gog_classroom_coursework_update", {
|
|
36912
|
-
description: "Update an existing coursework item.",
|
|
37259
|
+
description: "Update an existing coursework item." + PUBLISH_DESCRIPTION,
|
|
36913
37260
|
annotations: { destructiveHint: true },
|
|
36914
37261
|
inputSchema: external_exports.object({
|
|
36915
37262
|
courseId: external_exports.string().describe("Course ID"),
|
|
36916
37263
|
courseworkId: external_exports.string().describe("Coursework ID"),
|
|
36917
37264
|
title: external_exports.string().optional().describe("New title"),
|
|
36918
37265
|
...courseworkSharedFields,
|
|
36919
|
-
account: accountParam
|
|
37266
|
+
account: accountParam,
|
|
37267
|
+
confirmToken: confirmTokenParam
|
|
36920
37268
|
})
|
|
36921
|
-
}, async ({ courseId, courseworkId, title, description, type, state, maxPoints, due, dueDate, dueTime, scheduled, topic, account }) => {
|
|
37269
|
+
}, async ({ courseId, courseworkId, title, description, type, state, maxPoints, due, dueDate, dueTime, scheduled, topic, account, confirmToken }, ctx) => {
|
|
36922
37270
|
const args = ["classroom", "coursework", "update", pos(courseId), pos(courseworkId)];
|
|
36923
37271
|
if (title) args.push(`--title=${title}`);
|
|
36924
37272
|
if (description) args.push(`--description=${description}`);
|
|
@@ -36930,35 +37278,123 @@ function registerExtraClassroomTools(server) {
|
|
|
36930
37278
|
if (dueTime) args.push(`--due-time=${dueTime}`);
|
|
36931
37279
|
if (scheduled) args.push(`--scheduled=${scheduled}`);
|
|
36932
37280
|
if (topic) args.push(`--topic=${topic}`);
|
|
37281
|
+
const publishes = publishesWhen(state, scheduled);
|
|
37282
|
+
if (publishes) {
|
|
37283
|
+
const read = await readCourse(courseId, account, runOrDiagnose);
|
|
37284
|
+
if (read.error) return read.error;
|
|
37285
|
+
const current = await readClassroomWork("coursework", courseId, courseworkId, account, runOrDiagnose);
|
|
37286
|
+
if (current.error) return current.error;
|
|
37287
|
+
const published = description || current.work.description;
|
|
37288
|
+
const publishedTitle = title || current.work.title;
|
|
37289
|
+
const view = {
|
|
37290
|
+
course: read.course,
|
|
37291
|
+
coursework: { id: courseworkId, title: publishedTitle, state: current.work.state },
|
|
37292
|
+
publishes,
|
|
37293
|
+
descriptionPreview: bodyPreview(published)
|
|
37294
|
+
};
|
|
37295
|
+
const confirmation = await requireDispatchConfirmation(ctx, {
|
|
37296
|
+
action: "classroom.coursework-publish",
|
|
37297
|
+
message: "Review and confirm publishing this Classroom coursework to students:",
|
|
37298
|
+
confirmationLabel: "Confirm that this coursework should be published to the class.",
|
|
37299
|
+
details: view,
|
|
37300
|
+
unsupportedNote: "Leave it as a DRAFT; the user can review and publish it from Classroom.",
|
|
37301
|
+
fallback: {
|
|
37302
|
+
tool: "gog_classroom_coursework_update",
|
|
37303
|
+
account,
|
|
37304
|
+
confirmToken,
|
|
37305
|
+
subject: () => ({
|
|
37306
|
+
target: `${courseId}/${courseworkId}`,
|
|
37307
|
+
revision: current.work.updateTime,
|
|
37308
|
+
payload: { course: read.course, courseworkId, title: publishedTitle, description: published, type, state, maxPoints, due, dueDate, dueTime, scheduled, topic },
|
|
37309
|
+
preview: view
|
|
37310
|
+
})
|
|
37311
|
+
}
|
|
37312
|
+
});
|
|
37313
|
+
if (confirmation) return confirmation;
|
|
37314
|
+
}
|
|
36933
37315
|
return runOrDiagnose(args, { account });
|
|
36934
37316
|
});
|
|
36935
37317
|
server.registerTool("gog_classroom_coursework_delete", {
|
|
36936
|
-
description: "Delete a coursework item.",
|
|
37318
|
+
description: "Delete a coursework item \u2014 every student submission to it goes too, for good. Reads the course and the coursework and asks the MCP host to show the user a confirmation prompt naming both first; nothing is deleted unless they accept." + CONFIRM_FALLBACK_DESCRIPTION,
|
|
36937
37319
|
annotations: { destructiveHint: true },
|
|
36938
37320
|
inputSchema: external_exports.object({
|
|
36939
37321
|
courseId: external_exports.string().describe("Course ID"),
|
|
36940
37322
|
courseworkId: external_exports.string().describe("Coursework ID"),
|
|
36941
|
-
account: accountParam
|
|
37323
|
+
account: accountParam,
|
|
37324
|
+
confirmToken: confirmTokenParam
|
|
36942
37325
|
})
|
|
36943
|
-
}, async ({ courseId, courseworkId, account }) => {
|
|
37326
|
+
}, async ({ courseId, courseworkId, account, confirmToken }, ctx) => {
|
|
37327
|
+
const course = await readCourse(courseId, account, runOrDiagnose);
|
|
37328
|
+
if (course.error) return course.error;
|
|
37329
|
+
const work = await readCoursework(courseId, courseworkId, account, runOrDiagnose);
|
|
37330
|
+
if (work.error) return work.error;
|
|
37331
|
+
const view = { course: course.course, coursework: work.coursework, deletes: "the coursework and every student submission to it, for good" };
|
|
37332
|
+
const confirmation = await requireDispatchConfirmation(ctx, {
|
|
37333
|
+
action: "classroom.coursework-delete",
|
|
37334
|
+
message: "Review and confirm PERMANENTLY deleting this coursework and its submissions:",
|
|
37335
|
+
confirmationLabel: "Confirm that this coursework should be deleted now.",
|
|
37336
|
+
details: view,
|
|
37337
|
+
unsupportedNote: "Ask the user to delete it from Classroom.",
|
|
37338
|
+
fallback: {
|
|
37339
|
+
tool: "gog_classroom_coursework_delete",
|
|
37340
|
+
account,
|
|
37341
|
+
confirmToken,
|
|
37342
|
+
subject: () => ({ target: `${courseId}/${courseworkId}`, payload: view, preview: view })
|
|
37343
|
+
}
|
|
37344
|
+
});
|
|
37345
|
+
if (confirmation) return confirmation;
|
|
36944
37346
|
return runOrDiagnose(["classroom", "coursework", "delete", pos(courseId), pos(courseworkId), "--force"], { account });
|
|
36945
37347
|
});
|
|
36946
37348
|
server.registerTool("gog_classroom_announcements_update", {
|
|
36947
|
-
description: "Update an existing announcement.",
|
|
37349
|
+
description: "Update an existing announcement." + PUBLISH_DESCRIPTION,
|
|
36948
37350
|
annotations: { destructiveHint: true },
|
|
36949
37351
|
inputSchema: external_exports.object({
|
|
36950
37352
|
courseId: external_exports.string().describe("Course ID"),
|
|
36951
37353
|
announcementId: external_exports.string().describe("Announcement ID"),
|
|
36952
37354
|
text: external_exports.string().optional().describe("New text"),
|
|
36953
|
-
state: workState.optional().describe("State"),
|
|
36954
|
-
scheduled: external_exports.string().optional().describe("Scheduled publish time"),
|
|
36955
|
-
account: accountParam
|
|
37355
|
+
state: workState.optional().describe("State (PUBLISHED asks the user to confirm; DRAFT does not)"),
|
|
37356
|
+
scheduled: external_exports.string().optional().describe("Scheduled publish time (asks the user to confirm)"),
|
|
37357
|
+
account: accountParam,
|
|
37358
|
+
confirmToken: confirmTokenParam
|
|
36956
37359
|
})
|
|
36957
|
-
}, async ({ courseId, announcementId, text, state, scheduled, account }) => {
|
|
37360
|
+
}, async ({ courseId, announcementId, text, state, scheduled, account, confirmToken }, ctx) => {
|
|
36958
37361
|
const args = ["classroom", "announcements", "update", pos(courseId), pos(announcementId)];
|
|
36959
37362
|
if (text) args.push(`--text=${text}`);
|
|
36960
37363
|
if (state) args.push(`--state=${state}`);
|
|
36961
37364
|
if (scheduled) args.push(`--scheduled=${scheduled}`);
|
|
37365
|
+
const publishes = publishesWhen(state, scheduled);
|
|
37366
|
+
if (publishes) {
|
|
37367
|
+
const read = await readCourse(courseId, account, runOrDiagnose);
|
|
37368
|
+
if (read.error) return read.error;
|
|
37369
|
+
const current = await readClassroomWork("announcements", courseId, announcementId, account, runOrDiagnose);
|
|
37370
|
+
if (current.error) return current.error;
|
|
37371
|
+
const published = text || current.work.text;
|
|
37372
|
+
const view = {
|
|
37373
|
+
course: read.course,
|
|
37374
|
+
announcement: { id: announcementId, state: current.work.state },
|
|
37375
|
+
publishes,
|
|
37376
|
+
textPreview: bodyPreview(published)
|
|
37377
|
+
};
|
|
37378
|
+
const confirmation = await requireDispatchConfirmation(ctx, {
|
|
37379
|
+
action: "classroom.announcement-publish",
|
|
37380
|
+
message: "Review and confirm publishing this Classroom announcement to the class:",
|
|
37381
|
+
confirmationLabel: "Confirm that this announcement should be published to the class.",
|
|
37382
|
+
details: view,
|
|
37383
|
+
unsupportedNote: "Leave it as a DRAFT; the user can review and publish it from Classroom.",
|
|
37384
|
+
fallback: {
|
|
37385
|
+
tool: "gog_classroom_announcements_update",
|
|
37386
|
+
account,
|
|
37387
|
+
confirmToken,
|
|
37388
|
+
subject: () => ({
|
|
37389
|
+
target: `${courseId}/${announcementId}`,
|
|
37390
|
+
revision: current.work.updateTime,
|
|
37391
|
+
payload: { course: read.course, announcementId, text: published, state, scheduled },
|
|
37392
|
+
preview: view
|
|
37393
|
+
})
|
|
37394
|
+
}
|
|
37395
|
+
});
|
|
37396
|
+
if (confirmation) return confirmation;
|
|
37397
|
+
}
|
|
36962
37398
|
return runOrDiagnose(args, { account });
|
|
36963
37399
|
});
|
|
36964
37400
|
server.registerTool("gog_classroom_announcements_delete", {
|
|
@@ -37057,7 +37493,7 @@ await runMcp({
|
|
|
37057
37493
|
});
|
|
37058
37494
|
/*! Bundled license information:
|
|
37059
37495
|
|
|
37060
|
-
@modelcontextprotocol/server/dist/src-
|
|
37496
|
+
@modelcontextprotocol/server/dist/src-D-y6h4N7.mjs:
|
|
37061
37497
|
(*!
|
|
37062
37498
|
* content-type
|
|
37063
37499
|
* Copyright(c) 2015 Douglas Christopher Wilson
|