-
-
Notifications
You must be signed in to change notification settings - Fork 13
Expand file tree
/
Copy pathprompts.ts
More file actions
70 lines (65 loc) · 2.4 KB
/
Copy pathprompts.ts
File metadata and controls
70 lines (65 loc) · 2.4 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
import { z } from "zod";
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import {
mergePrompts,
readPromptsConfig,
substituteTemplate,
type PromptArg,
type PromptDef,
} from "./prompts-config.js";
/** Build a Zod raw shape from a prompt's declared arguments. */
function buildArgsSchema(args: PromptArg[]): Record<string, z.ZodTypeAny> {
const shape: Record<string, z.ZodTypeAny> = {};
for (const arg of args) {
if (!arg?.name) continue;
let field: z.ZodString = z.string();
if (arg.description) field = field.describe(arg.description);
shape[arg.name] = arg.required ? field : field.optional();
}
return shape;
}
/**
* Register all prompts — shipped built-ins (merged with any user overrides)
* plus user-defined custom prompts from `<configDir>/prompts.json`. Called by
* the stdio entrypoint once at startup and by the daemon per HTTP request
* (which is why daemon clients pick up edits on their next connection).
*
* Reads the config synchronously; never throws. A single malformed prompt is
* logged and skipped rather than failing the whole registration.
*/
export function registerPrompts(server: McpServer): void {
const prompts: PromptDef[] = mergePrompts(readPromptsConfig());
const seen = new Set<string>();
for (const prompt of prompts) {
if (!prompt.name || seen.has(prompt.name)) continue;
seen.add(prompt.name);
const render = (args: Record<string, unknown> = {}) => ({
description: prompt.description,
messages: [
{
role: "user" as const,
content: { type: "text" as const, text: substituteTemplate(prompt.template, args) },
},
],
});
try {
// No-arg prompts use the SDK's two-arg form (no argsSchema); arg-bearing
// prompts pass a Zod shape built from their declared arguments.
if (prompt.arguments.length === 0) {
server.registerPrompt(prompt.name, { title: prompt.name, description: prompt.description }, () => render());
} else {
server.registerPrompt(
prompt.name,
{
title: prompt.name,
description: prompt.description,
argsSchema: buildArgsSchema(prompt.arguments),
},
(args) => render(args as Record<string, unknown>),
);
}
} catch (err) {
console.error(`[perplexity-mcp] failed to register prompt '${prompt.name}':`, err);
}
}
}