@kya-os/mcp-i-cloudflare 1.4.1-canary.1 → 1.4.1-canary.3
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/dist/adapter.d.ts +6 -0
- package/dist/adapter.d.ts.map +1 -1
- package/dist/adapter.js +29 -0
- package/dist/adapter.js.map +1 -1
- package/dist/app.d.ts.map +1 -1
- package/dist/app.js +5 -0
- package/dist/app.js.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/dist/runtime.d.ts +11 -2
- package/dist/runtime.d.ts.map +1 -1
- package/dist/runtime.js +48 -4
- package/dist/runtime.js.map +1 -1
- package/dist/server.js +1 -1
- package/dist/server.js.map +1 -1
- package/dist/services/consent-config.service.d.ts +46 -0
- package/dist/services/consent-config.service.d.ts.map +1 -0
- package/dist/services/consent-config.service.js +157 -0
- package/dist/services/consent-config.service.js.map +1 -0
- package/dist/services/consent-page-renderer.d.ts +137 -0
- package/dist/services/consent-page-renderer.d.ts.map +1 -0
- package/dist/services/consent-page-renderer.js +489 -0
- package/dist/services/consent-page-renderer.js.map +1 -0
- package/dist/services/consent.service.d.ts +57 -3
- package/dist/services/consent.service.d.ts.map +1 -1
- package/dist/services/consent.service.js +360 -16
- package/dist/services/consent.service.js.map +1 -1
- package/dist/services/transport.service.d.ts +47 -0
- package/dist/services/transport.service.d.ts.map +1 -0
- package/dist/services/transport.service.js +76 -0
- package/dist/services/transport.service.js.map +1 -0
- package/package.json +2 -2
|
@@ -2,47 +2,391 @@
|
|
|
2
2
|
* Consent Service
|
|
3
3
|
*
|
|
4
4
|
* Handles consent page rendering and approval handling.
|
|
5
|
-
*
|
|
5
|
+
* Complete implementation for Phase 0.
|
|
6
|
+
*
|
|
7
|
+
* Related Spec: MCP-I Phase 0 Implementation Plan, Task B.5
|
|
6
8
|
*/
|
|
9
|
+
import { ConsentConfigService } from './consent-config.service';
|
|
10
|
+
import { ConsentPageRenderer } from './consent-page-renderer';
|
|
11
|
+
import { DEFAULT_AGENTSHIELD_URL, DEFAULT_SESSION_CACHE_TTL } from '../constants';
|
|
12
|
+
import { validateConsentApprovalRequest, } from '@kya-os/contracts/consent';
|
|
13
|
+
import { AGENTSHIELD_ENDPOINTS } from '@kya-os/contracts/agentshield-api';
|
|
7
14
|
export class ConsentService {
|
|
15
|
+
configService;
|
|
16
|
+
renderer;
|
|
17
|
+
env;
|
|
18
|
+
runtime;
|
|
19
|
+
constructor(env, runtime) {
|
|
20
|
+
this.env = env;
|
|
21
|
+
this.runtime = runtime;
|
|
22
|
+
this.configService = new ConsentConfigService(env);
|
|
23
|
+
this.renderer = new ConsentPageRenderer();
|
|
24
|
+
}
|
|
8
25
|
/**
|
|
9
26
|
* Handle consent requests
|
|
27
|
+
*
|
|
28
|
+
* Routes:
|
|
29
|
+
* - GET /consent - Render consent page
|
|
30
|
+
* - POST /consent/approve - Handle approval
|
|
31
|
+
* - GET /consent/success - Success page
|
|
32
|
+
*
|
|
10
33
|
* @param request - Incoming request
|
|
11
34
|
* @returns Response
|
|
12
35
|
*/
|
|
13
36
|
async handle(request) {
|
|
14
37
|
const url = new URL(request.url);
|
|
15
|
-
|
|
16
|
-
|
|
38
|
+
// GET /consent - Render page
|
|
39
|
+
if (request.method === 'GET' && url.pathname === '/consent') {
|
|
17
40
|
return this.renderConsentPage(url.searchParams);
|
|
18
41
|
}
|
|
19
|
-
|
|
20
|
-
|
|
42
|
+
// POST /consent/approve - Handle approval
|
|
43
|
+
if (request.method === 'POST' && url.pathname === '/consent/approve') {
|
|
21
44
|
return this.handleApproval(request);
|
|
22
45
|
}
|
|
46
|
+
// GET /consent/success - Success page
|
|
47
|
+
if (request.method === 'GET' && url.pathname === '/consent/success') {
|
|
48
|
+
return this.renderSuccessPage(url.searchParams);
|
|
49
|
+
}
|
|
23
50
|
return new Response('Method not allowed', { status: 405 });
|
|
24
51
|
}
|
|
25
52
|
/**
|
|
26
53
|
* Render consent page
|
|
27
|
-
*
|
|
54
|
+
*
|
|
55
|
+
* Query parameters:
|
|
56
|
+
* - tool: Tool name
|
|
57
|
+
* - scopes: Comma-separated scopes
|
|
58
|
+
* - agent_did: Agent DID
|
|
59
|
+
* - session_id: Session ID
|
|
60
|
+
* - project_id: Project ID
|
|
61
|
+
*
|
|
62
|
+
* @param params - URL search parameters
|
|
63
|
+
* @returns HTML response
|
|
28
64
|
*/
|
|
29
65
|
async renderConsentPage(params) {
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
66
|
+
try {
|
|
67
|
+
// Extract required parameters
|
|
68
|
+
const tool = params.get('tool');
|
|
69
|
+
const scopesParam = params.get('scopes');
|
|
70
|
+
const agentDid = params.get('agent_did');
|
|
71
|
+
const sessionId = params.get('session_id');
|
|
72
|
+
const projectId = params.get('project_id');
|
|
73
|
+
// Validate required parameters
|
|
74
|
+
if (!tool || !agentDid || !sessionId || !projectId) {
|
|
75
|
+
return new Response(JSON.stringify({
|
|
76
|
+
success: false,
|
|
77
|
+
error: 'Missing required parameters',
|
|
78
|
+
error_code: 'missing_parameters',
|
|
79
|
+
}), {
|
|
80
|
+
status: 400,
|
|
81
|
+
headers: { 'Content-Type': 'application/json' },
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
// Parse scopes
|
|
85
|
+
const scopes = scopesParam ? scopesParam.split(',').map((s) => s.trim()) : [];
|
|
86
|
+
// Get tool description (try to fetch from runtime or use default)
|
|
87
|
+
let toolDescription = `Execute ${tool}`;
|
|
88
|
+
if (this.runtime) {
|
|
89
|
+
try {
|
|
90
|
+
// Try to get tool description from runtime if available
|
|
91
|
+
// This is a placeholder - actual implementation depends on runtime API
|
|
92
|
+
toolDescription = `Execute ${tool} with requested permissions`;
|
|
93
|
+
}
|
|
94
|
+
catch {
|
|
95
|
+
// Fallback to default
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
// Get consent config from AgentShield or defaults
|
|
99
|
+
const consentConfig = await this.configService.getConsentConfig(projectId);
|
|
100
|
+
// Build server URL from request origin
|
|
101
|
+
// Try to get from env, otherwise construct from request
|
|
102
|
+
let serverUrl = this.env.MCP_SERVER_URL;
|
|
103
|
+
if (!serverUrl) {
|
|
104
|
+
// Fallback: construct from request origin
|
|
105
|
+
// Note: In Cloudflare Workers, we can't easily get the request origin
|
|
106
|
+
// This should be set via env var in production
|
|
107
|
+
serverUrl = 'https://example.com';
|
|
108
|
+
}
|
|
109
|
+
// Build consent page config
|
|
110
|
+
const pageConfig = {
|
|
111
|
+
tool,
|
|
112
|
+
toolDescription,
|
|
113
|
+
scopes,
|
|
114
|
+
agentDid,
|
|
115
|
+
sessionId,
|
|
116
|
+
projectId,
|
|
117
|
+
serverUrl,
|
|
118
|
+
branding: consentConfig.branding,
|
|
119
|
+
terms: consentConfig.terms,
|
|
120
|
+
customFields: consentConfig.customFields,
|
|
121
|
+
autoClose: consentConfig.ui?.autoClose,
|
|
122
|
+
};
|
|
123
|
+
// Render page
|
|
124
|
+
const html = this.renderer.render(pageConfig);
|
|
125
|
+
return new Response(html, {
|
|
126
|
+
status: 200,
|
|
127
|
+
headers: {
|
|
128
|
+
'Content-Type': 'text/html; charset=utf-8',
|
|
129
|
+
'Cache-Control': 'no-cache, no-store, must-revalidate',
|
|
130
|
+
},
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
catch (error) {
|
|
134
|
+
console.error('[ConsentService] Error rendering consent page:', error);
|
|
135
|
+
return new Response(JSON.stringify({
|
|
136
|
+
success: false,
|
|
137
|
+
error: 'Failed to render consent page',
|
|
138
|
+
error_code: 'render_error',
|
|
139
|
+
}), {
|
|
140
|
+
status: 500,
|
|
141
|
+
headers: { 'Content-Type': 'application/json' },
|
|
142
|
+
});
|
|
143
|
+
}
|
|
35
144
|
}
|
|
36
145
|
/**
|
|
37
146
|
* Handle consent approval
|
|
38
|
-
*
|
|
147
|
+
*
|
|
148
|
+
* Validates request, creates delegation via AgentShield API,
|
|
149
|
+
* stores token in KV, and returns success response.
|
|
150
|
+
*
|
|
151
|
+
* @param request - Approval request
|
|
152
|
+
* @returns JSON response
|
|
39
153
|
*/
|
|
40
154
|
async handleApproval(request) {
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
155
|
+
try {
|
|
156
|
+
// Parse and validate request body
|
|
157
|
+
const body = await request.json();
|
|
158
|
+
const validation = validateConsentApprovalRequest(body);
|
|
159
|
+
if (!validation.success) {
|
|
160
|
+
return new Response(JSON.stringify({
|
|
161
|
+
success: false,
|
|
162
|
+
error: 'Invalid request',
|
|
163
|
+
error_code: 'validation_error',
|
|
164
|
+
details: validation.error.errors,
|
|
165
|
+
}), {
|
|
166
|
+
status: 400,
|
|
167
|
+
headers: { 'Content-Type': 'application/json' },
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
const approvalRequest = validation.data;
|
|
171
|
+
// Validate terms acceptance if required
|
|
172
|
+
const consentConfig = await this.configService.getConsentConfig(approvalRequest.project_id);
|
|
173
|
+
if (consentConfig.terms?.required && !approvalRequest.termsAccepted) {
|
|
174
|
+
return new Response(JSON.stringify({
|
|
175
|
+
success: false,
|
|
176
|
+
error: 'Terms and conditions must be accepted',
|
|
177
|
+
error_code: 'terms_not_accepted',
|
|
178
|
+
}), {
|
|
179
|
+
status: 400,
|
|
180
|
+
headers: { 'Content-Type': 'application/json' },
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
// Create delegation via AgentShield API
|
|
184
|
+
const delegationResult = await this.createDelegation(approvalRequest);
|
|
185
|
+
if (!delegationResult.success) {
|
|
186
|
+
return new Response(JSON.stringify({
|
|
187
|
+
success: false,
|
|
188
|
+
error: delegationResult.error || 'Failed to create delegation',
|
|
189
|
+
error_code: delegationResult.error_code || 'delegation_creation_failed',
|
|
190
|
+
}), {
|
|
191
|
+
status: 500,
|
|
192
|
+
headers: { 'Content-Type': 'application/json' },
|
|
193
|
+
});
|
|
194
|
+
}
|
|
195
|
+
// Store delegation token in KV
|
|
196
|
+
await this.storeDelegationToken(approvalRequest.session_id, approvalRequest.agent_did, delegationResult.delegation_token, delegationResult.delegation_id);
|
|
197
|
+
// Return success response
|
|
198
|
+
const response = {
|
|
199
|
+
success: true,
|
|
200
|
+
delegation_id: delegationResult.delegation_id,
|
|
201
|
+
delegation_token: delegationResult.delegation_token,
|
|
202
|
+
};
|
|
203
|
+
return new Response(JSON.stringify(response), {
|
|
204
|
+
status: 200,
|
|
205
|
+
headers: { 'Content-Type': 'application/json' },
|
|
206
|
+
});
|
|
207
|
+
}
|
|
208
|
+
catch (error) {
|
|
209
|
+
console.error('[ConsentService] Error handling approval:', error);
|
|
210
|
+
return new Response(JSON.stringify({
|
|
211
|
+
success: false,
|
|
212
|
+
error: 'Internal server error',
|
|
213
|
+
error_code: 'internal_error',
|
|
214
|
+
}), {
|
|
215
|
+
status: 500,
|
|
216
|
+
headers: { 'Content-Type': 'application/json' },
|
|
217
|
+
});
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
221
|
+
* Create delegation via AgentShield API
|
|
222
|
+
*
|
|
223
|
+
* @param request - Approval request
|
|
224
|
+
* @returns Delegation creation result
|
|
225
|
+
*/
|
|
226
|
+
async createDelegation(request) {
|
|
227
|
+
const agentShieldUrl = this.env.AGENTSHIELD_API_URL || DEFAULT_AGENTSHIELD_URL;
|
|
228
|
+
const apiKey = this.env.AGENTSHIELD_API_KEY;
|
|
229
|
+
if (!apiKey) {
|
|
230
|
+
console.warn('[ConsentService] No API key configured, cannot create delegation');
|
|
231
|
+
return {
|
|
232
|
+
success: false,
|
|
233
|
+
error: 'API key not configured',
|
|
234
|
+
error_code: 'api_key_missing',
|
|
235
|
+
};
|
|
236
|
+
}
|
|
237
|
+
try {
|
|
238
|
+
// Calculate expiration (7 days from now)
|
|
239
|
+
const expiresAt = new Date();
|
|
240
|
+
expiresAt.setDate(expiresAt.getDate() + 7);
|
|
241
|
+
const expiresAtISO = expiresAt.toISOString();
|
|
242
|
+
// Create delegation request
|
|
243
|
+
// Note: AgentShield API may accept a simplified format for consent flows
|
|
244
|
+
// This is a simplified version - adjust based on actual API requirements
|
|
245
|
+
const delegationRequest = {
|
|
246
|
+
agent_did: request.agent_did,
|
|
247
|
+
scopes: request.scopes,
|
|
248
|
+
session_id: request.session_id,
|
|
249
|
+
project_id: request.project_id,
|
|
250
|
+
expires_at: expiresAtISO,
|
|
251
|
+
// Include custom fields if provided
|
|
252
|
+
...(request.customFields && Object.keys(request.customFields).length > 0
|
|
253
|
+
? { custom_fields: request.customFields }
|
|
254
|
+
: {}),
|
|
255
|
+
};
|
|
256
|
+
const response = await fetch(`${agentShieldUrl}${AGENTSHIELD_ENDPOINTS.DELEGATIONS_CREATE}`, {
|
|
257
|
+
method: 'POST',
|
|
258
|
+
headers: {
|
|
259
|
+
'Authorization': `Bearer ${apiKey}`,
|
|
260
|
+
'Content-Type': 'application/json',
|
|
261
|
+
},
|
|
262
|
+
body: JSON.stringify(delegationRequest),
|
|
263
|
+
});
|
|
264
|
+
if (!response.ok) {
|
|
265
|
+
const errorText = await response.text();
|
|
266
|
+
console.error('[ConsentService] Delegation creation failed:', response.status, errorText);
|
|
267
|
+
return {
|
|
268
|
+
success: false,
|
|
269
|
+
error: `API error: ${response.status}`,
|
|
270
|
+
error_code: 'api_error',
|
|
271
|
+
};
|
|
272
|
+
}
|
|
273
|
+
const responseData = (await response.json());
|
|
274
|
+
// Extract delegation_id and delegation_token from response
|
|
275
|
+
// Response format may vary - handle both wrapped and unwrapped formats
|
|
276
|
+
const delegationId = responseData.delegation_id ||
|
|
277
|
+
responseData.data?.delegation_id ||
|
|
278
|
+
responseData.delegation?.id ||
|
|
279
|
+
responseData.id;
|
|
280
|
+
const delegationToken = responseData.delegation_token ||
|
|
281
|
+
responseData.data?.delegation_token ||
|
|
282
|
+
responseData.token ||
|
|
283
|
+
responseData.data?.token;
|
|
284
|
+
if (!delegationId || !delegationToken) {
|
|
285
|
+
console.error('[ConsentService] Invalid response format:', responseData);
|
|
286
|
+
return {
|
|
287
|
+
success: false,
|
|
288
|
+
error: 'Invalid API response format',
|
|
289
|
+
error_code: 'invalid_response',
|
|
290
|
+
};
|
|
291
|
+
}
|
|
292
|
+
console.log('[ConsentService] ✅ Delegation created successfully:', {
|
|
293
|
+
delegationId,
|
|
294
|
+
agentDid: request.agent_did.substring(0, 20) + '...',
|
|
295
|
+
scopes: request.scopes,
|
|
296
|
+
});
|
|
297
|
+
return {
|
|
298
|
+
success: true,
|
|
299
|
+
delegation_id: delegationId,
|
|
300
|
+
delegation_token: delegationToken,
|
|
301
|
+
};
|
|
302
|
+
}
|
|
303
|
+
catch (error) {
|
|
304
|
+
console.error('[ConsentService] Error creating delegation:', error);
|
|
305
|
+
return {
|
|
306
|
+
success: false,
|
|
307
|
+
error: error instanceof Error ? error.message : 'Unknown error',
|
|
308
|
+
error_code: 'creation_error',
|
|
309
|
+
};
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
/**
|
|
313
|
+
* Store delegation token in KV
|
|
314
|
+
*
|
|
315
|
+
* Stores token using both session ID and agent DID keys for resilience.
|
|
316
|
+
*
|
|
317
|
+
* @param sessionId - Session ID
|
|
318
|
+
* @param agentDid - Agent DID
|
|
319
|
+
* @param token - Delegation token
|
|
320
|
+
* @param delegationId - Delegation ID
|
|
321
|
+
*/
|
|
322
|
+
async storeDelegationToken(sessionId, agentDid, token, delegationId) {
|
|
323
|
+
const delegationStorage = this.env.DELEGATION_STORAGE;
|
|
324
|
+
if (!delegationStorage) {
|
|
325
|
+
console.warn('[ConsentService] No delegation storage configured, token not stored');
|
|
326
|
+
return;
|
|
327
|
+
}
|
|
328
|
+
try {
|
|
329
|
+
// Default TTL: 7 days (same as delegation expiration)
|
|
330
|
+
const ttl = 7 * 24 * 60 * 60; // 7 days in seconds
|
|
331
|
+
// Store using agent DID (primary, survives session changes)
|
|
332
|
+
const agentKey = `agent:${agentDid}:delegation`;
|
|
333
|
+
await delegationStorage.put(agentKey, token, {
|
|
334
|
+
expirationTtl: ttl,
|
|
335
|
+
});
|
|
336
|
+
console.log('[ConsentService] ✅ Token stored with agent DID:', {
|
|
337
|
+
key: agentKey,
|
|
338
|
+
ttl,
|
|
339
|
+
delegationId,
|
|
340
|
+
});
|
|
341
|
+
// Store using session ID (secondary cache, shorter TTL for performance)
|
|
342
|
+
const sessionKey = `session:${sessionId}`;
|
|
343
|
+
await delegationStorage.put(sessionKey, token, {
|
|
344
|
+
expirationTtl: Math.min(ttl, DEFAULT_SESSION_CACHE_TTL),
|
|
345
|
+
});
|
|
346
|
+
console.log('[ConsentService] ✅ Token cached for session:', {
|
|
347
|
+
key: sessionKey,
|
|
348
|
+
ttl: Math.min(ttl, DEFAULT_SESSION_CACHE_TTL),
|
|
349
|
+
sessionId,
|
|
350
|
+
});
|
|
351
|
+
}
|
|
352
|
+
catch (error) {
|
|
353
|
+
// Storage errors are non-fatal - log but don't fail the request
|
|
354
|
+
console.error('[ConsentService] Storage error (non-fatal):', error);
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
/**
|
|
358
|
+
* Render success page
|
|
359
|
+
*
|
|
360
|
+
* @param params - URL search parameters (delegation_id)
|
|
361
|
+
* @returns HTML response
|
|
362
|
+
*/
|
|
363
|
+
renderSuccessPage(params) {
|
|
364
|
+
const delegationId = params.get('delegation_id') || 'unknown';
|
|
365
|
+
// Get consent config to check auto-close setting
|
|
366
|
+
const projectId = params.get('project_id');
|
|
367
|
+
let autoClose = false;
|
|
368
|
+
if (projectId) {
|
|
369
|
+
// Fetch config asynchronously but don't block on it
|
|
370
|
+
this.configService
|
|
371
|
+
.getConsentConfig(projectId)
|
|
372
|
+
.then((config) => {
|
|
373
|
+
autoClose = config.ui?.autoClose || false;
|
|
374
|
+
})
|
|
375
|
+
.catch(() => {
|
|
376
|
+
// Ignore errors, use default
|
|
377
|
+
});
|
|
378
|
+
}
|
|
379
|
+
const html = this.renderer.renderSuccess({
|
|
380
|
+
delegationId,
|
|
381
|
+
autoClose,
|
|
45
382
|
});
|
|
383
|
+
return Promise.resolve(new Response(html, {
|
|
384
|
+
status: 200,
|
|
385
|
+
headers: {
|
|
386
|
+
'Content-Type': 'text/html; charset=utf-8',
|
|
387
|
+
'Cache-Control': 'no-cache, no-store, must-revalidate',
|
|
388
|
+
},
|
|
389
|
+
}));
|
|
46
390
|
}
|
|
47
391
|
}
|
|
48
392
|
//# sourceMappingURL=consent.service.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"consent.service.js","sourceRoot":"","sources":["../../src/services/consent.service.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"consent.service.js","sourceRoot":"","sources":["../../src/services/consent.service.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Transport Detection Service
|
|
3
|
+
*
|
|
4
|
+
* Detects the transport type (HTTP, SSE, STDIO) and determines the appropriate
|
|
5
|
+
* consent strategy (server-hosted vs dashboard-hosted).
|
|
6
|
+
*
|
|
7
|
+
* Related Spec: MCP-I Phase 0 Implementation Plan, Task B.2
|
|
8
|
+
*/
|
|
9
|
+
export type TransportType = 'http' | 'sse' | 'stdio';
|
|
10
|
+
export type ConsentStrategy = 'server-hosted' | 'dashboard-hosted';
|
|
11
|
+
/**
|
|
12
|
+
* Transport Service
|
|
13
|
+
*
|
|
14
|
+
* Provides utilities for detecting transport type and determining consent strategy
|
|
15
|
+
*/
|
|
16
|
+
export declare class TransportService {
|
|
17
|
+
/**
|
|
18
|
+
* Detect the current transport type
|
|
19
|
+
*
|
|
20
|
+
* Detection logic:
|
|
21
|
+
* - Cloudflare Workers: Always HTTP capable (Request/Response available)
|
|
22
|
+
* - STDIO transport: process.stdin/stdout available (no HTTP server)
|
|
23
|
+
* - Default: HTTP (most common)
|
|
24
|
+
*
|
|
25
|
+
* @returns Detected transport type
|
|
26
|
+
*/
|
|
27
|
+
static detectTransport(): TransportType;
|
|
28
|
+
/**
|
|
29
|
+
* Get consent strategy based on transport type
|
|
30
|
+
*
|
|
31
|
+
* Strategy selection:
|
|
32
|
+
* - STDIO: dashboard-hosted (can't serve HTTP pages)
|
|
33
|
+
* - HTTP/SSE: server-hosted (can serve consent pages)
|
|
34
|
+
*
|
|
35
|
+
* @param transport - Optional transport type (auto-detected if not provided)
|
|
36
|
+
* @returns Consent strategy
|
|
37
|
+
*/
|
|
38
|
+
static getConsentStrategy(transport?: TransportType): ConsentStrategy;
|
|
39
|
+
/**
|
|
40
|
+
* Check if server-hosted consent is available
|
|
41
|
+
*
|
|
42
|
+
* @param transport - Optional transport type (auto-detected if not provided)
|
|
43
|
+
* @returns true if server-hosted consent is available
|
|
44
|
+
*/
|
|
45
|
+
static canServeConsentPage(transport?: TransportType): boolean;
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=transport.service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transport.service.d.ts","sourceRoot":"","sources":["../../src/services/transport.service.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,KAAK,GAAG,OAAO,CAAC;AACrD,MAAM,MAAM,eAAe,GAAG,eAAe,GAAG,kBAAkB,CAAC;AAEnE;;;;GAIG;AACH,qBAAa,gBAAgB;IAC3B;;;;;;;;;OASG;IACH,MAAM,CAAC,eAAe,IAAI,aAAa;IA2BvC;;;;;;;;;OASG;IACH,MAAM,CAAC,kBAAkB,CAAC,SAAS,CAAC,EAAE,aAAa,GAAG,eAAe;IAYrE;;;;;OAKG;IACH,MAAM,CAAC,mBAAmB,CAAC,SAAS,CAAC,EAAE,aAAa,GAAG,OAAO;CAG/D"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Transport Detection Service
|
|
3
|
+
*
|
|
4
|
+
* Detects the transport type (HTTP, SSE, STDIO) and determines the appropriate
|
|
5
|
+
* consent strategy (server-hosted vs dashboard-hosted).
|
|
6
|
+
*
|
|
7
|
+
* Related Spec: MCP-I Phase 0 Implementation Plan, Task B.2
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* Transport Service
|
|
11
|
+
*
|
|
12
|
+
* Provides utilities for detecting transport type and determining consent strategy
|
|
13
|
+
*/
|
|
14
|
+
export class TransportService {
|
|
15
|
+
/**
|
|
16
|
+
* Detect the current transport type
|
|
17
|
+
*
|
|
18
|
+
* Detection logic:
|
|
19
|
+
* - Cloudflare Workers: Always HTTP capable (Request/Response available)
|
|
20
|
+
* - STDIO transport: process.stdin/stdout available (no HTTP server)
|
|
21
|
+
* - Default: HTTP (most common)
|
|
22
|
+
*
|
|
23
|
+
* @returns Detected transport type
|
|
24
|
+
*/
|
|
25
|
+
static detectTransport() {
|
|
26
|
+
// Cloudflare Workers - always HTTP capable
|
|
27
|
+
// Check for Request/Response globals (Cloudflare Workers environment)
|
|
28
|
+
if (typeof Request !== 'undefined' && typeof Response !== 'undefined') {
|
|
29
|
+
return 'http';
|
|
30
|
+
}
|
|
31
|
+
// STDIO transport (Node.js with stdin/stdout, no HTTP server)
|
|
32
|
+
// Check for Node.js process object with stdin/stdout
|
|
33
|
+
// Use type assertion to avoid TypeScript errors in Cloudflare Workers environment
|
|
34
|
+
const proc = typeof globalThis !== 'undefined' && 'process' in globalThis
|
|
35
|
+
? globalThis.process
|
|
36
|
+
: undefined;
|
|
37
|
+
if (proc &&
|
|
38
|
+
proc.stdin &&
|
|
39
|
+
proc.stdout &&
|
|
40
|
+
!proc.env?.NODE_ENV?.includes('worker')) {
|
|
41
|
+
return 'stdio';
|
|
42
|
+
}
|
|
43
|
+
// Default to HTTP for unknown environments
|
|
44
|
+
// This covers most web-based scenarios
|
|
45
|
+
return 'http';
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Get consent strategy based on transport type
|
|
49
|
+
*
|
|
50
|
+
* Strategy selection:
|
|
51
|
+
* - STDIO: dashboard-hosted (can't serve HTTP pages)
|
|
52
|
+
* - HTTP/SSE: server-hosted (can serve consent pages)
|
|
53
|
+
*
|
|
54
|
+
* @param transport - Optional transport type (auto-detected if not provided)
|
|
55
|
+
* @returns Consent strategy
|
|
56
|
+
*/
|
|
57
|
+
static getConsentStrategy(transport) {
|
|
58
|
+
const detected = transport || this.detectTransport();
|
|
59
|
+
// STDIO can't serve HTTP pages, must use dashboard-hosted consent
|
|
60
|
+
if (detected === 'stdio') {
|
|
61
|
+
return 'dashboard-hosted';
|
|
62
|
+
}
|
|
63
|
+
// HTTP/SSE can serve consent pages directly
|
|
64
|
+
return 'server-hosted';
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Check if server-hosted consent is available
|
|
68
|
+
*
|
|
69
|
+
* @param transport - Optional transport type (auto-detected if not provided)
|
|
70
|
+
* @returns true if server-hosted consent is available
|
|
71
|
+
*/
|
|
72
|
+
static canServeConsentPage(transport) {
|
|
73
|
+
return this.getConsentStrategy(transport) === 'server-hosted';
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
//# sourceMappingURL=transport.service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transport.service.js","sourceRoot":"","sources":["../../src/services/transport.service.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAKH;;;;GAIG;AACH,MAAM,OAAO,gBAAgB;IAC3B;;;;;;;;;OASG;IACH,MAAM,CAAC,eAAe;QACpB,2CAA2C;QAC3C,sEAAsE;QACtE,IAAI,OAAO,OAAO,KAAK,WAAW,IAAI,OAAO,QAAQ,KAAK,WAAW,EAAE,CAAC;YACtE,OAAO,MAAM,CAAC;QAChB,CAAC;QAED,8DAA8D;QAC9D,qDAAqD;QACrD,kFAAkF;QAClF,MAAM,IAAI,GAAG,OAAO,UAAU,KAAK,WAAW,IAAI,SAAS,IAAI,UAAU;YACvE,CAAC,CAAE,UAA+F,CAAC,OAAO;YAC1G,CAAC,CAAC,SAAS,CAAC;QACd,IACE,IAAI;YACJ,IAAI,CAAC,KAAK;YACV,IAAI,CAAC,MAAM;YACX,CAAC,IAAI,CAAC,GAAG,EAAE,QAAQ,EAAE,QAAQ,CAAC,QAAQ,CAAC,EACvC,CAAC;YACD,OAAO,OAAO,CAAC;QACjB,CAAC;QAED,2CAA2C;QAC3C,uCAAuC;QACvC,OAAO,MAAM,CAAC;IAChB,CAAC;IAED;;;;;;;;;OASG;IACH,MAAM,CAAC,kBAAkB,CAAC,SAAyB;QACjD,MAAM,QAAQ,GAAG,SAAS,IAAI,IAAI,CAAC,eAAe,EAAE,CAAC;QAErD,kEAAkE;QAClE,IAAI,QAAQ,KAAK,OAAO,EAAE,CAAC;YACzB,OAAO,kBAAkB,CAAC;QAC5B,CAAC;QAED,4CAA4C;QAC5C,OAAO,eAAe,CAAC;IACzB,CAAC;IAED;;;;;OAKG;IACH,MAAM,CAAC,mBAAmB,CAAC,SAAyB;QAClD,OAAO,IAAI,CAAC,kBAAkB,CAAC,SAAS,CAAC,KAAK,eAAe,CAAC;IAChE,CAAC;CACF"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kya-os/mcp-i-cloudflare",
|
|
3
|
-
"version": "1.4.1-canary.
|
|
3
|
+
"version": "1.4.1-canary.3",
|
|
4
4
|
"description": "Cloudflare Workers implementation of MCP-I framework",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
"edge"
|
|
39
39
|
],
|
|
40
40
|
"dependencies": {
|
|
41
|
-
"@kya-os/contracts": "1.5.2-canary.
|
|
41
|
+
"@kya-os/contracts": "1.5.2-canary.1",
|
|
42
42
|
"@kya-os/mcp-i-core": "1.1.13-canary.1",
|
|
43
43
|
"@modelcontextprotocol/sdk": "^1.11.4",
|
|
44
44
|
"base-x": "^5.0.1"
|