signupgenius-mcp 1.1.3 → 1.1.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/marketplace.json +2 -2
- package/.claude-plugin/plugin.json +1 -1
- package/LICENSE +21 -0
- package/README.md +4 -0
- package/dist/bundle.js +198 -51
- package/dist/index.js +1 -1
- package/package.json +3 -3
- package/server.json +2 -2
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
},
|
|
8
8
|
"metadata": {
|
|
9
9
|
"description": "MCP server for SignUpGenius — read sign-ups, slot reports, and groups; add group members.",
|
|
10
|
-
"version": "1.1.
|
|
10
|
+
"version": "1.1.5"
|
|
11
11
|
},
|
|
12
12
|
"plugins": [
|
|
13
13
|
{
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
"displayName": "SignUpGenius",
|
|
16
16
|
"source": "./",
|
|
17
17
|
"description": "SignUpGenius MCP server for Claude — sign-ups, slot reports, and groups via natural language. Free or Pro accounts.",
|
|
18
|
-
"version": "1.1.
|
|
18
|
+
"version": "1.1.5",
|
|
19
19
|
"author": {
|
|
20
20
|
"name": "Chris Hall"
|
|
21
21
|
},
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "signupgenius-mcp",
|
|
3
3
|
"displayName": "SignUpGenius",
|
|
4
|
-
"version": "1.1.
|
|
4
|
+
"version": "1.1.5",
|
|
5
5
|
"description": "SignUpGenius MCP server for Claude — read sign-ups, slot reports, and groups; add group members. Three auth paths: Pro API key, email/password, or sign in via the fetchproxy browser extension.",
|
|
6
6
|
"author": {
|
|
7
7
|
"name": "Chris Hall",
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Chris Hall
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
# signupgenius-mcp
|
|
2
2
|
|
|
3
|
+
[](https://github.com/chrischall/signupgenius-mcp/actions/workflows/ci.yml)
|
|
4
|
+
[](https://www.npmjs.com/package/signupgenius-mcp)
|
|
5
|
+
[](LICENSE)
|
|
6
|
+
|
|
3
7
|
MCP server for [SignUpGenius](https://www.signupgenius.com). 13 read tools and 1 write across profile, groups, sign-ups, and reports.
|
|
4
8
|
|
|
5
9
|
Three auth modes (tried in this priority order — first match wins):
|
package/dist/bundle.js
CHANGED
|
@@ -13,7 +13,11 @@ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require
|
|
|
13
13
|
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
14
14
|
});
|
|
15
15
|
var __commonJS = (cb, mod) => function __require2() {
|
|
16
|
-
|
|
16
|
+
try {
|
|
17
|
+
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
|
|
18
|
+
} catch (e) {
|
|
19
|
+
throw mod = 0, e;
|
|
20
|
+
}
|
|
17
21
|
};
|
|
18
22
|
var __export = (target, all) => {
|
|
19
23
|
for (var name in all)
|
|
@@ -35860,10 +35864,20 @@ async function openEncryptedFrame(sessionKey, frame) {
|
|
|
35860
35864
|
|
|
35861
35865
|
// node_modules/@fetchproxy/server/dist/election.js
|
|
35862
35866
|
import { createServer, Server as HttpServer } from "node:http";
|
|
35867
|
+
var DEFAULT_BIND_TIMEOUT_MS = 5e3;
|
|
35863
35868
|
async function electRole(opts) {
|
|
35864
35869
|
const server = createServer();
|
|
35870
|
+
const bindTimeoutMs = opts.bindTimeoutMs ?? DEFAULT_BIND_TIMEOUT_MS;
|
|
35865
35871
|
return new Promise((resolve, reject) => {
|
|
35872
|
+
let timer;
|
|
35873
|
+
const clearBindTimer = () => {
|
|
35874
|
+
if (timer) {
|
|
35875
|
+
clearTimeout(timer);
|
|
35876
|
+
timer = void 0;
|
|
35877
|
+
}
|
|
35878
|
+
};
|
|
35866
35879
|
const onError = (e) => {
|
|
35880
|
+
clearBindTimer();
|
|
35867
35881
|
server.removeListener("listening", onListening);
|
|
35868
35882
|
if (e.code === "EADDRINUSE") {
|
|
35869
35883
|
try {
|
|
@@ -35876,11 +35890,25 @@ async function electRole(opts) {
|
|
|
35876
35890
|
}
|
|
35877
35891
|
};
|
|
35878
35892
|
const onListening = () => {
|
|
35893
|
+
clearBindTimer();
|
|
35879
35894
|
server.removeListener("error", onError);
|
|
35880
35895
|
resolve({ role: "host", server });
|
|
35881
35896
|
};
|
|
35882
35897
|
server.once("error", onError);
|
|
35883
35898
|
server.once("listening", onListening);
|
|
35899
|
+
if (bindTimeoutMs > 0) {
|
|
35900
|
+
timer = setTimeout(() => {
|
|
35901
|
+
server.removeListener("error", onError);
|
|
35902
|
+
server.removeListener("listening", onListening);
|
|
35903
|
+
try {
|
|
35904
|
+
server.close();
|
|
35905
|
+
} catch {
|
|
35906
|
+
}
|
|
35907
|
+
reject(new Error(`fetchproxy: bind to ${opts.host}:${opts.port} timed out after ${bindTimeoutMs}ms (port may be in a bad state)`));
|
|
35908
|
+
}, bindTimeoutMs);
|
|
35909
|
+
if (typeof timer.unref === "function")
|
|
35910
|
+
timer.unref();
|
|
35911
|
+
}
|
|
35884
35912
|
server.listen(opts.port, opts.host);
|
|
35885
35913
|
});
|
|
35886
35914
|
}
|
|
@@ -35973,6 +36001,44 @@ var SessionState = class {
|
|
|
35973
36001
|
}
|
|
35974
36002
|
};
|
|
35975
36003
|
|
|
36004
|
+
// node_modules/@fetchproxy/server/dist/session-ready.js
|
|
36005
|
+
var SESSION_READY_TIMEOUT_MS = 3e4;
|
|
36006
|
+
var FetchproxySessionNotReadyError = class extends Error {
|
|
36007
|
+
reason;
|
|
36008
|
+
pairCode;
|
|
36009
|
+
mcpId;
|
|
36010
|
+
hint;
|
|
36011
|
+
constructor(info) {
|
|
36012
|
+
const pairing = info.pairCode !== null && info.pairCode !== "";
|
|
36013
|
+
const hint = pairing ? `Open the Transporter extension popup and approve pair code ${info.pairCode} for "${info.mcpId}", then retry.` : `The extension is connected but hasn't confirmed a session for "${info.mcpId}" \u2014 sign in to the target site in that browser (and approve the requested scope if it changed), then retry.`;
|
|
36014
|
+
super(`fetchproxy: ${pairing ? "pairing not yet approved" : "no confirmed browser session"} for "${info.mcpId}". ${hint}`);
|
|
36015
|
+
this.name = "FetchproxySessionNotReadyError";
|
|
36016
|
+
this.reason = pairing ? "pair-required" : "not-ready";
|
|
36017
|
+
this.pairCode = pairing ? info.pairCode : null;
|
|
36018
|
+
this.mcpId = info.mcpId;
|
|
36019
|
+
this.hint = hint;
|
|
36020
|
+
Object.setPrototypeOf(this, new.target.prototype);
|
|
36021
|
+
}
|
|
36022
|
+
};
|
|
36023
|
+
async function awaitSessionReady(ready, opts) {
|
|
36024
|
+
const ms = opts.timeoutMs ?? SESSION_READY_TIMEOUT_MS;
|
|
36025
|
+
if (ms <= 0)
|
|
36026
|
+
return ready;
|
|
36027
|
+
let timer;
|
|
36028
|
+
const timeout = new Promise((_, reject) => {
|
|
36029
|
+
timer = setTimeout(() => {
|
|
36030
|
+
reject(new FetchproxySessionNotReadyError({ mcpId: opts.mcpId, pairCode: opts.pendingPairCode() }));
|
|
36031
|
+
}, ms);
|
|
36032
|
+
timer.unref?.();
|
|
36033
|
+
});
|
|
36034
|
+
try {
|
|
36035
|
+
return await Promise.race([ready, timeout]);
|
|
36036
|
+
} finally {
|
|
36037
|
+
if (timer)
|
|
36038
|
+
clearTimeout(timer);
|
|
36039
|
+
}
|
|
36040
|
+
}
|
|
36041
|
+
|
|
35976
36042
|
// node_modules/@fetchproxy/server/dist/host.js
|
|
35977
36043
|
var PUBLIC_ORIGIN_RE = /^https?:\/\/(?!(127\.0\.0\.1|localhost)(:|$))/i;
|
|
35978
36044
|
var enc2 = new TextEncoder();
|
|
@@ -36060,6 +36126,29 @@ async function startHost(opts) {
|
|
|
36060
36126
|
return;
|
|
36061
36127
|
}
|
|
36062
36128
|
if (frame.type === "hello" && frame.role === "server") {
|
|
36129
|
+
const peerEdPub = fromB64(frame.identityEd25519Pub);
|
|
36130
|
+
const peerSigMsg = concatBytes(enc2.encode(frame.mcpId), fromB64(frame.sessionNonce));
|
|
36131
|
+
const peerSig = fromB64(frame.sessionSig);
|
|
36132
|
+
let peerSigOk = false;
|
|
36133
|
+
try {
|
|
36134
|
+
peerSigOk = await ed25519Verify(peerEdPub, peerSigMsg, peerSig);
|
|
36135
|
+
} catch {
|
|
36136
|
+
peerSigOk = false;
|
|
36137
|
+
}
|
|
36138
|
+
if (!peerSigOk) {
|
|
36139
|
+
console.warn("[fetchproxy] peer hello signature invalid \u2014 refusing registration (possible squatter)");
|
|
36140
|
+
ws.close(1008, "peer hello signature invalid");
|
|
36141
|
+
return;
|
|
36142
|
+
}
|
|
36143
|
+
const existing = peers.get(frame.mcpId);
|
|
36144
|
+
if (existing && existing.ws !== ws) {
|
|
36145
|
+
const existingEdPub = existing.helloFrame.identityEd25519Pub;
|
|
36146
|
+
if (existingEdPub !== frame.identityEd25519Pub) {
|
|
36147
|
+
console.warn("[fetchproxy] peer mcpId already mapped to a different identity \u2014 refusing (mcpId squatting)");
|
|
36148
|
+
ws.close(1008, "mcpId already registered to another identity");
|
|
36149
|
+
return;
|
|
36150
|
+
}
|
|
36151
|
+
}
|
|
36063
36152
|
identified = "peer";
|
|
36064
36153
|
peerMcpId = frame.mcpId;
|
|
36065
36154
|
peers.set(frame.mcpId, { ws, helloFrame: frame });
|
|
@@ -36152,8 +36241,10 @@ async function startHost(opts) {
|
|
|
36152
36241
|
resetSessionPromise();
|
|
36153
36242
|
disconnectListeners.forEach((cb) => cb());
|
|
36154
36243
|
}
|
|
36155
|
-
if (identified === "peer" && peerMcpId)
|
|
36156
|
-
peers.
|
|
36244
|
+
if (identified === "peer" && peerMcpId) {
|
|
36245
|
+
if (peers.get(peerMcpId)?.ws === ws)
|
|
36246
|
+
peers.delete(peerMcpId);
|
|
36247
|
+
}
|
|
36157
36248
|
});
|
|
36158
36249
|
});
|
|
36159
36250
|
return {
|
|
@@ -36169,7 +36260,10 @@ async function startHost(opts) {
|
|
|
36169
36260
|
});
|
|
36170
36261
|
}),
|
|
36171
36262
|
sendOwnInner: async (inner) => {
|
|
36172
|
-
const session = await ownSessionReady
|
|
36263
|
+
const session = await awaitSessionReady(ownSessionReady, {
|
|
36264
|
+
mcpId: opts.ownMcpId,
|
|
36265
|
+
pendingPairCode: () => ownPendingPairCode
|
|
36266
|
+
});
|
|
36173
36267
|
if (!extensionWs)
|
|
36174
36268
|
throw new Error("host: no extension connected");
|
|
36175
36269
|
const sealed = await sealInnerFrame(session.sessionKey, opts.ownMcpId, session.nextOutboundSeq(), inner);
|
|
@@ -36274,7 +36368,10 @@ async function startPeer(opts) {
|
|
|
36274
36368
|
ws,
|
|
36275
36369
|
session: sessionPromise,
|
|
36276
36370
|
sendInner: async (inner) => {
|
|
36277
|
-
await sessionPromise
|
|
36371
|
+
await awaitSessionReady(sessionPromise, {
|
|
36372
|
+
mcpId: opts.mcpId,
|
|
36373
|
+
pendingPairCode: () => pendingPairCode
|
|
36374
|
+
});
|
|
36278
36375
|
const s = session;
|
|
36279
36376
|
const sealed = await sealInnerFrame(s.sessionKey, opts.mcpId, s.nextOutboundSeq(), inner);
|
|
36280
36377
|
ws.send(JSON.stringify(sealed));
|
|
@@ -36940,6 +37037,35 @@ var FetchproxyServer = class {
|
|
|
36940
37037
|
this.keepAliveTimer = null;
|
|
36941
37038
|
}
|
|
36942
37039
|
}
|
|
37040
|
+
/**
|
|
37041
|
+
* Send an inner request frame via whichever bridge handle is active. If the
|
|
37042
|
+
* send throws (e.g. `FetchproxySessionNotReadyError` — the session never
|
|
37043
|
+
* confirmed), the frame never reached the bridge, so no reply will arrive:
|
|
37044
|
+
* drop the just-registered pending resolver for this id (it lives in exactly
|
|
37045
|
+
* one of the op maps — request ids are unique) so it doesn't leak until the
|
|
37046
|
+
* server closes, then rethrow.
|
|
37047
|
+
*/
|
|
37048
|
+
async sendInnerFrame(inner) {
|
|
37049
|
+
try {
|
|
37050
|
+
if (this.hostHandle) {
|
|
37051
|
+
await this.hostHandle.sendOwnInner(inner);
|
|
37052
|
+
} else if (this.peerHandle) {
|
|
37053
|
+
await this.peerHandle.sendInner(inner);
|
|
37054
|
+
}
|
|
37055
|
+
} catch (err) {
|
|
37056
|
+
if ("id" in inner && typeof inner.id === "number") {
|
|
37057
|
+
const { id } = inner;
|
|
37058
|
+
this.pending.delete(id);
|
|
37059
|
+
this.pendingReadCookies.delete(id);
|
|
37060
|
+
this.pendingStorage.delete(id);
|
|
37061
|
+
this.pendingCapture.delete(id);
|
|
37062
|
+
this.pendingRedirect.delete(id);
|
|
37063
|
+
this.pendingDownload.delete(id);
|
|
37064
|
+
this.pendingIdb.delete(id);
|
|
37065
|
+
}
|
|
37066
|
+
throw err;
|
|
37067
|
+
}
|
|
37068
|
+
}
|
|
36943
37069
|
/**
|
|
36944
37070
|
* Single bridge round-trip, wrapped by `fetchTimeoutMs` when set.
|
|
36945
37071
|
* On timeout returns the `{ok:false, kind:'timeout'}` envelope —
|
|
@@ -36951,11 +37077,7 @@ var FetchproxyServer = class {
|
|
|
36951
37077
|
const pending = new Promise((resolve) => {
|
|
36952
37078
|
this.pending.set(id, resolve);
|
|
36953
37079
|
});
|
|
36954
|
-
|
|
36955
|
-
await this.hostHandle.sendOwnInner(inner);
|
|
36956
|
-
} else if (this.peerHandle) {
|
|
36957
|
-
await this.peerHandle.sendInner(inner);
|
|
36958
|
-
}
|
|
37080
|
+
await this.sendInnerFrame(inner);
|
|
36959
37081
|
const timeoutMs = this.opts.fetchTimeoutMs;
|
|
36960
37082
|
if (timeoutMs === void 0 || timeoutMs <= 0)
|
|
36961
37083
|
return pending;
|
|
@@ -36984,6 +37106,51 @@ var FetchproxyServer = class {
|
|
|
36984
37106
|
clearTimeout(timer);
|
|
36985
37107
|
}
|
|
36986
37108
|
}
|
|
37109
|
+
/**
|
|
37110
|
+
* FP-B2: bound a non-`fetch` verb's reply wait by `fetchTimeoutMs`.
|
|
37111
|
+
*
|
|
37112
|
+
* Before this, only `fetch()` raced its `pending` reply against a timer
|
|
37113
|
+
* (`_fetchOnceWithTimeout`); `readCookies`, the storage reads,
|
|
37114
|
+
* `capture_request_header`, `capture_redirect`, `download`, and
|
|
37115
|
+
* `read_indexed_db` awaited their `pending` promise with no race, so a
|
|
37116
|
+
* wedged extension hung the tool call indefinitely.
|
|
37117
|
+
*
|
|
37118
|
+
* `pending` is the already-registered reply promise. `pendingMap`/`id`
|
|
37119
|
+
* point at the op-specific map entry so we can drop it on expiry exactly
|
|
37120
|
+
* as `_fetchOnceWithTimeout` does — otherwise a late bridge reply would
|
|
37121
|
+
* resolve into a stale resolver / leak. On timeout we reject with a
|
|
37122
|
+
* `FetchproxyTimeoutError` (the same throwable the convenience methods
|
|
37123
|
+
* already surface for fetch timeouts). `0`/unset opts out (unbounded),
|
|
37124
|
+
* matching the fetch path.
|
|
37125
|
+
*/
|
|
37126
|
+
async _withVerbTimeout(pending, pendingMap, id, url2) {
|
|
37127
|
+
const timeoutMs = this.opts.fetchTimeoutMs;
|
|
37128
|
+
if (timeoutMs === void 0 || timeoutMs <= 0)
|
|
37129
|
+
return pending;
|
|
37130
|
+
let timer;
|
|
37131
|
+
const start = Date.now();
|
|
37132
|
+
try {
|
|
37133
|
+
return await Promise.race([
|
|
37134
|
+
pending,
|
|
37135
|
+
new Promise((_resolve, reject) => {
|
|
37136
|
+
timer = setTimeout(() => {
|
|
37137
|
+
pendingMap.delete(id);
|
|
37138
|
+
reject(new FetchproxyTimeoutError({
|
|
37139
|
+
url: url2,
|
|
37140
|
+
timeoutMs,
|
|
37141
|
+
role: this.role,
|
|
37142
|
+
port: this.opts.port,
|
|
37143
|
+
elapsedMs: Date.now() - start,
|
|
37144
|
+
retryAttempted: false
|
|
37145
|
+
}));
|
|
37146
|
+
}, timeoutMs);
|
|
37147
|
+
})
|
|
37148
|
+
]);
|
|
37149
|
+
} finally {
|
|
37150
|
+
if (timer)
|
|
37151
|
+
clearTimeout(timer);
|
|
37152
|
+
}
|
|
37153
|
+
}
|
|
36987
37154
|
/**
|
|
36988
37155
|
* Map an `ok:false` fetch result to its typed throwable. Centralizes
|
|
36989
37156
|
* the kind-to-error-class switch so `request()` and (via the same
|
|
@@ -37274,12 +37441,8 @@ var FetchproxyServer = class {
|
|
|
37274
37441
|
const pending = new Promise((resolve) => {
|
|
37275
37442
|
this.pendingReadCookies.set(id, resolve);
|
|
37276
37443
|
});
|
|
37277
|
-
|
|
37278
|
-
|
|
37279
|
-
} else if (this.peerHandle) {
|
|
37280
|
-
await this.peerHandle.sendInner(inner);
|
|
37281
|
-
}
|
|
37282
|
-
const result = await pending;
|
|
37444
|
+
await this.sendInnerFrame(inner);
|
|
37445
|
+
const result = await this._withVerbTimeout(pending, this.pendingReadCookies, id, `https://${host}`);
|
|
37283
37446
|
if (!result.ok) {
|
|
37284
37447
|
throw new FetchproxyProtocolError(result.error);
|
|
37285
37448
|
}
|
|
@@ -37345,12 +37508,8 @@ var FetchproxyServer = class {
|
|
|
37345
37508
|
const pending = new Promise((resolve, reject) => {
|
|
37346
37509
|
this.pendingStorage.set(id, { resolve, reject });
|
|
37347
37510
|
});
|
|
37348
|
-
|
|
37349
|
-
|
|
37350
|
-
} else if (this.peerHandle) {
|
|
37351
|
-
await this.peerHandle.sendInner(inner);
|
|
37352
|
-
}
|
|
37353
|
-
return pending;
|
|
37511
|
+
await this.sendInnerFrame(inner);
|
|
37512
|
+
return this._withVerbTimeout(pending, this.pendingStorage, id, `https://${host}`);
|
|
37354
37513
|
}
|
|
37355
37514
|
/**
|
|
37356
37515
|
* 0.3.0+: snapshot the next outgoing request's named header. Single-
|
|
@@ -37454,12 +37613,8 @@ var FetchproxyServer = class {
|
|
|
37454
37613
|
const pending = new Promise((resolve, reject) => {
|
|
37455
37614
|
this.pendingCapture.set(id, { resolve, reject });
|
|
37456
37615
|
});
|
|
37457
|
-
|
|
37458
|
-
|
|
37459
|
-
} else if (this.peerHandle) {
|
|
37460
|
-
await this.peerHandle.sendInner(inner);
|
|
37461
|
-
}
|
|
37462
|
-
return pending;
|
|
37616
|
+
await this.sendInnerFrame(inner);
|
|
37617
|
+
return this._withVerbTimeout(pending, this.pendingCapture, id, `https://${opts.host}${opts.path ?? "/*"}`);
|
|
37463
37618
|
}
|
|
37464
37619
|
/**
|
|
37465
37620
|
* Snapshot the redirect target URL of the next request the browser
|
|
@@ -37543,12 +37698,8 @@ var FetchproxyServer = class {
|
|
|
37543
37698
|
const pending = new Promise((resolve, reject) => {
|
|
37544
37699
|
this.pendingRedirect.set(id, { resolve, reject });
|
|
37545
37700
|
});
|
|
37546
|
-
|
|
37547
|
-
|
|
37548
|
-
} else if (this.peerHandle) {
|
|
37549
|
-
await this.peerHandle.sendInner(inner);
|
|
37550
|
-
}
|
|
37551
|
-
return pending;
|
|
37701
|
+
await this.sendInnerFrame(inner);
|
|
37702
|
+
return this._withVerbTimeout(pending, this.pendingRedirect, id, `https://${opts.host}${opts.path ?? "/*"}`);
|
|
37552
37703
|
}
|
|
37553
37704
|
/**
|
|
37554
37705
|
* Download `url` through the BROWSER's own network stack via
|
|
@@ -37629,12 +37780,8 @@ var FetchproxyServer = class {
|
|
|
37629
37780
|
const pending = new Promise((resolve, reject) => {
|
|
37630
37781
|
this.pendingDownload.set(id, { resolve, reject });
|
|
37631
37782
|
});
|
|
37632
|
-
|
|
37633
|
-
|
|
37634
|
-
} else if (this.peerHandle) {
|
|
37635
|
-
await this.peerHandle.sendInner(inner);
|
|
37636
|
-
}
|
|
37637
|
-
return pending;
|
|
37783
|
+
await this.sendInnerFrame(inner);
|
|
37784
|
+
return this._withVerbTimeout(pending, this.pendingDownload, id, opts.url);
|
|
37638
37785
|
}
|
|
37639
37786
|
/**
|
|
37640
37787
|
* 0.4.0+: read declared IndexedDB keys from the user's signed-in
|
|
@@ -37681,12 +37828,8 @@ var FetchproxyServer = class {
|
|
|
37681
37828
|
const pending = new Promise((resolve, reject) => {
|
|
37682
37829
|
this.pendingIdb.set(id, { resolve, reject });
|
|
37683
37830
|
});
|
|
37684
|
-
|
|
37685
|
-
|
|
37686
|
-
} else if (this.peerHandle) {
|
|
37687
|
-
await this.peerHandle.sendInner(inner);
|
|
37688
|
-
}
|
|
37689
|
-
return pending;
|
|
37831
|
+
await this.sendInnerFrame(inner);
|
|
37832
|
+
return this._withVerbTimeout(pending, this.pendingIdb, id, origin);
|
|
37690
37833
|
}
|
|
37691
37834
|
assertScopeSubset(requested, declared, label) {
|
|
37692
37835
|
const undeclared = undeclaredKeys(requested, declared);
|
|
@@ -38154,7 +38297,7 @@ function loadAccount(env = process.env) {
|
|
|
38154
38297
|
// package.json
|
|
38155
38298
|
var package_default = {
|
|
38156
38299
|
name: "signupgenius-mcp",
|
|
38157
|
-
version: "1.1.
|
|
38300
|
+
version: "1.1.5",
|
|
38158
38301
|
mcpName: "io.github.chrischall/signupgenius-mcp",
|
|
38159
38302
|
description: "SignUpGenius MCP server \u2014 read sign-ups, reports, and groups; add group members.",
|
|
38160
38303
|
author: "Claude Code (AI) <https://www.anthropic.com/claude>",
|
|
@@ -38191,7 +38334,7 @@ var package_default = {
|
|
|
38191
38334
|
"test:watch": "vitest"
|
|
38192
38335
|
},
|
|
38193
38336
|
dependencies: {
|
|
38194
|
-
"@chrischall/mcp-utils": "^0.
|
|
38337
|
+
"@chrischall/mcp-utils": "^0.10.4",
|
|
38195
38338
|
"@fetchproxy/bootstrap": "^1.0.0",
|
|
38196
38339
|
"@fetchproxy/server": "^1.0.0",
|
|
38197
38340
|
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
@@ -38199,7 +38342,7 @@ var package_default = {
|
|
|
38199
38342
|
zod: "^4.4.3"
|
|
38200
38343
|
},
|
|
38201
38344
|
devDependencies: {
|
|
38202
|
-
"@types/node": "^
|
|
38345
|
+
"@types/node": "^26.0.0",
|
|
38203
38346
|
"@vitest/coverage-v8": "^4.1.7",
|
|
38204
38347
|
esbuild: "^0.28.0",
|
|
38205
38348
|
typescript: "^6.0.3",
|
|
@@ -38296,7 +38439,7 @@ var CookieSessionManager = class {
|
|
|
38296
38439
|
isPermanentErrorFn;
|
|
38297
38440
|
constructor(opts) {
|
|
38298
38441
|
this.loginFn = opts.login;
|
|
38299
|
-
this.isExpiredFn = opts.isExpired;
|
|
38442
|
+
this.isExpiredFn = opts.isExpired ?? (() => false);
|
|
38300
38443
|
this.isPermanentErrorFn = opts.isPermanentError ?? (() => false);
|
|
38301
38444
|
}
|
|
38302
38445
|
/** The current session, or `undefined` before the first successful login. */
|
|
@@ -38366,6 +38509,10 @@ var CookieSessionManager = class {
|
|
|
38366
38509
|
* rather than looping. If the re-login itself fails, the original
|
|
38367
38510
|
* (expired-looking) response is returned so the caller can surface a clean
|
|
38368
38511
|
* sign-in error rather than the login failure.
|
|
38512
|
+
*
|
|
38513
|
+
* `call` resolves to `R` (the generic response type, default {@link Response});
|
|
38514
|
+
* the manager passes it untouched to {@link CookieSessionManagerOptions.isExpired}
|
|
38515
|
+
* and returns it untouched, so a custom transport type flows through cleanly.
|
|
38369
38516
|
*/
|
|
38370
38517
|
async withSession(call) {
|
|
38371
38518
|
const session = await this.ensure();
|
|
@@ -39195,7 +39342,7 @@ bannerLines.push(
|
|
|
39195
39342
|
);
|
|
39196
39343
|
await runMcp({
|
|
39197
39344
|
name: "signupgenius",
|
|
39198
|
-
version: "1.1.
|
|
39345
|
+
version: "1.1.5",
|
|
39199
39346
|
// x-release-please-version
|
|
39200
39347
|
banner: bannerLines.join("\n"),
|
|
39201
39348
|
deps: client,
|
package/dist/index.js
CHANGED
|
@@ -47,7 +47,7 @@ const bannerLines = account
|
|
|
47
47
|
bannerLines.push('[signupgenius-mcp] Developed and maintained by AI (Claude). Use at your own discretion.');
|
|
48
48
|
await runMcp({
|
|
49
49
|
name: 'signupgenius',
|
|
50
|
-
version: '1.1.
|
|
50
|
+
version: '1.1.5', // x-release-please-version
|
|
51
51
|
banner: bannerLines.join('\n'),
|
|
52
52
|
deps: client,
|
|
53
53
|
tools: [
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "signupgenius-mcp",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.5",
|
|
4
4
|
"mcpName": "io.github.chrischall/signupgenius-mcp",
|
|
5
5
|
"description": "SignUpGenius MCP server — read sign-ups, reports, and groups; add group members.",
|
|
6
6
|
"author": "Claude Code (AI) <https://www.anthropic.com/claude>",
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
"test:watch": "vitest"
|
|
38
38
|
},
|
|
39
39
|
"dependencies": {
|
|
40
|
-
"@chrischall/mcp-utils": "^0.
|
|
40
|
+
"@chrischall/mcp-utils": "^0.10.4",
|
|
41
41
|
"@fetchproxy/bootstrap": "^1.0.0",
|
|
42
42
|
"@fetchproxy/server": "^1.0.0",
|
|
43
43
|
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
@@ -45,7 +45,7 @@
|
|
|
45
45
|
"zod": "^4.4.3"
|
|
46
46
|
},
|
|
47
47
|
"devDependencies": {
|
|
48
|
-
"@types/node": "^
|
|
48
|
+
"@types/node": "^26.0.0",
|
|
49
49
|
"@vitest/coverage-v8": "^4.1.7",
|
|
50
50
|
"esbuild": "^0.28.0",
|
|
51
51
|
"typescript": "^6.0.3",
|
package/server.json
CHANGED
|
@@ -6,12 +6,12 @@
|
|
|
6
6
|
"url": "https://github.com/chrischall/signupgenius-mcp",
|
|
7
7
|
"source": "github"
|
|
8
8
|
},
|
|
9
|
-
"version": "1.1.
|
|
9
|
+
"version": "1.1.5",
|
|
10
10
|
"packages": [
|
|
11
11
|
{
|
|
12
12
|
"registryType": "npm",
|
|
13
13
|
"identifier": "signupgenius-mcp",
|
|
14
|
-
"version": "1.1.
|
|
14
|
+
"version": "1.1.5",
|
|
15
15
|
"transport": {
|
|
16
16
|
"type": "stdio"
|
|
17
17
|
},
|