brightspace-mcp-server 3.13.6 → 3.13.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/auth/auth-runner.js +29 -28
- package/build/tools/tool-helpers.js +6 -2
- package/package.json +1 -1
|
@@ -25,9 +25,9 @@ const AUTH_TIMEOUT_MS = 8 * 60 * 1000;
|
|
|
25
25
|
const KILL_GRACE_MS = 5000;
|
|
26
26
|
/**
|
|
27
27
|
* How long a caller keeps waiting for the background sign-in once the
|
|
28
|
-
* challenge is known: long enough to find a phone and approve. Applies
|
|
29
|
-
*
|
|
30
|
-
*
|
|
28
|
+
* challenge is known: long enough to find a phone and approve. Applies to a
|
|
29
|
+
* retry that joins the background child after the answer carrying the
|
|
30
|
+
* challenge (the first answer never waits; see attend). The retry
|
|
31
31
|
* used to wait only 5 s, so on clients that send no progress token (Claude
|
|
32
32
|
* Desktop) every retry re-answered "enter the number" and the model asked
|
|
33
33
|
* the user to confirm by hand instead of the server polling for the approval.
|
|
@@ -289,9 +289,9 @@ export class AuthRunner {
|
|
|
289
289
|
* challenge appears (an mfaPending error carrying the number to enter: the
|
|
290
290
|
* user cannot see it any other way), and the next call joins the background
|
|
291
291
|
* sign-in and polls it for up to MFA_POLL_MS, never past CALL_BUDGET_MS from
|
|
292
|
-
* that call. With onChallenge, the caller is handed the challenge
|
|
293
|
-
*
|
|
294
|
-
* approval within the window completes the caller's original request; past
|
|
292
|
+
* that call. With onChallenge, the caller is also handed the challenge
|
|
293
|
+
* mid-call, but is still answered at once: a client may accept progress
|
|
294
|
+
* notices without showing them. An approval within the window completes the caller's original request; past
|
|
295
295
|
* it, the caller gets the same mfaPending answer again and is expected to
|
|
296
296
|
* call once more. No caller waits past CALL_BUDGET_MS: a sign-in still
|
|
297
297
|
* short of its challenge by then answers inProgress and keeps running for
|
|
@@ -355,21 +355,24 @@ export class AuthRunner {
|
|
|
355
355
|
const childDone = this.childDone;
|
|
356
356
|
if (!childDone || !(error instanceof AuthProcessError))
|
|
357
357
|
throw error;
|
|
358
|
-
//
|
|
359
|
-
//
|
|
360
|
-
//
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
const windowMs = pollWindowMs(Date.now() - startedAt);
|
|
365
|
-
if (windowMs <= 0)
|
|
366
|
-
throw error;
|
|
358
|
+
// A new challenge always goes back in the answer, announced or not. A
|
|
359
|
+
// progress token says a client CAN receive mid-call notices, not that it
|
|
360
|
+
// shows them: Claude Desktop sends one and displays nothing, so holding
|
|
361
|
+
// the call open after announcing kept the number from the user for up
|
|
362
|
+
// to 45 seconds. The retry is what joins and waits for the approval.
|
|
363
|
+
// An automaticPending asks nothing of anyone, so keep waiting on it.
|
|
367
364
|
if (error.kind === "mfaPending") {
|
|
368
365
|
try {
|
|
369
366
|
onChallenge?.(error.numberMatch);
|
|
370
367
|
}
|
|
371
368
|
catch { /* Announcing must not interrupt authentication. */ }
|
|
369
|
+
throw error;
|
|
372
370
|
}
|
|
371
|
+
if (error.kind !== "automaticPending")
|
|
372
|
+
throw error;
|
|
373
|
+
const windowMs = pollWindowMs(Date.now() - startedAt);
|
|
374
|
+
if (windowMs <= 0)
|
|
375
|
+
throw error;
|
|
373
376
|
return this.awaitBackgroundChild(childDone, windowMs);
|
|
374
377
|
}
|
|
375
378
|
}
|
|
@@ -379,32 +382,30 @@ export class AuthRunner {
|
|
|
379
382
|
* exited, so unlike awaitBackgroundChild there is nothing here to join:
|
|
380
383
|
* the lock is the only thing to watch.
|
|
381
384
|
*
|
|
382
|
-
* The first answer is
|
|
383
|
-
* mid-call, because the number is what the user needs and every second
|
|
385
|
+
* The first answer is immediate, because the number is what the user needs and every second
|
|
384
386
|
* before it is a second the other sign-in's window runs down. A RETRY of the
|
|
385
387
|
* same challenge (already reported to a caller in this process) waits, like
|
|
386
388
|
* a retry joining a local child, instead of re-answering at once: answering
|
|
387
389
|
* a loop of retries in milliseconds made a model conclude the approval
|
|
388
390
|
* window had closed while the other sign-in was still waiting. A caller
|
|
389
|
-
* that can be told mid-call is told
|
|
390
|
-
* answering its own code has nothing to
|
|
391
|
+
* that can be told mid-call is told too, but is answered at once all the
|
|
392
|
+
* same (see attend), and an owner answering its own code has nothing to
|
|
393
|
+
* relay, so every caller waits.
|
|
391
394
|
*/
|
|
392
395
|
attendRelay(error, startedAt, onChallenge, toldBefore) {
|
|
393
396
|
const retry = toldBefore.has(relayKey(error.kind, error.numberMatch));
|
|
394
|
-
|
|
395
|
-
|| (error.kind === "mfaPending" && (Boolean(onChallenge) || retry));
|
|
396
|
-
if (!waits)
|
|
397
|
-
throw error;
|
|
398
|
-
const windowMs = pollWindowMs(Date.now() - startedAt);
|
|
399
|
-
if (windowMs <= 0)
|
|
400
|
-
throw error;
|
|
401
|
-
if (error.kind === "mfaPending" && onChallenge) {
|
|
397
|
+
if (error.kind === "mfaPending" && onChallenge && !retry) {
|
|
402
398
|
try {
|
|
403
399
|
onChallenge(error.numberMatch);
|
|
404
400
|
}
|
|
405
401
|
catch { /* Announcing must not interrupt authentication. */ }
|
|
406
|
-
this.noteRelayReported(error);
|
|
407
402
|
}
|
|
403
|
+
const waits = error.kind === "automaticPending" || (error.kind === "mfaPending" && retry);
|
|
404
|
+
if (!waits)
|
|
405
|
+
throw error;
|
|
406
|
+
const windowMs = pollWindowMs(Date.now() - startedAt);
|
|
407
|
+
if (windowMs <= 0)
|
|
408
|
+
throw error;
|
|
408
409
|
return this.awaitRelayedOwner(error, windowMs);
|
|
409
410
|
}
|
|
410
411
|
/**
|
|
@@ -110,7 +110,9 @@ const AUTH_FAILURE_GUIDANCE = {
|
|
|
110
110
|
"Call this tool again right away: the next call joins the same sign-in and returns the result " +
|
|
111
111
|
"as soon as it completes.",
|
|
112
112
|
mfaPending: "Approve the sign-in request on your phone (Microsoft Authenticator or Duo). " +
|
|
113
|
-
"Tell the user that,
|
|
113
|
+
"Tell the user that now, as text in your reply, before you make any other tool call: they " +
|
|
114
|
+
"can't see tool results, and some apps show nothing until you write it. Then call this tool " +
|
|
115
|
+
"again right away without waiting for them to " +
|
|
114
116
|
"confirm: each call waits up to 45 seconds for the approval and returns the result as soon " +
|
|
115
117
|
"as the sign-in completes. Keep calling until it succeeds or reports a different error. " +
|
|
116
118
|
MFA_SOLO_CALL,
|
|
@@ -141,7 +143,9 @@ function authFailureMessage(error) {
|
|
|
141
143
|
return AUTOMATIC_ALREADY_REPORTED;
|
|
142
144
|
if (error.kind === "mfaPending" && error.numberMatch) {
|
|
143
145
|
return `Open Microsoft Authenticator and enter ${error.numberMatch} within 5 minutes. ` +
|
|
144
|
-
"
|
|
146
|
+
"Show the user that number now, as text in your reply, before you make any other tool call: " +
|
|
147
|
+
"they can't see tool results, and some apps show nothing until you write it. Then call this " +
|
|
148
|
+
"tool again right away without waiting for them " +
|
|
145
149
|
"to confirm: each call waits up to 45 seconds for the approval and returns the result as " +
|
|
146
150
|
"soon as the sign-in completes. Keep calling until it succeeds or reports a different error. " +
|
|
147
151
|
MFA_SOLO_CALL;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "brightspace-mcp-server",
|
|
3
|
-
"version": "3.13.
|
|
3
|
+
"version": "3.13.8",
|
|
4
4
|
"mcpName": "io.github.RohanMuppa/brightspace",
|
|
5
5
|
"description": "MCP server for Brightspace (D2L). Check grades, due dates, assignments, announcements, syllabus, rosters and more via Claude, ChatGPT, Cursor, Windsurf, or any MCP client.",
|
|
6
6
|
"type": "module",
|