gmail-workspace-mcp-server 0.4.7 → 0.4.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/node_modules/@pulsemcp/mcp-elicitation/build/config.d.ts +8 -6
- package/node_modules/@pulsemcp/mcp-elicitation/build/config.js +11 -6
- package/node_modules/@pulsemcp/mcp-elicitation/build/elicitation.d.ts +6 -1
- package/node_modules/@pulsemcp/mcp-elicitation/build/elicitation.js +30 -14
- package/node_modules/@pulsemcp/mcp-elicitation/build/types.d.ts +10 -0
- package/node_modules/@pulsemcp/mcp-elicitation/package.json +1 -1
- package/package.json +1 -1
|
@@ -3,11 +3,13 @@ import type { ElicitationConfig } from './types.js';
|
|
|
3
3
|
* Reads elicitation configuration from environment variables.
|
|
4
4
|
*
|
|
5
5
|
* Environment variables:
|
|
6
|
-
* ELICITATION_ENABLED
|
|
7
|
-
* ELICITATION_REQUEST_URL
|
|
8
|
-
* ELICITATION_POLL_URL
|
|
9
|
-
* ELICITATION_TTL_MS
|
|
10
|
-
* ELICITATION_POLL_INTERVAL_MS
|
|
11
|
-
* ELICITATION_SESSION_ID
|
|
6
|
+
* ELICITATION_ENABLED - "true" (default) or "false"
|
|
7
|
+
* ELICITATION_REQUEST_URL - POST endpoint for HTTP fallback
|
|
8
|
+
* ELICITATION_POLL_URL - GET endpoint for HTTP fallback polling
|
|
9
|
+
* ELICITATION_TTL_MS - Request TTL in milliseconds (default: 300000)
|
|
10
|
+
* ELICITATION_POLL_INTERVAL_MS - Poll interval in milliseconds (default: 5000, min: 1000)
|
|
11
|
+
* ELICITATION_SESSION_ID - Session identifier for HTTP fallback `_meta`
|
|
12
|
+
* ELICITATION_PREFER_HTTP_FALLBACK - "true" forces HTTP fallback over native elicitation
|
|
13
|
+
* when both are available. Default: "false".
|
|
12
14
|
*/
|
|
13
15
|
export declare function readElicitationConfig(env?: Record<string, string | undefined>): ElicitationConfig;
|
|
@@ -14,16 +14,20 @@ function parsePositiveInt(value, defaultValue) {
|
|
|
14
14
|
* Reads elicitation configuration from environment variables.
|
|
15
15
|
*
|
|
16
16
|
* Environment variables:
|
|
17
|
-
* ELICITATION_ENABLED
|
|
18
|
-
* ELICITATION_REQUEST_URL
|
|
19
|
-
* ELICITATION_POLL_URL
|
|
20
|
-
* ELICITATION_TTL_MS
|
|
21
|
-
* ELICITATION_POLL_INTERVAL_MS
|
|
22
|
-
* ELICITATION_SESSION_ID
|
|
17
|
+
* ELICITATION_ENABLED - "true" (default) or "false"
|
|
18
|
+
* ELICITATION_REQUEST_URL - POST endpoint for HTTP fallback
|
|
19
|
+
* ELICITATION_POLL_URL - GET endpoint for HTTP fallback polling
|
|
20
|
+
* ELICITATION_TTL_MS - Request TTL in milliseconds (default: 300000)
|
|
21
|
+
* ELICITATION_POLL_INTERVAL_MS - Poll interval in milliseconds (default: 5000, min: 1000)
|
|
22
|
+
* ELICITATION_SESSION_ID - Session identifier for HTTP fallback `_meta`
|
|
23
|
+
* ELICITATION_PREFER_HTTP_FALLBACK - "true" forces HTTP fallback over native elicitation
|
|
24
|
+
* when both are available. Default: "false".
|
|
23
25
|
*/
|
|
24
26
|
export function readElicitationConfig(env = process.env) {
|
|
25
27
|
const enabledRaw = env.ELICITATION_ENABLED;
|
|
26
28
|
const enabled = enabledRaw === undefined ? true : enabledRaw.toLowerCase() !== 'false';
|
|
29
|
+
const preferHttpFallbackRaw = env.ELICITATION_PREFER_HTTP_FALLBACK;
|
|
30
|
+
const preferHttpFallback = preferHttpFallbackRaw !== undefined && preferHttpFallbackRaw.toLowerCase() === 'true';
|
|
27
31
|
const pollIntervalMs = Math.max(MIN_POLL_INTERVAL_MS, parsePositiveInt(env.ELICITATION_POLL_INTERVAL_MS, DEFAULT_POLL_INTERVAL_MS));
|
|
28
32
|
return {
|
|
29
33
|
enabled,
|
|
@@ -32,5 +36,6 @@ export function readElicitationConfig(env = process.env) {
|
|
|
32
36
|
ttlMs: parsePositiveInt(env.ELICITATION_TTL_MS, DEFAULT_TTL_MS),
|
|
33
37
|
pollIntervalMs,
|
|
34
38
|
sessionId: env.ELICITATION_SESSION_ID,
|
|
39
|
+
preferHttpFallback,
|
|
35
40
|
};
|
|
36
41
|
}
|
|
@@ -2,12 +2,17 @@ import type { ElicitationConfig, ElicitationRequestedSchema, ElicitationResult,
|
|
|
2
2
|
/**
|
|
3
3
|
* Requests user confirmation through the best available mechanism.
|
|
4
4
|
*
|
|
5
|
-
* Decision tree:
|
|
5
|
+
* Decision tree (default):
|
|
6
6
|
* 1. If elicitation is disabled (`ELICITATION_ENABLED=false`), returns `accept` immediately.
|
|
7
7
|
* 2. If the client supports native elicitation, uses `server.elicitInput()`.
|
|
8
8
|
* 3. If HTTP fallback URLs are configured, posts to the external endpoint and polls.
|
|
9
9
|
* 4. Otherwise, throws an error indicating no elicitation mechanism is available.
|
|
10
10
|
*
|
|
11
|
+
* When `cfg.preferHttpFallback` is true (set via `ELICITATION_PREFER_HTTP_FALLBACK=true`)
|
|
12
|
+
* AND both fallback URLs are configured, tier 3 runs before tier 2. This is intended for
|
|
13
|
+
* headless agent runtimes that falsely advertise elicitation capability but cannot actually
|
|
14
|
+
* surface the prompt to a user.
|
|
15
|
+
*
|
|
11
16
|
* @param options - Configuration for the confirmation request.
|
|
12
17
|
* @param config - Elicitation config (defaults to reading from env vars).
|
|
13
18
|
* @returns The user's response.
|
|
@@ -98,15 +98,37 @@ async function pollElicitationStatus(config, requestId, expiresAt) {
|
|
|
98
98
|
}
|
|
99
99
|
return { action: 'expired' };
|
|
100
100
|
}
|
|
101
|
+
/**
|
|
102
|
+
* Runs the HTTP fallback flow: POST a request, then poll until resolved or expired.
|
|
103
|
+
*/
|
|
104
|
+
async function httpFallbackElicit(cfg, options) {
|
|
105
|
+
const clientRequestId = randomUUID();
|
|
106
|
+
const expiresAt = Date.now() + cfg.ttlMs;
|
|
107
|
+
const meta = {
|
|
108
|
+
'com.pulsemcp/request-id': clientRequestId,
|
|
109
|
+
'com.pulsemcp/expires-at': new Date(expiresAt).toISOString(),
|
|
110
|
+
...(cfg.sessionId && { 'com.pulsemcp/session-id': cfg.sessionId }),
|
|
111
|
+
...options.meta,
|
|
112
|
+
};
|
|
113
|
+
const postResponse = await postElicitationRequest(cfg, options.message, options.requestedSchema, meta);
|
|
114
|
+
// Use the server-provided requestId if available, otherwise fall back to the client-generated one
|
|
115
|
+
const requestId = postResponse.requestId || clientRequestId;
|
|
116
|
+
return pollElicitationStatus(cfg, requestId, expiresAt);
|
|
117
|
+
}
|
|
101
118
|
/**
|
|
102
119
|
* Requests user confirmation through the best available mechanism.
|
|
103
120
|
*
|
|
104
|
-
* Decision tree:
|
|
121
|
+
* Decision tree (default):
|
|
105
122
|
* 1. If elicitation is disabled (`ELICITATION_ENABLED=false`), returns `accept` immediately.
|
|
106
123
|
* 2. If the client supports native elicitation, uses `server.elicitInput()`.
|
|
107
124
|
* 3. If HTTP fallback URLs are configured, posts to the external endpoint and polls.
|
|
108
125
|
* 4. Otherwise, throws an error indicating no elicitation mechanism is available.
|
|
109
126
|
*
|
|
127
|
+
* When `cfg.preferHttpFallback` is true (set via `ELICITATION_PREFER_HTTP_FALLBACK=true`)
|
|
128
|
+
* AND both fallback URLs are configured, tier 3 runs before tier 2. This is intended for
|
|
129
|
+
* headless agent runtimes that falsely advertise elicitation capability but cannot actually
|
|
130
|
+
* surface the prompt to a user.
|
|
131
|
+
*
|
|
110
132
|
* @param options - Configuration for the confirmation request.
|
|
111
133
|
* @param config - Elicitation config (defaults to reading from env vars).
|
|
112
134
|
* @returns The user's response.
|
|
@@ -117,24 +139,18 @@ export async function requestConfirmation(options, config) {
|
|
|
117
139
|
if (!cfg.enabled) {
|
|
118
140
|
return { action: 'accept' };
|
|
119
141
|
}
|
|
142
|
+
const httpFallbackAvailable = Boolean(cfg.requestUrl && cfg.pollUrl);
|
|
143
|
+
// Opt-in: prefer HTTP fallback over native elicitation when both are available.
|
|
144
|
+
if (cfg.preferHttpFallback && httpFallbackAvailable) {
|
|
145
|
+
return httpFallbackElicit(cfg, options);
|
|
146
|
+
}
|
|
120
147
|
// Tier 2: Native elicitation
|
|
121
148
|
if (clientSupportsElicitation(options.server)) {
|
|
122
149
|
return nativeElicit(options.server, options.message, options.requestedSchema);
|
|
123
150
|
}
|
|
124
151
|
// Tier 3: HTTP fallback
|
|
125
|
-
if (
|
|
126
|
-
|
|
127
|
-
const expiresAt = Date.now() + cfg.ttlMs;
|
|
128
|
-
const meta = {
|
|
129
|
-
'com.pulsemcp/request-id': clientRequestId,
|
|
130
|
-
'com.pulsemcp/expires-at': new Date(expiresAt).toISOString(),
|
|
131
|
-
...(cfg.sessionId && { 'com.pulsemcp/session-id': cfg.sessionId }),
|
|
132
|
-
...options.meta,
|
|
133
|
-
};
|
|
134
|
-
const postResponse = await postElicitationRequest(cfg, options.message, options.requestedSchema, meta);
|
|
135
|
-
// Use the server-provided requestId if available, otherwise fall back to the client-generated one
|
|
136
|
-
const requestId = postResponse.requestId || clientRequestId;
|
|
137
|
-
return pollElicitationStatus(cfg, requestId, expiresAt);
|
|
152
|
+
if (httpFallbackAvailable) {
|
|
153
|
+
return httpFallbackElicit(cfg, options);
|
|
138
154
|
}
|
|
139
155
|
// Tier 4: No mechanism available
|
|
140
156
|
throw new Error('Elicitation is enabled but no mechanism is available. ' +
|
|
@@ -64,6 +64,16 @@ export interface ElicitationConfig {
|
|
|
64
64
|
pollIntervalMs: number;
|
|
65
65
|
/** Session identifier included as `com.pulsemcp/session-id` in `_meta` of HTTP fallback requests. */
|
|
66
66
|
sessionId?: string;
|
|
67
|
+
/**
|
|
68
|
+
* When true, prefer HTTP fallback (Tier 3) over native elicitation (Tier 2)
|
|
69
|
+
* when both are available. Default: false.
|
|
70
|
+
*
|
|
71
|
+
* Useful for headless agent runtimes (e.g., Claude Code under Agent Orchestrator)
|
|
72
|
+
* that advertise the `elicitation` client capability but have no real interactive
|
|
73
|
+
* user — native `elicitInput()` calls auto-cancel without ever surfacing a prompt.
|
|
74
|
+
* Forcing the HTTP fallback routes the request to an external approval UI instead.
|
|
75
|
+
*/
|
|
76
|
+
preferHttpFallback?: boolean;
|
|
67
77
|
}
|
|
68
78
|
/**
|
|
69
79
|
* The result of an elicitation request.
|