Skip to content

Commit 7d7547f

Browse files
Merge pull request #63 from sveltejs/automatic-prompt-sync-with-docs
2 parents ec9c5b3 + 0360d00 commit 7d7547f

File tree

9 files changed

+322
-102
lines changed

9 files changed

+322
-102
lines changed

.changeset/common-vans-poke.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@sveltejs/mcp': patch
3+
---
4+
5+
fix: minor tweaks to the prompt to allow for automatic sync
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
name: Update Prompt Documentation
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
paths:
8+
- 'packages/mcp-server/src/mcp/handlers/prompts/**'
9+
10+
permissions:
11+
contents: write
12+
pull-requests: write
13+
14+
jobs:
15+
update-docs:
16+
# prevents this action from running on forks
17+
if: github.repository == 'sveltejs/mcp'
18+
name: Update Prompt Documentation
19+
runs-on: ubuntu-latest
20+
steps:
21+
- name: Checkout
22+
uses: actions/checkout@v5
23+
with:
24+
fetch-depth: 0
25+
26+
- name: Setup Node.js
27+
uses: actions/setup-node@v5
28+
with:
29+
node-version: 24
30+
package-manager-cache: false # pnpm is not installed yet
31+
32+
- name: Install pnpm
33+
shell: bash
34+
run: |
35+
PNPM_VER=$(jq -r '.packageManager | if .[0:5] == "pnpm@" then .[5:] else "packageManager in package.json does not start with pnpm@\n" | halt_error(1) end' package.json)
36+
echo installing pnpm version $PNPM_VER
37+
npm i -g pnpm@$PNPM_VER
38+
39+
- name: Setup Node.js with pnpm cache
40+
uses: actions/setup-node@v5
41+
with:
42+
node-version: 24
43+
package-manager-cache: true # caches pnpm via packageManager field in package.json
44+
45+
- name: Install dependencies
46+
run: pnpm install --frozen-lockfile --prefer-offline --ignore-scripts
47+
48+
- name: Generate prompt documentation
49+
run: pnpm generate-prompt-docs
50+
51+
- name: Check for changes
52+
id: git-check
53+
run: |
54+
git diff --exit-code documentation/docs/30-capabilities/30-prompts.md || echo "changed=true" >> $GITHUB_OUTPUT
55+
56+
- name: Create Pull Request
57+
if: steps.git-check.outputs.changed == 'true'
58+
uses: peter-evans/create-pull-request@v7
59+
with:
60+
token: ${{ secrets.GITHUB_TOKEN }}
61+
commit-message: 'docs: update prompts documentation'
62+
branch: docs/update-prompt-docs
63+
delete-branch: true
64+
title: 'docs: update prompt documentation'
65+
body: |
66+
## Summary
67+
Automatically generated documentation update for MCP prompts.
68+
69+
This PR was triggered by changes to the prompts folder in `packages/mcp-server/src/mcp/handlers/prompts/`.
70+
71+
## Changes
72+
- Updated `documentation/docs/30-capabilities/30-prompts.md` with latest prompt definitions
73+
74+
## Generated by
75+
GitHub Action: Update Prompt Documentation
76+
labels: |
77+
documentation
78+
automated

.vscode/mcp-snippets.code-snippets

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,4 +30,62 @@
3030
],
3131
"description": "Create a setup export for an autofixer",
3232
},
33+
"Prompt Generator": {
34+
"scope": "javascript,typescript",
35+
"prefix": "!prompt",
36+
"body": [
37+
"import type { SvelteMcp } from '../../index.js';",
38+
"",
39+
"/**",
40+
" * Function that actually generates the prompt string. You can use this in the MCP server handler to generate the prompt, it can accept arguments",
41+
" * if needed (it will always be invoked manually so it's up to you to provide the arguments).",
42+
" */",
43+
"function ${1:prompt_name}() {",
44+
"\treturn `$0`;",
45+
"}",
46+
"",
47+
"/**",
48+
" * This function is used to generate the prompt to update the docs in the script `/scripts/update-docs-prompts.ts` it should use the default export",
49+
" * function and pass in the arguments. Since it will be included in the documentation if it's an argument that the MCP will expose it should",
50+
" * be in the format [NAME_OF_THE_ARGUMENT] to signal the user that it can substitute it.",
51+
" * ",
52+
" * The name NEEDS to be `generate_for_docs`.",
53+
" */",
54+
"export async function generate_for_docs() {",
55+
"\treturn ${1:prompt_name}();",
56+
"}",
57+
"",
58+
"/**",
59+
" * Human readable description of what the prompt does. It will be included in the documentation.",
60+
" * ",
61+
" * The name NEEDS to be `docs_description`.",
62+
" */",
63+
"export const docs_description = '';",
64+
"",
65+
"export function setup_${1:prompt_name}(server: SvelteMcp) {",
66+
"\tserver.prompt(",
67+
"\t\t{",
68+
"\t\t\tname: '${1:prompt_name}',",
69+
"\t\t\ttitle: '${2:title}',",
70+
"\t\t\tdescription:",
71+
"\t\t\t\t'${3:llm_description}',",
72+
"\t\t},",
73+
"\t\tasync () => {",
74+
"\t\t\treturn {",
75+
"\t\t\t\tmessages: [",
76+
"\t\t\t\t\t{",
77+
"\t\t\t\t\t\trole: 'assistant',",
78+
"\t\t\t\t\t\tcontent: {",
79+
"\t\t\t\t\t\t\ttype: 'text',",
80+
"\t\t\t\t\t\t\ttext: ${1:prompt_name}(),",
81+
"\t\t\t\t\t\t},",
82+
"\t\t\t\t\t},",
83+
"\t\t\t\t],",
84+
"\t\t\t};",
85+
"\t\t},",
86+
"\t);",
87+
"}",
88+
],
89+
"description": "Create a setup export for a prompt generator",
90+
},
3391
}

package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
"test:watch": "npm run test:unit -- --watch",
1818
"inspect": "pnpm mcp-inspector",
1919
"generate-summaries": "pnpm --filter @sveltejs/mcp-server run generate-summaries",
20+
"generate-prompt-docs": "node --import node-resolve-ts/register scripts/update-docs-prompts.ts",
2021
"debug:generate-summaries": "pnpm --filter @sveltejs/mcp-server run debug:generate-summaries",
2122
"release": "pnpm --filter @sveltejs/mcp run build && changeset publish",
2223
"changeset:version": "changeset version && pnpm --filter @sveltejs/mcp run update:version && git add --all"
@@ -39,6 +40,7 @@
3940
"eslint-plugin-import": "^2.32.0",
4041
"eslint-plugin-svelte": "^3.12.3",
4142
"globals": "^16.0.0",
43+
"node-resolve-ts": "^1.0.2",
4244
"prettier": "^3.4.2",
4345
"prettier-plugin-svelte": "^3.3.3",
4446
"publint": "^0.3.13",
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
export * from './svelte-task.js';
1+
export { setup_svelte_task } from './svelte-task.js';

packages/mcp-server/src/mcp/handlers/prompts/svelte-task.ts

Lines changed: 54 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,68 @@ import type { SvelteMcp } from '../../index.js';
22
import * as v from 'valibot';
33
import { format_sections_list } from '../../utils.js';
44

5+
/**
6+
* Function that actually generates the prompt string. You can use this in the MCP server handler to generate the prompt, it can accept arguments
7+
* if needed (it will always be invoked manually so it's up to you to provide the arguments).
8+
*/
9+
function svelte_task(available_docs: string, task: string) {
10+
return `You are a Svelte expert tasked to build components and utilities for Svelte developers. If you need documentation for anything related to Svelte you can invoke the tool \`get_documentation\` with one of the following paths:
11+
<available-docs>
12+
13+
${available_docs}
14+
15+
</available-docs>
16+
17+
Every time you write a Svelte component or a Svelte module you MUST invoke the \`svelte-autofixer\` tool providing the code. The tool will return a list of issues or suggestions. If there are any issues or suggestions you MUST fix them and call the tool again with the updated code. You MUST keep doing this until the tool returns no issues or suggestions. Only then you can return the code to the user.
18+
19+
This is the task you will work on:
20+
21+
<task>
22+
${task}
23+
</task>
24+
25+
If you are not writing the code into a file, once you have the final version of the code ask the user if it wants to generate a playground link to quickly check the code in it and if it answer yes call the \`playground-link\` tool and return the url to the user nicely formatted. The playground link MUST be generated only once you have the final version of the code and you are ready to share it, it MUST include an entry point file called \`App.svelte\` where the main component should live. If you have multiple files to include in the playground link you can include them all at the root.`;
26+
}
27+
28+
/**
29+
* This function is used to generate the prompt to update the docs in the script `/scripts/update-docs-prompts.ts` it should use the default export
30+
* function and pass in the arguments. Since it will be included in the documentation if it's an argument that the MCP will expose it should
31+
* be in the format [NAME_OF_THE_ARGUMENT] to signal the user that it can substitute it.
32+
*
33+
* The name NEEDS to be `generate_for_docs`.
34+
*/
35+
export async function generate_for_docs() {
36+
const available_docs = await format_sections_list();
37+
return svelte_task(available_docs, '[YOUR TASK HERE]');
38+
}
39+
40+
/**
41+
* Human readable description of what the prompt does. It will be included in the documentation.
42+
*
43+
* The name NEEDS to be `docs_description`.
44+
*/
45+
export const docs_description =
46+
'This prompt should be used whenever you are asking the model to work on a Svelte-related task. It will instruct the LLM which documentation sections are available, which tools to invoke, when to invoke them, and how to interpret the results.';
47+
548
export function setup_svelte_task(server: SvelteMcp) {
649
server.prompt(
750
{
8-
name: 'svelte-task-prompt',
51+
name: 'svelte-task',
952
title: 'Svelte-Task-Prompt',
1053
description:
1154
'Use this Prompt to ask for any svelte related task. It will automatically instruct the LLM on how to best use the autofixer and how to query for documentation pages.',
1255
schema: v.object({
1356
task: v.pipe(v.string(), v.description('The task to be performed')),
1457
}),
58+
complete: {
59+
task() {
60+
return {
61+
completion: {
62+
values: [''],
63+
},
64+
};
65+
},
66+
},
1567
},
1668
async ({ task }) => {
1769
const available_docs = await format_sections_list();
@@ -22,21 +74,7 @@ export function setup_svelte_task(server: SvelteMcp) {
2274
role: 'user',
2375
content: {
2476
type: 'text',
25-
text: `You are a Svelte expert tasked to build components and utilities for Svelte developers. If you need documentation for anything related to Svelte you can invoke the tool \`get_documentation\` with one of the following paths:
26-
<available-docs>
27-
${available_docs}
28-
</available-docs>
29-
30-
Every time you write a Svelte component or a Svelte module you MUST invoke the \`svelte-autofixer\` tool providing the code. The tool will return a list of issues or suggestions. If there are any issues or suggestions you MUST fix them and call the tool again with the updated code. You MUST keep doing this until the tool returns no issues or suggestions. Only then you can return the code to the user.
31-
32-
This is the task you will work on:
33-
34-
<task>
35-
${task}
36-
</task>
37-
38-
If you are not writing the code into a file, once you have the final version of the code ask the user if it wants to generate a playground link to quickly check the code in it and if it answer yes call the \`playground-link\` tool and return the url to the user nicely formatted. The playground link MUST be generated only once you have the final version of the code and you are ready to share it, it MUST include an entry point file called \`App.svelte\` where the main component should live. If you have multiple files to include in the playground link you can include them all at the root.
39-
`,
77+
text: svelte_task(available_docs, task),
4078
},
4179
},
4280
],

packages/mcp-server/src/mcp/utils.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,6 @@ export async function get_sections() {
5151
export async function format_sections_list() {
5252
const sections = await get_sections();
5353
return sections
54-
.map((s) => `* title: ${s.title}, use_cases: ${s.use_cases}, path: ${s.slug}`)
54+
.map((s) => `- title: ${s.title}, use_cases: ${s.use_cases}, path: ${s.slug}`)
5555
.join('\n');
5656
}

0 commit comments

Comments
 (0)