Compare commits

..

1 Commits

Author SHA1 Message Date
paoloricciuti
b56aeefec4 fix: lint 2025-10-17 17:29:31 +02:00
41 changed files with 411 additions and 776 deletions

View File

@@ -0,0 +1,5 @@
---
'@sveltejs/mcp': patch
---
fix: prevent `imported_runes` suggestion from being added for libs that are not svelte

View File

@@ -1,5 +0,0 @@
---
'@sveltejs/mcp': patch
---
chore: update tmcp

1
.github/FUNDING.yml vendored
View File

@@ -1 +0,0 @@
open_collective: svelte

View File

@@ -18,12 +18,12 @@ jobs:
- name: Setup pnpm
uses: pnpm/action-setup@v4
with:
version: 10.20.0
version: 10.18.2
- name: Setup Node.js
uses: actions/setup-node@v6
with:
node-version: '24'
node-version: '22'
cache: 'pnpm'
- name: Install dependencies

View File

@@ -18,12 +18,12 @@ jobs:
- name: Setup pnpm
uses: pnpm/action-setup@v4
with:
version: 10.20.0
version: 10.18.2
- name: Setup Node.js
uses: actions/setup-node@v6
with:
node-version: '24'
node-version: '22'
cache: 'pnpm'
- name: Install dependencies

View File

@@ -5,7 +5,6 @@ on:
secrets:
MCP_KEY:
required: true
workflow_dispatch:
jobs:
publish-mcp:
@@ -20,12 +19,12 @@ jobs:
env:
MCP_KEY: ${{ secrets.MCP_KEY }}
run: |
NAME=mcp-publisher_$(uname -s | tr '[:upper:]' '[:lower:]')_$(uname -m | sed 's/x86_64/amd64/;s/aarch64/arm64/').tar.gz
# Download MCP Publisher pinned to v1.3.3 using latest https for security and save it to a file named mcp-publisher.tar.gz
curl --proto '=https' --proto-redir '=https' --tlsv1.2 -fL "https://github.com/modelcontextprotocol/registry/releases/download/v1.3.3/$NAME" -O
NAME=mcp-publisher_1.2.3_$(uname -s | tr '[:upper:]' '[:lower:]')_$(uname -m | sed 's/x86_64/amd64/;s/aarch64/arm64/').tar.gz
# Download MCP Publisher pinned to v1.2.3 using latest https for security and save it to a file named mcp-publisher.tar.gz
curl --proto '=https' --proto-redir '=https' --tlsv1.2 -fL "https://github.com/modelcontextprotocol/registry/releases/download/v1.2.3/$NAME" -O
# Verify the SHA256 checksum of the downloaded file
sha256sum --ignore-missing -c ./checksums/registry_1.3.3_checksums.txt
sha256sum --ignore-missing -c ./checksums/registry_1.2.3_checksums.txt
# Extract the tarball
mkdir tmp

View File

@@ -18,12 +18,12 @@ jobs:
- name: Setup pnpm
uses: pnpm/action-setup@v4
with:
version: 10.20.0
version: 10.18.2
- name: Setup Node.js
uses: actions/setup-node@v6
with:
node-version: '24'
node-version: '22'
cache: 'pnpm'
- name: Install dependencies

View File

@@ -11,5 +11,4 @@ bun.lockb
/**/.svelte-kit/*
# Claude Code
.claude/
.changeset/
.claude/

View File

@@ -12,7 +12,6 @@
"body": [
"import type { SvelteMcp } from '../../index.js';",
"import * as v from 'valibot';",
"import { icons } from '../../icons/index.js';",
"",
"export function ${1:function_name}(server: SvelteMcp) {",
"\t$0",
@@ -36,7 +35,6 @@
"prefix": "!prompt",
"body": [
"import type { SvelteMcp } from '../../index.js';",
"import { icons } from '../../icons/index.js';",
"",
"/**",
" * Function that actually generates the prompt string. You can use this in the MCP server handler to generate the prompt, it can accept arguments",
@@ -71,7 +69,6 @@
"\t\t\ttitle: '${2:title}',",
"\t\t\tdescription:",
"\t\t\t\t'${3:llm_description}',",
"\t\t\ticons,",
"\t\t},",
"\t\tasync () => {",
"\t\t\treturn {",

View File

@@ -41,7 +41,7 @@
"@eslint/js": "^9.36.0",
"@libsql/client": "^0.15.0",
"@modelcontextprotocol/inspector": "^0.17.0",
"@sveltejs/adapter-vercel": "^6.0.0",
"@sveltejs/adapter-vercel": "^5.6.3",
"@sveltejs/kit": "^2.22.0",
"@sveltejs/vite-plugin-svelte": "^6.0.0",
"@types/node": "^24.3.1",
@@ -59,13 +59,12 @@
"typescript": "^5.0.0",
"vite": "^7.0.4",
"vite-plugin-devtools-json": "^1.0.0",
"vitest": "^4.0.0"
"vitest": "^3.2.3"
},
"dependencies": {
"@sveltejs/mcp-schema": "workspace:^",
"@sveltejs/mcp-server": "workspace:^",
"@tmcp/transport-http": "catalog:mcp",
"@vercel/analytics": "^1.5.0",
"tmcp": "catalog:mcp"
"@tmcp/transport-http": "^0.6.3",
"tmcp": "^1.14.0"
}
}

View File

@@ -1,13 +1,8 @@
import { dev } from '$app/environment';
import { http_transport } from '$lib/mcp/index.js';
import { db } from '$lib/server/db/index.js';
import { redirect } from '@sveltejs/kit';
import { track } from '@vercel/analytics/server';
export async function handle({ event, resolve }) {
if (event.request.method === 'POST') {
console.log(await event.request.clone().text());
}
if (event.request.method === 'GET') {
const accept = event.request.headers.get('accept');
if (accept) {
@@ -21,12 +16,6 @@ export async function handle({ event, resolve }) {
}
const mcp_response = await http_transport.respond(event.request, {
db,
// only add analytics in production
track: dev
? undefined
: async (session_id, event, slug) => {
await track(event, { session_id, ...(slug ? { slug } : {}) });
},
});
// we are deploying on vercel the SSE connection will timeout after 5 minutes...for
// the moment we are not sending back any notifications (logs, or list changed notifications)
@@ -36,14 +25,11 @@ export async function handle({ event, resolve }) {
// 200 or the MCP client will complain)
if (mcp_response && event.request.method === 'GET') {
try {
return mcp_response;
} finally {
try {
await mcp_response.body?.cancel();
} catch {
// ignore
}
await mcp_response.body?.cancel();
} catch {
// ignore
}
return new Response('', { status: 200 });
}
return mcp_response ?? resolve(event);
}

View File

@@ -3,5 +3,4 @@ import { HttpTransport } from '@tmcp/transport-http';
export const http_transport = new HttpTransport(server, {
cors: true,
path: '/mcp',
});

View File

@@ -1,6 +1,8 @@
import { createClient } from '@libsql/client';
import { drizzle } from 'drizzle-orm/libsql';
import * as schema from './schema.js';
// let's disable it for the moment...i can't figure out a way to make it wotk with eslint
// eslint-disable-next-line import/extensions
import { DATABASE_TOKEN, DATABASE_URL } from '$env/static/private';
if (!DATABASE_URL) throw new Error('DATABASE_URL is not set');
if (!DATABASE_TOKEN) throw new Error('DATABASE_TOKEN is not set');

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

View File

@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path d="M416.9 93.1c-41.1-58.9-122.4-76.3-181.2-38.9L132.5 120c-28.2 17.7-47.6 46.5-53.5 79.3-4.9 27.3-.6 55.5 12.3 80-8.8 13.4-14.9 28.5-17.7 44.2-5.9 33.4 1.8 67.8 21.6 95.4 41.2 58.9 122.4 76.3 181.2 38.9L379.6 392c28.2-17.7 47.6-46.5 53.5-79.3 4.9-27.3.6-55.5-12.3-80 8.8-13.4 14.9-28.4 17.7-44.2 5.8-33.4-1.9-67.8-21.6-95.4" style="fill:#ff3e00"/><path d="M225.6 424.5c-33.3 8.6-68.4-4.4-88-32.6-11.9-16.6-16.5-37.3-13-57.4.6-3.3 1.4-6.5 2.5-9.6l1.9-5.9 5.3 3.9c12.2 9 25.9 15.8 40.4 20.2l3.8 1.2-.4 3.8c-.5 5.4 1 10.9 4.2 15.3 5.9 8.5 16.5 12.4 26.5 9.8 2.2-.6 4.4-1.5 6.3-2.8l103.2-65.8c5.1-3.2 8.6-8.4 9.7-14.4 1.1-6.1-.3-12.3-3.9-17.3-5.9-8.5-16.5-12.4-26.5-9.8-2.2.6-4.4 1.5-6.3 2.8L252 291c-6.5 4.1-13.5 7.2-21 9.2-33.3 8.6-68.4-4.4-88-32.6-11.9-16.6-16.5-37.3-13-57.4 3.5-19.7 15.2-37 32.2-47.7l103.2-65.8c6.5-4.1 13.5-7.2 21-9.2 33.3-8.6 68.4 4.4 88 32.6 11.9 16.6 16.5 37.3 13 57.4-.6 3.3-1.4 6.5-2.5 9.6L383 193l-5.3-3.9c-12.2-9-25.9-15.8-40.4-20.2l-3.8-1.2.4-3.8c.5-5.4-1-10.9-4.2-15.3-5.9-8.5-16.5-12.4-26.5-9.8-2.2.6-4.4 1.5-6.3 2.8l-103.2 65.8c-5.1 3.2-8.6 8.4-9.7 14.4-1.1 6.1.3 12.3 3.9 17.3 5.9 8.5 16.5 12.4 26.5 9.8 2.2-.6 4.4-1.5 6.3-2.8L260 221c6.5-4.1 13.5-7.2 21-9.2 33.3-8.6 68.4 4.4 88 32.6 11.9 16.6 16.5 37.3 13 57.4-3.5 19.7-15.2 37-32.2 47.7l-103.2 65.8c-6.5 4.1-13.6 7.2-21 9.2" style="fill:#fff"/></svg>

Before

Width:  |  Height:  |  Size: 1.4 KiB

View File

@@ -105,13 +105,13 @@ It will open a file with your MCP servers where you can add the following config
```json
{
"mcpServers": {
"svelte": {
"type": "http",
"url": "https://mcp.svelte.dev/mcp",
"tools": ["*"]
}
}
"mcpServers" {
"svelte": {
"type": "http",
"url": "https://mcp.svelte.dev/mcp",
"tools": ["*"]
}
}
}
```

View File

@@ -25,7 +25,6 @@ You are a Svelte expert tasked to build components and utilities for Svelte deve
- title: drizzle, use_cases: database setup, sql queries, orm integration, data modeling, postgresql, mysql, sqlite, server-side data access, database migrations, type-safe queries, path: cli/drizzle
- title: eslint, use_cases: code quality, linting, error detection, project setup, code standards, team collaboration, typescript projects, path: cli/eslint
- title: lucia, use_cases: authentication, login systems, user management, registration pages, session handling, auth setup, path: cli/lucia
- title: mcp, use_cases: use title and path to estimate use case, path: cli/mcp
- title: mdsvex, use_cases: blog, content sites, markdown rendering, documentation sites, technical writing, cms integration, article pages, path: cli/mdsvex
- title: paraglide, use_cases: internationalization, multi-language sites, i18n, translation, localization, language switching, global apps, multilingual content, path: cli/paraglide
- title: playwright, use_cases: browser testing, e2e testing, integration testing, test automation, quality assurance, ci/cd pipelines, testing user flows, path: cli/playwright

View File

@@ -13,7 +13,7 @@ const gitignore_path = fileURLToPath(new URL('./.gitignore', import.meta.url));
export default /** @type {import("eslint").Linter.Config} */ ([
includeIgnoreFile(gitignore_path),
{
ignores: ['.claude/**/*', '.changeset/*'],
ignores: ['.claude/**/*'],
},
js.configs.recommended,
...ts.configs.recommended,
@@ -48,17 +48,13 @@ export default /** @type {import("eslint").Linter.Config} */ ([
'import/no-unresolved': 'off', // this doesn't work well with typescript path mapping
'import/extensions': [
'error',
'ignorePackages',
{
ignorePackages: true,
pattern: {
js: 'always',
mjs: 'always',
cjs: 'always',
ts: 'always',
svelte: 'always',
svg: 'always',
json: 'always',
},
js: 'always',
mjs: 'always',
cjs: 'always',
ts: 'always',
svelte: 'always',
},
],
},

View File

@@ -3,7 +3,7 @@
"version": "0.0.1",
"description": "The official Svelte MCP server implementation",
"type": "module",
"packageManager": "pnpm@10.20.0",
"packageManager": "pnpm@10.18.2",
"scripts": {
"build": "pnpm -r run build",
"dev": "pnpm --filter @sveltejs/mcp-remote run dev",
@@ -46,7 +46,7 @@
"publint": "^0.3.13",
"typescript": "^5.0.0",
"typescript-eslint": "^8.44.1",
"vitest": "^4.0.0"
"vitest": "^3.2.3"
},
"pnpm": {
"onlyBuiltDependencies": [

View File

@@ -20,23 +20,22 @@
"drizzle-orm": "^0.44.0"
},
"dependencies": {
"@mcp-ui/server": "^5.12.0",
"@sveltejs/mcp-schema": "workspace:^",
"@tmcp/adapter-valibot": "catalog:mcp",
"@tmcp/adapter-valibot": "^0.1.4",
"@typescript-eslint/parser": "^8.44.0",
"eslint": "^9.36.0",
"eslint-plugin-svelte": "^3.12.5",
"eslint-plugin-svelte": "^3.12.3",
"svelte": "^5.39.2",
"svelte-eslint-parser": "^1.4.0",
"tmcp": "catalog:mcp",
"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": "^4.0.0",
"vitest": "^3.2.4",
"zimmerframe": "^1.1.4"
},
"devDependencies": {
"@anthropic-ai/sdk": "^0.68.0",
"@anthropic-ai/sdk": "^0.65.0",
"@sveltejs/kit": "^2.42.2",
"@types/eslint-scope": "^8.3.2",
"@types/estree": "^1.0.8",

View File

@@ -11,7 +11,6 @@ export const base_runes = [
export const nested_runes = [
'$state.raw',
'$state.snapshot',
'$state.eager',
'$effect.pre',
'$effect.tracking',
'$effect.pending',

View File

@@ -8,7 +8,6 @@ export function add_autofixers_issues(
code: string,
desired_svelte_version: number,
filename = 'Component.svelte',
async = false,
) {
const parsed = parse(code, filename);
@@ -16,7 +15,7 @@ export function add_autofixers_issues(
for (const autofixer of Object.values(autofixers)) {
walk(
parsed.ast as unknown as Node,
{ output: content, parsed, desired_svelte_version, async },
{ output: content, parsed, desired_svelte_version },
autofixer,
);
}

View File

@@ -7,7 +7,6 @@ export function add_compile_issues(
code: string,
desired_svelte_version: number,
filename = 'Component.svelte',
async = false,
) {
let compile = compile_component;
const extension = extname(filename);
@@ -28,7 +27,6 @@ export function add_compile_issues(
filename: filename || 'Component.svelte',
generate: false,
runes: desired_svelte_version >= 5,
experimental: { async },
});
for (const warning of compilation_result.warnings) {

View File

@@ -51,7 +51,7 @@ function base_config(svelte_config: Config): ESLint.Options['baseConfig'] {
];
}
function get_linter(version: number, async = false) {
function get_linter(version: number) {
if (version < 5) {
return (svelte_4_linter ??= new ESLint({
overrideConfigFile: true,
@@ -67,7 +67,6 @@ function get_linter(version: number, async = false) {
baseConfig: base_config({
compilerOptions: {
runes: true,
experimental: { async },
},
}),
}));
@@ -78,9 +77,8 @@ export async function add_eslint_issues(
code: string,
desired_svelte_version: number,
filename = 'Component.svelte',
async = false,
) {
const eslint = get_linter(desired_svelte_version, async);
const eslint = get_linter(desired_svelte_version);
const results = await eslint.lintText(code, { filePath: filename || './Component.svelte' });
for (const message of results[0]?.messages ?? []) {

View File

@@ -7,7 +7,6 @@ export type AutofixerState = {
output: { issues: string[]; suggestions: string[] };
parsed: ParseResult;
desired_svelte_version: number;
async?: boolean;
};
export type Autofixer = Visitors<Node | AST.SvelteNode, AutofixerState>;

View File

@@ -1,7 +1,6 @@
import type { SvelteMcp } from '../../index.js';
import * as v from 'valibot';
import { format_sections_list } from '../../utils.js';
import { icons } from '../../icons/index.js';
/**
* Function that actually generates the prompt string. You can use this in the MCP server handler to generate the prompt, it can accept arguments
@@ -65,12 +64,8 @@ export function setup_svelte_task(server: SvelteMcp) {
};
},
},
icons,
},
async ({ task }) => {
if (server.ctx.sessionId && server.ctx.custom?.track) {
await server.ctx.custom?.track?.(server.ctx.sessionId, 'svelte-task');
}
const available_docs = await format_sections_list();
return {

View File

@@ -1,6 +1,5 @@
import type { SvelteMcp } from '../../index.js';
import { get_sections, fetch_with_timeout } from '../../utils.js';
import { icons } from '../../icons/index.js';
export async function list_sections(server: SvelteMcp) {
const sections = await get_sections();
@@ -43,16 +42,8 @@ export async function list_sections(server: SvelteMcp) {
},
},
uri: 'svelte://{/slug*}.md',
icons,
},
async (uri, { slug }) => {
if (server.ctx.sessionId && server.ctx.custom?.track) {
await server.ctx.custom?.track?.(
server.ctx.sessionId,
'svelte-doc-section',
Array.isArray(slug) ? slug.join(',') : slug,
);
}
const section = sections.find((section) => {
return slug === section.slug;
});

View File

@@ -2,7 +2,6 @@ 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';
import { icons } from '../../icons/index.js';
export function get_documentation(server: SvelteMcp) {
server.tool(
@@ -18,12 +17,8 @@ export function get_documentation(server: SvelteMcp) {
),
),
}),
icons,
},
async ({ section }) => {
if (server.ctx.sessionId && server.ctx.custom?.track) {
await server.ctx.custom?.track?.(server.ctx.sessionId, 'get-documentation');
}
let sections: string[];
if (Array.isArray(section)) {

View File

@@ -1,7 +1,6 @@
import type { SvelteMcp } from '../../index.js';
import { format_sections_list } from '../../utils.js';
import { SECTIONS_LIST_INTRO, SECTIONS_LIST_OUTRO } from './prompts.js';
import { icons } from '../../icons/index.js';
export function list_sections(server: SvelteMcp) {
server.tool(
@@ -9,12 +8,8 @@ export function list_sections(server: SvelteMcp) {
name: 'list-sections',
description:
'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.',
icons,
},
async () => {
if (server.ctx.sessionId && server.ctx.custom?.track) {
await server.ctx.custom?.track?.(server.ctx.sessionId, 'list-sections');
}
const formatted_sections = await format_sections_list();
return {

View File

@@ -1,7 +1,5 @@
import type { SvelteMcp } from '../../index.js';
import * as v from 'valibot';
import { icons } from '../../icons/index.js';
import { createUIResource } from '@mcp-ui/server';
async function compress_and_encode_text(input: string) {
const reader = new Blob([input]).stream().pipeThrough(new CompressionStream('gzip')).getReader();
@@ -56,12 +54,8 @@ export function playground_link(server: SvelteMcp) {
outputSchema: v.object({
url: v.string(),
}),
icons,
},
async ({ files, name, tailwind }) => {
if (server.ctx.sessionId && server.ctx.custom?.track) {
await server.ctx.custom?.track?.(server.ctx.sessionId, 'playground-link');
}
const playground_base = new URL('https://svelte.dev/playground');
const playground_files: File[] = [];
@@ -79,9 +73,6 @@ export function playground_link(server: SvelteMcp) {
}
if (!has_app_svelte) {
if (server.ctx.sessionId && server.ctx.custom?.track) {
await server.ctx.custom?.track?.(server.ctx.sessionId, 'playground-link-no-app-svelte');
}
return {
isError: true,
content: [
@@ -107,26 +98,12 @@ export function playground_link(server: SvelteMcp) {
url: playground_base.toString(),
};
// use the embed path to have a cleaner UI for mcp-ui
playground_base.pathname = '/playground/embed';
return {
content: [
{
type: 'text',
text: JSON.stringify(content),
},
createUIResource({
uri: 'ui://svelte/playground-link',
content: {
type: 'externalUrl',
iframeUrl: playground_base.toString(),
},
uiMetadata: {
'preferred-frame-size': ['100%', '1200px'],
},
encoding: 'text',
}),
],
structuredContent: content,
};

View File

@@ -1,155 +0,0 @@
import { beforeEach, describe, expect, it } from 'vitest';
import { server } from '../../index.js';
/**
* Small utility to create a JSON-RPC request without having to always specify as const
*/
function request<const T>(request: T) {
return request;
}
async function autofixer_tool_call(
code: string,
is_error = false,
desired_svelte_version = 5,
async = false,
) {
const result = await server.receive({
jsonrpc: '2.0',
id: 2,
method: 'tools/call',
params: {
name: 'svelte-autofixer',
arguments: {
code,
desired_svelte_version,
filename: 'App.svelte',
async,
},
},
});
expect(result).toBeDefined();
expect(result.result).toBeDefined();
if (is_error) {
return result.result;
}
expect(result.result.structuredContent).toBeDefined();
return result.result.structuredContent;
}
describe('svelte-autofixer tool', () => {
beforeEach(async () => {
const initialize_request = request({
jsonrpc: '2.0',
id: 1,
method: 'initialize',
params: {
protocolVersion: '2025-06-18',
capabilities: {
roots: { listChanged: true },
},
clientInfo: {
name: 'test-client',
version: '1.0.0',
},
},
});
await server.receive(initialize_request, {
sessionId: 'svelte-autofixer-session',
});
});
it('should add suggestions for js parse errors', async () => {
const content = await autofixer_tool_call(`<script>
$state count = 0;
</script>`);
expect(content.issues.length).toBeGreaterThan(0);
expect(content.suggestions).toContain(
"The code can't be compiled because a Javascript parse error. In case you are using runes like this `$state variable_name = 3;` or `$derived variable_name = 3 * count` that's not how runes are used. You need to use them as function calls without importing them: `const variable_name = $state(3)` and `const variable_name = $derived(3 * count)`.",
);
});
it('should error out if async is true with a version less than 5', async () => {
const content = await autofixer_tool_call(
`<script>
$state count = 0;
</script>`,
true,
4,
true,
);
expect(content.isError).toBeTruthy();
expect(content.content[0]).toBeDefined();
expect(content.content[0].text).toBe(
'The async option can only be used with Svelte version 5 or higher.',
);
});
it('should not add suggestion/issues if async is true and await is used in the template/derived', async () => {
const content = await autofixer_tool_call(
`<script>
import { slow_double } from './utils.js';
let count = $state(0);
let double = $derived(await slow_double(count));
</script>
{double}
{await slow_double(count)}`,
false,
5,
true,
);
expect(content.issues).toHaveLength(0);
expect(content.suggestions).toHaveLength(0);
expect(content.require_another_tool_call_after_fixing).toBeFalsy();
});
it('should add suggestion/issues if async is false and await is used in the template/derived', async () => {
const content = await autofixer_tool_call(
`<script>
import { slow_double } from './utils.js';
let count = $state(0);
let double = $derived(await slow_double(count));
</script>
{double}
{await slow_double(count)}`,
false,
5,
);
expect(content.issues.length).toBeGreaterThanOrEqual(1);
expect(content.issues).toEqual(
expect.arrayContaining([expect.stringContaining('experimental_async')]),
);
expect(content.require_another_tool_call_after_fixing).toBeTruthy();
});
it('should add suggestions for css invalid identifier', async () => {
const content = await autofixer_tool_call(`<script>
let my_color = $state('red');
</script>
<style>
.my-class {
color: {my_color};
}
</style>`);
expect(content.issues.length).toBeGreaterThan(0);
expect(content.suggestions).toContain(
"The code can't be compiled because a valid CSS identifier is expected. This sometimes means you are trying to use a variable in CSS like this: `color: {my_color}` but Svelte doesn't support that. You can use inline CSS variables for that `<div style:--color={my_color}></div>` and then use the variable as usual in CSS with `color: var(--color)`.",
);
});
it('should error in case the passed in version is different from 4 or 5', async () => {
const content = await autofixer_tool_call(`whatever`, true, 3);
expect(content.content).toBeDefined();
expect(content.content[0]).toBeDefined();
expect(content.content[0].text).toContain(
'The desired_svelte_version MUST be either 4 or 5 but received "3"',
);
});
});

View File

@@ -4,7 +4,6 @@ import * as v from 'valibot';
import { add_compile_issues } from '../../autofixers/add-compile-issues.js';
import { add_eslint_issues } from '../../autofixers/add-eslint-issues.js';
import { add_autofixers_issues } from '../../autofixers/add-autofixers-issues.js';
import { icons } from '../../icons/index.js';
export function svelte_autofixer(server: SvelteMcp) {
server.tool(
@@ -21,12 +20,6 @@ export function svelte_autofixer(server: SvelteMcp) {
'The desired svelte version...if possible read this from the package.json of the user project, otherwise use some hint from the wording (if the user asks for runes it wants version 5). Default to 5 in case of doubt.',
),
),
async: v.pipe(
v.optional(v.boolean()),
v.description(
'If true the code is an async component/module and might use await in the markup or top-level awaits in the script tag. If possible check the svelte.config.js/svelte.config.ts to check if the option is enabled otherwise asks the user if they prefer using it or not. You can only use this option if the version is 5.',
),
),
filename: v.pipe(
v.optional(v.string()),
v.description(
@@ -45,26 +38,18 @@ export function svelte_autofixer(server: SvelteMcp) {
readOnlyHint: true,
openWorldHint: false,
},
icons,
},
async ({
code,
filename: filename_or_path,
desired_svelte_version: desired_svelte_version_unchecked,
async,
}) => {
if (server.ctx.sessionId && server.ctx.custom?.track) {
await server.ctx.custom?.track?.(server.ctx.sessionId, 'svelte-autofixer');
}
// we validate manually because some clients don't support union in the input schema (looking at you cursor)
const parsed_version = v.safeParse(
v.union([v.literal(4), v.literal(5), v.literal('4'), v.literal('5')]),
desired_svelte_version_unchecked,
);
if (parsed_version.success === false) {
if (server.ctx.sessionId && server.ctx.custom?.track) {
await server.ctx.custom?.track?.(server.ctx.sessionId, 'svelte-autofixer-wrong-version');
}
return {
isError: true,
content: [
@@ -78,18 +63,6 @@ export function svelte_autofixer(server: SvelteMcp) {
const desired_svelte_version = parsed_version.output;
if (async && +desired_svelte_version < 5) {
return {
isError: true,
content: [
{
type: 'text',
text: `The async option can only be used with Svelte version 5 or higher.`,
},
],
};
}
const content: {
issues: string[];
suggestions: string[];
@@ -101,11 +74,11 @@ export function svelte_autofixer(server: SvelteMcp) {
const filename = filename_or_path ? basename(filename_or_path) : 'Component.svelte';
add_compile_issues(content, code, +desired_svelte_version, filename, async);
add_compile_issues(content, code, +desired_svelte_version, filename);
add_autofixers_issues(content, code, +desired_svelte_version, filename, async);
add_autofixers_issues(content, code, +desired_svelte_version, filename);
await add_eslint_issues(content, code, +desired_svelte_version, filename, async);
await add_eslint_issues(content, code, +desired_svelte_version, filename);
} catch (e: unknown) {
const error = e as Error & { start?: { line: number; column: number } };
content.issues.push(
@@ -115,10 +88,6 @@ export function svelte_autofixer(server: SvelteMcp) {
content.suggestions.push(
"The code can't be compiled because a Javascript parse error. In case you are using runes like this `$state variable_name = 3;` or `$derived variable_name = 3 * count` that's not how runes are used. You need to use them as function calls without importing them: `const variable_name = $state(3)` and `const variable_name = $derived(3 * count)`.",
);
} else if (error.message.includes('css_expected_identifier')) {
content.suggestions.push(
"The code can't be compiled because a valid CSS identifier is expected. This sometimes means you are trying to use a variable in CSS like this: `color: {my_color}` but Svelte doesn't support that. You can use inline CSS variables for that `<div style:--color={my_color}></div>` and then use the variable as usual in CSS with `color: var(--color)`.",
);
}
}

View File

@@ -1,14 +0,0 @@
export const icons = [
{
src: 'https://mcp.svelte.dev/logo.svg',
mimeType: 'image/svg+xml',
},
{
src: 'https://mcp.svelte.dev/logo.png',
mimeType: 'image/png',
},
{
src: 'data:image/png;base64,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',
mimeType: 'image/png',
},
];

View File

@@ -3,15 +3,12 @@ import { McpServer } from 'tmcp';
import { setup_prompts, setup_resources, setup_tools } from './handlers/index.js';
import type { LibSQLDatabase } from 'drizzle-orm/libsql';
import type { Schema } from '@sveltejs/mcp-schema';
import { icons } from './icons/index.js';
export const server = new McpServer(
{
name: 'Svelte MCP',
version: '0.0.1',
description: 'The official Svelte MCP server implementation',
websiteUrl: 'https://mcp.svelte.dev',
icons,
},
{
adapter: new ValibotJsonSchemaAdapter(),
@@ -24,10 +21,7 @@ export const server = new McpServer(
instructions:
'This is the official Svelte MCP server. It MUST be used whenever svelte development is involved. It can provide official documentation, code examples and correct your code. After you correct the component call this tool again to confirm all the issues are fixed.',
},
).withContext<{
db: LibSQLDatabase<Schema>;
track?: (sessionId: string, event: string, slug?: string) => Promise<void>;
}>();
).withContext<{ db: LibSQLDatabase<Schema> }>();
export type SvelteMcp = typeof server;

View File

@@ -1,53 +1,5 @@
# @sveltejs/mcp
## 0.1.11
### Patch Changes
- fix: add `async` parameter to `svelte-autofixer` ([#94](https://github.com/sveltejs/mcp/pull/94))
- fix: install latest eslint svelte packages to support `$state.eager` ([`f6ce89f`](https://github.com/sveltejs/mcp/commit/f6ce89ff34faabc3d746a350ea347298ecfed2ec))
## 0.1.10
### Patch Changes
- fix: add icons to `server.json` ([`02c951b`](https://github.com/sveltejs/mcp/commit/02c951baa86ac8103ffc158a202c06cfe6b15c01))
- fix: add `preferred-frame-size` to UI resource ([`3fabcc0`](https://github.com/sveltejs/mcp/commit/3fabcc0f9bfee916c0deb9c2ffa931ed2168af2d))
- feat: support: `$state.eager` ([#90](https://github.com/sveltejs/mcp/pull/90))
## 0.1.9
### Patch Changes
- feat: return `mcp-ui` resource from `playground-link` ([#84](https://github.com/sveltejs/mcp/pull/84))
- feat: suggest against js variables in css ([#78](https://github.com/sveltejs/mcp/pull/78))
## 0.1.8
### Patch Changes
- fix: upgrade registry publisher cli ([`5fa2baa`](https://github.com/sveltejs/mcp/commit/5fa2baa27009f01e0e4e91cee7984b81a81c1c29))
## 0.1.7
### Patch Changes
- fix: use correct server schema version ([`579be87`](https://github.com/sveltejs/mcp/commit/579be877fa9f87f7f173450ca5bc918824d68282))
## 0.1.6
### Patch Changes
- fix: prevent `imported_runes` suggestion from being added for libs that are not svelte ([`87af64f`](https://github.com/sveltejs/mcp/commit/87af64f4bc6d07b75640eb987a33655654363997))
- feat: add svelte icon and website url for mcp server ([#75](https://github.com/sveltejs/mcp/pull/75))
- fix: use `data:` uri for local icon & add icons to tools + resources + prompts ([`cf62286`](https://github.com/sveltejs/mcp/commit/cf622869129382a97ad059bb1389f115907adc8e))
## 0.1.5
### Patch Changes

View File

@@ -0,0 +1,25 @@
4e7c92f289d903d4649c59f82df6e7b014caebb49d8b5c1d2466667fd6caf68c mcp-publisher_1.2.3_darwin_amd64.tar.gz
09637600871bec7cce25e098d6ce23b7c7577a8e537f618d24a5630d2d782afa mcp-publisher_1.2.3_darwin_amd64.tar.gz.sbom.json
9ac90d3182bae9af4b48fb3cd19c3cade3e52c8ea25d7aa14327326a209bcf71 mcp-publisher_1.2.3_darwin_arm64.tar.gz
0b2cedf3f42c5a7b33bdd3f72ce7f4c938ff4fe2aca5cabd60094dc4b855c1f6 mcp-publisher_1.2.3_darwin_arm64.tar.gz.sbom.json
868a54268f21580ec97ec9dfc4fc3442a7f69c241ee7c745c7032f2e43cdf47b mcp-publisher_1.2.3_linux_amd64.tar.gz
a7bce190ea1c1b5682d1b5069b20dd9c67f3688e02dbc93e7273e942097dac4d mcp-publisher_1.2.3_linux_amd64.tar.gz.sbom.json
319cdefb4c4f19fa35eeb0337e30be3169dbf3107a8c160651691a6342a6783b mcp-publisher_1.2.3_linux_arm64.tar.gz
bc9309ab843531e811990dcf637b9912c470fc38eddc13a5af0512fcef498944 mcp-publisher_1.2.3_linux_arm64.tar.gz.sbom.json
298026e0252547046f50dcb7817239d44107f5a3ae64f4e43b6a31d0c5b89f9b mcp-publisher_1.2.3_windows_amd64.tar.gz
971b835ce4df2b37ddcf8591d4400dc94d1e3f730b181b325c905261b75b9e6e mcp-publisher_1.2.3_windows_amd64.tar.gz.sbom.json
64da67b451d0fba12f15f7b0f6ab8d71c718bb2263f90f198ff1fe15a5ff2024 mcp-publisher_1.2.3_windows_arm64.tar.gz
f591b2153f1277cb67817763a23de9e77188fa94b893fac00e91d13160d696e3 mcp-publisher_1.2.3_windows_arm64.tar.gz.sbom.json
265377b343500898e3c3fea798926ff2695fe7500c1225c8a97f390a5892d849 registry-1.2.3.tar.gz
a9c03a84d2e30176d6ed7b493e7e3a8a05d446f1611a35bad6007fbe3ba80657 registry_1.2.3_darwin_amd64.tar.gz
4db4e8a0b1f3d0ca193e5356fef89b74c0666cdf56d6f3c8fc2d0aba1cac3b55 registry_1.2.3_darwin_amd64.tar.gz.sbom.json
2933a11990db16035e4896f394ada389166046911e6868f79b84636048dfe6fb registry_1.2.3_darwin_arm64.tar.gz
edd36e62f4b1c5b857da1862f20cbcf6dd3dfd9717888c08bd5c25740d8b11f6 registry_1.2.3_darwin_arm64.tar.gz.sbom.json
59bdd9977795891220e6fdb8f79dd7d14f48166362e94699bee59e745f7c7df6 registry_1.2.3_linux_amd64.tar.gz
7f7efb180aa312f674377e32a92ac3600e50c62e37d697d2d16acfe60227a2fd registry_1.2.3_linux_amd64.tar.gz.sbom.json
7fef1088a664850dd75e54a699fce6a5fb32e8ebbdc0d2869b6b34945727ba9c registry_1.2.3_linux_arm64.tar.gz
ca0488e5cbb04c8ee515e1b80e08b755a55d6af1784368a2f55e429137359a25 registry_1.2.3_linux_arm64.tar.gz.sbom.json
5bc29310aacc08437dcc973cfc1e1129f7065d2050396012f5ed98c4eb0ea75b registry_1.2.3_windows_amd64.tar.gz
e918c604f23e6d33f9952f18eddf0e50e50d7ce3e87ca5258bf78f4f1da243ab registry_1.2.3_windows_amd64.tar.gz.sbom.json
394cad1e6f5e37a583defdd522edbff854de5035d6e025a195664db31b58c0c0 registry_1.2.3_windows_arm64.tar.gz
c93df66f3257ba4b9c29f7bfded4cf04d712ec220b044ddfa019da3e4bd6475f registry_1.2.3_windows_arm64.tar.gz.sbom.json

View File

@@ -1,25 +0,0 @@
704f15b3ccba80990fbaaeb858e2e893120dea3ebb9340e04a36065987e089c5 mcp-publisher_darwin_amd64.tar.gz
9eadadeb80998cd5b29e009dd3959634730d3754b9e201c0a3bb39dd6ae85933 mcp-publisher_darwin_amd64.tar.gz.sbom.json
f80265eadc6b052d2885a7dfa47a1ecc7ca95926c143197ced747317793dcc11 mcp-publisher_darwin_arm64.tar.gz
f063c462512eed8f2ce9610a6a125534cb552060ddb5364d8d49b32196416fbe mcp-publisher_darwin_arm64.tar.gz.sbom.json
1113b9d6bf59b000966c4f17752cf87b51db03dcc5482721421fd843ce3bf048 mcp-publisher_linux_amd64.tar.gz
d3e46855b3b906aa84571b0d16384ad6074fd08709108a47d724908e91947b9d mcp-publisher_linux_amd64.tar.gz.sbom.json
34be13ec07490ab1250194d56820af222b49b85db6062ff848d33f9cf6eb41ce mcp-publisher_linux_arm64.tar.gz
a1ff3c26d53007c98301b747f97e5e241bfdb860b6a761db8627c9ba9ba71d88 mcp-publisher_linux_arm64.tar.gz.sbom.json
9ba8b538744652c4837d08b7b83ae85d2dbea98c897cfcf4d90835df4fe075b3 mcp-publisher_windows_amd64.tar.gz
924a0adcebd9360aed4ee5959e664e4e99b8259ed871ac91be5ace5657afba7d mcp-publisher_windows_amd64.tar.gz.sbom.json
a3eeab18ee6fd1d76d7ec153779ebe1bb404d7ea561f117781174e4396d90565 mcp-publisher_windows_arm64.tar.gz
9351f3acc39f89402ce5f72be1b45f3bf1b16f8441c97496195188f276e6c227 mcp-publisher_windows_arm64.tar.gz.sbom.json
9767b6f2afe1b60c597d4c66468d491be3466b25de8b4d4e7a21e61950856ef7 registry-1.3.3.tar.gz
a7867ff2c15905a765dc77636d86241ea04a17d0a90f086913a3cea4fe899213 registry_darwin_amd64.tar.gz
f0ed44b6ebdfcba40daefe7ca556f385de0cbae95dca3077c406f75cdb6abb9b registry_darwin_amd64.tar.gz.sbom.json
b4d93d6fc2d831d287cde79953822b434cb8406eea4f38f180628df227f6569e registry_darwin_arm64.tar.gz
dde0ed7f350eda98eb6f474d19aa0e4c717dd9f120609949acf05d7986cf6fcc registry_darwin_arm64.tar.gz.sbom.json
6772a573828f3482a192c88dac4223ee71ff4f521c8819480a194757e46a8272 registry_linux_amd64.tar.gz
ac177354d5f43f86bdf7f36738837a2792ba136198209eb61d4d4dd9ab408853 registry_linux_amd64.tar.gz.sbom.json
61c1fb9126977e0694d5aad8990a9d4c2d0e933e6aa469789559fad3865e8b7f registry_linux_arm64.tar.gz
9b81dfe2c81c49f7731072b8c217f05d609f7094ea94aaf9491f33880f2dec7f registry_linux_arm64.tar.gz.sbom.json
7fb5752de50a841614c6990f20807820bda33a72eaf7be51ae6cbd4e9acb2b87 registry_windows_amd64.tar.gz
fd44139231d4725c75b2a5a96fb670d3137f628db91c8281f6348e842792d514 registry_windows_amd64.tar.gz.sbom.json
a85ba7eb1a06a9e668b8a2097e00ab010e454a2afeb4e29ebeb7b702a31cccd3 registry_windows_arm64.tar.gz
93503683d32a2971b741e87f2879cb2a3f41acd184c618e04d17a98926915f2d registry_windows_arm64.tar.gz.sbom.json

View File

@@ -1,6 +1,6 @@
{
"name": "@sveltejs/mcp",
"version": "0.1.11",
"version": "0.1.5",
"type": "module",
"license": "MIT",
"mcpName": "dev.svelte/mcp",
@@ -32,15 +32,14 @@
},
"devDependencies": {
"@sveltejs/mcp-server": "workspace:^",
"@tmcp/transport-stdio": "catalog:mcp",
"@tmcp/transport-stdio": "^0.3.1",
"@types/node": "^22.15.17",
"publint": "^0.3.13",
"tsdown": "^0.15.0",
"typescript": "^5.8.3",
"vitest": "^4.0.0"
"vitest": "^3.1.3"
},
"dependencies": {
"eslint": "^9.36.0",
"tmcp": "catalog:mcp"
"eslint": "^9.36.0"
}
}

View File

@@ -1,5 +1,5 @@
{
"$schema": "https://static.modelcontextprotocol.io/schemas/2025-10-17/server.schema.json",
"$schema": "https://static.modelcontextprotocol.io/schemas/2025-09-29/server.schema.json",
"name": "dev.svelte/mcp",
"description": "The official Svelte MCP server providing docs and autofixing tools for Svelte development",
"repository": {
@@ -8,23 +8,13 @@
"subfolder": "packages/mcp-stdio",
"source": "github"
},
"version": "0.1.11",
"version": "0.1.5",
"websiteUrl": "https://svelte.dev/docs/mcp/overview",
"icons": [
{
"src": "https://mcp.svelte.dev/logo.svg",
"mimeType": "image/svg+xml"
},
{
"src": "https://mcp.svelte.dev/logo.png",
"mimeType": "image/png"
}
],
"packages": [
{
"registryType": "npm",
"identifier": "@sveltejs/mcp",
"version": "0.1.11",
"version": "0.1.5",
"runtimeHint": "npx",
"transport": {
"type": "stdio"

660
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

View File

@@ -3,10 +3,3 @@ packages:
- './apps/*'
useNodeVersion: 22.19.0
catalogs:
mcp:
tmcp: '^1.16.0'
'@tmcp/transport-http': '^0.8.0'
'@tmcp/transport-stdio': '^0.4.0'
'@tmcp/adapter-valibot': '^0.1.4'