Compare commits

...

145 Commits

Author SHA1 Message Date
paoloricciuti
cb9764c234 docs: add link to CLAUDE.md and AGENTS.md docs 2025-10-08 17:22:15 +02:00
paoloricciuti
73d7625b3c chore: changesets 2025-10-07 21:34:19 +02:00
Paolo Ricciuti
c7060c8bdb Merge pull request #20 from sveltejs/attachments-autofixer 2025-10-07 21:31:50 +02:00
Paolo Ricciuti
ef2d569934 Merge pull request #26 from sveltejs/function-call-in-effect 2025-10-07 21:31:21 +02:00
Paolo Ricciuti
7ba57b45ae Merge pull request #52 from theetherGit/zed-config 2025-10-07 12:04:00 +02:00
Paolo Ricciuti
fe393bf480 docs: remove command shortcut 2025-10-07 11:59:21 +02:00
theetherGit
a63deba99d chore: Lint 2025-10-07 15:05:36 +05:30
Paolo Ricciuti
668a2e4481 Merge pull request #51 from sveltejs/renovate/all-minor-patch 2025-10-07 10:23:08 +02:00
Shivam Meena
04c82875f3 Add MCP to zed guide 2025-10-07 12:12:05 +05:30
renovate[bot]
84601f9ab0 chore(deps): update pnpm to v10.18.1 2025-10-06 14:34:35 +00:00
Paolo Ricciuti
e01a050017 Merge pull request #50 from sveltejs/changeset-release/main 2025-10-06 12:36:23 +02:00
github-actions[bot]
5920f7482f Version Packages 2025-10-06 10:30:53 +00:00
Paolo Ricciuti
fa90a2be8d Merge pull request #49 from sveltejs/allow-ts-modules 2025-10-06 12:30:23 +02:00
paoloricciuti
73bf0c3782 fix: allow TS .svelte.ts modules 2025-10-06 12:13:22 +02:00
Paolo Ricciuti
8785ad224c Merge pull request #40 from sveltejs/changeset-release/main 2025-10-05 11:24:27 +02:00
github-actions[bot]
75e676d928 Version Packages 2025-10-04 22:54:37 +00:00
Paolo Ricciuti
5b16bdd80b Merge pull request #41 from 43081j/effect-pre-assign
fix: check effect.pre in assign-in-effect
2025-10-05 00:54:12 +02:00
James Garbutt
f3ee4ed59c chore: run format 2025-10-04 20:12:47 +01:00
paoloricciuti
725f785766 chore: changeset 2025-10-04 16:50:04 +02:00
paoloricciuti
485e60e245 fix: change title names to allow claude code to invoke the prompt 2025-10-04 16:49:23 +02:00
Paolo Ricciuti
480bfca557 Merge pull request #38 from sveltejs/renovate/actions-setup-node-5.x 2025-10-04 16:40:42 +02:00
renovate[bot]
06f9fc6d63 chore(deps): update actions/setup-node action to v5 2025-10-04 14:39:44 +00:00
Paolo Ricciuti
f1f85d2445 Merge pull request #33 from sveltejs/renovate/actions-checkout-5.x 2025-10-04 16:39:20 +02:00
renovate[bot]
b9c0a011e2 chore(deps): update actions/checkout action to v5 2025-10-04 14:37:40 +00:00
Paolo Ricciuti
b92dd95dee Merge pull request #32 from sveltejs/renovate/all-minor-patch 2025-10-04 16:37:15 +02:00
Paolo Ricciuti
99537cfa25 chore: add changesets 2025-10-04 16:34:43 +02:00
James Garbutt
f93a6cee60 fix: check effect.pre in assign-in-effect
It seems like the intention here was to check `$effect` _and_
`$effect.pre`, but the condition (`in_effect`) was filtering those out.
The `is_rune` helper already does the same checks, so we can just remove
the ones here and delegate to that.
2025-10-04 12:18:08 +01:00
renovate[bot]
e8989db548 chore(deps): update all non-major dependencies 2025-10-04 07:55:47 +00:00
paoloricciuti
cb316c5b3e fix: enable doc tools 2025-10-04 09:54:14 +02:00
Paolo Ricciuti
7c762109b6 Merge pull request #39 from sveltejs/llms-txt 2025-10-04 01:58:09 +02:00
paoloricciuti
e3dbb5c098 fix: lint 2025-10-04 01:57:09 +02:00
paoloricciuti
03ce6c50c0 fix: package.json and lock 2025-10-04 01:55:42 +02:00
Paolo Ricciuti
273c78092d Merge branch 'main' into llms-txt 2025-10-04 01:53:03 +02:00
Paolo Ricciuti
891fae8127 Merge pull request #29 from sveltejs/llms-txt-plus-use-cases
Generate use_cases documentation metadata
2025-10-04 01:46:05 +02:00
Paolo Ricciuti
fa969feb28 fix: update package name 2025-10-04 01:32:13 +02:00
Paolo Ricciuti
1dbd93a1ce Update use_cases documentation metadata format 2025-10-04 01:30:58 +02:00
paoloricciuti
3bb71f3963 chore: infer when possible, move schemas, add tsconfig to scripts 2025-10-04 01:27:27 +02:00
Stanislav Khromov
a881cb5938 move to devdeps 2025-10-04 01:19:48 +02:00
Stanislav Khromov
03859141ed rewrite to valibot 2025-10-04 01:07:15 +02:00
Stanislav Khromov
f747c4ac65 remove tsx 2025-10-04 00:55:11 +02:00
Stanislav Khromov
1916c410e6 use --experimental-strip-types 2025-10-04 00:53:37 +02:00
Stanislav Khromov
1e7ebeaf5b Merge branch 'llms-txt-plus-use-cases' of https://github.com/sveltejs/mcp into llms-txt-plus-use-cases 2025-10-04 00:48:43 +02:00
Stanislav Khromov
f82ceac79d validate sections 2025-10-04 00:48:41 +02:00
Stanislav Khromov
cde6d700e6 Update packages/mcp-server/src/mcp/utils.ts
Co-authored-by: Paolo Ricciuti <ricciutipaolo@gmail.com>
2025-10-04 00:46:23 +02:00
Stanislav Khromov
522fae6017 Update packages/mcp-server/src/mcp/utils.ts
Co-authored-by: Paolo Ricciuti <ricciutipaolo@gmail.com>
2025-10-04 00:39:44 +02:00
Stanislav Khromov
1f94d33dc9 Update packages/mcp-server/src/mcp/utils.ts
Co-authored-by: Paolo Ricciuti <ricciutipaolo@gmail.com>
2025-10-04 00:39:26 +02:00
Paolo Ricciuti
7ada706deb Merge pull request #37 from sveltejs/minor-text-fixes 2025-10-03 23:32:30 +02:00
Stanislav Khromov
796c38ee23 doc nits 2025-10-03 23:25:02 +02:00
Paolo Ricciuti
1f296e5277 Merge pull request #35 from sveltejs/changeset-release/main 2025-10-03 22:42:11 +02:00
github-actions[bot]
121395e98e Version Packages 2025-10-03 20:38:35 +00:00
paoloricciuti
8e7c881838 fix: just build we can figure out later if we want to avoid it 2025-10-03 22:38:08 +02:00
Paolo Ricciuti
91c396e675 Merge pull request #25 from sveltejs/setup-changesets 2025-10-03 22:35:50 +02:00
paoloricciuti
baad760634 chore: add changeset to trigger release 2025-10-03 22:34:55 +02:00
paoloricciuti
b2275587ee fix: remove package manager from inner packages 2025-10-03 22:33:56 +02:00
Paolo Ricciuti
4964303100 chore: apply suggestions from code review
Co-authored-by: Dominik G. <dominik.goepel@gmx.de>
2025-10-03 22:31:46 +02:00
paoloricciuti
81901b2564 fix: small configs 2025-10-03 22:03:59 +02:00
paoloricciuti
5aa1aa401a Merge branch 'main' into setup-changesets 2025-10-03 21:52:45 +02:00
Rich Harris
4201627f53 Merge pull request #31 from sveltejs/docs
docs: add documentation for svelte.dev
2025-10-03 15:22:59 -04:00
paoloricciuti
9a70fbe3aa feat: redirect to docs in case someone visits via browser 2025-10-03 21:12:42 +02:00
Paolo Ricciuti
dc16a42c65 chore: apply suggestions from code review
Co-authored-by: Rich Harris <hello@rich-harris.dev>
2025-10-03 19:11:14 +02:00
Paolo Ricciuti
3b50014b09 chore: apply suggestions from code review
Co-authored-by: Rich Harris <hello@rich-harris.dev>
2025-10-03 18:43:56 +02:00
Paolo Ricciuti
e9214bc470 chore: apply suggestions from code review
Co-authored-by: Rich Harris <hello@rich-harris.dev>
2025-10-03 18:33:31 +02:00
Paolo Ricciuti
3106305902 chore: apply suggestions from code review
Co-authored-by: Rich Harris <hello@rich-harris.dev>
2025-10-03 18:24:35 +02:00
paoloricciuti
3c14872068 fix: LLM -> model 2025-10-03 17:20:38 +02:00
paoloricciuti
216a470bd2 docs: add documentation for svelte.dev 2025-10-03 16:49:43 +02:00
paoloricciuti
b5a88c454d fix: small typos 2025-10-03 16:49:24 +02:00
Stanislav Khromov
937216e1de use format function 2025-10-02 23:44:38 +02:00
Stanislav Khromov
6a23b9c87f use slug for path 2025-10-02 23:44:27 +02:00
Stanislav Khromov
8064a4f5cf remove docs/ prefix 2025-10-02 23:42:19 +02:00
Stanislav Khromov
005b9d45bd Prioritize use_cases from metadata, fallback to JSON, then empty string
Updated get_sections() to use a three-tier priority system for use_cases:
1. section.metadata.use_cases (from API)
2. summaries[section.slug] (from use_cases.json)
3. '' (empty string fallback)

This ensures we always have the most up-to-date use cases from the API
while maintaining local fallbacks for sections that haven't been updated yet.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-02 23:04:32 +02:00
Stanislav Khromov
12a80515a0 Update utils.ts 2025-10-02 23:03:02 +02:00
Stanislav Khromov
7acbaad478 Merge main into llms-txt-plus-use-cases
Resolved conflicts by adopting main's dynamic documentation fetching approach:
- utils.ts: Use dynamic fetch from svelte.dev instead of hardcoded sections
- utils.ts: Read use_cases from metadata instead of hardcoded JSON
- svelte-task.ts: Keep format_sections_list() for formatted output
- Added new schemas/index.ts from main

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-02 23:01:57 +02:00
Stanislav Khromov
55f9009a77 wip 2025-10-02 22:56:17 +02:00
Stanislav Khromov
02042daa02 Update svelte-task.ts 2025-10-02 22:53:34 +02:00
Stanislav Khromov
eb5444e3b6 format 2025-10-02 22:43:27 +02:00
Stanislav Khromov
c3134bdfde Update prompts.ts 2025-10-02 22:40:00 +02:00
Stanislav Khromov
334f9330e7 Update list-sections.ts 2025-10-02 22:38:52 +02:00
Stanislav Khromov
b16448b6df wip 2025-10-02 22:35:17 +02:00
Stanislav Khromov
b0888d6ac3 format, delete readme 2025-10-02 22:28:34 +02:00
Stanislav Khromov
6fc0419fc5 wip 2025-10-02 22:24:32 +02:00
Stanislav Khromov
d138349c46 fixes 2025-10-02 22:07:03 +02:00
Stanislav Khromov
e1a1cb1d84 Update anthropic.ts 2025-10-02 22:04:43 +02:00
Stanislav Khromov
e723198db0 Update utils.ts 2025-10-02 22:01:43 +02:00
Paolo Ricciuti
7b5bea6549 Merge pull request #28 from sveltejs/llms-txt
feat: simplified documentation listing
2025-10-02 11:46:33 +02:00
paoloricciuti
a36d0d17a8 fix: validate response and default use_cases 2025-10-02 11:29:35 +02:00
paoloricciuti
70f14bddca feat: use endpoint to get sections 2025-10-02 08:03:03 +02:00
Stanislav Khromov
7dedb277be fix paths 2025-10-02 01:28:42 +02:00
Stanislav Khromov
de45c1b015 Update generate-summaries.ts 2025-10-02 01:24:05 +02:00
Stanislav Khromov
94f12964cb fix path 2025-10-02 01:23:51 +02:00
Stanislav Khromov
7366dad0e9 wip 2025-10-02 01:18:32 +02:00
Stanislav Khromov
22aaad43f3 wip 2025-10-02 01:16:43 +02:00
Stanislav Khromov
1332513847 Update utils.ts 2025-10-02 01:14:20 +02:00
Stanislav Khromov
988da97816 add example summaries 2025-10-02 01:10:08 +02:00
Stanislav Khromov
b086e634fe wip 2025-10-02 01:01:09 +02:00
Stanislav Khromov
fd72afc2a3 Update generate-summaries.ts 2025-10-02 00:58:53 +02:00
Stanislav Khromov
5736e853e6 Update generate-summaries.ts 2025-10-02 00:55:41 +02:00
Stanislav Khromov
0f2747423b refactor 2025-10-02 00:53:28 +02:00
Stanislav Khromov
a49773f0ff wip 2025-10-02 00:47:33 +02:00
Stanislav Khromov
56b47f1108 wip 2025-10-02 00:46:48 +02:00
Stanislav Khromov
207d1f80bf Create README.md 2025-10-02 00:43:28 +02:00
Stanislav Khromov
0cda036ab6 add initial 2025-10-02 00:43:24 +02:00
paoloricciuti
a281ef4b66 fix: use server.template with list and complete for docs resources 2025-09-28 12:19:43 +02:00
paoloricciuti
5bc812e4db fix: enable list-sections tool 2025-09-28 12:19:21 +02:00
paoloricciuti
82319661dd feat: add sections to prompt 2025-09-28 12:19:03 +02:00
paoloricciuti
ce0861c1ca chore: use mocked current version of sections 2025-09-28 12:18:52 +02:00
Stanislav Khromov
5dd83d151e Update utils.ts 2025-09-27 00:14:00 +02:00
Stanislav Khromov
76a35f5dc8 format 2025-09-27 00:13:37 +02:00
Stanislav Khromov
54763e0f55 Update packages/mcp-server/src/mcp/utils.ts
Co-authored-by: Paolo Ricciuti <ricciutipaolo@gmail.com>
2025-09-27 00:07:18 +02:00
Stanislav Khromov
01d5803b5d reduce duplication 2025-09-27 00:06:37 +02:00
Stanislav Khromov
0366bc785b Merge branch 'llms-txt' of https://github.com/sveltejs/mcp into llms-txt 2025-09-27 00:03:49 +02:00
Stanislav Khromov
6a6417d3a5 Use Promise.allSettled() 2025-09-27 00:03:40 +02:00
Stanislav Khromov
77af7ebcc6 Update packages/mcp-server/src/mcp/handlers/tools/get-documentation.ts
Co-authored-by: Paolo Ricciuti <ricciutipaolo@gmail.com>
2025-09-27 00:01:50 +02:00
Stanislav Khromov
b1a196497d Update list-sections.ts 2025-09-27 00:00:15 +02:00
Stanislav Khromov
fb2d19fd07 Update list-sections.ts 2025-09-26 23:59:18 +02:00
Stanislav Khromov
8328a3572b eslint 2025-09-26 23:51:58 +02:00
Stanislav Khromov
c05b6c257a eslint 2025-09-26 23:51:48 +02:00
Stanislav Khromov
7f9ea742d8 don't lint .claude dir 2025-09-26 23:48:15 +02:00
Stanislav Khromov
bf477a6ccf Update get-documentation.ts 2025-09-26 23:46:07 +02:00
Stanislav Khromov
0f5482477a Update get-documentation.ts 2025-09-26 22:44:28 +02:00
Stanislav Khromov
b774b463fe Update get-documentation.ts 2025-09-26 22:42:42 +02:00
Stanislav Khromov
c49b24d36a wip 2025-09-26 22:39:52 +02:00
Stanislav Khromov
6cb97ac11d Update get-documentation.ts 2025-09-26 22:36:30 +02:00
Stanislav Khromov
d33a374417 Update get-documentation.ts 2025-09-26 21:56:38 +02:00
Stanislav Khromov
1bb171cea7 cleanup 2025-09-26 20:44:41 +02:00
Stanislav Khromov
e314ab57b2 Update list-sections.ts 2025-09-26 20:43:04 +02:00
Stanislav Khromov
19cacf7ed9 refactor 2025-09-26 20:39:22 +02:00
Stanislav Khromov
68cf69a117 wip 2025-09-26 20:38:17 +02:00
Stanislav Khromov
917fdf63b1 enable 2025-09-26 20:34:57 +02:00
Stanislav Khromov
972cadc410 Update package.json 2025-09-26 20:30:16 +02:00
Stanislav Khromov
dc6c87ce37 Merge branch 'main' into llms-txt 2025-09-26 20:30:11 +02:00
Stanislav Khromov
e7431e9024 Update README.md 2025-09-26 20:29:55 +02:00
Stanislav Khromov
07737a8edd Add Claude Code .mcp.json config 2025-09-26 20:22:50 +02:00
Stanislav Khromov
fdb7689992 fix stdio path 2025-09-26 20:21:43 +02:00
paoloricciuti
8483bd672d feat: add autofixer to tell the LLM to check if some function called in effect is assigning state 2025-09-26 13:04:11 +02:00
paoloricciuti
1a283f60bc chore: disable unimplemented tools/resources 2025-09-24 22:11:21 +02:00
paoloricciuti
bb16ccca3a fix: pnpm versions and package.json 2025-09-24 16:06:32 +02:00
paoloricciuti
23ddaf9495 fix: update pnpm version 2025-09-24 15:59:34 +02:00
paoloricciuti
4228302ed0 fix: package.json's 2025-09-24 15:57:17 +02:00
Paolo Ricciuti
0bc4d75e13 chore: use the right repo name 🤦
Co-authored-by: Dominik G. <dominik.goepel@gmx.de>
2025-09-24 15:53:12 +02:00
paoloricciuti
4679549401 chore: setup changesets 2025-09-24 15:43:42 +02:00
paoloricciuti
8414ffbcc8 fix: move attachments fixer 2025-09-23 23:05:53 +02:00
paoloricciuti
5798b50ceb Merge branch 'main' into attachments-autofixer 2025-09-23 23:04:38 +02:00
paoloricciuti
e560932211 Merge branch 'main' into attachments-autofixer 2025-09-23 23:03:13 +02:00
paoloricciuti
9504e6bac9 feat: autofixer action -> attachment 2025-09-23 00:49:09 +02:00
paoloricciuti
7086e8e55f feat: add bind:this -> attachment autofixer 2025-09-23 00:17:36 +02:00
54 changed files with 2669 additions and 561 deletions

8
.changeset/README.md Normal file
View File

@@ -0,0 +1,8 @@
# Changesets
Hello and welcome! This folder has been automatically generated by `@changesets/cli`, a build tool that works
with multi-package repos, or single-package repos to help you version and publish your code. You can
find the full documentation for it [in our repository](https://github.com/changesets/changesets)
We have a quick list of common questions to get you started engaging with this project in
[our documentation](https://github.com/changesets/changesets/blob/main/docs/common-questions.md)

11
.changeset/config.json Normal file
View File

@@ -0,0 +1,11 @@
{
"$schema": "https://unpkg.com/@changesets/config@3.1.1/schema.json",
"changelog": ["@svitejs/changesets-changelog-github-compact", { "repo": "sveltejs/mcp" }],
"commit": false,
"fixed": [],
"linked": [],
"access": "public",
"baseBranch": "main",
"updateInternalDependencies": "patch",
"ignore": []
}

View File

@@ -0,0 +1,5 @@
---
'@sveltejs/mcp': patch
---
feat: add autofixer to tell the LLM to check if some function called in effect is assigning state #26

View File

@@ -0,0 +1,5 @@
---
'@sveltejs/mcp': patch
---
feat: add bind:this -> attachment and action -> attachment autofixer #20

View File

@@ -1,2 +1,3 @@
.claude
.github
.github
.vscode

1
.cocominify Normal file
View File

@@ -0,0 +1 @@
packages/mcp-server/src/use_cases.json

View File

@@ -13,15 +13,15 @@ jobs:
steps:
- name: Checkout Repository
uses: actions/checkout@v4
uses: actions/checkout@v5
- name: Setup pnpm
uses: pnpm/action-setup@v4
with:
version: 10
version: 10.18.1
- name: Setup Node.js
uses: actions/setup-node@v4
uses: actions/setup-node@v5
with:
node-version: '22'
cache: 'pnpm'

View File

@@ -13,15 +13,15 @@ jobs:
steps:
- name: Checkout Repository
uses: actions/checkout@v4
uses: actions/checkout@v5
- name: Setup pnpm
uses: pnpm/action-setup@v4
with:
version: 10
version: 10.18.1
- name: Setup Node.js
uses: actions/setup-node@v4
uses: actions/setup-node@v5
with:
node-version: '22'
cache: 'pnpm'

58
.github/workflows/release.yml vendored Normal file
View File

@@ -0,0 +1,58 @@
name: Release
on:
push:
branches:
- main
permissions: {}
jobs:
release:
permissions:
contents: write # to create release (changesets/action)
id-token: write # OpenID Connect token needed for provenance
pull-requests: write # to create pull request (changesets/action)
# prevents this action from running on forks
if: github.repository == 'sveltejs/mcp'
name: Release
runs-on: ${{ matrix.os }}
strategy:
matrix:
# pseudo-matrix for convenience, NEVER use more than a single combination
node: [24]
os: [ubuntu-latest]
steps:
- name: checkout
uses: actions/checkout@v5
with:
# This makes Actions fetch all Git history so that Changesets can generate changelogs with the correct commits
fetch-depth: 0
- uses: actions/setup-node@v5
with:
node-version: ${{ matrix.node }}
package-manager-cache: false # pnpm is not installed yet
- name: install pnpm
shell: bash
run: |
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)
echo installing pnpm version $PNPM_VER
npm i -g pnpm@$PNPM_VER
- uses: actions/setup-node@v5
with:
node-version: ${{ matrix.node }}
package-manager-cache: true # caches pnpm via packageManager field in package.json
- name: install
run: pnpm install --frozen-lockfile --prefer-offline --ignore-scripts
- name: build
run: pnpm run --filter ./packages/mcp-stdio/ build
- name: Create Release Pull Request or Publish to npm
id: changesets
# pinned for security, always review third party action code before updating
uses: changesets/action@e0145edc7d9d8679003495b11f87bd8ef63c0cba # v1.5.3
with:
# This expects you to have a script called release which does a build for your packages and calls changeset publish
publish: pnpm release
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
NPM_CONFIG_PROVENANCE: true

View File

@@ -13,15 +13,15 @@ jobs:
steps:
- name: Checkout Repository
uses: actions/checkout@v4
uses: actions/checkout@v5
- name: Setup pnpm
uses: pnpm/action-setup@v4
with:
version: 10
version: 10.18.1
- name: Setup Node.js
uses: actions/setup-node@v4
uses: actions/setup-node@v5
with:
node-version: '22'
cache: 'pnpm'

View File

@@ -1,8 +1,9 @@
{
"mcpServers": {
"svelte-llm": {
"type": "http",
"url": "https://svelte-llm.stanislav.garden/mcp/mcp"
"svelte": {
"type": "stdio",
"command": "node",
"args": ["packages/mcp-stdio/dist/index.js"]
}
}
}

View File

@@ -8,4 +8,7 @@ bun.lockb
# Miscellaneous
/static/
/drizzle/
/**/.svelte-kit/*
/**/.svelte-kit/*
# Claude Code
.claude/

2
.vscode/mcp.json vendored
View File

@@ -3,7 +3,7 @@
"Svelte MCP": {
"type": "stdio",
"command": "node",
"args": ["dist/lib/stdio.js"]
"args": ["packages/mcp-stdio/dist/index.js"]
}
},
"inputs": []

View File

@@ -90,12 +90,12 @@ When connected to the svelte-llm MCP server, you have access to comprehensive Sv
## Available MCP Tools:
### 1. list_sections
### 1. list-sections
Use this FIRST to discover all available documentation sections. Returns a structured list with titles and paths.
When asked about Svelte or SvelteKit topics, ALWAYS use this tool at the start of the chat to find relevant sections.
### 2. get_documentation
### 2. get-documentation
Retrieves full documentation content for specific sections. Accepts single or multiple sections.
After calling the list_sections tool, you MUST analyze the returned documentation sections and then use the get_documentation tool to fetch ALL documentation sections that are relevant for the users task.
After calling the list-sections tool, you MUST analyze the returned documentation sections and then use the get_documentation tool to fetch ALL documentation sections that are relevant for the users task.

View File

@@ -6,7 +6,7 @@ Repo for the official Svelte MCP server.
```
pnpm i
cp .env.example .env
cp apps/mcp-remote/.env.example apps/mcp-remote/.env
pnpm dev
```

View File

@@ -39,15 +39,15 @@
"devDependencies": {
"@eslint/compat": "^1.3.2",
"@eslint/js": "^9.36.0",
"@libsql/client": "^0.14.0",
"@modelcontextprotocol/inspector": "^0.16.7",
"@libsql/client": "^0.15.0",
"@modelcontextprotocol/inspector": "^0.17.0",
"@sveltejs/adapter-vercel": "^5.6.3",
"@sveltejs/kit": "^2.22.0",
"@sveltejs/vite-plugin-svelte": "^6.0.0",
"@types/node": "^24.3.1",
"@typescript-eslint/parser": "^8.44.0",
"drizzle-kit": "^0.30.2",
"drizzle-orm": "^0.40.0",
"drizzle-kit": "^0.31.0",
"drizzle-orm": "^0.44.0",
"eslint-config-prettier": "^10.0.1",
"eslint-plugin-svelte": "^3.12.3",
"globals": "^16.0.0",

View File

@@ -1,7 +1,19 @@
import { http_transport } from '$lib/mcp/index.js';
import { db } from '$lib/server/db/index.js';
import { redirect } from '@sveltejs/kit';
export async function handle({ event, resolve }) {
if (event.request.method === 'GET') {
const accept = event.request.headers.get('accept');
if (accept) {
const accepts = accept.split(',');
if (!accepts.includes('text/event-stream')) {
// the request it's a browser request, not an MCP client request
// it means someone probably opened it from the docs...we should redirect to the docs
redirect(302, 'https://svelte.dev/docs/mcp/overview');
}
}
}
const mcp_response = await http_transport.respond(event.request, {
db,
});

View File

@@ -0,0 +1,44 @@
---
title: Overview
---
The Svelte MCP ([Model Context Protocol](https://modelcontextprotocol.io/docs/getting-started/intro)) server can help your LLM or agent of choice write better Svelte code. It works by providing documentation relevant to the task at hand, and statically analysing generated code so that it can suggest fixes and best practices.
## Setup
The setup varies based on the version of the MCP you prefer — remote or local — and your chosen MCP client (e.g. Claude Code, Codex CLI or GitHub Copilot):
- [local setup](local-setup) using `@sveltejs/mcp`
- [remote setup](remote-setup) using `https://mcp.svelte.dev/mcp`
## Usage
To get the most out of the MCP server we recommend including the following prompt in your [`AGENTS.md`](https://agents.md) (or [`CLAUDE.md`](https://docs.claude.com/en/docs/claude-code/memory#claude-md-imports), if using Claude Code). This will tell the LLM which tools are available and when it's appropriate to use them.
```md
You are able to use the Svelte MCP server, where you have access to comprehensive Svelte 5 and SvelteKit documentation. Here's how to use the available tools effectively:
## Available MCP Tools:
### 1. list-sections
Use this FIRST to discover all available documentation sections. Returns a structured list with titles, use_cases, and paths.
When asked about Svelte or SvelteKit topics, ALWAYS use this tool at the start of the chat to find relevant sections.
### 2. get-documentation
Retrieves full documentation content for specific sections. Accepts single or multiple sections.
After calling the list-sections tool, you MUST analyze the returned documentation sections (especially the use_cases field) and then use the get-documentation tool to fetch ALL documentation sections that are relevant for the user's task.
### 3. svelte-autofixer
Analyzes Svelte code and returns issues and suggestions.
You MUST use this tool whenever writing Svelte code before sending it to the user. Keep calling it until no issues or suggestions are returned.
### 4. playground-link
Generates a Svelte Playground link with the provided code.
After completing the code, ask the user if they want a playground link. Only call this tool after user confirmation and NEVER if code was written to files in their project.
```
If your MCP client supports it, we also recommend using the [svelte-task](prompts#svelte-task) prompt to instruct the LLM on the best way to use the MCP server.

View File

@@ -0,0 +1,3 @@
---
title: Introduction
---

View File

@@ -0,0 +1,132 @@
---
title: Local setup
---
The local (or stdio) version of the MCP server is available via the [`@sveltejs/mcp`](https://www.npmjs.com/package/@sveltejs/mcp) npm package. You can either install it globally and then reference it in your configuration or run it with `npx`:
```bash
npx -y @sveltejs/mcp
```
Here's how to set it up in some common MCP clients:
## Claude Code
To include the local MCP version in Claude Code, simply run the following command:
```bash
claude mcp add -t stdio -s [scope] svelte npx -y @sveltejs/mcp
```
The `[scope]` must be `user`, `project` or `local`.
## Claude Desktop
In the Settings > Developer section, click on Edit Config. It will open the folder with a `claude_desktop_config.json` file in it. Edit the file to include the following configuration:
```json
{
"mcpServers": {
"svelte": {
"command": "npx",
"args": ["-y", "@sveltejs/mcp"]
}
}
}
```
## Codex CLI
Add the following to your `config.toml` (which defaults to `~/.codex/config.toml`, but refer to [the configuration documentation](https://github.com/openai/codex/blob/main/docs/config.md) for more advanced setups):
```toml
[mcp_servers.svelte]
command = "npx"
args = ["-y", "@sveltejs/mcp"]
```
## Gemini CLI
To include the local MCP version in Gemini CLI, simply run the following command:
```bash
gemini mcp add -t stdio -s [scope] svelte npx -y @sveltejs/mcp
```
The `[scope]` must be `user`, `project` or `local`.
## OpenCode
Run the command:
```bash
opencode mcp add
```
and follow the instructions, selecting 'Local' under the 'Select MCP server type' prompt:
```bash
opencode mcp add
┌ Add MCP server
◇ Enter MCP server name
│ svelte
◇ Select MCP server type
│ Local
◆ Enter command to run
│ npx -y @sveltejs/mcp
```
## VS Code
- Open the command palette
- Select "MCP: Add Server..."
- Select "Command (stdio)"
- Insert `npx -y @sveltejs/mcp` in the input and press `Enter`
- When prompted for a name, insert `svelte`
- Select if you want to add it as a `Global` or `Workspace` MCP server
## Cursor
- Open the command palette
- Select "View: Open MCP Settings"
- Click on "Add custom MCP"
It will open a file with your MCP servers where you can add the following configuration:
```json
{
"mcpServers": {
"svelte": {
"command": "npx",
"args": ["-y", "@sveltejs/mcp"]
}
}
}
```
## Zed
- Open the command palette
- Search and select "agent:open settings"
- In settings panel look for `Model Context Protocol (MCP) Servers`
- Click on "Add Server"
- Select: "Add Custom Server"
It will open a popup with MCP server config where you can add the following configuration:
```json
{
"svelte": {
"command": "npx",
"args": ["-y", "@sveltejs/mcp"]
}
}
```
## Other clients
If we didn't include the MCP client you are using, refer to their documentation for `stdio` servers and use `npx` as the command and `-y @sveltejs/mcp` as the arguments.

View File

@@ -0,0 +1,101 @@
---
title: Remote setup
---
The remote version of the MCP server is available at `https://mcp.svelte.dev/mcp`.
Here's how to set it up in some common MCP clients:
## Claude Code
To include the remote MCP version in Claude Code, simply run the following command:
```bash
claude mcp add -t http -s [scope] svelte https://mcp.svelte.dev/mcp
```
You can choose your preferred `scope` (it must be `user`, `project` or `local`) and `name`.
## Claude Desktop
- Open Settings > Connectors
- Click on Add Custom Connector
- When prompted for a name, enter `svelte`
- Under the Remote MCP server URL input, use `https://mcp.svelte.dev/mcp`
- Click Add
## Codex CLI
Add the following to your `config.toml` (which defaults to `~/.codex/config.toml`, but refer to [the configuration documentation](https://github.com/openai/codex/blob/main/docs/config.md) for more advanced setups):
```toml
experimental_use_rmcp_client = true
[mcp_servers.svelte]
url = "https://mcp.svelte.dev/mcp"
```
## Gemini CLI
To use the remote MCP server with Gemini CLI, simply run the following command:
```bash
gemini mcp add -t http -s [scope] svelte https://mcp.svelte.dev/mcp
```
The `[scope]` must be `user`, `project` or `local`.
## OpenCode
Run the command:
```bash
opencode mcp add
```
and follow the instructions, selecting 'Remote' under the 'Select MCP server type' prompt:
```bash
opencode mcp add
┌ Add MCP server
◇ Enter MCP server name
│ svelte
◇ Select MCP server type
│ Remote
◇ Enter MCP server URL
│ https://mcp.svelte.dev/mcp
```
## VS Code
- Open the command palette
- Select "MCP: Add Server..."
- Select "HTTP (HTTP or Server-Sent-Events)"
- Insert `https://mcp.svelte.dev/mcp` in the input and press `Enter`
- Insert your preferred name
- Select if you want to add it as a `Global` or `Workspace` MCP server
## Cursor
- Open the command palette
- Select "View: Open MCP Settings"
- Click on "Add custom MCP"
It will open a file with your MCP servers where you can add the following configuration:
```json
{
"mcpServers": {
"svelte": {
"url": "https://mcp.svelte.dev/mcp"
}
}
}
```
## Other clients
If we didn't include the MCP client you are using, refer to their documentation for `remote` servers and use `https://mcp.svelte.dev/mcp` as the URL.

View File

@@ -0,0 +1,3 @@
---
title: Setup
---

View File

@@ -0,0 +1,21 @@
---
title: Tools
---
The following tools are provided by the MCP server to the model you are using, which can decide to call one or more of them during a session:
## list-sections
Provides a list of all the available documentation sections.
## get-documentation
Allows the model to get the full (and up-to-date) documentation for the requested sections directly from [svelte.dev/docs](/docs).
## svelte-autofixer
Uses static analysis to provide suggestions for code that your LLM generates. It can be invoked in an agentic loop by your model until all issues and suggestions are resolved.
## playground-link
Generates an ephemeral playground link with the generated code. It's useful when the generated code is not written to a file in your project and you want to quickly test the generated solution. The code is not stored anywhere except the URL itself (which will often, as a consequence, be quite large).

View File

@@ -0,0 +1,9 @@
---
title: Resources
---
This is the list of available resources provided by the MCP server. Resources are included by the user (not by the LLM) and are useful if you want to include specific knowledge in your session. For example, if you know that the component will need to use transitions you can include the transition documentation directly without asking the LLM to do it for you.
## doc-section
This dynamic resource allows you to add every section of the Svelte documentation as a resource. The URI looks like this `svelte://slug-of-the-docs.md` and the returned resource will contain the `llms.txt` version of the specific page you selected.

View File

@@ -0,0 +1,9 @@
---
title: Prompts
---
This is the list of available prompts provided by the MCP server. Prompts are selected by the user and are sent as a user message. They can be useful to write repetitive instructions for the LLM on how to properly use the MCP server.
## svelte-task
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.

View File

@@ -0,0 +1,3 @@
---
title: Capabilities
---

View File

@@ -0,0 +1,3 @@
---
title: MCP
---

View File

@@ -12,6 +12,9 @@ const gitignore_path = fileURLToPath(new URL('./.gitignore', import.meta.url));
export default /** @type {import("eslint").Linter.Config} */ ([
includeIgnoreFile(gitignore_path),
{
ignores: ['.claude/**/*'],
},
js.configs.recommended,
...ts.configs.recommended,
...svelte.configs.recommended,

View File

@@ -3,16 +3,22 @@
"version": "0.0.1",
"description": "The official Svelte MCP server implementation",
"type": "module",
"packageManager": "pnpm@10.18.1",
"scripts": {
"build": "pnpm -r run build",
"dev": "pnpm --filter @sveltejs/mcp-remote run dev",
"check": "pnpm -r run check",
"check:publint": "pnpm -r run check:publint",
"format": "prettier --write .",
"lint": "prettier --check . && eslint .",
"lint:fix": "prettier --write . && eslint . --fix",
"test:unit": "vitest",
"test": "npm run test:unit -- --run",
"test:watch": "npm run test:unit -- --watch",
"inspect": "pnpm mcp-inspector"
"inspect": "pnpm mcp-inspector",
"generate-summaries": "pnpm --filter @sveltejs/mcp-server run generate-summaries",
"debug:generate-summaries": "pnpm --filter @sveltejs/mcp-server run debug:generate-summaries",
"release": "pnpm --filter @sveltejs/mcp run build && changeset publish"
},
"keywords": [
"svelte",
@@ -22,9 +28,11 @@
],
"private": true,
"devDependencies": {
"@changesets/cli": "^2.29.7",
"@eslint/compat": "^1.3.2",
"@eslint/js": "^9.36.0",
"@modelcontextprotocol/inspector": "^0.16.7",
"@modelcontextprotocol/inspector": "^0.17.0",
"@svitejs/changesets-changelog-github-compact": "^1.2.0",
"eslint": "^9.36.0",
"eslint-config-prettier": "^10.0.1",
"eslint-plugin-import": "^2.32.0",
@@ -32,6 +40,7 @@
"globals": "^16.0.0",
"prettier": "^3.4.2",
"prettier-plugin-svelte": "^3.3.3",
"publint": "^0.3.13",
"typescript": "^5.0.0",
"typescript-eslint": "^8.44.1",
"vitest": "^3.2.3"

View File

@@ -12,9 +12,8 @@
"keywords": [],
"author": "",
"license": "ISC",
"packageManager": "pnpm@10.15.1",
"type": "module",
"dependencies": {
"drizzle-orm": "^0.40.1"
"drizzle-orm": "^0.44.0"
}
}

View File

@@ -0,0 +1,2 @@
# Anthropic API Key from: https://console.anthropic.com/
ANTHROPIC_API_KEY=your_api_key_here

View File

@@ -7,16 +7,17 @@
"keywords": [],
"author": "",
"license": "ISC",
"packageManager": "pnpm@10.15.1",
"type": "module",
"scripts": {
"test": "vitest"
"test": "vitest",
"generate-summaries": "node scripts/generate-summaries.ts --experimental-strip-types",
"debug:generate-summaries": "DEBUG_MODE=1 node scripts/generate-summaries.ts --experimental-strip-types"
},
"exports": {
".": "./src/index.ts"
},
"peerDependencies": {
"drizzle-orm": "^0.40.0"
"drizzle-orm": "^0.44.0"
},
"dependencies": {
"@sveltejs/mcp-schema": "workspace:^",
@@ -27,15 +28,18 @@
"svelte": "^5.39.2",
"svelte-eslint-parser": "^1.3.2",
"tmcp": "^1.13.0",
"ts-blank-space": "^0.6.2",
"typescript-eslint": "^8.44.0",
"valibot": "^1.1.0",
"vitest": "^3.2.4",
"zimmerframe": "^1.1.4"
},
"devDependencies": {
"@anthropic-ai/sdk": "^0.65.0",
"@sveltejs/kit": "^2.42.2",
"@types/eslint-scope": "^8.3.2",
"@types/estree": "^1.0.8",
"@typescript-eslint/types": "^8.44.0"
"@typescript-eslint/types": "^8.44.0",
"dotenv": "^17.2.3"
}
}

View File

@@ -0,0 +1,244 @@
#!/usr/bin/env node
import 'dotenv/config';
import { writeFile, mkdir } from 'fs/promises';
import path from 'path';
import { fileURLToPath } from 'url';
import { get_sections } from '../src/mcp/utils.ts';
import { AnthropicProvider } from '../src/lib/anthropic.ts';
import { type AnthropicBatchRequest, type SummaryData } from '../src/lib/schemas.ts';
const current_filename = fileURLToPath(import.meta.url);
const current_dirname = path.dirname(current_filename);
const USE_CASES_PROMPT = `
You are tasked with analyzing Svelte 5 and SvelteKit documentation pages to identify when they would be useful.
Your task:
1. Read the documentation page content provided
2. Identify the main use cases, scenarios, or queries where this documentation would be relevant
3. Create a VERY SHORT, comma-separated list of use cases (maximum 200 characters total)
4. Think about what a developer might be trying to build or accomplish when they need this documentation
Guidelines:
- Focus on WHEN this documentation would be needed, not WHAT it contains
- Consider specific project types (e.g., "e-commerce site", "blog", "dashboard", "social media app")
- Consider specific features (e.g., "authentication", "forms", "data fetching", "animations")
- Consider specific components (e.g., "slider", "modal", "dropdown", "card")
- Consider development stages (e.g., "project setup", "deployment", "testing", "migration")
- Use "always" for fundamental concepts that apply to virtually all Svelte projects
- Be concise but specific
- Use lowercase
- Separate multiple use cases with commas
Examples of good use_cases:
- "always, any svelte project, core reactivity"
- "authentication, login systems, user management"
- "e-commerce, product listings, shopping carts"
- "forms, user input, data submission"
- "deployment, production builds, hosting setup"
- "animation, transitions, interactive ui"
- "routing, navigation, multi-page apps"
- "blog, content sites, markdown rendering"
Requirements:
- Maximum 200 characters (including spaces and commas)
- Lowercase only
- Comma-separated list of use cases
- Focus on WHEN/WHY someone would need this, not what it is
- Be specific about project types, features, or components when applicable
- Use "always" sparingly, only for truly universal concepts
- Do not include quotes or special formatting in your response
- Respond with ONLY the use cases text, no additional text
Here is the documentation page content to analyze:
`;
async function fetch_section_content(url: string) {
const response = await fetch(url, { signal: AbortSignal.timeout(30000) });
if (!response.ok) {
throw new Error(`Failed to fetch ${url}: ${response.status} ${response.statusText}`);
}
return await response.text();
}
async function main() {
console.log('🚀 Starting use cases generation...');
// Check for API key
const api_key = process.env.ANTHROPIC_API_KEY;
if (!api_key) {
console.error('❌ Error: ANTHROPIC_API_KEY environment variable is required');
console.error('Please set it in packages/mcp-server/.env file or export it:');
console.error('export ANTHROPIC_API_KEY=your_api_key_here');
process.exit(1);
}
// Get all sections
console.log('📚 Fetching documentation sections...');
let sections = await get_sections();
console.log(`Found ${sections.length} sections`);
// Debug mode: limit to 2 sections
const debug_mode = process.env.DEBUG_MODE === '1';
if (debug_mode) {
console.log('🐛 DEBUG_MODE enabled - processing only 2 sections');
sections = sections.slice(0, 2);
}
// Fetch content for each section
console.log('📥 Downloading section content...');
const sections_with_content: Array<{
section: (typeof sections)[number];
content: string;
index: number;
}> = [];
const download_errors: Array<{ section: string; error: string }> = [];
for (let i = 0; i < sections.length; i++) {
const section = sections[i]!;
try {
console.log(`Fetching ${i + 1}/${sections.length}: ${section.title}`);
const content = await fetch_section_content(section.url);
sections_with_content.push({
section,
content,
index: i,
});
} catch (error) {
const error_msg = error instanceof Error ? error.message : String(error);
console.error(`⚠️ Failed to fetch ${section.title}:`, error_msg);
download_errors.push({ section: section.title, error: error_msg });
}
}
console.log(`✅ Successfully downloaded ${sections_with_content.length} sections`);
if (sections_with_content.length === 0) {
console.error('❌ No sections were successfully downloaded');
process.exit(1);
}
// Initialize Anthropic client
console.log('🤖 Initializing Anthropic API...');
const anthropic = new AnthropicProvider('claude-sonnet-4-5-20250929', api_key);
// Prepare batch requests
console.log('📦 Preparing batch requests...');
const batch_requests: AnthropicBatchRequest[] = sections_with_content.map(
({ content, index }) => ({
custom_id: `section-${index}`,
params: {
model: anthropic.get_model_identifier(),
max_tokens: 250,
messages: [
{
role: 'user',
content: USE_CASES_PROMPT + content,
},
],
temperature: 0,
},
}),
);
// Create and process batch
console.log('🚀 Creating batch job...');
const batch_response = await anthropic.create_batch(batch_requests);
console.log(`✅ Batch created with ID: ${batch_response.id}`);
// Poll for completion
console.log('⏳ Waiting for batch to complete...');
let batch_status = await anthropic.get_batch_status(batch_response.id);
while (batch_status.processing_status === 'in_progress') {
const { succeeded, processing, errored } = batch_status.request_counts;
console.log(` Progress: ${succeeded} succeeded, ${processing} processing, ${errored} errored`);
await new Promise((resolve) => setTimeout(resolve, 5000));
batch_status = await anthropic.get_batch_status(batch_response.id);
}
console.log('✅ Batch processing completed!');
// Get results
if (!batch_status.results_url) {
throw new Error('Batch completed but no results URL available');
}
console.log('📥 Downloading results...');
const results = await anthropic.get_batch_results(batch_status.results_url);
// Process results
console.log('📊 Processing results...');
const summaries: Record<string, string> = {};
const errors: Array<{ section: string; error: string }> = [];
for (const result of results) {
const index = parseInt(result.custom_id.split('-')[1] ?? '0');
const section_data = sections_with_content.find((s) => s.index === index);
if (!section_data) {
console.warn(`⚠️ Could not find section for index ${index}`);
continue;
}
const { section } = section_data;
if (result.result.type !== 'succeeded' || !result.result.message) {
const error_msg = result.result.error?.message || 'Failed or no message';
console.error(`${section.title}: ${error_msg}`);
errors.push({ section: section.title, error: error_msg });
continue;
}
const output_content = result.result.message.content[0]?.text;
if (output_content) {
summaries[section.slug] = output_content.trim();
console.log(`${section.title}`);
}
}
// Write output to JSON file
console.log('💾 Writing results to file...');
const output_path = path.join(current_dirname, '../src/use_cases.json');
const output_dir = path.dirname(output_path);
await mkdir(output_dir, { recursive: true });
const summary_data: SummaryData = {
generated_at: new Date().toISOString(),
model: anthropic.get_model_identifier(),
total_sections: sections.length,
successful_summaries: Object.keys(summaries).length,
failed_summaries: errors.length,
summaries,
errors: errors.length > 0 ? errors : undefined,
download_errors: download_errors.length > 0 ? download_errors : undefined,
};
await writeFile(output_path, JSON.stringify(summary_data, null, 2), 'utf-8');
// Print summary
console.log('\n📊 Summary:');
console.log(` Total sections: ${sections.length}`);
console.log(` Successfully downloaded: ${sections_with_content.length}`);
console.log(` Download failures: ${download_errors.length}`);
console.log(` Successfully analyzed: ${Object.keys(summaries).length}`);
console.log(` Analysis failures: ${errors.length}`);
console.log(`\n✅ Results written to: ${output_path}`);
if (download_errors.length > 0) {
console.log('\n⚠ Some sections failed to download:');
download_errors.forEach((e) => console.log(` - ${e.section}: ${e.error}`));
}
if (errors.length > 0) {
console.log('\n⚠ Some sections failed to analyze:');
errors.forEach((e) => console.log(` - ${e.section}: ${e.error}`));
}
}
main().catch((error) => {
console.error('❌ Fatal error:', error);
process.exit(1);
});

View File

@@ -0,0 +1,6 @@
{
"extends": "../../../tsconfig.json",
"compilerOptions": {
"allowImportingTsExtensions": true
}
}

View File

@@ -0,0 +1,172 @@
import { Anthropic } from '@anthropic-ai/sdk';
import type { Model } from '@anthropic-ai/sdk/resources/messages/messages.js';
import * as v from 'valibot';
import {
anthropic_batch_response_schema,
anthropic_batch_result_schema,
type AnthropicBatchRequest,
} from './schemas.js';
export class AnthropicProvider {
private client: Anthropic;
private modelId: Model;
private baseUrl: string;
private apiKey: string;
name = 'Anthropic';
constructor(model_id: Model, api_key: string) {
if (!api_key) {
throw new Error('ANTHROPIC_API_KEY is required');
}
this.apiKey = api_key;
this.client = new Anthropic({ apiKey: api_key, timeout: 1800000 });
this.modelId = model_id;
this.baseUrl = 'https://api.anthropic.com/v1';
}
get_client(): Anthropic {
return this.client;
}
get_model_identifier(): Model {
return this.modelId;
}
async create_batch(requests: AnthropicBatchRequest[]) {
try {
const response = await fetch(`${this.baseUrl}/messages/batches`, {
method: 'POST',
headers: {
'x-api-key': this.apiKey,
'anthropic-version': '2023-06-01',
'content-type': 'application/json',
},
body: JSON.stringify({ requests }),
});
if (!response.ok) {
const error_text = await response.text();
throw new Error(
`Failed to create batch: ${response.status} ${response.statusText} - ${error_text}`,
);
}
const json_data = await response.json();
const validated_response = v.safeParse(anthropic_batch_response_schema, json_data);
if (!validated_response.success) {
throw new Error(
`Invalid batch response from Anthropic API: ${JSON.stringify(validated_response.issues)}`,
);
}
return validated_response.output;
} catch (error) {
console.error('Error creating batch with Anthropic:', error);
throw new Error(
`Failed to create batch: ${error instanceof Error ? error.message : String(error)}`,
);
}
}
async get_batch_status(batch_id: string, max_retries = 10, retry_delay = 30000) {
let retry_count = 0;
while (retry_count <= max_retries) {
try {
const response = await fetch(`${this.baseUrl}/messages/batches/${batch_id}`, {
method: 'GET',
headers: {
'x-api-key': this.apiKey,
'anthropic-version': '2023-06-01',
},
});
if (!response.ok) {
const error_text = await response.text();
throw new Error(
`Failed to get batch status: ${response.status} ${response.statusText} - ${error_text}`,
);
}
const json_data = await response.json();
const validated_response = v.safeParse(anthropic_batch_response_schema, json_data);
if (!validated_response.success) {
throw new Error(
`Invalid batch status response from Anthropic API: ${JSON.stringify(validated_response.issues)}`,
);
}
return validated_response.output;
} catch (error) {
retry_count++;
if (retry_count > max_retries) {
console.error(
`Error getting batch status for ${batch_id} after ${max_retries} retries:`,
error,
);
throw new Error(
`Failed to get batch status after ${max_retries} retries: ${
error instanceof Error ? error.message : String(error)
}`,
);
}
console.warn(
`Error getting batch status for ${batch_id} (attempt ${retry_count}/${max_retries}):`,
error,
);
console.log(`Retrying in ${retry_delay / 1000} seconds...`);
await new Promise((resolve) => setTimeout(resolve, retry_delay));
}
}
// This should never be reached due to the throw in the catch block, but TypeScript needs a return
throw new Error(`Failed to get batch status for ${batch_id} after ${max_retries} retries`);
}
async get_batch_results(results_url: string) {
try {
const response = await fetch(results_url, {
method: 'GET',
headers: {
'x-api-key': this.apiKey,
'anthropic-version': '2023-06-01',
},
});
if (!response.ok) {
const error_text = await response.text();
throw new Error(
`Failed to get batch results: ${response.status} ${response.statusText} - ${error_text}`,
);
}
const text = await response.text();
// Parse JSONL format (one JSON object per line)
const parsed_results = text
.split('\n')
.filter((line) => line.trim())
.map((line) => JSON.parse(line));
// Validate all results
const validated_results = v.safeParse(v.array(anthropic_batch_result_schema), parsed_results);
if (!validated_results.success) {
throw new Error(
`Invalid batch results from Anthropic API: ${JSON.stringify(validated_results.issues)}`,
);
}
return validated_results.output;
} catch (error) {
console.error(`Error getting batch results:`, error);
throw new Error(
`Failed to get batch results: ${error instanceof Error ? error.message : String(error)}`,
);
}
}
}

View File

@@ -0,0 +1,122 @@
import * as v from 'valibot';
export const documentation_sections_schema = v.record(
v.string(),
v.object({
metadata: v.object({
title: v.string(),
use_cases: v.optional(v.string()),
}),
slug: v.string(),
}),
);
// Valibot schemas for Batch API
export const summary_data_schema = v.object({
generated_at: v.string(),
model: v.string(),
total_sections: v.number(),
successful_summaries: v.number(),
failed_summaries: v.number(),
summaries: v.record(v.string(), v.string()),
errors: v.optional(
v.array(
v.object({
section: v.string(),
error: v.string(),
}),
),
),
download_errors: v.optional(
v.array(
v.object({
section: v.string(),
error: v.string(),
}),
),
),
});
export const anthropic_batch_request_schema = v.object({
custom_id: v.string(),
params: v.object({
model: v.string(),
max_tokens: v.number(),
messages: v.array(
v.object({
role: v.union([v.literal('user'), v.literal('assistant')]),
content: v.union([
v.string(),
v.array(
v.object({
type: v.string(),
text: v.string(),
}),
),
]),
}),
),
}),
});
export const anthropic_batch_response_schema = v.object({
id: v.string(),
type: v.string(),
processing_status: v.union([v.literal('in_progress'), v.literal('ended')]),
request_counts: v.object({
processing: v.number(),
succeeded: v.number(),
errored: v.number(),
canceled: v.number(),
expired: v.number(),
}),
ended_at: v.nullable(v.string()),
created_at: v.string(),
expires_at: v.string(),
cancel_initiated_at: v.nullable(v.string()),
results_url: v.nullable(v.string()),
});
export const anthropic_batch_result_schema = v.object({
custom_id: v.string(),
result: v.object({
type: v.union([
v.literal('succeeded'),
v.literal('errored'),
v.literal('canceled'),
v.literal('expired'),
]),
message: v.optional(
v.object({
id: v.string(),
type: v.string(),
role: v.string(),
model: v.string(),
content: v.array(
v.object({
type: v.string(),
text: v.string(),
}),
),
stop_reason: v.string(),
stop_sequence: v.nullable(v.string()),
usage: v.object({
input_tokens: v.number(),
output_tokens: v.number(),
}),
}),
),
error: v.optional(
v.object({
type: v.string(),
message: v.string(),
}),
),
}),
});
// Export inferred types
export type SummaryData = v.InferOutput<typeof summary_data_schema>;
export type AnthropicBatchRequest = v.InferOutput<typeof anthropic_batch_request_schema>;
export type AnthropicBatchResponse = v.InferOutput<typeof anthropic_batch_response_schema>;
export type AnthropicBatchResult = v.InferOutput<typeof anthropic_batch_result_schema>;

View File

@@ -61,7 +61,7 @@ describe('add_autofixers_issues', () => {
<script>
const count = ${init}(0);
</script>
<button onclick={() => count = 43}>Increment</button>
`);
@@ -74,7 +74,7 @@ describe('add_autofixers_issues', () => {
const content = run_autofixers_on_code(`
<script>
const count = 0;
$effect(() => {
count = 43;
});
@@ -89,7 +89,7 @@ describe('add_autofixers_issues', () => {
const content = run_autofixers_on_code(`
<script>
let count = ${init}(0);
$effect(() => {
count++;
});
@@ -105,7 +105,7 @@ describe('add_autofixers_issues', () => {
const content = run_autofixers_on_code(`
<script>
let count = ${init}({ value: 0 });
$effect(() => {
count.value = 42;
});
@@ -116,6 +116,52 @@ describe('add_autofixers_issues', () => {
'The stateful variable "count" is assigned inside an $effect which is generally consider a malpractice. Consider using $derived if possible.',
);
});
it(`should add a suggestion for variables that are mutated within an effect.pre`, () => {
const content = run_autofixers_on_code(`
<script>
let count = ${init}({ value: 0 });
$effect.pre(() => {
count.value = 42;
});
</script>
`);
expect(content.suggestions).toContain(
'The stateful variable "count" is assigned inside an $effect which is generally consider a malpractice. Consider using $derived if possible.',
);
});
});
it('should add a suggestion when calling a function inside an effect', () => {
const content = run_autofixers_on_code(`
<script>
import { fetch_data } from './data.js';
$effect(() => {
fetch_data();
});
</script>`);
expect(content.suggestions.length).toBeGreaterThanOrEqual(1);
expect(content.suggestions).toContain(
`You are calling the function \`fetch_data\` inside an $effect. Please check if the function is reassigning a stateful variable because that's considered malpractice and check if it could use \`$derived\` instead. Ignore this suggestion if you are sure this function is not assigning any stateful variable or if you can't check if it does.`,
);
});
it('should add a suggestion when calling a function inside an effect (with non identifier callee)', () => {
const content = run_autofixers_on_code(`
<script>
import { fetch_data } from './data.js';
$effect(() => {
fetch_data.fetch();
});
</script>`);
expect(content.suggestions.length).toBeGreaterThanOrEqual(1);
expect(content.suggestions).toContain(
`You are calling a function inside an $effect. Please check if the function is reassigning a stateful variable because that's considered malpractice and check if it could use \`$derived\` instead. Ignore this suggestion if you are sure this function is not assigning any stateful variable or if you can't check if it does.`,
);
});
});
@@ -468,4 +514,177 @@ describe('add_autofixers_issues', () => {
);
});
});
describe('suggest_attachments', () => {
describe('bind:this', () => {
it('should add suggestions when using bind:this on an element', () => {
const content = run_autofixers_on_code(`
<script>
let a = $state();
</script>
<a bind:this={a} />`);
expect(content.suggestions.length).toBeGreaterThanOrEqual(1);
expect(content.suggestions).toContain(
'The usage of `bind:this` can often be replaced with an easier to read `action` or even better an `attachment`. Consider using the latter if possible.',
);
});
it('should not add suggestions when using bind:this on a component', () => {
const content = run_autofixers_on_code(`
<script>
import Child from './Child.svelte';
let a = $state();
</script>
<Child bind:this={a} />`);
expect(content.suggestions).not.toContain(
'The usage of `bind:this` can often be replaced with an easier to read `action` or even better an `attachment`. Consider using the latter if possible.',
);
});
it('should not add suggestions when using bind:this on a component nested in an element', () => {
const content = run_autofixers_on_code(`
<script>
import Child from './Child.svelte';
let a = $state();
</script>
<div>
<Child bind:this={a} />
</div>`);
expect(content.suggestions).not.toContain(
'The usage of `bind:this` can often be replaced with an easier to read `action` or even better an `attachment`. Consider using the latter if possible.',
);
});
it('should add suggestions but not suggest attachments when using bind:this on an element and the desired svelte version is 4', () => {
const content = run_autofixers_on_code(
`
<script>
let a;
</script>
<a bind:this={a} />`,
4,
);
expect(content.suggestions.length).toBeGreaterThanOrEqual(1);
expect(content.suggestions).toContain(
'The usage of `bind:this` can often be replaced with an easier to read `action`. Consider using the latter if possible.',
);
});
});
describe('use:', () => {
it('should add suggestions when using use: on an element and the action is declared as a function', () => {
const content = run_autofixers_on_code(
`<script>
function my_action(node) {
// do something with the node
}
</script>
<a use:my_action />`,
);
expect(content.suggestions.length).toBeGreaterThanOrEqual(1);
expect(content.suggestions).toContain(
'Consider using an `attachment` instead of an `action` for "my_action".',
);
});
it('should add suggestions when using use: on an element and the action is declared as a variable', () => {
const content = run_autofixers_on_code(
`<script>
const my_action = (node) => {
// do something with the node
}
</script>
<a use:my_action />`,
);
expect(content.suggestions.length).toBeGreaterThanOrEqual(1);
expect(content.suggestions).toContain(
'Consider using an `attachment` instead of an `action` for "my_action".',
);
});
it('should add suggestions when using use: on an element and the action is declared as an object', () => {
const content = run_autofixers_on_code(
`<script>
const my_action = {
action: (node) => {
// do something with the node
}
};
</script>
<a use:my_action.action />`,
);
expect(content.suggestions.length).toBeGreaterThanOrEqual(1);
expect(content.suggestions).toContain(
'Consider using an `attachment` instead of an `action` for "my_action".',
);
});
it('should not add suggestions when using use: on an element and the desired svelte version is 4', () => {
const content = run_autofixers_on_code(
`<script>
function my_action(node) {
// do something with the node
}
</script>
<a use:my_action />`,
4,
);
expect(content.suggestions).not.toContain(
'Consider using an `attachment` instead of an `action` for "my_action".',
);
});
it('should not add suggestions when using use: on an element and the action comes from an import', () => {
const content = run_autofixers_on_code(
`<script>
import { my_action } from './actions.js';
</script>
<a use:my_action />`,
);
expect(content.suggestions).not.toContain(
'Consider using an `attachment` instead of an `action` for "my_action".',
);
});
it('should not add suggestions when using use: on an element and the action comes from the props', () => {
const content = run_autofixers_on_code(
`<script>
const { my_action } = $props();
</script>
<a use:my_action />`,
);
expect(content.suggestions).not.toContain(
'Consider using an `attachment` instead of an `action` for "my_action".',
);
});
it('should not add suggestions when using use: on an element and the action comes from a global variable', () => {
const content = run_autofixers_on_code(`<a use:my_action />`);
expect(content.suggestions).not.toContain(
'Consider using an `attachment` instead of an `action` for "my_action".',
);
});
});
});
});

View File

@@ -1,4 +1,6 @@
import { compile } from 'svelte/compiler';
import { compile as compile_component, compileModule } from 'svelte/compiler';
import { extname } from 'path';
import ts from 'ts-blank-space';
export function add_compile_issues(
content: { issues: string[]; suggestions: string[] },
@@ -6,6 +8,21 @@ export function add_compile_issues(
desired_svelte_version: number,
filename = 'Component.svelte',
) {
let compile = compile_component;
const extension = extname(filename);
if (extension !== '.svelte') {
compile = compileModule;
// compile module doesn't accept .ts files so we need to transpile them first with ts-blank-space
// a fast and lightweight typescript transpiler that can strips types replacing them with white spaces
// so the code positions are not affected
if (extension === '.ts') {
code = ts(code, (node) => {
content.issues.push(
`The provided file is a module but it contains invalid TypeScript code: ${node.getText()} at ${node.getStart()}`,
);
});
}
}
const compilation_result = compile(code, {
filename: filename || 'Component.svelte',
generate: false,

View File

@@ -12,7 +12,7 @@ function base_config(svelte_config: Config): ESLint.Options['baseConfig'] {
return [
...svelte.configs.recommended,
{
files: ['*.svelte'],
files: ['*.svelte', '*.svelte.ts', '*.svelte.js'],
rules: {
'no-self-assign': 'warn',
'svelte/infinite-reactive-loop': 'warn',

View File

@@ -1,4 +1,10 @@
import type { AssignmentExpression, Identifier, Node, UpdateExpression } from 'estree';
import type {
AssignmentExpression,
CallExpression,
Identifier,
Node,
UpdateExpression,
} from 'estree';
import type { Autofixer, AutofixerState } from './index.js';
import { left_most_id } from '../ast/utils.js';
import type { AST } from 'svelte-eslint-parser';
@@ -11,25 +17,17 @@ function run_if_in_effect(
) {
const in_effect = path.findLast(
(node) =>
node.type === 'CallExpression' &&
node.callee.type === 'Identifier' &&
node.callee.name === '$effect',
node.type === 'CallExpression' && state.parsed.is_rune(node, ['$effect', '$effect.pre']),
);
if (
in_effect &&
in_effect.type === 'CallExpression' &&
(in_effect.callee.type === 'Identifier' || in_effect.callee.type === 'MemberExpression')
) {
if (state.parsed.is_rune(in_effect, ['$effect', '$effect.pre'])) {
to_run();
}
if (in_effect) {
to_run();
}
}
function visitor(
function assign_or_update_visitor(
node: UpdateExpression | AssignmentExpression,
{ state, path }: Context<Node | AST.SvelteNode, AutofixerState>,
{ state, path, next }: Context<Node | AST.SvelteNode, AutofixerState>,
) {
run_if_in_effect(path, state, () => {
function check_if_stateful_id(id: Identifier) {
@@ -58,9 +56,25 @@ function visitor(
}
}
});
next();
}
function call_expression_visitor(
node: CallExpression,
{ state, path, next }: Context<Node | AST.SvelteNode, AutofixerState>,
) {
run_if_in_effect(path, state, () => {
const function_name =
node.callee.type === 'Identifier' ? `the function \`${node.callee.name}\`` : 'a function';
state.output.suggestions.push(
`You are calling ${function_name} inside an $effect. Please check if the function is reassigning a stateful variable because that's considered malpractice and check if it could use \`$derived\` instead. Ignore this suggestion if you are sure this function is not assigning any stateful variable or if you can't check if it does.`,
);
});
next();
}
export const assign_in_effect: Autofixer = {
UpdateExpression: visitor,
AssignmentExpression: visitor,
UpdateExpression: assign_or_update_visitor,
AssignmentExpression: assign_or_update_visitor,
CallExpression: call_expression_visitor,
};

View File

@@ -16,3 +16,4 @@ export * from './wrong-property-access-state.js';
export * from './imported-runes.js';
export * from './derived-with-function.js';
export * from './use-runes-instead-of-store.js';
export * from './suggest-attachments.js';

View File

@@ -0,0 +1,47 @@
import type { Identifier } from 'estree';
import type { Autofixer } from './index.js';
import { left_most_id } from '../ast/utils.js';
export const suggest_attachments: Autofixer = {
SvelteDirective(node, { state, next, path }) {
if (node.kind === 'Binding' && node.key.name.name === 'this') {
const parent_element = path.findLast((p) => p.type === 'SvelteElement');
if (parent_element?.kind === 'html' && parent_element.startTag.attributes.includes(node)) {
let better_an_attachment = ` or even better an \`attachment\``;
if (state.desired_svelte_version === 4) {
better_an_attachment = ``;
}
state.output.suggestions.push(
`The usage of \`bind:this\` can often be replaced with an easier to read \`action\`${better_an_attachment}. Consider using the latter if possible.`,
);
}
} else if (node.kind === 'Action' && state.desired_svelte_version === 5) {
let id: Identifier | null = null;
if (node.key.name.type === 'Identifier') {
id = node.key.name;
} else if (node.key.name.type === 'MemberExpression') {
id = left_most_id(node.key.name);
}
if (id) {
const reference = state.parsed.find_reference_by_id(id);
const definition = reference?.resolved?.defs[0];
console.log(definition);
if (
definition &&
(definition.type === 'Variable' ||
!(definition.type === 'ImportBinding' || definition.type === 'Parameter')) &&
!(
definition.type === 'Variable' &&
definition.node.init?.type === 'CallExpression' &&
state.parsed.is_rune(definition.node.init, ['$props'])
)
) {
state.output.suggestions.push(
`Consider using an \`attachment\` instead of an \`action\` for "${id.name}".`,
);
}
}
}
next();
},
};

View File

@@ -1,11 +1,12 @@
import type { SvelteMcp } from '../../index.js';
import * as v from 'valibot';
import { format_sections_list } from '../../utils.js';
export function setup_svelte_task(server: SvelteMcp) {
server.prompt(
{
name: 'svelte-task-prompt',
title: 'Svelte Task Prompt',
title: 'Svelte-Task-Prompt',
description:
'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.',
schema: v.object({
@@ -13,8 +14,7 @@ export function setup_svelte_task(server: SvelteMcp) {
}),
},
async ({ task }) => {
// TODO: implement logic to fetch the available docs paths to return in the prompt
const available_docs: string[] = [];
const available_docs = await format_sections_list();
return {
messages: [
@@ -23,9 +23,9 @@ export function setup_svelte_task(server: SvelteMcp) {
content: {
type: 'text',
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:
<available-docs-paths>
${JSON.stringify(available_docs, null, 2)}
</available-docs-paths>
<available-docs>
${available_docs}
</available-docs>
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.

View File

@@ -0,0 +1,64 @@
import type { SvelteMcp } from '../../index.js';
import { get_sections, fetch_with_timeout } from '../../utils.js';
export async function list_sections(server: SvelteMcp) {
const sections = await get_sections();
server.template(
{
name: 'Svelte-Doc-Section',
description: 'A single documentation section',
list() {
return sections.map((section) => {
const section_name = section.slug;
const resource_name = section_name;
const resource_uri = `svelte://${section_name}.md`;
return {
name: resource_name,
description: section.use_cases,
uri: resource_uri,
title: section.title,
};
});
},
complete: {
slug: (query) => {
const values = sections
.reduce<string[]>((acc, section) => {
const section_name = section.slug;
const resource_name = section_name;
if (section_name.includes(query.toLowerCase())) {
acc.push(resource_name);
}
return acc;
}, [])
// there's a hard limit of 100 for completions
.slice(0, 100);
return {
completion: {
values,
},
};
},
},
uri: 'svelte://{/slug*}.md',
},
async (uri, { slug }) => {
const section = sections.find((section) => {
return slug === section.slug;
});
if (!section) throw new Error(`Section not found: ${slug}`);
const response = await fetch_with_timeout(section.url);
const content = await response.text();
return {
contents: [
{
uri,
type: 'text',
text: content,
},
],
};
},
);
}

View File

@@ -1 +1 @@
export * from './list-sections.js';
export * from './doc-section.js';

View File

@@ -1,25 +0,0 @@
import type { SvelteMcp } from '../../index.js';
export function list_sections(server: SvelteMcp) {
server.resource(
{
name: 'list-sections',
enabled: () => false,
description:
'The list of all the available Svelte 5 and SvelteKit documentation sections in a structured format.',
uri: 'svelte://list-sections',
title: 'Svelte Documentation Section',
},
async (uri) => {
return {
contents: [
{
uri,
type: 'text',
text: 'resource list-sections called',
},
],
};
},
);
}

View File

@@ -1,23 +1,24 @@
import type { SvelteMcp } from '../../index.js';
import * as v from 'valibot';
import { get_sections, fetch_with_timeout, format_sections_list } from '../../utils.js';
import { SECTIONS_LIST_INTRO, SECTIONS_LIST_OUTRO } from './prompts.js';
export function get_documentation(server: SvelteMcp) {
server.tool(
{
name: 'get-documentation',
enabled: () => false,
description:
'Retrieves full documentation content for Svelte 5 or SvelteKit sections. Supports flexible search by title (e.g., "$state", "routing") or file path (e.g., "docs/svelte/state.md"). Can accept a single section name or an array of sections. Before running this, make sure to analyze the users query, as well as the output from list_sections (which should be called first). Then ask for ALL relevant sections the user might require. For example, if the user asks to build anything interactive, you will need to fetch all relevant runes, and so on.',
'Retrieves full documentation content for Svelte 5 or SvelteKit sections. Supports flexible search by title (e.g., "$state", "routing") or file path (e.g., "cli/overview"). Can accept a single section name or an array of sections. Before running this, make sure to analyze the users query, as well as the output from list-sections (which should be called first). Then ask for ALL relevant sections the user might require. For example, if the user asks to build anything interactive, you will need to fetch all relevant runes, and so on.',
schema: v.object({
section: v.pipe(
v.union([v.string(), v.array(v.string())]),
v.description(
'The section name(s) to retrieve. Can search by title (e.g., "$state", "load functions") or file path (e.g., "docs/svelte/state.md"). Supports single string and array of strings',
'The section name(s) to retrieve. Can search by title (e.g., "$state", "load functions") or file path (e.g., "cli/overview"). Supports single string and array of strings',
),
),
}),
},
({ section }) => {
async ({ section }) => {
let sections: string[];
if (Array.isArray(section)) {
@@ -43,13 +44,69 @@ export function get_documentation(server: SvelteMcp) {
sections = [];
}
const sections_list = sections.length > 0 ? sections.join(', ') : 'no sections';
const available_sections = await get_sections();
const settled_results = await Promise.allSettled(
sections.map(async (requested_section) => {
const matched_section = available_sections.find(
(s) =>
s.title.toLowerCase() === requested_section.toLowerCase() ||
s.slug === requested_section ||
s.url === requested_section,
);
if (matched_section) {
try {
const response = await fetch_with_timeout(matched_section.url);
if (response.ok) {
const content = await response.text();
return { success: true, content: `## ${matched_section.title}\n\n${content}` };
} else {
return {
success: false,
content: `## ${matched_section.title}\n\nError: Could not fetch documentation (HTTP ${response.status})`,
};
}
} catch (error) {
return {
success: false,
content: `## ${matched_section.title}\n\nError: Failed to fetch documentation - ${error}`,
};
}
} else {
return {
success: false,
content: `## ${requested_section}\n\nError: Section not found.`,
};
}
}),
);
const results = settled_results.map((result) => {
if (result.status === 'fulfilled') {
return result.value;
} else {
return {
success: false,
content: `Error: Couldn't fetch - ${result.reason}`,
};
}
});
const has_any_success = results.some((result) => result.success);
let final_text = results.map((r) => r.content).join('\n\n---\n\n');
if (!has_any_success) {
const formatted_sections = await format_sections_list();
final_text += `\n\n---\n\n${SECTIONS_LIST_INTRO}\n\n${formatted_sections}\n\n${SECTIONS_LIST_OUTRO}`;
}
return {
content: [
{
type: 'text',
text: `called for sections: ${sections_list}`,
text: final_text,
},
],
};

View File

@@ -1,19 +1,22 @@
import type { SvelteMcp } from '../../index.js';
import { format_sections_list } from '../../utils.js';
import { SECTIONS_LIST_INTRO, SECTIONS_LIST_OUTRO } from './prompts.js';
export function list_sections(server: SvelteMcp) {
server.tool(
{
name: 'list-sections',
enabled: () => false,
description:
'Lists all available Svelte 5 and SvelteKit documentation sections in a structured format. Returns sections as a list of "* title: [section_title], path: [file_path]" - you can use either the title or path when querying a specific section via the get_documentation tool. Always run list_sections first for any query related to Svelte development to discover available content.',
'Lists all available Svelte 5 and SvelteKit documentation sections in a structured format. Each section includes a "use_cases" field that describes WHEN this documentation would be useful. You should carefully analyze the use_cases field to determine which sections are relevant for the user\'s query. The use_cases contain comma-separated keywords describing project types (e.g., "e-commerce", "blog"), features (e.g., "authentication", "forms"), components (e.g., "slider", "modal"), development stages (e.g., "deployment", "testing"), or "always" for fundamental concepts. Match these use_cases against the user\'s intent - for example, if building an e-commerce site, fetch sections with use_cases containing "e-commerce", "product listings", "shopping cart", etc. If building a slider, look for "slider", "carousel", "animation", etc. Returns sections as "* title: [section_title], use_cases: [use_cases], path: [file_path]". Always run list-sections FIRST for any Svelte query, then analyze ALL use_cases to identify relevant sections, and finally use get_documentation to fetch ALL relevant sections at once.',
},
() => {
async () => {
const formatted_sections = await format_sections_list();
return {
content: [
{
type: 'text',
text: 'tool list_sections called',
text: `${SECTIONS_LIST_INTRO}\n\n${formatted_sections}\n\n${SECTIONS_LIST_OUTRO}`,
},
],
};

View File

@@ -0,0 +1,5 @@
export const SECTIONS_LIST_INTRO =
'List of available Svelte documentation sections with their intended use cases. The "use_cases" field describes WHEN each section would be useful - analyze these carefully to determine which sections match the user\'s query:';
export const SECTIONS_LIST_OUTRO =
"Carefully analyze the use_cases field for each section to identify which documentation is relevant for the user's specific query. The use_cases contain keywords for project types, features, components, and development stages. After identifying relevant sections, use the get-documentation tool with ALL relevant section titles or paths at once (can pass multiple sections as an array).";

View File

@@ -0,0 +1,56 @@
import * as v from 'valibot';
import { documentation_sections_schema } from '../lib/schemas.js';
import summary_data from '../use_cases.json' with { type: 'json' };
export async function fetch_with_timeout(
url: string,
timeout_ms: number = 10000,
): Promise<Response> {
try {
const response = await fetch(url, { signal: AbortSignal.timeout(timeout_ms) });
return response;
} catch (error) {
if (error instanceof Error && error.name === 'AbortError') {
throw new Error(`Request timed out after ${timeout_ms}ms`);
}
throw error;
}
}
const summaries = (summary_data.summaries || {}) as Record<string, string>;
export async function get_sections() {
const sections = await fetch_with_timeout(
'https://svelte.dev/docs/experimental/sections.json',
).then((res) => res.json());
const validated_sections = v.safeParse(documentation_sections_schema, sections);
if (!validated_sections.success) return [];
const mapped_sections = Object.entries(validated_sections.output).map(([, section]) => {
const original_slug = section.slug;
const cleaned_slug = original_slug.startsWith('docs/')
? original_slug.slice('docs/'.length)
: original_slug;
return {
title: section.metadata.title,
use_cases:
section.metadata.use_cases ??
summaries[original_slug] ??
summaries[cleaned_slug] ??
'use title and path to estimate use case',
slug: cleaned_slug,
// Use original slug in URL to ensure it still works
url: `https://svelte.dev/${original_slug}/llms.txt`,
};
});
return mapped_sections;
}
export async function format_sections_list() {
const sections = await get_sections();
return sections
.map((s) => `* title: ${s.title}, use_cases: ${s.use_cases}, path: ${s.slug}`)
.join('\n');
}

View File

@@ -0,0 +1,176 @@
{
"generated_at": "2025-10-02T20:29:23.410Z",
"model": "claude-sonnet-4-5-20250929",
"total_sections": 167,
"successful_summaries": 167,
"failed_summaries": 0,
"summaries": {
"docs/cli/overview": "project setup, creating new svelte apps, scaffolding, cli tools, initializing projects",
"docs/cli/faq": "project setup, initializing new svelte projects, troubleshooting cli installation, package manager configuration",
"docs/cli/sv-create": "project setup, starting new sveltekit app, initializing project, creating from playground, choosing project template",
"docs/cli/sv-add": "project setup, adding features to existing projects, integrating tools, testing setup, styling setup, authentication, database setup, deployment adapters",
"docs/cli/sv-check": "code quality, ci/cd pipelines, error checking, typescript projects, pre-commit hooks, finding unused css, accessibility auditing, production builds",
"docs/cli/sv-migrate": "migration, upgrading svelte versions, upgrading sveltekit versions, modernizing codebase, svelte 3 to 4, svelte 4 to 5, sveltekit 1 to 2, adopting runes, refactoring deprecated apis",
"docs/cli/devtools-json": "development setup, chrome devtools integration, browser-based editing, local development workflow, debugging setup",
"docs/cli/drizzle": "database setup, sql queries, orm integration, data modeling, postgresql, mysql, sqlite, server-side data access, database migrations, type-safe queries",
"docs/cli/eslint": "code quality, linting, error detection, project setup, code standards, team collaboration, typescript projects",
"docs/cli/lucia": "authentication, login systems, user management, registration pages, session handling, auth setup",
"docs/cli/mdsvex": "blog, content sites, markdown rendering, documentation sites, technical writing, cms integration, article pages",
"docs/cli/paraglide": "internationalization, multi-language sites, i18n, translation, localization, language switching, global apps, multilingual content",
"docs/cli/playwright": "browser testing, e2e testing, integration testing, test automation, quality assurance, ci/cd pipelines, testing user flows",
"docs/cli/prettier": "code formatting, project setup, code style consistency, team collaboration, linting configuration",
"docs/cli/storybook": "component development, design systems, ui library, isolated component testing, documentation, visual testing, component showcase",
"docs/cli/sveltekit-adapter": "deployment, production builds, hosting setup, choosing deployment platform, configuring adapters, static site generation, node server, vercel, cloudflare, netlify",
"docs/cli/tailwind": "project setup, styling, css framework, rapid prototyping, utility-first css, design systems, responsive design, adding tailwind to svelte",
"docs/cli/vitest": "testing, unit tests, component testing, test setup, quality assurance, ci/cd pipelines, test-driven development",
"docs/kit/introduction": "learning sveltekit, project setup, understanding framework basics, choosing between svelte and sveltekit, getting started with full-stack apps",
"docs/kit/creating-a-project": "project setup, starting new sveltekit app, initial development environment, first-time sveltekit users, scaffolding projects",
"docs/kit/project-types": "deployment, project setup, choosing adapters, ssg, spa, ssr, serverless, mobile apps, desktop apps, pwa, offline apps, browser extensions, separate backend, docker containers",
"docs/kit/project-structure": "project setup, understanding file structure, organizing code, starting new project, learning sveltekit basics",
"docs/kit/web-standards": "always, any sveltekit project, data fetching, forms, api routes, server-side rendering, deployment to various platforms",
"docs/kit/routing": "routing, navigation, multi-page apps, project setup, file structure, api endpoints, data loading, layouts, error pages, always",
"docs/kit/load": "data fetching, api calls, database queries, dynamic routes, page initialization, loading states, authentication checks, ssr data, form data, content rendering",
"docs/kit/form-actions": "forms, user input, data submission, authentication, login systems, user registration, progressive enhancement, validation errors",
"docs/kit/page-options": "prerendering static sites, ssr configuration, spa setup, client-side rendering control, url trailing slash handling, adapter deployment config, build optimization",
"docs/kit/state-management": "sveltekit, server-side rendering, ssr, state management, authentication, data persistence, load functions, context api, navigation, component lifecycle",
"docs/kit/remote-functions": "data fetching, server-side logic, database queries, type-safe client-server communication, forms, user input, mutations, authentication, crud operations, optimistic updates",
"docs/kit/building-your-app": "production builds, deployment preparation, build process optimization, adapter configuration, preview before deployment",
"docs/kit/adapters": "deployment, production builds, hosting setup, choosing deployment platform, configuring adapters",
"docs/kit/adapter-auto": "deployment, production builds, hosting setup, choosing deployment platform, ci/cd configuration",
"docs/kit/adapter-node": "deployment, production builds, node.js hosting, custom server setup, environment configuration, reverse proxy setup, docker deployment, systemd services",
"docs/kit/adapter-static": "static site generation, ssg, prerendering, deployment, github pages, spa mode, blogs, documentation sites, marketing sites",
"docs/kit/single-page-apps": "spa mode, single-page apps, client-only rendering, static hosting, mobile app wrappers, no server-side logic, adapter-static setup, fallback pages",
"docs/kit/adapter-cloudflare": "deployment, cloudflare workers, cloudflare pages, hosting setup, production builds, serverless deployment, edge computing",
"docs/kit/adapter-cloudflare-workers": "deploying to cloudflare workers, cloudflare workers sites deployment, legacy cloudflare adapter, wrangler configuration, cloudflare platform bindings",
"docs/kit/adapter-netlify": "deployment, netlify hosting, production builds, serverless functions, edge functions, static site hosting",
"docs/kit/adapter-vercel": "deployment, vercel hosting, production builds, serverless functions, edge functions, isr, image optimization, environment variables",
"docs/kit/writing-adapters": "custom deployment, building adapters, unsupported platforms, adapter development, custom hosting environments",
"docs/kit/advanced-routing": "advanced routing, dynamic routes, file viewers, nested paths, custom 404 pages, url validation, route parameters, multi-level navigation",
"docs/kit/hooks": "authentication, logging, error tracking, request interception, api proxying, custom routing, internationalization, database initialization, middleware logic, session management",
"docs/kit/errors": "error handling, custom error pages, 404 pages, api error responses, production error logging, error tracking, type-safe errors",
"docs/kit/link-options": "routing, navigation, multi-page apps, performance optimization, link preloading, forms with get method, search functionality, focus management, scroll behavior",
"docs/kit/service-workers": "offline support, pwa, caching strategies, performance optimization, precaching assets, network resilience, progressive web apps",
"docs/kit/server-only-modules": "api keys, environment variables, sensitive data protection, backend security, preventing data leaks, server-side code isolation",
"docs/kit/snapshots": "forms, user input, preserving form data, multi-step forms, navigation state, preventing data loss, textarea content, input fields, comment systems, surveys",
"docs/kit/shallow-routing": "modals, dialogs, image galleries, overlays, history-driven ui, mobile-friendly navigation, photo viewers, lightboxes, drawer menus",
"docs/kit/observability": "performance monitoring, debugging, observability, tracing requests, production diagnostics, analyzing slow requests, finding bottlenecks, monitoring server-side operations",
"docs/kit/packaging": "building component libraries, publishing npm packages, creating reusable svelte components, library development, package distribution",
"docs/kit/auth": "authentication, login systems, user management, session handling, jwt tokens, protected routes, user credentials, authorization checks",
"docs/kit/performance": "performance optimization, slow loading pages, production deployment, debugging performance issues, reducing bundle size, improving load times",
"docs/kit/icons": "icons, ui components, styling, css frameworks, tailwind, unocss, performance optimization, dependency management",
"docs/kit/images": "image optimization, responsive images, performance, hero images, product photos, galleries, cms integration, cdn setup, asset management",
"docs/kit/accessibility": "always, any sveltekit project, screen reader support, keyboard navigation, multi-page apps, client-side routing, internationalization, multilingual sites",
"docs/kit/seo": "seo optimization, search engine ranking, content sites, blogs, marketing sites, public-facing apps, sitemaps, amp pages, meta tags, performance optimization",
"docs/kit/faq": "troubleshooting package imports, library compatibility issues, client-side code execution, external api integration, middleware setup, database configuration, view transitions, yarn configuration",
"docs/kit/integrations": "project setup, css preprocessors, postcss, scss, sass, less, stylus, typescript setup, adding integrations, tailwind, testing, auth, linting, formatting",
"docs/kit/debugging": "debugging, breakpoints, development workflow, troubleshooting issues, vscode setup, ide configuration, inspecting code execution",
"docs/kit/migrating-to-sveltekit-2": "migration, upgrading from sveltekit 1 to 2, breaking changes, version updates",
"docs/kit/migrating": "migrating from sapper, upgrading legacy projects, sapper to sveltekit conversion, project modernization",
"docs/kit/additional-resources": "troubleshooting, getting help, finding examples, learning sveltekit, project templates, common issues, community support",
"docs/kit/glossary": "rendering strategies, performance optimization, deployment configuration, seo requirements, static sites, spas, server-side rendering, prerendering, edge deployment, pwa development",
"docs/kit/@sveltejs-kit": "forms, form actions, server-side validation, form submission, error handling, redirects, json responses, http errors, server utilities",
"docs/kit/@sveltejs-kit-hooks": "middleware, request processing, authentication chains, logging, multiple hooks, request/response transformation",
"docs/kit/@sveltejs-kit-node-polyfills": "node.js environments, custom servers, non-standard runtimes, ssr setup, web api compatibility, polyfill requirements",
"docs/kit/@sveltejs-kit-node": "node.js adapter, custom server setup, http integration, streaming files, node deployment, server-side rendering with node",
"docs/kit/@sveltejs-kit-vite": "project setup, vite configuration, initial sveltekit setup, build tooling",
"docs/kit/$app-environment": "always, conditional logic, client-side code, server-side code, build-time logic, prerendering, development vs production, environment detection",
"docs/kit/$app-forms": "forms, user input, data submission, progressive enhancement, custom form handling, form validation",
"docs/kit/$app-navigation": "routing, navigation, multi-page apps, programmatic navigation, data reloading, preloading, shallow routing, navigation lifecycle, scroll handling, view transitions",
"docs/kit/$app-paths": "static assets, images, fonts, public files, base path configuration, subdirectory deployment, cdn setup, asset urls, links, navigation",
"docs/kit/$app-server": "remote functions, server-side logic, data fetching, form handling, api endpoints, client-server communication, prerendering, file reading, batch queries",
"docs/kit/$app-state": "routing, navigation, multi-page apps, loading states, url parameters, form handling, error states, version updates, page metadata, shallow routing",
"docs/kit/$app-stores": "legacy projects, sveltekit pre-2.12, migration from stores to runes, maintaining older codebases, accessing page data, navigation state, app version updates",
"docs/kit/$app-types": "routing, navigation, type safety, route parameters, dynamic routes, link generation, pathname validation, multi-page apps",
"docs/kit/$env-dynamic-private": "api keys, secrets management, server-side config, environment variables, backend logic, deployment-specific settings, private data handling",
"docs/kit/$env-dynamic-public": "environment variables, client-side config, runtime configuration, public api keys, deployment-specific settings, multi-environment apps",
"docs/kit/$env-static-private": "server-side api keys, backend secrets, database credentials, private configuration, build-time optimization, server endpoints, authentication tokens",
"docs/kit/$env-static-public": "environment variables, public config, client-side data, api endpoints, build-time configuration, public constants",
"docs/kit/$lib": "project setup, component organization, importing shared components, reusable ui elements, code structure",
"docs/kit/$service-worker": "offline support, pwa, service workers, caching strategies, progressive web apps, offline-first apps",
"docs/kit/configuration": "project setup, configuration, adapters, deployment, build settings, environment variables, routing customization, prerendering, csp security, csrf protection, path configuration, typescript setup",
"docs/kit/cli": "project setup, typescript configuration, generated types, ./$types imports, initial project configuration",
"docs/kit/types": "typescript, type safety, route parameters, api endpoints, load functions, form actions, generated types, jsconfig setup",
"docs/svelte/overview": "always, any svelte project, getting started, learning svelte, introduction, project setup, understanding framework basics",
"docs/svelte/getting-started": "project setup, starting new svelte project, initial installation, choosing between sveltekit and vite, editor configuration",
"docs/svelte/svelte-files": "always, any svelte project, component creation, project setup, learning svelte basics",
"docs/svelte/svelte-js-files": "shared reactive state, reusable reactive logic, state management across components, global stores, custom reactive utilities",
"docs/svelte/what-are-runes": "always, any svelte 5 project, understanding core syntax, learning svelte 5, migration from svelte 4",
"docs/svelte/$state": "always, any svelte project, core reactivity, state management, counters, forms, todo apps, interactive ui, data updates, class-based components",
"docs/svelte/$derived": "always, any svelte project, computed values, reactive calculations, derived data, transforming state, dependent values",
"docs/svelte/$effect": "canvas drawing, third-party library integration, dom manipulation, side effects, intervals, timers, network requests, analytics tracking",
"docs/svelte/$props": "always, any svelte project, passing data to components, component communication, reusable components, component props",
"docs/svelte/$bindable": "forms, user input, two-way data binding, custom input components, parent-child communication, reusable form fields",
"docs/svelte/$inspect": "debugging, development, tracking state changes, reactive state monitoring, troubleshooting reactivity issues",
"docs/svelte/$host": "custom elements, web components, dispatching custom events, component library, framework-agnostic components",
"docs/svelte/basic-markup": "always, any svelte project, basic markup, html templating, component structure, attributes, events, props, text rendering",
"docs/svelte/if": "always, conditional rendering, showing/hiding content, dynamic ui, user permissions, loading states, error handling, form validation",
"docs/svelte/each": "always, lists, arrays, iteration, product listings, todos, tables, grids, dynamic content, shopping carts, user lists, comments, feeds",
"docs/svelte/key": "animations, transitions, component reinitialization, forcing component remount, value-based ui updates, resetting component state",
"docs/svelte/await": "async data fetching, api calls, loading states, promises, error handling, lazy loading components, dynamic imports",
"docs/svelte/snippet": "reusable markup, component composition, passing content to components, table rows, list items, conditional rendering, reducing duplication",
"docs/svelte/@render": "reusable ui patterns, component composition, conditional rendering, fallback content, layout components, slot alternatives, template reuse",
"docs/svelte/@html": "rendering html strings, cms content, rich text editors, markdown to html, blog posts, wysiwyg output, sanitized html injection, dynamic html content",
"docs/svelte/@attach": "tooltips, popovers, dom manipulation, third-party libraries, canvas drawing, element lifecycle, interactive ui, custom directives, wrapper components",
"docs/svelte/@const": "computed values in loops, derived calculations in blocks, local variables in each iterations, complex list rendering",
"docs/svelte/@debug": "debugging, development, troubleshooting, tracking state changes, monitoring variables, reactive data inspection",
"docs/svelte/bind": "forms, user input, two-way data binding, interactive ui, media players, file uploads, checkboxes, radio buttons, select dropdowns, contenteditable, dimension tracking",
"docs/svelte/use": "custom directives, dom manipulation, third-party library integration, tooltips, click outside, gestures, focus management, element lifecycle hooks",
"docs/svelte/transition": "animations, interactive ui, modals, dropdowns, notifications, conditional content, show/hide elements, smooth state changes",
"docs/svelte/in-and-out": "animation, transitions, interactive ui, conditional rendering, independent enter/exit effects, modals, tooltips, notifications",
"docs/svelte/animate": "sortable lists, drag and drop, reorderable items, todo lists, kanban boards, playlist editors, priority queues, animated list reordering",
"docs/svelte/style": "dynamic styling, conditional styles, theming, dark mode, responsive design, interactive ui, component styling",
"docs/svelte/class": "always, conditional styling, dynamic classes, tailwind css, component styling, reusable components, responsive design",
"docs/svelte/await-expressions": "async data fetching, loading states, server-side rendering, awaiting promises in components, async validation, concurrent data loading",
"docs/svelte/scoped-styles": "always, styling components, scoped css, component-specific styles, preventing style conflicts, animations, keyframes",
"docs/svelte/global-styles": "global styles, third-party libraries, css resets, animations, styling body/html, overriding component styles, shared keyframes, base styles",
"docs/svelte/custom-properties": "theming, custom styling, reusable components, design systems, dynamic colors, component libraries, ui customization",
"docs/svelte/nested-style-elements": "component styling, scoped styles, dynamic styles, conditional styling, nested style tags, custom styling logic",
"docs/svelte/svelte-boundary": "error handling, async data loading, loading states, error recovery, flaky components, error reporting, resilient ui",
"docs/svelte/svelte-window": "keyboard shortcuts, scroll tracking, window resize handling, responsive layouts, online/offline detection, viewport dimensions, global event listeners",
"docs/svelte/svelte-document": "document events, visibility tracking, fullscreen detection, pointer lock, focus management, document-level interactions",
"docs/svelte/svelte-body": "mouse tracking, hover effects, cursor interactions, global body events, drag and drop, custom cursors, interactive backgrounds, body-level actions",
"docs/svelte/svelte-head": "seo optimization, page titles, meta tags, social media sharing, dynamic head content, multi-page apps, blog posts, product pages",
"docs/svelte/svelte-element": "dynamic content, cms integration, user-generated content, configurable ui, runtime element selection, flexible components",
"docs/svelte/svelte-options": "migration, custom elements, web components, legacy mode compatibility, runes mode setup, svg components, mathml components, css injection control",
"docs/svelte/stores": "shared state, cross-component data, reactive values, async data streams, manual control over updates, rxjs integration, extracting logic",
"docs/svelte/context": "shared state, avoiding prop drilling, component communication, theme providers, user context, authentication state, configuration sharing, deeply nested components",
"docs/svelte/lifecycle-hooks": "component initialization, cleanup tasks, timers, subscriptions, dom measurements, chat windows, autoscroll features, migration from svelte 4",
"docs/svelte/imperative-component-api": "project setup, client-side rendering, server-side rendering, ssr, hydration, testing, programmatic component creation, tooltips, dynamic mounting",
"docs/svelte/testing": "testing, quality assurance, unit tests, integration tests, component tests, e2e tests, vitest setup, playwright setup, test automation",
"docs/svelte/typescript": "typescript setup, type safety, component props typing, generic components, wrapper components, dom type augmentation, project configuration",
"docs/svelte/custom-elements": "web components, custom elements, component library, design system, framework-agnostic components, embedding svelte in non-svelte apps, shadow dom",
"docs/svelte/v4-migration-guide": "upgrading svelte 3 to 4, version migration, updating dependencies, breaking changes, legacy project maintenance",
"docs/svelte/v5-migration-guide": "migrating from svelte 4 to 5, upgrading projects, learning svelte 5 syntax changes, runes migration, event handler updates",
"docs/svelte/faq": "getting started, learning svelte, beginner setup, project initialization, vs code setup, formatting, testing, routing, mobile apps, troubleshooting, community support",
"docs/svelte/svelte": "migration from svelte 4 to 5, upgrading legacy code, component lifecycle hooks, context api, mounting components, event dispatchers, typescript component types",
"docs/svelte/svelte-action": "typescript types, actions, use directive, dom manipulation, element lifecycle, custom behaviors, third-party library integration",
"docs/svelte/svelte-animate": "animated lists, sortable items, drag and drop, reordering elements, todo lists, kanban boards, playlist management, smooth position transitions",
"docs/svelte/svelte-attachments": "library development, component libraries, programmatic element manipulation, migrating from actions to attachments, spreading props onto elements",
"docs/svelte/svelte-compiler": "build tools, custom compilers, ast manipulation, preprocessors, code transformation, migration scripts, syntax analysis, bundler plugins, dev tools",
"docs/svelte/svelte-easing": "animations, transitions, custom easing, smooth motion, interactive ui, modals, dropdowns, carousels, page transitions, scroll effects",
"docs/svelte/svelte-events": "window events, document events, global event listeners, event delegation, programmatic event handling, cleanup functions, media queries",
"docs/svelte/svelte-legacy": "migration from svelte 4 to svelte 5, upgrading legacy code, event modifiers, class components, imperative component instantiation",
"docs/svelte/svelte-motion": "animation, smooth transitions, interactive ui, sliders, counters, physics-based motion, drag gestures, accessibility, reduced motion",
"docs/svelte/svelte-reactivity-window": "responsive design, viewport tracking, scroll effects, window resize handling, online/offline detection, zoom level tracking",
"docs/svelte/svelte-reactivity": "reactive data structures, state management with maps/sets, game boards, selection tracking, url manipulation, query params, real-time clocks, media queries, responsive design",
"docs/svelte/svelte-server": "server-side rendering, ssr, static site generation, seo optimization, initial page load, pre-rendering, node.js server, custom server setup",
"docs/svelte/svelte-store": "state management, shared data, reactive stores, cross-component communication, global state, computed values, data synchronization, legacy svelte projects",
"docs/svelte/svelte-transition": "animations, transitions, interactive ui, modals, dropdowns, tooltips, notifications, svg animations, list animations, page transitions",
"docs/svelte/compiler-errors": "animation, transitions, keyed each blocks, list animations",
"docs/svelte/compiler-warnings": "accessibility, a11y compliance, wcag standards, screen readers, keyboard navigation, aria attributes, semantic html, interactive elements",
"docs/svelte/runtime-errors": "debugging errors, error handling, troubleshooting runtime issues, migration to svelte 5, component binding, effects and reactivity",
"docs/svelte/runtime-warnings": "debugging state proxies, console logging reactive values, inspecting state changes, development troubleshooting",
"docs/svelte/legacy-overview": "migrating from svelte 3/4 to svelte 5, maintaining legacy components, understanding deprecated features, gradual upgrade process",
"docs/svelte/legacy-let": "migration, legacy svelte projects, upgrading from svelte 4, understanding old reactivity, maintaining existing code, learning runes differences",
"docs/svelte/legacy-reactive-assignments": "legacy mode, migration from svelte 4, reactive statements, computed values, derived state, side effects",
"docs/svelte/legacy-export-let": "legacy mode, migration from svelte 4, maintaining older projects, component props without runes, exporting component methods, renaming reserved word props",
"docs/svelte/legacy-$$props-and-$$restProps": "legacy mode migration, component wrappers, prop forwarding, button components, reusable ui components, spreading props to child elements",
"docs/svelte/legacy-on": "legacy mode, event handling, button clicks, forms, user interactions, component communication, event forwarding, event modifiers",
"docs/svelte/legacy-slots": "legacy mode, migrating from svelte 4, component composition, reusable components, passing content to components, modals, layouts, wrappers",
"docs/svelte/legacy-$$slots": "legacy mode, conditional slot rendering, optional content sections, checking if slots provided, migrating from legacy to runes",
"docs/svelte/legacy-svelte-fragment": "named slots, component composition, layout systems, avoiding wrapper divs, legacy svelte projects, slot content organization",
"docs/svelte/legacy-svelte-component": "dynamic components, component switching, conditional rendering, legacy mode migration, tabbed interfaces, multi-step forms",
"docs/svelte/legacy-svelte-self": "recursive components, tree structures, nested menus, file explorers, comment threads, hierarchical data",
"docs/svelte/legacy-component-api": "migration from svelte 3/4 to 5, legacy component api, maintaining old projects, understanding deprecated patterns"
}
}

View File

@@ -0,0 +1,25 @@
# @sveltejs/mcp
## 0.0.4
### Patch Changes
- fix: allow TS `.svelte.ts` modules ([#49](https://github.com/sveltejs/mcp/pull/49))
## 0.0.3
### Patch Changes
- fix: check effect.pre in assign-in-effect ([#41](https://github.com/sveltejs/mcp/pull/41))
- feat: `use_cases` documentation metadata ([#29](https://github.com/sveltejs/mcp/pull/29))
- fix: change title names to allow for claude code to use the prompt ([`725f785`](https://github.com/sveltejs/mcp/commit/725f785766d04e9ed810a7c3f6bcfdb2e2b8234c))
- fix: enable doc tools ([`cb316c5`](https://github.com/sveltejs/mcp/commit/cb316c5b3ebc712946969d2d57236d159e796d58))
## 0.0.2
### Patch Changes
- feat: latest version ([#25](https://github.com/sveltejs/mcp/pull/25))

View File

@@ -1,6 +1,6 @@
{
"name": "@sveltejs/mcp",
"version": "0.0.1",
"version": "0.0.4",
"type": "module",
"license": "MIT",
"homepage": "https://github.com/sveltejs/mcp#readme",
@@ -22,17 +22,18 @@
"access": "public"
},
"scripts": {
"build": "tsdown",
"build": "tsdown && publint",
"dev": "tsdown --watch",
"test": "vitest",
"check": "tsc --noEmit"
"check": "tsc --noEmit",
"check:publint": "publint --strict"
},
"devDependencies": {
"@sveltejs/mcp-server": "workspace:^",
"@tmcp/transport-stdio": "^0.3.1",
"@types/node": "^22.15.17",
"publint": "^0.3.13",
"tsdown": "^0.11.9",
"tsdown": "^0.15.0",
"typescript": "^5.8.3",
"vitest": "^3.1.3"
},

1378
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff