@decocms/runtime 1.0.0-alpha.40 → 1.0.0-alpha.42
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 +1 -1
- package/src/index.ts +9 -0
- package/src/oauth.ts +1 -5
- package/src/tools.ts +141 -2
package/package.json
CHANGED
package/src/index.ts
CHANGED
|
@@ -14,6 +14,15 @@ import {
|
|
|
14
14
|
type CreateMCPServerOptions,
|
|
15
15
|
MCPServer,
|
|
16
16
|
} from "./tools.ts";
|
|
17
|
+
export {
|
|
18
|
+
createPrompt,
|
|
19
|
+
createPublicPrompt,
|
|
20
|
+
type Prompt,
|
|
21
|
+
type PromptArgsRawShape,
|
|
22
|
+
type PromptExecutionContext,
|
|
23
|
+
type CreatedPrompt,
|
|
24
|
+
type GetPromptResult,
|
|
25
|
+
} from "./tools.ts";
|
|
17
26
|
import type { Binding } from "./wrangler.ts";
|
|
18
27
|
export { proxyConnectionForId, BindingOf } from "./bindings.ts";
|
|
19
28
|
export { type CORSOptions, type CORSOrigin } from "./cors.ts";
|
package/src/oauth.ts
CHANGED
|
@@ -480,11 +480,7 @@ export function createOAuthHandlers(oauth: OAuthConfig) {
|
|
|
480
480
|
/**
|
|
481
481
|
* Check if request has authentication token
|
|
482
482
|
*/
|
|
483
|
-
const hasAuth = (req: Request)
|
|
484
|
-
const authHeader = req.headers.get("Authorization");
|
|
485
|
-
const meshToken = req.headers.get("x-mesh-token");
|
|
486
|
-
return !!(authHeader || meshToken);
|
|
487
|
-
};
|
|
483
|
+
const hasAuth = (req: Request) => req.headers.has("Authorization");
|
|
488
484
|
|
|
489
485
|
return {
|
|
490
486
|
handleProtectedResourceMetadata,
|
package/src/tools.ts
CHANGED
|
@@ -7,6 +7,7 @@ import {
|
|
|
7
7
|
type EventBusBindingClient,
|
|
8
8
|
} from "@decocms/bindings";
|
|
9
9
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
10
|
+
import type { GetPromptResult } from "@modelcontextprotocol/sdk/types.js";
|
|
10
11
|
import { z } from "zod";
|
|
11
12
|
import { zodToJsonSchema } from "zod-to-json-schema";
|
|
12
13
|
import { BindingRegistry } from "./bindings.ts";
|
|
@@ -81,6 +82,58 @@ export type CreatedTool = {
|
|
|
81
82
|
}): Promise<unknown>;
|
|
82
83
|
};
|
|
83
84
|
|
|
85
|
+
// Re-export GetPromptResult for external use
|
|
86
|
+
export type { GetPromptResult } from "@modelcontextprotocol/sdk/types.js";
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Prompt argument schema shape - must be string types per MCP specification.
|
|
90
|
+
* Unlike tool arguments, prompt arguments are always strings.
|
|
91
|
+
*/
|
|
92
|
+
export type PromptArgsRawShape = {
|
|
93
|
+
[k: string]:
|
|
94
|
+
| z.ZodType<string, z.ZodTypeDef, string>
|
|
95
|
+
| z.ZodOptional<z.ZodType<string, z.ZodTypeDef, string>>;
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Context passed to prompt execute functions.
|
|
100
|
+
*/
|
|
101
|
+
export interface PromptExecutionContext<
|
|
102
|
+
TArgs extends PromptArgsRawShape = PromptArgsRawShape,
|
|
103
|
+
> {
|
|
104
|
+
args: z.objectOutputType<TArgs, z.ZodTypeAny>;
|
|
105
|
+
runtimeContext: AppContext;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Prompt interface with generic argument types for type-safe prompt creation.
|
|
110
|
+
*/
|
|
111
|
+
export interface Prompt<TArgs extends PromptArgsRawShape = PromptArgsRawShape> {
|
|
112
|
+
name: string;
|
|
113
|
+
title?: string;
|
|
114
|
+
description?: string;
|
|
115
|
+
argsSchema?: TArgs;
|
|
116
|
+
execute(
|
|
117
|
+
context: PromptExecutionContext<TArgs>,
|
|
118
|
+
): Promise<GetPromptResult> | GetPromptResult;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* CreatedPrompt is a permissive type that any Prompt can be assigned to.
|
|
123
|
+
* Uses a structural type with relaxed execute signature to allow prompts with any schema.
|
|
124
|
+
*/
|
|
125
|
+
export type CreatedPrompt = {
|
|
126
|
+
name: string;
|
|
127
|
+
title?: string;
|
|
128
|
+
description?: string;
|
|
129
|
+
argsSchema?: PromptArgsRawShape;
|
|
130
|
+
// Use a permissive execute signature - accepts any args shape
|
|
131
|
+
execute(context: {
|
|
132
|
+
args: Record<string, string | undefined>;
|
|
133
|
+
runtimeContext: AppContext;
|
|
134
|
+
}): Promise<GetPromptResult> | GetPromptResult;
|
|
135
|
+
};
|
|
136
|
+
|
|
84
137
|
/**
|
|
85
138
|
* creates a private tool that always ensure for athentication before being executed
|
|
86
139
|
*/
|
|
@@ -134,6 +187,43 @@ export function createTool<
|
|
|
134
187
|
};
|
|
135
188
|
}
|
|
136
189
|
|
|
190
|
+
/**
|
|
191
|
+
* Creates a public prompt that does not require authentication.
|
|
192
|
+
*/
|
|
193
|
+
export function createPublicPrompt<TArgs extends PromptArgsRawShape>(
|
|
194
|
+
opts: Prompt<TArgs>,
|
|
195
|
+
): Prompt<TArgs> {
|
|
196
|
+
return {
|
|
197
|
+
...opts,
|
|
198
|
+
execute: (input: PromptExecutionContext<TArgs>) => {
|
|
199
|
+
return opts.execute({
|
|
200
|
+
...input,
|
|
201
|
+
runtimeContext: createRuntimeContext(input.runtimeContext),
|
|
202
|
+
});
|
|
203
|
+
},
|
|
204
|
+
};
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
/**
|
|
208
|
+
* Creates a prompt that always ensures authentication before being executed.
|
|
209
|
+
* This is the default and recommended way to create prompts.
|
|
210
|
+
*/
|
|
211
|
+
export function createPrompt<TArgs extends PromptArgsRawShape>(
|
|
212
|
+
opts: Prompt<TArgs>,
|
|
213
|
+
): Prompt<TArgs> {
|
|
214
|
+
const execute = opts.execute;
|
|
215
|
+
return createPublicPrompt({
|
|
216
|
+
...opts,
|
|
217
|
+
execute: (input: PromptExecutionContext<TArgs>) => {
|
|
218
|
+
const env = input.runtimeContext.env;
|
|
219
|
+
if (env) {
|
|
220
|
+
env.MESH_REQUEST_CONTEXT?.ensureAuthenticated();
|
|
221
|
+
}
|
|
222
|
+
return execute(input);
|
|
223
|
+
},
|
|
224
|
+
});
|
|
225
|
+
}
|
|
226
|
+
|
|
137
227
|
export interface ViewExport {
|
|
138
228
|
title: string;
|
|
139
229
|
icon: string;
|
|
@@ -260,6 +350,17 @@ export interface CreateMCPServerOptions<
|
|
|
260
350
|
| Promise<CreatedTool[]>
|
|
261
351
|
>
|
|
262
352
|
| ((env: TEnv) => CreatedTool[] | Promise<CreatedTool[]>);
|
|
353
|
+
prompts?:
|
|
354
|
+
| Array<
|
|
355
|
+
(
|
|
356
|
+
env: TEnv,
|
|
357
|
+
) =>
|
|
358
|
+
| Promise<CreatedPrompt>
|
|
359
|
+
| CreatedPrompt
|
|
360
|
+
| CreatedPrompt[]
|
|
361
|
+
| Promise<CreatedPrompt[]>
|
|
362
|
+
>
|
|
363
|
+
| ((env: TEnv) => CreatedPrompt[] | Promise<CreatedPrompt[]>);
|
|
263
364
|
}
|
|
264
365
|
|
|
265
366
|
export type Fetch<TEnv = unknown> = (
|
|
@@ -399,7 +500,7 @@ export const createMCPServer = <
|
|
|
399
500
|
|
|
400
501
|
const server = new McpServer(
|
|
401
502
|
{ name: "@deco/mcp-api", version: "1.0.0" },
|
|
402
|
-
{ capabilities: { tools: {} } },
|
|
503
|
+
{ capabilities: { tools: {}, prompts: {} } },
|
|
403
504
|
);
|
|
404
505
|
|
|
405
506
|
const toolsFn =
|
|
@@ -466,7 +567,45 @@ export const createMCPServer = <
|
|
|
466
567
|
);
|
|
467
568
|
}
|
|
468
569
|
|
|
469
|
-
|
|
570
|
+
// Resolve and register prompts
|
|
571
|
+
const promptsFn =
|
|
572
|
+
typeof options.prompts === "function"
|
|
573
|
+
? options.prompts
|
|
574
|
+
: async (bindings: TEnv) => {
|
|
575
|
+
if (typeof options.prompts === "function") {
|
|
576
|
+
return await options.prompts(bindings);
|
|
577
|
+
}
|
|
578
|
+
return await Promise.all(
|
|
579
|
+
options.prompts?.flatMap(async (prompt) => {
|
|
580
|
+
const promptResult = prompt(bindings);
|
|
581
|
+
const awaited = await promptResult;
|
|
582
|
+
if (Array.isArray(awaited)) {
|
|
583
|
+
return awaited;
|
|
584
|
+
}
|
|
585
|
+
return [awaited];
|
|
586
|
+
}) ?? [],
|
|
587
|
+
).then((p) => p.flat());
|
|
588
|
+
};
|
|
589
|
+
const prompts = await promptsFn(bindings);
|
|
590
|
+
|
|
591
|
+
for (const prompt of prompts) {
|
|
592
|
+
server.registerPrompt(
|
|
593
|
+
prompt.name,
|
|
594
|
+
{
|
|
595
|
+
title: prompt.title,
|
|
596
|
+
description: prompt.description,
|
|
597
|
+
argsSchema: prompt.argsSchema,
|
|
598
|
+
},
|
|
599
|
+
async (args) => {
|
|
600
|
+
return await prompt.execute({
|
|
601
|
+
args: args as Record<string, string | undefined>,
|
|
602
|
+
runtimeContext: createRuntimeContext(),
|
|
603
|
+
});
|
|
604
|
+
},
|
|
605
|
+
);
|
|
606
|
+
}
|
|
607
|
+
|
|
608
|
+
return { server, tools, prompts };
|
|
470
609
|
};
|
|
471
610
|
|
|
472
611
|
const fetch = async (req: Request, env: TEnv) => {
|