Compare commits

..

39 Commits

Author SHA1 Message Date
Paolo Ricciuti
9a74df198d Merge pull request #57 from sveltejs/changeset-release/main 2025-10-09 18:34:54 +02:00
github-actions[bot]
f1280b9876 Version Packages 2025-10-09 16:33:34 +00:00
paoloricciuti
132943db3b feat: publish mcp to registry (maybe for real this time) 2025-10-09 18:30:21 +02:00
paoloricciuti
5ed1454e2c fix: use right curl param 2025-10-09 18:27:21 +02:00
Paolo Ricciuti
bd072bd324 Merge pull request #54 from sveltejs/changeset-release/main 2025-10-09 18:24:56 +02:00
github-actions[bot]
c35be898da Version Packages 2025-10-09 16:23:57 +00:00
paoloricciuti
b960301ced fix: add id-token: write permission to release.yml 2025-10-09 18:23:26 +02:00
Paolo Ricciuti
43408f5504 Merge pull request #45 from sveltejs/publish-to-registry 2025-10-09 18:18:26 +02:00
Paolo Ricciuti
bf4dcda7e1 Merge pull request #55 from mquandalle/fix-claude-code-command-docs
docs: fix CLI command syntax for Claude Code and Gemini CLI
2025-10-09 08:25:22 +02:00
Paolo Ricciuti
35691c464b docs: fix gemini 2025-10-09 08:10:38 +02:00
Paolo Ricciuti
a5decb4cf3 Merge pull request #56 from sveltejs/link-to-docs 2025-10-08 17:36:30 +02:00
paoloricciuti
cb9764c234 docs: add link to CLAUDE.md and AGENTS.md docs 2025-10-08 17:22:15 +02:00
paoloricciuti
3fbc786383 fix: verify checksum 2025-10-08 17:20:16 +02:00
Maxime Quandalle
3b680232a0 Fix CLI command syntax for Claude Code and Gemini CLI
Add missing `--` separator between CLI options and npx command.
Without this separator, the `-y` option is incorrectly parsed as a
CLI option instead of being passed to npx.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-08 10:22:01 +02:00
paoloricciuti
c5c08ccd13 fix: lint 2025-10-08 00:09:23 +02:00
paoloricciuti
4ac35bf258 chore: separate workflows 2025-10-08 00:06:12 +02:00
paoloricciuti
ecbbf70d98 fix: call changeset version in script 2025-10-07 23:50:10 +02:00
paoloricciuti
aaac49cdef chore: update version of server.json on release 2025-10-07 23:49:28 +02:00
paoloricciuti
558d964919 Merge branch 'main' into publish-to-registry 2025-10-07 23:35:45 +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
paoloricciuti
11cd2447fc feat: publish to registry 2025-10-05 12:13:34 +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
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
21 changed files with 483 additions and 18 deletions

View File

@@ -18,7 +18,7 @@ jobs:
- name: Setup pnpm
uses: pnpm/action-setup@v4
with:
version: 10.18.0
version: 10.18.1
- name: Setup Node.js
uses: actions/setup-node@v5

View File

@@ -18,7 +18,7 @@ jobs:
- name: Setup pnpm
uses: pnpm/action-setup@v4
with:
version: 10.18.0
version: 10.18.1
- name: Setup Node.js
uses: actions/setup-node@v5

37
.github/workflows/publish-mcp.yml vendored Normal file
View File

@@ -0,0 +1,37 @@
name: Publish to MCP Registry
on:
workflow_call:
permissions:
id-token: write # OpenID Connect token needed for MCP registry authentication
jobs:
publish-mcp:
name: Publish to MCP Registry
runs-on: ubuntu-latest
steps:
- name: checkout
uses: actions/checkout@v5
- name: Publish to MCP Registry
working-directory: packages/mcp-stdio
run: |
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.2.3_checksums.txt
# Extract the tarball
tar -xzf $NAME --no-same-owner --no-same-permissions -C tmp
# Install the MCP Publisher binary
install -m 0755 tmp/mcp-publisher
# Login using GitHub OIDC
./mcp-publisher login github-oidc
# Publish to MCP Registry
./mcp-publisher publish

View File

@@ -16,6 +16,8 @@ jobs:
if: github.repository == 'sveltejs/mcp'
name: Release
runs-on: ${{ matrix.os }}
outputs:
published: ${{ steps.changesets.outputs.published }}
strategy:
matrix:
# pseudo-matrix for convenience, NEVER use more than a single combination
@@ -51,8 +53,17 @@ jobs:
# 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 changeset:version version that calls changeset version and updated what it needs to be updated
version: pnpm changeset:version
# 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
publish-mcp:
needs: release
if: needs.release.outputs.published == 'true'
permissions:
id-token: write
uses: ./.github/workflows/publish-mcp.yml

View File

@@ -18,7 +18,7 @@ jobs:
- name: Setup pnpm
uses: pnpm/action-setup@v4
with:
version: 10.18.0
version: 10.18.1
- name: Setup Node.js
uses: actions/setup-node@v5

View File

@@ -13,7 +13,7 @@ The setup varies based on the version of the MCP you prefer — remote or local
## Usage
To get the most out of the MCP server we recommend including the following prompt in your `AGENTS.md` (or `CLAUDE.md`, if using Claude Code). This will tell the LLM which tools are available and when it's appropriate to use them.
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:

View File

@@ -15,7 +15,7 @@ Here's how to set it up in some common MCP clients:
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
claude mcp add -t stdio -s [scope] svelte -- npx -y @sveltejs/mcp
```
The `[scope]` must be `user`, `project` or `local`.
@@ -108,6 +108,25 @@ It will open a file with your MCP servers where you can add the following config
}
```
## 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

@@ -3,7 +3,7 @@
"version": "0.0.1",
"description": "The official Svelte MCP server implementation",
"type": "module",
"packageManager": "pnpm@10.18.0",
"packageManager": "pnpm@10.18.1",
"scripts": {
"build": "pnpm -r run build",
"dev": "pnpm --filter @sveltejs/mcp-remote run dev",
@@ -18,7 +18,8 @@
"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"
"release": "pnpm --filter @sveltejs/mcp run build && changeset publish",
"changeset:version": "changeset version && pnpm --filter @sveltejs/mcp run update:version && git add --all"
},
"keywords": [
"svelte",

View File

@@ -28,6 +28,7 @@
"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",
@@ -35,10 +36,10 @@
},
"devDependencies": {
"@anthropic-ai/sdk": "^0.65.0",
"dotenv": "^17.2.3",
"@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

@@ -133,6 +133,36 @@ describe('add_autofixers_issues', () => {
);
});
});
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.`,
);
});
});
with_possible_inits('($init)', ({ init }) => {
@@ -484,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';
@@ -19,9 +25,9 @@ function run_if_in_effect(
}
}
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) {
@@ -50,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,5 +1,29 @@
# @sveltejs/mcp
## 0.1.1
### Patch Changes
- feat: publish mcp to registry (maybe for real this time) ([`132943d`](https://github.com/sveltejs/mcp/commit/132943db3b04dbbd322d08926c0880c990a61f5f))
## 0.1.0
### Minor Changes
- feat: publish to registry ([#45](https://github.com/sveltejs/mcp/pull/45))
### Patch Changes
- feat: add autofixer to tell the LLM to check if some function called in effect is assigning state #26 ([`73d7625`](https://github.com/sveltejs/mcp/commit/73d7625b3ca6a812ba91883ea668d80ff1e7c703))
- feat: add bind:this -> attachment and action -> attachment autofixer #20 ([`73d7625`](https://github.com/sveltejs/mcp/commit/73d7625b3ca6a812ba91883ea668d80ff1e7c703))
## 0.0.4
### Patch Changes
- fix: allow TS `.svelte.ts` modules ([#49](https://github.com/sveltejs/mcp/pull/49))
## 0.0.3
### 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,8 +1,9 @@
{
"name": "@sveltejs/mcp",
"version": "0.0.3",
"version": "0.1.1",
"type": "module",
"license": "MIT",
"mcpName": "io.github.sveltejs/svelte",
"homepage": "https://github.com/sveltejs/mcp#readme",
"bugs": {
"url": "https://github.com/sveltejs/mcp/issues"
@@ -26,7 +27,8 @@
"dev": "tsdown --watch",
"test": "vitest",
"check": "tsc --noEmit",
"check:publint": "publint --strict"
"check:publint": "publint --strict",
"update:version": "node scripts/update-version.ts"
},
"devDependencies": {
"@sveltejs/mcp-server": "workspace:^",

View File

@@ -0,0 +1,14 @@
import { readFile, writeFile } from 'node:fs/promises';
import { resolve } from 'node:path';
const package_json_string = await readFile(resolve('./package.json'), 'utf-8');
const package_json = JSON.parse(package_json_string);
const server_json_path = resolve('./server.json');
const server_json_string = await readFile(server_json_path, 'utf-8');
const server_json = JSON.parse(server_json_string);
server_json.version = package_json.version;
server_json.packages[0].version = package_json.version;
await writeFile(server_json_path, JSON.stringify(server_json, null, '\t') + '\n', 'utf-8');

View File

@@ -0,0 +1,30 @@
{
"$schema": "https://static.modelcontextprotocol.io/schemas/2025-09-29/server.schema.json",
"name": "io.github.sveltejs/svelte",
"description": "The official Svelte MCP server providing docs and autofixing tools for Svelte development",
"repository": {
"id": "1054419133",
"url": "https://github.com/sveltejs/mcp",
"subfolder": "packages/mcp-stdio",
"source": "github"
},
"version": "0.1.1",
"websiteUrl": "https://svelte.dev/docs/mcp/overview",
"packages": [
{
"registryType": "npm",
"identifier": "@sveltejs/mcp",
"version": "0.1.1",
"runtimeHint": "npx",
"transport": {
"type": "stdio"
}
}
],
"remotes": [
{
"url": "https://mcp.svelte.dev/mcp",
"type": "streamable-http"
}
]
}

11
pnpm-lock.yaml generated
View File

@@ -177,6 +177,9 @@ importers:
tmcp:
specifier: ^1.13.0
version: 1.14.0(typescript@5.9.2)
ts-blank-space:
specifier: ^0.6.2
version: 0.6.2
typescript-eslint:
specifier: ^8.44.0
version: 8.44.1(eslint@9.36.0(jiti@2.6.0))(typescript@5.9.2)
@@ -3719,6 +3722,10 @@ packages:
peerDependencies:
typescript: '>=4.8.4'
ts-blank-space@0.6.2:
resolution: {integrity: sha512-hZjcHdHrveEKI67v8OzI90a1bizgoDkY7ekE4fH89qJhZgxvmjfBOv98aibCU7OpKbvV3R9p/qd3DrzZqT1cFQ==}
engines: {node: '>=18.0.0'}
ts-node@10.9.2:
resolution: {integrity: sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==}
hasBin: true
@@ -7586,6 +7593,10 @@ snapshots:
dependencies:
typescript: 5.9.2
ts-blank-space@0.6.2:
dependencies:
typescript: 5.9.2
ts-node@10.9.2(@types/node@24.5.2)(typescript@5.9.2):
dependencies:
'@cspotcode/source-map-support': 0.8.1