@ottocode/server 0.1.264 → 0.1.266
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/package.json +3 -3
- package/src/routes/auth/copilot.ts +699 -0
- package/src/routes/auth/oauth.ts +578 -0
- package/src/routes/auth/onboarding.ts +45 -0
- package/src/routes/auth/providers.ts +189 -0
- package/src/routes/auth/service.ts +167 -0
- package/src/routes/auth/state.ts +23 -0
- package/src/routes/auth/status.ts +203 -0
- package/src/routes/auth/wallet.ts +229 -0
- package/src/routes/auth.ts +12 -2080
- package/src/routes/config/models-service.ts +411 -0
- package/src/routes/config/models.ts +6 -426
- package/src/routes/config/providers-service.ts +237 -0
- package/src/routes/config/providers.ts +10 -242
- package/src/routes/files/handlers.ts +297 -0
- package/src/routes/files/service.ts +313 -0
- package/src/routes/files.ts +12 -608
- package/src/routes/git/commit-service.ts +207 -0
- package/src/routes/git/commit.ts +6 -220
- package/src/routes/git/remote-service.ts +116 -0
- package/src/routes/git/remote.ts +8 -115
- package/src/routes/git/staging-service.ts +111 -0
- package/src/routes/git/staging.ts +10 -205
- package/src/routes/mcp/auth.ts +338 -0
- package/src/routes/mcp/lifecycle.ts +263 -0
- package/src/routes/mcp/servers.ts +212 -0
- package/src/routes/mcp/service.ts +664 -0
- package/src/routes/mcp/state.ts +13 -0
- package/src/routes/mcp.ts +6 -1233
- package/src/routes/ottorouter/billing.ts +593 -0
- package/src/routes/ottorouter/service.ts +92 -0
- package/src/routes/ottorouter/topup.ts +301 -0
- package/src/routes/ottorouter/wallet.ts +370 -0
- package/src/routes/ottorouter.ts +6 -1319
- package/src/routes/research/service.ts +339 -0
- package/src/routes/research.ts +12 -390
- package/src/routes/sessions/crud.ts +563 -0
- package/src/routes/sessions/queue.ts +242 -0
- package/src/routes/sessions/retry.ts +121 -0
- package/src/routes/sessions/service.ts +768 -0
- package/src/routes/sessions/share.ts +434 -0
- package/src/routes/sessions.ts +8 -1977
- package/src/routes/skills/service.ts +221 -0
- package/src/routes/skills/spec.ts +309 -0
- package/src/routes/skills.ts +31 -909
- package/src/routes/terminals/service.ts +326 -0
- package/src/routes/terminals.ts +19 -295
- package/src/routes/tunnel/service.ts +217 -0
- package/src/routes/tunnel.ts +29 -219
- package/src/runtime/agent/registry-prompts.ts +147 -0
- package/src/runtime/agent/registry.ts +6 -124
- package/src/runtime/agent/runner-errors.ts +116 -0
- package/src/runtime/agent/runner-reminders.ts +45 -0
- package/src/runtime/agent/runner-setup-model.ts +75 -0
- package/src/runtime/agent/runner-setup-prompt.ts +185 -0
- package/src/runtime/agent/runner-setup-tools.ts +103 -0
- package/src/runtime/agent/runner-setup-utils.ts +21 -0
- package/src/runtime/agent/runner-setup.ts +54 -288
- package/src/runtime/agent/runner-telemetry.ts +112 -0
- package/src/runtime/agent/runner-text.ts +108 -0
- package/src/runtime/agent/runner-tool-observer.ts +86 -0
- package/src/runtime/agent/runner.ts +79 -378
- package/src/runtime/ask/service.ts +1 -0
- package/src/runtime/provider/custom.ts +73 -0
- package/src/runtime/provider/index.ts +6 -85
- package/src/runtime/provider/reasoning-builders.ts +280 -0
- package/src/runtime/provider/reasoning.ts +68 -264
- package/src/runtime/provider/xai.ts +8 -0
- package/src/tools/adapter/events.ts +116 -0
- package/src/tools/adapter/execution.ts +160 -0
- package/src/tools/adapter/pending.ts +37 -0
- package/src/tools/adapter/persistence.ts +166 -0
- package/src/tools/adapter/results.ts +97 -0
- package/src/tools/adapter.ts +124 -451
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import { execFile } from 'node:child_process';
|
|
2
|
+
import { promisify } from 'node:util';
|
|
3
|
+
import type { Context } from 'hono';
|
|
4
|
+
import {
|
|
5
|
+
gitDeleteSchema,
|
|
6
|
+
gitRestoreSchema,
|
|
7
|
+
gitStageSchema,
|
|
8
|
+
gitUnstageSchema,
|
|
9
|
+
} from './schemas.ts';
|
|
10
|
+
import { validateAndGetGitRoot } from './utils.ts';
|
|
11
|
+
|
|
12
|
+
const execFileAsync = promisify(execFile);
|
|
13
|
+
|
|
14
|
+
type StagingAction = 'stage' | 'unstage' | 'restore' | 'delete';
|
|
15
|
+
|
|
16
|
+
const actionConfig: Record<
|
|
17
|
+
StagingAction,
|
|
18
|
+
{
|
|
19
|
+
schema: typeof gitStageSchema;
|
|
20
|
+
command: (files: string[]) => string[];
|
|
21
|
+
dataKey: 'staged' | 'unstaged' | 'restored' | 'deleted';
|
|
22
|
+
fallbackError: string;
|
|
23
|
+
}
|
|
24
|
+
> = {
|
|
25
|
+
stage: {
|
|
26
|
+
schema: gitStageSchema,
|
|
27
|
+
command: (files) => ['add', ...files],
|
|
28
|
+
dataKey: 'staged',
|
|
29
|
+
fallbackError: 'Failed to stage files',
|
|
30
|
+
},
|
|
31
|
+
unstage: {
|
|
32
|
+
schema: gitUnstageSchema,
|
|
33
|
+
command: (files) => ['reset', 'HEAD', '--', ...files],
|
|
34
|
+
dataKey: 'unstaged',
|
|
35
|
+
fallbackError: 'Failed to unstage files',
|
|
36
|
+
},
|
|
37
|
+
restore: {
|
|
38
|
+
schema: gitRestoreSchema,
|
|
39
|
+
command: (files) => ['restore', '--', ...files],
|
|
40
|
+
dataKey: 'restored',
|
|
41
|
+
fallbackError: 'Failed to restore files',
|
|
42
|
+
},
|
|
43
|
+
delete: {
|
|
44
|
+
schema: gitDeleteSchema,
|
|
45
|
+
command: (files) => ['clean', '-f', '--', ...files],
|
|
46
|
+
dataKey: 'deleted',
|
|
47
|
+
fallbackError: 'Failed to delete files',
|
|
48
|
+
},
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
async function handleStagingAction(c: Context, action: StagingAction) {
|
|
52
|
+
const config = actionConfig[action];
|
|
53
|
+
try {
|
|
54
|
+
const body = await c.req.json();
|
|
55
|
+
const { files, project } = config.schema.parse(body);
|
|
56
|
+
const requestedPath = project || process.cwd();
|
|
57
|
+
|
|
58
|
+
const validation = await validateAndGetGitRoot(requestedPath);
|
|
59
|
+
if ('error' in validation) {
|
|
60
|
+
return c.json(
|
|
61
|
+
{ status: 'error', error: validation.error, code: validation.code },
|
|
62
|
+
400,
|
|
63
|
+
);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
if (files.length === 0) {
|
|
67
|
+
return c.json(
|
|
68
|
+
{
|
|
69
|
+
status: 'error',
|
|
70
|
+
error: 'No files specified',
|
|
71
|
+
},
|
|
72
|
+
400,
|
|
73
|
+
);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
await execFileAsync('git', config.command(files), {
|
|
77
|
+
cwd: validation.gitRoot,
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
return c.json({
|
|
81
|
+
status: 'ok',
|
|
82
|
+
data: {
|
|
83
|
+
[config.dataKey]: files,
|
|
84
|
+
},
|
|
85
|
+
});
|
|
86
|
+
} catch (error) {
|
|
87
|
+
return c.json(
|
|
88
|
+
{
|
|
89
|
+
status: 'error',
|
|
90
|
+
error: error instanceof Error ? error.message : config.fallbackError,
|
|
91
|
+
},
|
|
92
|
+
500,
|
|
93
|
+
);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
export function handleStageFiles(c: Context) {
|
|
98
|
+
return handleStagingAction(c, 'stage');
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
export function handleUnstageFiles(c: Context) {
|
|
102
|
+
return handleStagingAction(c, 'unstage');
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
export function handleRestoreFiles(c: Context) {
|
|
106
|
+
return handleStagingAction(c, 'restore');
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
export function handleDeleteFiles(c: Context) {
|
|
110
|
+
return handleStagingAction(c, 'delete');
|
|
111
|
+
}
|
|
@@ -1,16 +1,11 @@
|
|
|
1
1
|
import type { Hono } from 'hono';
|
|
2
|
-
import { execFile } from 'node:child_process';
|
|
3
|
-
import { promisify } from 'node:util';
|
|
4
|
-
import {
|
|
5
|
-
gitStageSchema,
|
|
6
|
-
gitUnstageSchema,
|
|
7
|
-
gitRestoreSchema,
|
|
8
|
-
gitDeleteSchema,
|
|
9
|
-
} from './schemas.ts';
|
|
10
|
-
import { validateAndGetGitRoot } from './utils.ts';
|
|
11
2
|
import { openApiRoute } from '../../openapi/route.ts';
|
|
12
|
-
|
|
13
|
-
|
|
3
|
+
import {
|
|
4
|
+
handleDeleteFiles,
|
|
5
|
+
handleRestoreFiles,
|
|
6
|
+
handleStageFiles,
|
|
7
|
+
handleUnstageFiles,
|
|
8
|
+
} from './staging-service.ts';
|
|
14
9
|
|
|
15
10
|
export function registerStagingRoutes(app: Hono) {
|
|
16
11
|
openApiRoute(
|
|
@@ -104,52 +99,7 @@ export function registerStagingRoutes(app: Hono) {
|
|
|
104
99
|
},
|
|
105
100
|
},
|
|
106
101
|
},
|
|
107
|
-
|
|
108
|
-
try {
|
|
109
|
-
const body = await c.req.json();
|
|
110
|
-
const { files, project } = gitStageSchema.parse(body);
|
|
111
|
-
|
|
112
|
-
const requestedPath = project || process.cwd();
|
|
113
|
-
|
|
114
|
-
const validation = await validateAndGetGitRoot(requestedPath);
|
|
115
|
-
if ('error' in validation) {
|
|
116
|
-
return c.json(
|
|
117
|
-
{ status: 'error', error: validation.error, code: validation.code },
|
|
118
|
-
400,
|
|
119
|
-
);
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
const { gitRoot } = validation;
|
|
123
|
-
|
|
124
|
-
if (files.length === 0) {
|
|
125
|
-
return c.json(
|
|
126
|
-
{
|
|
127
|
-
status: 'error',
|
|
128
|
-
error: 'No files specified',
|
|
129
|
-
},
|
|
130
|
-
400,
|
|
131
|
-
);
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
await execFileAsync('git', ['add', ...files], { cwd: gitRoot });
|
|
135
|
-
|
|
136
|
-
return c.json({
|
|
137
|
-
status: 'ok',
|
|
138
|
-
data: {
|
|
139
|
-
staged: files,
|
|
140
|
-
},
|
|
141
|
-
});
|
|
142
|
-
} catch (error) {
|
|
143
|
-
return c.json(
|
|
144
|
-
{
|
|
145
|
-
status: 'error',
|
|
146
|
-
error:
|
|
147
|
-
error instanceof Error ? error.message : 'Failed to stage files',
|
|
148
|
-
},
|
|
149
|
-
500,
|
|
150
|
-
);
|
|
151
|
-
}
|
|
152
|
-
},
|
|
102
|
+
handleStageFiles,
|
|
153
103
|
);
|
|
154
104
|
|
|
155
105
|
openApiRoute(
|
|
@@ -243,56 +193,7 @@ export function registerStagingRoutes(app: Hono) {
|
|
|
243
193
|
},
|
|
244
194
|
},
|
|
245
195
|
},
|
|
246
|
-
|
|
247
|
-
try {
|
|
248
|
-
const body = await c.req.json();
|
|
249
|
-
const { files, project } = gitUnstageSchema.parse(body);
|
|
250
|
-
|
|
251
|
-
const requestedPath = project || process.cwd();
|
|
252
|
-
|
|
253
|
-
const validation = await validateAndGetGitRoot(requestedPath);
|
|
254
|
-
if ('error' in validation) {
|
|
255
|
-
return c.json(
|
|
256
|
-
{ status: 'error', error: validation.error, code: validation.code },
|
|
257
|
-
400,
|
|
258
|
-
);
|
|
259
|
-
}
|
|
260
|
-
|
|
261
|
-
const { gitRoot } = validation;
|
|
262
|
-
|
|
263
|
-
if (files.length === 0) {
|
|
264
|
-
return c.json(
|
|
265
|
-
{
|
|
266
|
-
status: 'error',
|
|
267
|
-
error: 'No files specified',
|
|
268
|
-
},
|
|
269
|
-
400,
|
|
270
|
-
);
|
|
271
|
-
}
|
|
272
|
-
|
|
273
|
-
await execFileAsync('git', ['reset', 'HEAD', '--', ...files], {
|
|
274
|
-
cwd: gitRoot,
|
|
275
|
-
});
|
|
276
|
-
|
|
277
|
-
return c.json({
|
|
278
|
-
status: 'ok',
|
|
279
|
-
data: {
|
|
280
|
-
unstaged: files,
|
|
281
|
-
},
|
|
282
|
-
});
|
|
283
|
-
} catch (error) {
|
|
284
|
-
return c.json(
|
|
285
|
-
{
|
|
286
|
-
status: 'error',
|
|
287
|
-
error:
|
|
288
|
-
error instanceof Error
|
|
289
|
-
? error.message
|
|
290
|
-
: 'Failed to unstage files',
|
|
291
|
-
},
|
|
292
|
-
500,
|
|
293
|
-
);
|
|
294
|
-
}
|
|
295
|
-
},
|
|
196
|
+
handleUnstageFiles,
|
|
296
197
|
);
|
|
297
198
|
|
|
298
199
|
openApiRoute(
|
|
@@ -380,56 +281,7 @@ export function registerStagingRoutes(app: Hono) {
|
|
|
380
281
|
},
|
|
381
282
|
},
|
|
382
283
|
},
|
|
383
|
-
|
|
384
|
-
try {
|
|
385
|
-
const body = await c.req.json();
|
|
386
|
-
const { files, project } = gitRestoreSchema.parse(body);
|
|
387
|
-
|
|
388
|
-
const requestedPath = project || process.cwd();
|
|
389
|
-
|
|
390
|
-
const validation = await validateAndGetGitRoot(requestedPath);
|
|
391
|
-
if ('error' in validation) {
|
|
392
|
-
return c.json(
|
|
393
|
-
{ status: 'error', error: validation.error, code: validation.code },
|
|
394
|
-
400,
|
|
395
|
-
);
|
|
396
|
-
}
|
|
397
|
-
|
|
398
|
-
const { gitRoot } = validation;
|
|
399
|
-
|
|
400
|
-
if (files.length === 0) {
|
|
401
|
-
return c.json(
|
|
402
|
-
{
|
|
403
|
-
status: 'error',
|
|
404
|
-
error: 'No files specified',
|
|
405
|
-
},
|
|
406
|
-
400,
|
|
407
|
-
);
|
|
408
|
-
}
|
|
409
|
-
|
|
410
|
-
await execFileAsync('git', ['restore', '--', ...files], {
|
|
411
|
-
cwd: gitRoot,
|
|
412
|
-
});
|
|
413
|
-
|
|
414
|
-
return c.json({
|
|
415
|
-
status: 'ok',
|
|
416
|
-
data: {
|
|
417
|
-
restored: files,
|
|
418
|
-
},
|
|
419
|
-
});
|
|
420
|
-
} catch (error) {
|
|
421
|
-
return c.json(
|
|
422
|
-
{
|
|
423
|
-
status: 'error',
|
|
424
|
-
error:
|
|
425
|
-
error instanceof Error
|
|
426
|
-
? error.message
|
|
427
|
-
: 'Failed to restore files',
|
|
428
|
-
},
|
|
429
|
-
500,
|
|
430
|
-
);
|
|
431
|
-
}
|
|
432
|
-
},
|
|
284
|
+
handleRestoreFiles,
|
|
433
285
|
);
|
|
434
286
|
|
|
435
287
|
openApiRoute(
|
|
@@ -517,53 +369,6 @@ export function registerStagingRoutes(app: Hono) {
|
|
|
517
369
|
},
|
|
518
370
|
},
|
|
519
371
|
},
|
|
520
|
-
|
|
521
|
-
try {
|
|
522
|
-
const body = await c.req.json();
|
|
523
|
-
const { files, project } = gitDeleteSchema.parse(body);
|
|
524
|
-
|
|
525
|
-
const requestedPath = project || process.cwd();
|
|
526
|
-
|
|
527
|
-
const validation = await validateAndGetGitRoot(requestedPath);
|
|
528
|
-
if ('error' in validation) {
|
|
529
|
-
return c.json(
|
|
530
|
-
{ status: 'error', error: validation.error, code: validation.code },
|
|
531
|
-
400,
|
|
532
|
-
);
|
|
533
|
-
}
|
|
534
|
-
|
|
535
|
-
const { gitRoot } = validation;
|
|
536
|
-
|
|
537
|
-
if (files.length === 0) {
|
|
538
|
-
return c.json(
|
|
539
|
-
{
|
|
540
|
-
status: 'error',
|
|
541
|
-
error: 'No files specified',
|
|
542
|
-
},
|
|
543
|
-
400,
|
|
544
|
-
);
|
|
545
|
-
}
|
|
546
|
-
|
|
547
|
-
await execFileAsync('git', ['clean', '-f', '--', ...files], {
|
|
548
|
-
cwd: gitRoot,
|
|
549
|
-
});
|
|
550
|
-
|
|
551
|
-
return c.json({
|
|
552
|
-
status: 'ok',
|
|
553
|
-
data: {
|
|
554
|
-
deleted: files,
|
|
555
|
-
},
|
|
556
|
-
});
|
|
557
|
-
} catch (error) {
|
|
558
|
-
return c.json(
|
|
559
|
-
{
|
|
560
|
-
status: 'error',
|
|
561
|
-
error:
|
|
562
|
-
error instanceof Error ? error.message : 'Failed to delete files',
|
|
563
|
-
},
|
|
564
|
-
500,
|
|
565
|
-
);
|
|
566
|
-
}
|
|
567
|
-
},
|
|
372
|
+
handleDeleteFiles,
|
|
568
373
|
);
|
|
569
374
|
}
|
|
@@ -0,0 +1,338 @@
|
|
|
1
|
+
import type { Hono } from 'hono';
|
|
2
|
+
import { openApiRoute } from '../../openapi/route.ts';
|
|
3
|
+
import {
|
|
4
|
+
completeMCPAuth,
|
|
5
|
+
getMCPAuthStatus,
|
|
6
|
+
initiateMCPAuth,
|
|
7
|
+
revokeMCPAuth,
|
|
8
|
+
} from './service.ts';
|
|
9
|
+
import { copilotMCPOAuthStore, copilotMCPSessions } from './state.ts';
|
|
10
|
+
|
|
11
|
+
export function registerMCPAuthRoutes(app: Hono) {
|
|
12
|
+
openApiRoute(
|
|
13
|
+
app,
|
|
14
|
+
{
|
|
15
|
+
method: 'post',
|
|
16
|
+
path: '/v1/mcp/servers/{name}/auth',
|
|
17
|
+
tags: ['mcp'],
|
|
18
|
+
operationId: 'initiateMCPAuth',
|
|
19
|
+
summary: 'Initiate auth for an MCP server',
|
|
20
|
+
parameters: [
|
|
21
|
+
{
|
|
22
|
+
in: 'path',
|
|
23
|
+
name: 'name',
|
|
24
|
+
required: true,
|
|
25
|
+
schema: {
|
|
26
|
+
type: 'string',
|
|
27
|
+
},
|
|
28
|
+
description: 'MCP server name',
|
|
29
|
+
},
|
|
30
|
+
],
|
|
31
|
+
responses: {
|
|
32
|
+
'200': {
|
|
33
|
+
description: 'OK',
|
|
34
|
+
content: {
|
|
35
|
+
'application/json': {
|
|
36
|
+
schema: {
|
|
37
|
+
type: 'object',
|
|
38
|
+
properties: {
|
|
39
|
+
ok: {
|
|
40
|
+
type: 'boolean',
|
|
41
|
+
},
|
|
42
|
+
name: {
|
|
43
|
+
type: 'string',
|
|
44
|
+
},
|
|
45
|
+
authUrl: {
|
|
46
|
+
type: 'string',
|
|
47
|
+
},
|
|
48
|
+
authType: {
|
|
49
|
+
type: 'string',
|
|
50
|
+
},
|
|
51
|
+
authenticated: {
|
|
52
|
+
type: 'boolean',
|
|
53
|
+
},
|
|
54
|
+
sessionId: {
|
|
55
|
+
type: 'string',
|
|
56
|
+
},
|
|
57
|
+
userCode: {
|
|
58
|
+
type: 'string',
|
|
59
|
+
},
|
|
60
|
+
verificationUri: {
|
|
61
|
+
type: 'string',
|
|
62
|
+
},
|
|
63
|
+
interval: {
|
|
64
|
+
type: 'integer',
|
|
65
|
+
},
|
|
66
|
+
message: {
|
|
67
|
+
type: 'string',
|
|
68
|
+
},
|
|
69
|
+
error: {
|
|
70
|
+
type: 'string',
|
|
71
|
+
},
|
|
72
|
+
},
|
|
73
|
+
required: ['ok'],
|
|
74
|
+
},
|
|
75
|
+
},
|
|
76
|
+
},
|
|
77
|
+
},
|
|
78
|
+
'404': {
|
|
79
|
+
description: 'Bad Request',
|
|
80
|
+
content: {
|
|
81
|
+
'application/json': {
|
|
82
|
+
schema: {
|
|
83
|
+
type: 'object',
|
|
84
|
+
properties: {
|
|
85
|
+
error: {
|
|
86
|
+
type: 'string',
|
|
87
|
+
},
|
|
88
|
+
},
|
|
89
|
+
required: ['error'],
|
|
90
|
+
},
|
|
91
|
+
},
|
|
92
|
+
},
|
|
93
|
+
},
|
|
94
|
+
},
|
|
95
|
+
},
|
|
96
|
+
async (c) => {
|
|
97
|
+
const result = await initiateMCPAuth({
|
|
98
|
+
name: c.req.param('name'),
|
|
99
|
+
oAuthStore: copilotMCPOAuthStore,
|
|
100
|
+
sessions: copilotMCPSessions,
|
|
101
|
+
});
|
|
102
|
+
return result.ok
|
|
103
|
+
? c.json(result.body)
|
|
104
|
+
: c.json(result.body, result.status);
|
|
105
|
+
},
|
|
106
|
+
);
|
|
107
|
+
|
|
108
|
+
openApiRoute(
|
|
109
|
+
app,
|
|
110
|
+
{
|
|
111
|
+
method: 'post',
|
|
112
|
+
path: '/v1/mcp/servers/{name}/auth/callback',
|
|
113
|
+
tags: ['mcp'],
|
|
114
|
+
operationId: 'completeMCPAuth',
|
|
115
|
+
summary: 'Complete MCP server auth callback',
|
|
116
|
+
parameters: [
|
|
117
|
+
{
|
|
118
|
+
in: 'path',
|
|
119
|
+
name: 'name',
|
|
120
|
+
required: true,
|
|
121
|
+
schema: {
|
|
122
|
+
type: 'string',
|
|
123
|
+
},
|
|
124
|
+
description: 'MCP server name',
|
|
125
|
+
},
|
|
126
|
+
],
|
|
127
|
+
requestBody: {
|
|
128
|
+
required: true,
|
|
129
|
+
content: {
|
|
130
|
+
'application/json': {
|
|
131
|
+
schema: {
|
|
132
|
+
type: 'object',
|
|
133
|
+
properties: {
|
|
134
|
+
code: {
|
|
135
|
+
type: 'string',
|
|
136
|
+
},
|
|
137
|
+
sessionId: {
|
|
138
|
+
type: 'string',
|
|
139
|
+
},
|
|
140
|
+
},
|
|
141
|
+
},
|
|
142
|
+
},
|
|
143
|
+
},
|
|
144
|
+
},
|
|
145
|
+
responses: {
|
|
146
|
+
'200': {
|
|
147
|
+
description: 'OK',
|
|
148
|
+
content: {
|
|
149
|
+
'application/json': {
|
|
150
|
+
schema: {
|
|
151
|
+
type: 'object',
|
|
152
|
+
properties: {
|
|
153
|
+
ok: {
|
|
154
|
+
type: 'boolean',
|
|
155
|
+
},
|
|
156
|
+
status: {
|
|
157
|
+
type: 'string',
|
|
158
|
+
enum: ['complete', 'pending', 'error'],
|
|
159
|
+
},
|
|
160
|
+
name: {
|
|
161
|
+
type: 'string',
|
|
162
|
+
},
|
|
163
|
+
connected: {
|
|
164
|
+
type: 'boolean',
|
|
165
|
+
},
|
|
166
|
+
tools: {
|
|
167
|
+
type: 'array',
|
|
168
|
+
items: {
|
|
169
|
+
type: 'object',
|
|
170
|
+
properties: {
|
|
171
|
+
name: {
|
|
172
|
+
type: 'string',
|
|
173
|
+
},
|
|
174
|
+
description: {
|
|
175
|
+
type: 'string',
|
|
176
|
+
},
|
|
177
|
+
},
|
|
178
|
+
},
|
|
179
|
+
},
|
|
180
|
+
error: {
|
|
181
|
+
type: 'string',
|
|
182
|
+
},
|
|
183
|
+
},
|
|
184
|
+
required: ['ok'],
|
|
185
|
+
},
|
|
186
|
+
},
|
|
187
|
+
},
|
|
188
|
+
},
|
|
189
|
+
'400': {
|
|
190
|
+
description: 'Bad Request',
|
|
191
|
+
content: {
|
|
192
|
+
'application/json': {
|
|
193
|
+
schema: {
|
|
194
|
+
type: 'object',
|
|
195
|
+
properties: {
|
|
196
|
+
error: {
|
|
197
|
+
type: 'string',
|
|
198
|
+
},
|
|
199
|
+
},
|
|
200
|
+
required: ['error'],
|
|
201
|
+
},
|
|
202
|
+
},
|
|
203
|
+
},
|
|
204
|
+
},
|
|
205
|
+
},
|
|
206
|
+
},
|
|
207
|
+
async (c) => {
|
|
208
|
+
const result = await completeMCPAuth({
|
|
209
|
+
name: c.req.param('name'),
|
|
210
|
+
body: await c.req.json(),
|
|
211
|
+
oAuthStore: copilotMCPOAuthStore,
|
|
212
|
+
sessions: copilotMCPSessions,
|
|
213
|
+
});
|
|
214
|
+
return result.ok
|
|
215
|
+
? c.json(result.body)
|
|
216
|
+
: c.json(result.body, result.status);
|
|
217
|
+
},
|
|
218
|
+
);
|
|
219
|
+
|
|
220
|
+
openApiRoute(
|
|
221
|
+
app,
|
|
222
|
+
{
|
|
223
|
+
method: 'get',
|
|
224
|
+
path: '/v1/mcp/servers/{name}/auth/status',
|
|
225
|
+
tags: ['mcp'],
|
|
226
|
+
operationId: 'getMCPAuthStatus',
|
|
227
|
+
summary: 'Get auth status for an MCP server',
|
|
228
|
+
parameters: [
|
|
229
|
+
{
|
|
230
|
+
in: 'path',
|
|
231
|
+
name: 'name',
|
|
232
|
+
required: true,
|
|
233
|
+
schema: {
|
|
234
|
+
type: 'string',
|
|
235
|
+
},
|
|
236
|
+
description: 'MCP server name',
|
|
237
|
+
},
|
|
238
|
+
],
|
|
239
|
+
responses: {
|
|
240
|
+
'200': {
|
|
241
|
+
description: 'OK',
|
|
242
|
+
content: {
|
|
243
|
+
'application/json': {
|
|
244
|
+
schema: {
|
|
245
|
+
type: 'object',
|
|
246
|
+
properties: {
|
|
247
|
+
authenticated: {
|
|
248
|
+
type: 'boolean',
|
|
249
|
+
},
|
|
250
|
+
authType: {
|
|
251
|
+
type: 'string',
|
|
252
|
+
},
|
|
253
|
+
},
|
|
254
|
+
required: ['authenticated'],
|
|
255
|
+
},
|
|
256
|
+
},
|
|
257
|
+
},
|
|
258
|
+
},
|
|
259
|
+
},
|
|
260
|
+
},
|
|
261
|
+
async (c) => {
|
|
262
|
+
return c.json(
|
|
263
|
+
await getMCPAuthStatus({
|
|
264
|
+
name: c.req.param('name'),
|
|
265
|
+
oAuthStore: copilotMCPOAuthStore,
|
|
266
|
+
}),
|
|
267
|
+
);
|
|
268
|
+
},
|
|
269
|
+
);
|
|
270
|
+
|
|
271
|
+
openApiRoute(
|
|
272
|
+
app,
|
|
273
|
+
{
|
|
274
|
+
method: 'delete',
|
|
275
|
+
path: '/v1/mcp/servers/{name}/auth',
|
|
276
|
+
tags: ['mcp'],
|
|
277
|
+
operationId: 'revokeMCPAuth',
|
|
278
|
+
summary: 'Revoke auth for an MCP server',
|
|
279
|
+
parameters: [
|
|
280
|
+
{
|
|
281
|
+
in: 'path',
|
|
282
|
+
name: 'name',
|
|
283
|
+
required: true,
|
|
284
|
+
schema: {
|
|
285
|
+
type: 'string',
|
|
286
|
+
},
|
|
287
|
+
description: 'MCP server name',
|
|
288
|
+
},
|
|
289
|
+
],
|
|
290
|
+
responses: {
|
|
291
|
+
'200': {
|
|
292
|
+
description: 'OK',
|
|
293
|
+
content: {
|
|
294
|
+
'application/json': {
|
|
295
|
+
schema: {
|
|
296
|
+
type: 'object',
|
|
297
|
+
properties: {
|
|
298
|
+
ok: {
|
|
299
|
+
type: 'boolean',
|
|
300
|
+
},
|
|
301
|
+
error: {
|
|
302
|
+
type: 'string',
|
|
303
|
+
},
|
|
304
|
+
},
|
|
305
|
+
required: ['ok'],
|
|
306
|
+
},
|
|
307
|
+
},
|
|
308
|
+
},
|
|
309
|
+
},
|
|
310
|
+
'400': {
|
|
311
|
+
description: 'Bad Request',
|
|
312
|
+
content: {
|
|
313
|
+
'application/json': {
|
|
314
|
+
schema: {
|
|
315
|
+
type: 'object',
|
|
316
|
+
properties: {
|
|
317
|
+
error: {
|
|
318
|
+
type: 'string',
|
|
319
|
+
},
|
|
320
|
+
},
|
|
321
|
+
required: ['error'],
|
|
322
|
+
},
|
|
323
|
+
},
|
|
324
|
+
},
|
|
325
|
+
},
|
|
326
|
+
},
|
|
327
|
+
},
|
|
328
|
+
async (c) => {
|
|
329
|
+
const result = await revokeMCPAuth({
|
|
330
|
+
name: c.req.param('name'),
|
|
331
|
+
oAuthStore: copilotMCPOAuthStore,
|
|
332
|
+
});
|
|
333
|
+
return result.ok
|
|
334
|
+
? c.json(result.body)
|
|
335
|
+
: c.json(result.body, result.status);
|
|
336
|
+
},
|
|
337
|
+
);
|
|
338
|
+
}
|