mcp-google-multi 6.0.0-alpha.31 → 6.0.0-alpha.32
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.
|
@@ -27,6 +27,16 @@ export type AddValidation = {
|
|
|
27
27
|
/** Validate the collected form against the alias rules, dup check, and the
|
|
28
28
|
* bundle catalog. Pure (no I/O) for unit testing. */
|
|
29
29
|
export declare function validateAddForm(input: Partial<AddForm>, existingAliases: string[]): AddValidation;
|
|
30
|
+
/** URL-mode elicitation params. `elicitationId` is REQUIRED by the spec
|
|
31
|
+
* schema; omitting it made every url-mode request fail client-side
|
|
32
|
+
* validation, so the branch silently never worked. Pure, so the shape is
|
|
33
|
+
* testable against the SDK's own schema without a live client. */
|
|
34
|
+
export declare function urlElicitationParams(alias: string, url: string, elicitationId: string): {
|
|
35
|
+
mode: 'url';
|
|
36
|
+
elicitationId: string;
|
|
37
|
+
message: string;
|
|
38
|
+
url: string;
|
|
39
|
+
};
|
|
30
40
|
/** Map direct tool arguments onto the elicitation form shape: the argument-
|
|
31
41
|
* mode fallback for clients without form elicitation. All bundle picks travel
|
|
32
42
|
* through otherBundles, which validateAddForm resolves and validates. Pure. */
|
|
@@ -71,6 +71,18 @@ export function validateAddForm(input, existingAliases) {
|
|
|
71
71
|
}
|
|
72
72
|
return { ok: true, alias, email, bundles, admin: input.admin === true };
|
|
73
73
|
}
|
|
74
|
+
/** URL-mode elicitation params. `elicitationId` is REQUIRED by the spec
|
|
75
|
+
* schema; omitting it made every url-mode request fail client-side
|
|
76
|
+
* validation, so the branch silently never worked. Pure, so the shape is
|
|
77
|
+
* testable against the SDK's own schema without a live client. */
|
|
78
|
+
export function urlElicitationParams(alias, url, elicitationId) {
|
|
79
|
+
return {
|
|
80
|
+
mode: 'url',
|
|
81
|
+
elicitationId,
|
|
82
|
+
message: `Authorize the "${alias}" Google account in your browser.`,
|
|
83
|
+
url,
|
|
84
|
+
};
|
|
85
|
+
}
|
|
74
86
|
/** Map direct tool arguments onto the elicitation form shape: the argument-
|
|
75
87
|
* mode fallback for clients without form elicitation. All bundle picks travel
|
|
76
88
|
* through otherBundles, which validateAddForm resolves and validates. Pure. */
|
|
@@ -125,11 +137,16 @@ async function runConsent(server, alias) {
|
|
|
125
137
|
const scopes = resolveScopesForAccount(alias);
|
|
126
138
|
const url = client.generateAuthUrl({ access_type: 'offline', prompt: 'consent', scope: scopes, login_hint: cfg.email, state: expectedState });
|
|
127
139
|
const consent = loop.finish(client, expectedState);
|
|
140
|
+
// Capability probe: the spec advertises each elicitation mode as a PRESENT
|
|
141
|
+
// object, not a boolean, so test presence rather than truthiness.
|
|
128
142
|
const caps = server.server.getClientCapabilities?.();
|
|
129
143
|
let opened = false;
|
|
130
|
-
if (caps?.elicitation?.url) {
|
|
144
|
+
if (caps?.elicitation?.url !== undefined) {
|
|
131
145
|
try {
|
|
132
|
-
|
|
146
|
+
// elicitationId is REQUIRED by the spec schema; omitting it made every
|
|
147
|
+
// url-mode request fail client-side validation, so this branch always
|
|
148
|
+
// fell through to the server-side browser open.
|
|
149
|
+
const r = await server.server.elicitInput(urlElicitationParams(alias, url, randomBytes(16).toString('hex')));
|
|
133
150
|
if (r.action !== 'accept') {
|
|
134
151
|
loop.close();
|
|
135
152
|
return { ok: false, text: 'confirmation_declined: consent was cancelled; the account row was kept but no token was stored (doctor will show it as "missing").' };
|
|
@@ -148,7 +165,9 @@ async function runConsent(server, alias) {
|
|
|
148
165
|
tokens = await consent;
|
|
149
166
|
}
|
|
150
167
|
catch (e) {
|
|
151
|
-
|
|
168
|
+
// Always surface the URL: the browser hand-off can succeed and consent
|
|
169
|
+
// still fail (declined, timed out), and the URL is the only recovery.
|
|
170
|
+
return { ok: false, text: `${e.message}\nOpen this URL to authorize:\n${url}` };
|
|
152
171
|
}
|
|
153
172
|
writeToken(alias, tokens);
|
|
154
173
|
return { ok: true, missing: scopeGrantDiff(scopes, typeof tokens.scope === 'string' ? tokens.scope : undefined) };
|
|
@@ -196,15 +215,16 @@ export function registerAccountWizardTools(registry, server) {
|
|
|
196
215
|
input = argsToAddForm(a);
|
|
197
216
|
}
|
|
198
217
|
else {
|
|
218
|
+
// Modes are advertised as PRESENT objects, not booleans.
|
|
199
219
|
const caps = server.server.getClientCapabilities?.();
|
|
200
|
-
if (
|
|
220
|
+
if (caps?.elicitation?.form === undefined) {
|
|
201
221
|
return textResult('E_NO_FORM_ELICITATION: this client does not support the interactive form. Call account_add again with arguments instead, e.g. {"alias": "work", "email": "you@example.com"} (optional: "bundles" as a comma-separated list, "allBundles": true, "admin": true).', true);
|
|
202
222
|
}
|
|
203
223
|
const form = await server.server.elicitInput({ message: 'Add a Google account', requestedSchema: addFormSchema() });
|
|
204
224
|
if (form.action !== 'accept') {
|
|
205
225
|
return textResult('confirmation_declined: no account was added.');
|
|
206
226
|
}
|
|
207
|
-
input = form.content ?? {};
|
|
227
|
+
input = (form.content ?? {});
|
|
208
228
|
}
|
|
209
229
|
const validated = validateAddForm(input, getAccountSet().aliases);
|
|
210
230
|
if (!validated.ok)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mcp-google-multi",
|
|
3
|
-
"version": "6.0.0-alpha.
|
|
3
|
+
"version": "6.0.0-alpha.32",
|
|
4
4
|
"mcpName": "io.github.bakissation/mcp-google-multi",
|
|
5
5
|
"description": "Local MCP server for Google Workspace (Gmail, Drive, Calendar, Sheets, Docs, Contacts, Tasks, Meet, Search Console, +Forms/Chat/Admin) across multiple accounts — OAuth-only, encrypted token storage, deny-by-default writes.",
|
|
6
6
|
"type": "module",
|