Compare commits

..

11 Commits

Author SHA1 Message Date
github-actions[bot]
45c961417f Version Packages (#141)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-01-16 19:26:42 +01:00
paoloricciuti
57e2d1def1 fix: show toast after a few seconds to avoid race condition 2026-01-16 19:21:42 +01:00
Paolo Ricciuti
398a703580 feat: opencode plugin (#142)
Co-authored-by: Rich Harris <hello@rich-harris.dev>
2026-01-16 12:41:02 -05:00
Paolo Ricciuti
75c802a115 feat: add lsp config for claude plugin (#140) 2026-01-15 15:00:38 +01:00
Paolo Ricciuti
53a634cdb0 feat: expose playground link as MCP App (#138) 2026-01-15 14:59:46 +01:00
paoloricciuti
bcdc33e7a5 fix: automatically accept edits in the svelte file editor agent 2026-01-05 22:18:46 +01:00
github-actions[bot]
825ae33427 Version Packages (#136)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-01-05 09:43:10 +01:00
Paolo Ricciuti
ccf940cc45 feat: claude skill + marketplace (#110)
Co-authored-by: Stanislav Khromov <stanislav.khromov+github@gmail.com>
2026-01-04 23:00:03 +01:00
Paolo Ricciuti
b2f195fb7b fix: add suggestion for snippets declared in script tag (#132) 2026-01-04 12:00:33 +01:00
renovate[bot]
d8e4b18bff chore(deps): update pnpm to v10.27.0 (#133)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-01-03 15:40:19 +01:00
renovate[bot]
6a2198b433 chore(deps): update dependency globals to v17 (#134)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-01-03 15:40:10 +01:00
35 changed files with 962 additions and 78 deletions

View File

@@ -7,5 +7,5 @@
"access": "public",
"baseBranch": "main",
"updateInternalDependencies": "patch",
"ignore": ["!@sveltejs/mcp"]
"ignore": ["!@sveltejs/mcp", "!@sveltejs/opencode"]
}

View File

@@ -7,7 +7,16 @@
{
"name": "svelte",
"source": "./plugins/svelte",
"description": "A plugin for all things Svelte development, MCP, skills, and more."
"description": "A plugin for all things Svelte development, MCP, skills, and more.",
"lspServers": {
"svelte": {
"command": "svelte-language-server",
"args": ["--stdio"],
"extensionToLanguage": {
".svelte": "svelte"
}
}
}
}
]
}

View File

@@ -18,10 +18,10 @@ jobs:
- name: Setup pnpm
uses: pnpm/action-setup@v4
with:
version: 10.26.2
version: 10.27.0
- name: Setup Node.js
uses: actions/setup-node@v6
uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0
with:
node-version: '24'
cache: 'pnpm'

View File

@@ -18,10 +18,10 @@ jobs:
- name: Setup pnpm
uses: pnpm/action-setup@v4
with:
version: 10.26.2
version: 10.27.0
- name: Setup Node.js
uses: actions/setup-node@v6
uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0
with:
node-version: '24'
cache: 'pnpm'

View File

@@ -12,7 +12,7 @@ jobs:
uses: actions/checkout@v6
- run: corepack enable
- uses: actions/setup-node@v6
- uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0
with:
node-version: 24
cache: 'pnpm'
@@ -20,4 +20,4 @@ jobs:
- name: Install dependencies
run: pnpm install
- run: pnpm dlx pkg-pr-new publish --compact './packages/mcp-stdio' --pnpm
- run: pnpm dlx pkg-pr-new publish --compact './packages/mcp-stdio' './packages/opencode' --pnpm

View File

@@ -29,7 +29,7 @@ jobs:
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@v6
- uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0
with:
node-version: ${{ matrix.node }}
package-manager-cache: false # pnpm is not installed yet
@@ -39,10 +39,11 @@ jobs:
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@v6
- uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0
with:
node-version: ${{ matrix.node }}
package-manager-cache: true # caches pnpm via packageManager field in package.json
cache: 'pnpm'
- name: install
run: pnpm install --frozen-lockfile --prefer-offline --ignore-scripts
- name: build

View File

@@ -18,10 +18,10 @@ jobs:
- name: Setup pnpm
uses: pnpm/action-setup@v4
with:
version: 10.26.2
version: 10.27.0
- name: Setup Node.js
uses: actions/setup-node@v6
uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0
with:
node-version: '24'
cache: 'pnpm'

View File

@@ -0,0 +1,78 @@
name: Update OpenCode JSON Schema
on:
push:
branches:
- main
paths:
- 'packages/opencode/config.ts'
permissions:
contents: write
pull-requests: write
jobs:
update-docs:
# prevents this action from running on forks
if: github.repository == 'sveltejs/mcp'
name: Update OpenCode JSON Schema
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Setup Node.js
uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0
with:
node-version: 24
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
- name: Setup Node.js with pnpm cache
uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0
with:
node-version: 24
package-manager-cache: true # caches pnpm via packageManager field in package.json
cache: 'pnpm'
- name: Install dependencies
run: pnpm install --frozen-lockfile --prefer-offline --ignore-scripts
- name: Generate opencode JSON schema
run: pnpm generate-opencode-jsonschema
- name: Check for changes
id: git-check
run: |
git diff --exit-code packages/opencode/schema.json || echo "changed=true" >> $GITHUB_OUTPUT
- name: Create Pull Request
if: steps.git-check.outputs.changed == 'true'
uses: peter-evans/create-pull-request@98357b18bf14b5342f975ff684046ec3b2a07725 # v8.0.0
with:
token: ${{ secrets.GITHUB_TOKEN }}
commit-message: 'docs: update opencode JSON schema'
branch: docs/update-opencode-jsonschema
delete-branch: true
title: 'docs: update opencode JSON schema'
body: |
## Summary
Automatically generated update for OpenCode JSON schema.
This PR was triggered by changes to the OpenCode configuration file `packages/opencode/config.ts`.
## Changes
- Updated `packages/opencode/schema.json` with latest JSON schema
## Generated by
GitHub Action: Update OpenCode JSON Schema
labels: |
automated

View File

@@ -24,7 +24,7 @@ jobs:
fetch-depth: 0
- name: Setup Node.js
uses: actions/setup-node@v6
uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0
with:
node-version: 24
package-manager-cache: false # pnpm is not installed yet
@@ -37,10 +37,11 @@ jobs:
npm i -g pnpm@$PNPM_VER
- name: Setup Node.js with pnpm cache
uses: actions/setup-node@v6
uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0
with:
node-version: 24
package-manager-cache: true # caches pnpm via packageManager field in package.json
cache: 'pnpm'
- name: Install dependencies
run: pnpm install --frozen-lockfile --prefer-offline --ignore-scripts
@@ -55,7 +56,7 @@ jobs:
- name: Create Pull Request
if: steps.git-check.outputs.changed == 'true'
uses: peter-evans/create-pull-request@v8
uses: peter-evans/create-pull-request@98357b18bf14b5342f975ff684046ec3b2a07725 # v8.0.0
with:
token: ${{ secrets.GITHUB_TOKEN }}
commit-message: 'docs: update prompts documentation'

View File

@@ -12,4 +12,6 @@ bun.lockb
# Claude Code
.claude/
.changeset/
.changeset/
/packages/opencode/schema.json

View File

@@ -57,7 +57,7 @@ The `[scope]` must be `user`, `project` or `local`.
## OpenCode
Run the command:
You can automatically configure the MCP server using the [OpenCode plugin](opencode-plugin) (recommended). If you prefer to configure the MCP server manually, run:
```bash
opencode mcp add

View File

@@ -48,7 +48,7 @@ The `[scope]` must be `user` or `project`.
## OpenCode
Run the command:
You can automatically configure the MCP server using the [OpenCode plugin](opencode-plugin) (recommended). If you prefer to configure the MCP server manually, run:
```bash
opencode mcp add

View File

@@ -0,0 +1,3 @@
---
title: OpenCode Plugin
---

View File

@@ -0,0 +1,39 @@
---
title: Overview
---
OpenCode has a [plugin system](https://opencode.ai/docs/plugins/) that allows developers to add MCP servers, agents and commands programmatically. Svelte has an OpenCode plugin published under `@sveltejs/opencode`.
## Installation
To install the plugin in OpenCode you can edit your [OpenCode config]() (either the global or the local one), adding `@sveltejs/opencode` to the list of plugins.
```json
{
"$schema": "https://opencode.ai/config.json",
"plugin": ["@sveltejs/opencode"]
}
```
That's it! You now have the Svelte MCP server and the [file editor subagent](opencode-subagent) configured for you.
## Configuration
The default configuration for the Svelte OpenCode plugin looks like this...
```json
{
"$schema": "https://raw.githubusercontent.com/sveltejs/mcp/refs/heads/main/packages/opencode/schema.json",
"mcp": {
"type": "remote",
"enabled": true
},
"subagent": {
"enabled": true
}
}
```
...but if you prefer, you can enable only the subagent, only the MCP, or configure the kind of MCP server you want to use (`local` or `remote`).
You can place this file in `~/.config/opencode/svelte.json` or, if you have an `OPENCODE_CONFIG_DIR` environment variable specified, at `$OPENCODE_CONFIG_DIR/svelte.json`.

View File

@@ -0,0 +1,11 @@
---
title: Subagent
---
The Svelte plugin includes a specialized subagent called `svelte-file-editor` designed for creating, editing, and reviewing Svelte files.
## Benefits
The subagent has access to its own context window, allowing it to fetch the documentation, iterate with the `svelte-autofixer` tool and write to the file system without wasting context in the main agent.
The delegation should happen automatically when appropriate, but you can also explicitly request the subagent be used for Svelte-related tasks.

View File

@@ -3,7 +3,7 @@
"version": "0.0.1",
"description": "The official Svelte MCP server implementation",
"type": "module",
"packageManager": "pnpm@10.26.2",
"packageManager": "pnpm@10.27.0",
"scripts": {
"build": "pnpm -r run build",
"dev": "pnpm --filter @sveltejs/mcp-remote run dev",
@@ -18,6 +18,7 @@
"test": "npm run test:unit -- --run",
"test:watch": "npm run test:unit -- --watch",
"inspect": "pnpm mcp-inspector",
"generate-opencode-jsonschema": "pnpm --filter @sveltejs/opencode run generate-schema",
"generate-summaries": "pnpm --filter @sveltejs/mcp-server run generate-summaries",
"generate-prompt-docs": "node --import node-resolve-ts/register scripts/update-docs-prompts.ts",
"debug:generate-summaries": "pnpm --filter @sveltejs/mcp-server run debug:generate-summaries",

View File

@@ -67,6 +67,24 @@ describe('playground-link tool', () => {
);
});
it('should have tool _meta with resource URI for MCP Apps hosts', async () => {
const tools = await session.listTools();
const playground_tool = tools.tools.find((t) => t.name === 'playground-link');
expect(playground_tool).toBeDefined();
expect(playground_tool?._meta).toStrictEqual({
ui: { resourceUri: 'ui://svelte/playground-link' },
});
});
it('should expose a resource for MCP Apps hosts', async () => {
const resources = await session.listResources();
const playground_resource = resources.resources.find(
(r) => r.uri === 'ui://svelte/playground-link',
);
expect(playground_resource).toBeDefined();
expect(playground_resource?.name).toBe('playground-link-ui');
});
it('should not create a playground link if App.svelte is missing', async () => {
const result = await session.callTool<{ url: string }>('playground-link', {
name: 'My Playground',

View File

@@ -1,8 +1,8 @@
import type { SvelteMcp } from '../../index.js';
import * as v from 'valibot';
import { icons } from '../../icons/index.js';
import { createUIResource } from '@mcp-ui/server';
import { tool } from 'tmcp/utils';
import * as v from 'valibot';
import { icons } from '../../icons/index.js';
import type { SvelteMcp } from '../../index.js';
async function compress_and_encode_text(input: string) {
const reader = new Blob([input]).stream().pipeThrough(new CompressionStream('gzip')).getReader();
@@ -97,7 +97,106 @@ export async function playground_link_handler({
};
}
// Create the UI resource for MCP Apps hosts (with adapter)
// This will be registered as a resource that MCP Apps hosts can fetch
const playground_ui_resource = createUIResource({
uri: 'ui://svelte/playground-link',
encoding: 'text',
resourceProps: {
_meta: {
ui: {
csp: {
connectDomains: ['https://svelte.dev'],
resourceDomains: ['https://svelte.dev'],
frameDomains: ['https://svelte.dev'],
baseUriDomains: ['https://svelte.dev'],
},
},
},
},
content: {
type: 'rawHtml',
// This is a placeholder HTML - the actual iframe URL will be set per-request
// MCP Apps hosts receive the tool input/output via postMessage
htmlString: `<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
html, body { width: 100%; height: 100%; }
iframe { width: 100%; height: 100%; border: none; display: none; }
.loading { display: flex; align-items: center; justify-content: center; height: 100%; font-family: system-ui, sans-serif; color: #666; }
</style>
</head>
<body>
<div class="loading" id="loading">Loading playground...</div>
<iframe id="playground" allow="clipboard-write"></iframe>
<script>
function size_changed() {
const width = document.body.scrollWidth;
window.parent.postMessage({
jsonrpc: '2.0',
method: 'ui/notifications/size-changed',
params: {
width,
height: 800
}
}, '*');
}
// Signal that the widget is ready
window.parent.postMessage({ type: 'ui-lifecycle-iframe-ready' }, '*');
// Listen for render data from the adapter (for MCP Apps hosts)
window.addEventListener('message', (event) => {
if (event.data.type === 'ui-lifecycle-iframe-render-data') {
const renderData = event.data.payload.renderData || {};
const toolOutput = renderData.toolOutput;
// The tool output contains the iframe URL
if (toolOutput && toolOutput.structuredContent && toolOutput.structuredContent.url) {
const iframe = document.getElementById('playground');
const loading = document.getElementById('loading');
// Convert the URL to embed URL
const embedUrl = toolOutput.structuredContent.url.replace('/playground#', '/playground/embed#');
iframe.src = embedUrl;
iframe.style.display = 'block';
iframe.addEventListener("load", () => {
size_changed();
});
loading.style.display = 'none';
}
}
});
</script>
</body>
</html>`,
},
uiMetadata: {
'preferred-frame-size': ['100%', '1200px'],
},
adapters: {
mcpApps: { enabled: true },
},
});
export function playground_link(server: SvelteMcp) {
// Register the UI resource so MCP Apps hosts can fetch it
server.resource(
{
name: 'playground-link-ui',
description: 'UI resource for the Svelte Playground widget',
uri: playground_ui_resource.resource.uri,
icons,
},
() => {
return {
contents: [playground_ui_resource.resource],
};
},
);
server.tool(
{
name: 'playground-link',
@@ -112,6 +211,12 @@ export function playground_link(server: SvelteMcp) {
openWorldHint: false,
},
icons,
// For MCP Apps hosts - points to the registered resource
_meta: {
ui: {
resourceUri: playground_ui_resource.resource.uri,
},
},
},
async ({ files, name, tailwind }) => {
if (server.ctx.sessionId && server.ctx.custom?.track) {
@@ -125,6 +230,7 @@ export function playground_link(server: SvelteMcp) {
type: 'text',
text: JSON.stringify({ url: result.url }),
},
// Embedded resource for MCP-UI hosts (no adapter, uses externalUrl)
createUIResource({
uri: 'ui://svelte/playground-link',
content: {

View File

@@ -53,6 +53,18 @@ describe('svelte-autofixer tool', () => {
);
});
it('should add suggestions for snippets declared in script tag', async () => {
const content = await autofixer_tool_call(`<script>
{#snippet my_snippet()}
some content
{/snippet}
</script>`);
expect(content.issues.length).toBeGreaterThan(0);
expect(content.suggestions).toContain(
"The code can't be compiled because a Javascript parse error. The error suggests you have a `{#snippet ...}` block inside the `<script>` tag. Snippets are template syntax and should be declared in the markup section of the component, not in the script. Move the snippet outside of the `<script>` tag. Snippets declared in the markup can also be accessed in the script tag in case you need them.",
);
});
it('should error out if async is true with a version less than 5', async () => {
const content = await autofixer_tool_call(
`<script>

View File

@@ -75,14 +75,21 @@ export async function svelte_autofixer_handler({
await add_eslint_issues(content, code, +desired_svelte_version, filename, async);
} catch (e: unknown) {
const error = e as Error & { start?: { line: number; column: number } };
const error = e as Error & { start?: { line: number; column: number }; frame?: string };
content.issues.push(
`${error.message} at line ${error.start?.line}, column ${error.start?.column}`,
);
if (error.message.includes('js_parse_error')) {
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)`.",
);
// Check if the error frame contains template syntax that was incorrectly placed in the script tag
if (error.frame?.includes('{#snippet')) {
content.suggestions.push(
"The code can't be compiled because a Javascript parse error. The error suggests you have a `{#snippet ...}` block inside the `<script>` tag. Snippets are template syntax and should be declared in the markup section of the component, not in the script. Move the snippet outside of the `<script>` tag. Snippets declared in the markup can also be accessed in the script tag in case you need them.",
);
} else {
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,5 +1,17 @@
# @sveltejs/mcp
## 0.1.18
### Patch Changes
- feat: expose playground link as MCP App ([#138](https://github.com/sveltejs/mcp/pull/138))
## 0.1.17
### Patch Changes
- fix: add suggestion for snippets declared in script tag ([#132](https://github.com/sveltejs/mcp/pull/132))
## 0.1.16
### Patch Changes

View File

@@ -1,6 +1,6 @@
{
"name": "@sveltejs/mcp",
"version": "0.1.16",
"version": "0.1.18",
"type": "module",
"license": "MIT",
"mcpName": "dev.svelte/mcp",

View File

@@ -9,7 +9,7 @@
"subfolder": "packages/mcp-stdio",
"source": "github"
},
"version": "0.1.16",
"version": "0.1.18",
"websiteUrl": "https://svelte.dev/docs/mcp/overview",
"icons": [
{
@@ -25,7 +25,7 @@
{
"registryType": "npm",
"identifier": "@sveltejs/mcp",
"version": "0.1.16",
"version": "0.1.18",
"runtimeHint": "npx",
"transport": {
"type": "stdio"

View File

@@ -0,0 +1,7 @@
# @sveltejs/opencode
## 0.0.2
### Patch Changes
- fix: show toast after a few seconds to avoid race condition ([`57e2d1d`](https://github.com/sveltejs/mcp/commit/57e2d1def1f5590d0a3dd6d269ac39f6397ffecf))

147
packages/opencode/config.ts Normal file
View File

@@ -0,0 +1,147 @@
import type { PluginInput } from '@opencode-ai/plugin';
import { existsSync, readFileSync } from 'fs';
import { homedir } from 'os';
import { join } from 'path';
import * as v from 'valibot';
const default_config = {
mcp: {
type: 'remote' as 'remote' | 'local',
enabled: true,
},
subagent: {
enabled: true,
},
instructions: {
enabled: true,
},
};
export const config_schema = v.object({
mcp: v.optional(
v.object({
type: v.optional(v.picklist(['remote', 'local'])),
enabled: v.optional(v.boolean()),
}),
),
subagent: v.optional(
v.object({
enabled: v.optional(v.boolean()),
}),
),
instructions: v.optional(
v.object({
enabled: v.optional(v.boolean()),
}),
),
});
export type McpConfig = v.InferInput<typeof config_schema>;
const GLOBAL_CONFIG_DIR = join(homedir(), '.config', 'opencode');
const GLOBAL_CONFIG_PATH = join(GLOBAL_CONFIG_DIR, 'svelte.json');
interface ConfigLoadResult {
data: Record<string, unknown> | null;
parse_error?: string;
}
function get_config_paths() {
// Global: ~/.config/opencode/svelte.json
let global_path: string | null = null;
if (existsSync(GLOBAL_CONFIG_PATH)) {
global_path = GLOBAL_CONFIG_PATH;
}
// Custom config directory: $OPENCODE_CONFIG_DIR/svelte.json
let config_dir_path: string | null = null;
const opencode_config_dir = process.env.OPENCODE_CONFIG_DIR;
if (opencode_config_dir) {
const config_json = join(opencode_config_dir, 'svelte.json');
if (existsSync(config_json)) {
config_dir_path = config_json;
}
}
// returning config_dir first so it has higher priority
return [config_dir_path, global_path];
}
function load_config_file(config_path: string): ConfigLoadResult {
let file_content: string;
try {
file_content = readFileSync(config_path, 'utf-8');
} catch {
// File doesn't exist or can't be read
return { data: null };
}
try {
const parsed = JSON.parse(file_content);
if (parsed === undefined || parsed === null) {
return { data: null, parse_error: 'Config file is empty or invalid' };
}
return { data: parsed };
} catch (error: unknown) {
return {
data: null,
parse_error: error instanceof Error ? error.message : 'Failed to parse config',
};
}
}
function merge_with_defaults(user_config: Partial<McpConfig>): McpConfig {
return {
mcp: {
...default_config.mcp,
...user_config.mcp,
},
subagent: {
...default_config.subagent,
...user_config.subagent,
},
instructions: {
...default_config.instructions,
...user_config.instructions,
},
};
}
export function get_mcp_config(ctx: PluginInput) {
const config_paths = get_config_paths();
for (const path of config_paths) {
if (path && existsSync(path)) {
const result = load_config_file(path);
if (result.parse_error) {
setTimeout(() => {
ctx.client.tui.showToast({
body: {
title: 'Svelte: Invalid opencode plugin config',
message: `${result.parse_error}\nUsing default values`,
variant: 'warning',
duration: 7000,
},
});
}, 7000);
return default_config;
}
const parsed = v.safeParse(config_schema, result.data);
if (parsed.success) {
return merge_with_defaults(parsed.output);
} else {
setTimeout(() => {
ctx.client.tui.showToast({
body: {
title: 'Svelte: Invalid opencode plugin config',
message: `${result.parse_error}\nUsing default values`,
variant: 'warning',
duration: 7000,
},
});
}, 7000);
}
}
}
return default_config;
}

View File

@@ -0,0 +1,72 @@
import type { Plugin } from '@opencode-ai/plugin';
import { readdir } from 'node:fs/promises';
import { dirname, join } from 'node:path';
import { fileURLToPath } from 'node:url';
import { get_mcp_config } from './config.js';
const current_dir = dirname(fileURLToPath(import.meta.url));
export const svelte_plugin: Plugin = async (ctx) => {
return {
async config(input) {
input.agent ??= {};
input.mcp ??= {};
input.instructions ??= [];
// by default we use svelte as the name for the svelte MCP server
let svelte_mcp_name = 'svelte';
// we loop over every mcp server to see if any of them is already the svelte MCP server
for (const name in input.mcp) {
const mcp = input.mcp[name];
if (
(mcp?.type === 'remote' && mcp.url.includes('https://mcp.svelte.dev/mcp')) ||
(mcp?.type === 'local' &&
mcp.command.some((cmd: string) => cmd.includes('@sveltejs/mcp')))
) {
// if we found the svelte MCP server, we store its name and break
svelte_mcp_name = name;
break;
}
}
const mcp_config = get_mcp_config(ctx);
if (mcp_config.instructions?.enabled !== false) {
const instructions_dir = join(current_dir, 'instructions');
const instructions_paths = await readdir(instructions_dir);
input.instructions.push(...instructions_paths.map((file) => join(instructions_dir, file)));
}
// if the user doesn't have the MCP server already we add one based on config
if (!input.mcp[svelte_mcp_name] && mcp_config.mcp?.enabled !== false) {
if (mcp_config.mcp?.type === 'remote') {
input.mcp[svelte_mcp_name] = {
type: 'remote',
url: 'https://mcp.svelte.dev/mcp',
};
} else {
input.mcp[svelte_mcp_name] = {
type: 'local',
command: ['npx', '-y', '@sveltejs/mcp'],
};
}
}
if (mcp_config.subagent?.enabled !== false) {
// we add the editor subagent that will be used when editing Svelte files to prevent wasting context on the main agent
input.agent['svelte-file-editor'] = {
color: '#ff3e00',
mode: 'subagent',
prompt: `You are a specialized Svelte coder. Always use the tools from the svelte MCP server to fetch documentation with \`get_documentation\` and validating the code with \`svelte_autofixer\`. If the autofixer returns any issue or suggestions solve them before summarizing the changes for the main agent.`,
description:
'Specialized Svelte 5 code editor. MUST BE USED PROACTIVELY when creating, editing, or reviewing any .svelte file or .svelte.ts/.svelte.js module and MUST use the tools from the MCP server. Fetches relevant documentation and validates code using the Svelte MCP server tools.',
permission: {
bash: 'ask',
edit: 'allow',
webfetch: 'ask',
},
tools: {
[`${svelte_mcp_name}_*`]: true,
},
};
}
},
};
};

View File

@@ -0,0 +1,23 @@
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.

View File

@@ -0,0 +1,35 @@
{
"name": "@sveltejs/opencode",
"version": "0.0.2",
"type": "module",
"license": "MIT",
"homepage": "https://github.com/sveltejs/mcp#readme",
"bugs": {
"url": "https://github.com/sveltejs/mcp/issues"
},
"scripts": {
"check": "tsc --noEmit",
"generate-schema": "node --import node-resolve-ts/register scripts/generate-schema.ts"
},
"files": [
"index.ts",
"config.ts",
"instructions"
],
"repository": {
"type": "git",
"url": "git+https://github.com/sveltejs/mcp.git",
"path": "packages/opencode"
},
"publishConfig": {
"access": "public"
},
"dependencies": {
"valibot": "catalog:tooling"
},
"devDependencies": {
"@opencode-ai/plugin": "catalog:ai",
"@valibot/to-json-schema": "catalog:tooling",
"@types/node": "catalog:tooling"
}
}

View File

@@ -0,0 +1,40 @@
{
"type": "object",
"properties": {
"mcp": {
"type": "object",
"properties": {
"type": {
"enum": [
"remote",
"local"
]
},
"enabled": {
"type": "boolean"
}
},
"required": []
},
"subagent": {
"type": "object",
"properties": {
"enabled": {
"type": "boolean"
}
},
"required": []
},
"instructions": {
"type": "object",
"properties": {
"enabled": {
"type": "boolean"
}
},
"required": []
}
},
"required": [],
"$schema": "http://json-schema.org/draft-07/schema#"
}

View File

@@ -0,0 +1,8 @@
import { toJsonSchema } from '@valibot/to-json-schema';
import { config_schema } from '../config.js';
import fs from 'node:fs';
import path from 'node:path';
const json_schema = toJsonSchema(config_schema);
fs.writeFileSync(path.resolve('./schema.json'), JSON.stringify(json_schema, null, '\t'));

View File

@@ -0,0 +1,5 @@
{
"extends": "../../tsconfig.json",
"include": ["index.ts", "config.ts", "scripts/*"],
"exclude": ["node_modules"]
}

View File

@@ -4,5 +4,14 @@
"version": "1.0.0",
"author": {
"name": "Svelte"
},
"lspServers": {
"svelte": {
"command": "svelte-language-server",
"args": ["--stdio"],
"extensionToLanguage": {
".svelte": "svelte"
}
}
}
}

View File

@@ -1,6 +1,7 @@
---
name: svelte-file-editor
description: Specialized Svelte 5 code editor. MUST BE USED PROACTIVELY when creating, editing, or reviewing any .svelte file or .svelte.ts/.svelte.js module and MUST use the tools from the MCP server. Fetches relevant documentation and validates code using the Svelte MCP server tools.
permissionMode: acceptEdits
---
You are a Svelte 5 expert responsible for writing, editing, and validating Svelte components and modules. You have access to the Svelte MCP server which provides documentation and code analysis tools. Always use the tools from the svelte MCP server to fetch documentation with `get_documentation` and validating the code with `svelte_autofixer`. If the autofixer returns any issue or suggestions try to solve them.

327
pnpm-lock.yaml generated
View File

@@ -10,11 +10,14 @@ catalogs:
specifier: ^0.71.0
version: 0.71.0
'@mcp-ui/server':
specifier: ^5.12.0
version: 5.12.0
specifier: ^5.16.3
version: 5.16.3
'@modelcontextprotocol/inspector':
specifier: ^0.18.0
version: 0.18.0
'@opencode-ai/plugin':
specifier: ^1.1.21
version: 1.1.21
lint:
'@eslint/compat':
specifier: ^2.0.0
@@ -47,8 +50,8 @@ catalogs:
specifier: ^3.12.5
version: 3.12.5
globals:
specifier: ^16.0.0
version: 16.4.0
specifier: ^17.0.0
version: 17.0.0
prettier:
specifier: ^3.4.2
version: 3.6.2
@@ -116,6 +119,9 @@ catalogs:
'@types/node':
specifier: ^24.3.1
version: 24.5.2
'@valibot/to-json-schema':
specifier: ^1.5.0
version: 1.5.0
'@vercel/analytics':
specifier: ^1.5.0
version: 1.5.0
@@ -141,8 +147,8 @@ catalogs:
specifier: ^5.0.0
version: 5.9.2
valibot:
specifier: ^1.1.0
version: 1.1.0
specifier: ^1.2.0
version: 1.2.0
vite:
specifier: ^7.0.4
version: 7.1.7
@@ -195,7 +201,7 @@ importers:
version: 3.12.5(eslint@9.36.0(jiti@2.6.0))(svelte@5.39.6)(ts-node@10.9.2(@types/node@24.5.2)(typescript@5.9.2))
globals:
specifier: catalog:lint
version: 16.4.0
version: 17.0.0
node-resolve-ts:
specifier: catalog:tooling
version: 1.0.2
@@ -277,7 +283,7 @@ importers:
version: 3.12.5(eslint@9.36.0(jiti@2.6.0))(svelte@5.39.6)(ts-node@10.9.2(@types/node@24.5.2)(typescript@5.9.2))
globals:
specifier: catalog:lint
version: 16.4.0
version: 17.0.0
prettier:
specifier: catalog:lint
version: 3.6.2
@@ -316,7 +322,7 @@ importers:
dependencies:
'@mcp-ui/server':
specifier: catalog:ai
version: 5.12.0
version: 5.16.3(hono@4.11.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(zod@4.1.8)
'@sveltejs/mcp-schema':
specifier: workspace:^
version: link:../mcp-schema
@@ -365,7 +371,7 @@ importers:
devDependencies:
'@anthropic-ai/sdk':
specifier: catalog:ai
version: 0.71.0(zod@3.25.76)
version: 0.71.0(zod@4.1.8)
'@sveltejs/kit':
specifier: catalog:svelte
version: 2.43.5(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.39.6)(vite@7.1.7(@types/node@24.5.2)(jiti@2.6.0)(tsx@4.20.6)(yaml@2.8.1)))(svelte@5.39.6)(vite@7.1.7(@types/node@24.5.2)(jiti@2.6.0)(tsx@4.20.6)(yaml@2.8.1))
@@ -416,6 +422,22 @@ importers:
specifier: catalog:tooling
version: 4.0.1(@types/node@24.5.2)(jiti@2.6.0)(tsx@4.20.6)(yaml@2.8.1)
packages/opencode:
dependencies:
valibot:
specifier: catalog:tooling
version: 1.2.0(typescript@5.9.2)
devDependencies:
'@opencode-ai/plugin':
specifier: catalog:ai
version: 1.1.21
'@types/node':
specifier: catalog:tooling
version: 24.5.2
'@valibot/to-json-schema':
specifier: catalog:tooling
version: 1.5.0(valibot@1.2.0(typescript@5.9.2))
packages:
'@anthropic-ai/sdk@0.71.0':
@@ -1018,8 +1040,21 @@ packages:
engines: {node: '>=18'}
hasBin: true
'@mcp-ui/server@5.12.0':
resolution: {integrity: sha512-ZAAHsvzfrBgA0gkyIOjoKNTBTsD0VSJT4KXKHe+Fx/kBASctG6mrzK5gvxD/LLLliantN2UWLTKtEeI4DH4FRQ==}
'@mcp-ui/server@5.16.3':
resolution: {integrity: sha512-MZttML9tQC1B8f4SPgoT1BORfCDXqs4Ywb/mQ0wSwIYS9AuIWFLj1KXmvqC/zrG0SlNMlyvMSxEX/eVYsIoZaA==}
'@modelcontextprotocol/ext-apps@0.2.2':
resolution: {integrity: sha512-h8sN3QIBLqMsRXjKL76M5VmBQf3N0I1G1DiDiSYAgtdynYQctHqCs79WEo1d5wClyZVYBWXdRcxgiR/WBfSOqw==}
peerDependencies:
'@modelcontextprotocol/sdk': ^1.24.0
react: ^17.0.0 || ^18.0.0 || ^19.0.0
react-dom: ^17.0.0 || ^18.0.0 || ^19.0.0
zod: ^3.25.0 || ^4.0.0
peerDependenciesMeta:
react:
optional: true
react-dom:
optional: true
'@modelcontextprotocol/inspector-cli@0.18.0':
resolution: {integrity: sha512-QMPjKx8zKmX17S1LF2gWuwbYglKexkdgB0HhKZFXzGrQ0MYoKUsIgokMyV48xr4LipaLS3b2v3ut3nV/jhWeSg==}
@@ -1038,10 +1073,6 @@ packages:
engines: {node: '>=22.7.5'}
hasBin: true
'@modelcontextprotocol/sdk@1.18.2':
resolution: {integrity: sha512-beedclIvFcCnPrYgHsylqiYJVJ/CI47Vyc4tY8no1/Li/O8U4BTlJfy6ZwxkYwx+Mx10nrgwSVrA7VBbhh4slg==}
engines: {node: '>=18'}
'@modelcontextprotocol/sdk@1.25.1':
resolution: {integrity: sha512-yO28oVFFC7EBoiKdAn+VqRm+plcfv4v0xp6osG/VsCB0NlPZWi87ajbCZZ8f/RvOFLEu7//rSRmuZZ7lMoe3gQ==}
engines: {node: '>=18'}
@@ -1070,6 +1101,67 @@ packages:
resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==}
engines: {node: '>= 8'}
'@opencode-ai/plugin@1.1.21':
resolution: {integrity: sha512-oAWVlKG7LACGFYawfdHGMN6e+6lyN6F+zPVncFUB99BrTl/TjELE5gTZwU7MalGpjwfU77yslBOZm4BXVAYGvw==}
'@opencode-ai/sdk@1.1.21':
resolution: {integrity: sha512-4M6lBjRPlPz99Rb5rS5ZqKrb0UDDxOT9VTG06JpNxvA7ynTd8C50ckc2NGzWtvjarmxfaAk1VeuBYN/cq2pIKQ==}
'@oven/bun-darwin-aarch64@1.3.5':
resolution: {integrity: sha512-8GvNtMo0NINM7Emk9cNAviCG3teEgr3BUX9be0+GD029zIagx2Sf54jMui1Eu1IpFm7nWHODuLEefGOQNaJ0gQ==}
cpu: [arm64]
os: [darwin]
'@oven/bun-darwin-x64-baseline@1.3.5':
resolution: {integrity: sha512-p5q3rJk48qhLuLBOFehVc+kqCE03YrswTc6NCxbwsxiwfySXwcAvpF2KWKF/ZZObvvR8hCCvqe1F81b2p5r2dg==}
cpu: [x64]
os: [darwin]
'@oven/bun-darwin-x64@1.3.5':
resolution: {integrity: sha512-r33eHQOHAwkuiBJIwmkXIyqONQOQMnd1GMTpDzaxx9vf9+svby80LZO9Hcm1ns6KT/TBRFyODC/0loA7FAaffg==}
cpu: [x64]
os: [darwin]
'@oven/bun-linux-aarch64-musl@1.3.5':
resolution: {integrity: sha512-HKBeUlJdNduRkzJKZ5DXM+pPqntfC50/Hu2X65jVX0Y7hu/6IC8RaUTqpr8FtCZqqmc9wDK0OTL+Mbi9UQIKYQ==}
cpu: [arm64]
os: [linux]
'@oven/bun-linux-aarch64@1.3.5':
resolution: {integrity: sha512-zkcHPI23QxJ1TdqafhgkXt1NOEN8o5C460sVeNnrhfJ43LwZgtfcvcQE39x/pBedu67fatY8CU0iY00nOh46ZQ==}
cpu: [arm64]
os: [linux]
'@oven/bun-linux-x64-baseline@1.3.5':
resolution: {integrity: sha512-FeCQyBU62DMuB0nn01vPnf3McXrKOsrK9p7sHaBFYycw0mmoU8kCq/WkBkGMnLuvQljJSyen8QBTx+fXdNupWg==}
cpu: [x64]
os: [linux]
'@oven/bun-linux-x64-musl-baseline@1.3.5':
resolution: {integrity: sha512-TJiYC7KCr0XxFTsxgwQOeE7dncrEL/RSyL0EzSL3xRkrxJMWBCvCSjQn7LV1i6T7hFst0+3KoN3VWvD5BinqHA==}
cpu: [x64]
os: [linux]
'@oven/bun-linux-x64-musl@1.3.5':
resolution: {integrity: sha512-XkCCHkByYn8BIDvoxnny898znju4xnW2kvFE8FT5+0Y62cWdcBGMZ9RdsEUTeRz16k8hHtJpaSfLcEmNTFIwRQ==}
cpu: [x64]
os: [linux]
'@oven/bun-linux-x64@1.3.5':
resolution: {integrity: sha512-n7zhKTSDZS0yOYg5Rq8easZu5Y/o47sv0c7yGr2ciFdcie9uYV55fZ7QMqhWMGK33ezCSikh5EDkUMCIvfWpjA==}
cpu: [x64]
os: [linux]
'@oven/bun-windows-x64-baseline@1.3.5':
resolution: {integrity: sha512-rtVQB9/1XK8FWJgFtsOthbPifRMYypgJwxu+pK3NHx8WvFKmq7HcPDqNr8xLzGULjQEO7eAo2aOZfONOwYz+5g==}
cpu: [x64]
os: [win32]
'@oven/bun-windows-x64@1.3.5':
resolution: {integrity: sha512-T3xkODItb/0ftQPFsZDc7EAX2D6A4TEazQ2YZyofZToO8Q7y8YT8ooWdhd0BQiTCd66uEvgE1DCZetynwg2IoA==}
cpu: [x64]
os: [win32]
'@oxc-project/types@0.101.0':
resolution: {integrity: sha512-nuFhqlUzJX+gVIPPfuE6xurd4lST3mdcWOhyK/rZO0B9XWMKm79SuszIQEnSMmmDhq1DC8WWVYGVd+6F93o1gQ==}
@@ -1581,11 +1673,21 @@ packages:
cpu: [arm64]
os: [darwin]
'@rollup/rollup-darwin-arm64@4.55.1':
resolution: {integrity: sha512-p3grE2PHcQm2e8PSGZdzIhCKbMCw/xi9XvMPErPhwO17vxtvCN5FEA2mSLgmKlCjHGMQTP6phuQTYWUnKewwGg==}
cpu: [arm64]
os: [darwin]
'@rollup/rollup-darwin-x64@4.52.2':
resolution: {integrity: sha512-h11KikYrUCYTrDj6h939hhMNlqU2fo/X4NB0OZcys3fya49o1hmFaczAiJWVAFgrM1NCP6RrO7lQKeVYSKBPSQ==}
cpu: [x64]
os: [darwin]
'@rollup/rollup-darwin-x64@4.55.1':
resolution: {integrity: sha512-rDUjG25C9qoTm+e02Esi+aqTKSBYwVTaoS1wxcN47/Luqef57Vgp96xNANwt5npq9GDxsH7kXxNkJVEsWEOEaQ==}
cpu: [x64]
os: [darwin]
'@rollup/rollup-freebsd-arm64@4.52.2':
resolution: {integrity: sha512-/eg4CI61ZUkLXxMHyVlmlGrSQZ34xqWlZNW43IAU4RmdzWEx0mQJ2mN/Cx4IHLVZFL6UBGAh+/GXhgvGb+nVxw==}
cpu: [arm64]
@@ -1611,6 +1713,11 @@ packages:
cpu: [arm64]
os: [linux]
'@rollup/rollup-linux-arm64-gnu@4.55.1':
resolution: {integrity: sha512-a59mwd1k6x8tXKcUxSyISiquLwB5pX+fJW9TkWU46lCqD/GRDe9uDN31jrMmVP3feI3mhAdvcCClhV8V5MhJFQ==}
cpu: [arm64]
os: [linux]
'@rollup/rollup-linux-arm64-musl@4.52.2':
resolution: {integrity: sha512-s+OPucLNdJHvuZHuIz2WwncJ+SfWHFEmlC5nKMUgAelUeBUnlB4wt7rXWiyG4Zn07uY2Dd+SGyVa9oyLkVGOjA==}
cpu: [arm64]
@@ -1646,6 +1753,11 @@ packages:
cpu: [x64]
os: [linux]
'@rollup/rollup-linux-x64-gnu@4.55.1':
resolution: {integrity: sha512-a8G4wiQxQG2BAvo+gU6XrReRRqj+pLS2NGXKm8io19goR+K8lw269eTrPkSdDTALwMmJp4th2Uh0D8J9bEV1vg==}
cpu: [x64]
os: [linux]
'@rollup/rollup-linux-x64-musl@4.52.2':
resolution: {integrity: sha512-LSeBHnGli1pPKVJ79ZVJgeZWWZXkEe/5o8kcn23M8eMKCUANejchJbF/JqzM4RRjOJfNRhKJk8FuqL1GKjF5oQ==}
cpu: [x64]
@@ -1676,6 +1788,11 @@ packages:
cpu: [x64]
os: [win32]
'@rollup/rollup-win32-x64-msvc@4.55.1':
resolution: {integrity: sha512-SPEpaL6DX4rmcXtnhdrQYgzQ5W2uW3SCJch88lB2zImhJRhIIK44fkUrgIV/Q8yUNfw5oyZ5vkeQsZLhCb06lw==}
cpu: [x64]
os: [win32]
'@rtsao/scc@1.1.0':
resolution: {integrity: sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==}
@@ -1870,6 +1987,11 @@ packages:
peerDependencies:
valibot: ^1.1.0
'@valibot/to-json-schema@1.5.0':
resolution: {integrity: sha512-GE7DmSr1C2UCWPiV0upRH6mv0cCPsqYGs819fb6srCS1tWhyXrkGGe+zxUiwzn/L1BOfADH4sNjY/YHCuP8phQ==}
peerDependencies:
valibot: ^1.2.0
'@vercel/analytics@1.5.0':
resolution: {integrity: sha512-MYsBzfPki4gthY5HnYN7jgInhAZ7Ac1cYDoRWFomwGHWEX7odTEzbtg9kf/QSo7XEsEAqlQugA6gJ2WS2DEa3g==}
peerDependencies:
@@ -2833,6 +2955,10 @@ packages:
resolution: {integrity: sha512-ob/2LcVVaVGCYN+r14cnwnoDPUufjiYgSqRhiFD0Q1iI4Odora5RE8Iv1D24hAz5oMophRGkGz+yuvQmmUMnMw==}
engines: {node: '>=18'}
globals@17.0.0:
resolution: {integrity: sha512-gv5BeD2EssA793rlFWVPMMCqefTlpusw6/2TbAVMy0FzcG8wKJn4O+NqJ4+XWmmwrayJgw5TzrmWjFgmz1XPqw==}
engines: {node: '>=18'}
globalthis@1.0.4:
resolution: {integrity: sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==}
engines: {node: '>= 0.4'}
@@ -4139,6 +4265,14 @@ packages:
typescript:
optional: true
valibot@1.2.0:
resolution: {integrity: sha512-mm1rxUsmOxzrwnX5arGS+U4T25RdvpPjPN4yR0u9pUBov9+zGVtO84tif1eY4r6zWxVxu3KzIyknJy3rxfRZZg==}
peerDependencies:
typescript: '>=5'
peerDependenciesMeta:
typescript:
optional: true
vary@1.1.2:
resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==}
engines: {node: '>= 0.8'}
@@ -4342,11 +4476,6 @@ packages:
zimmerframe@1.1.4:
resolution: {integrity: sha512-B58NGBEoc8Y9MWWCQGl/gq9xBCe4IiKM0a2x7GZdQKOW5Exr8S1W24J6OgM1njK8xCRGvAJIL/MxXHf6SkmQKQ==}
zod-to-json-schema@3.24.6:
resolution: {integrity: sha512-h/z3PKvcTcTetyjl1fkj79MHNEjm+HpD6NXheWjzOekY7kV+lwDYnHw+ivHkijnCSMz1yJaWBD9vu/Fcmk+vEg==}
peerDependencies:
zod: ^3.24.1
zod-to-json-schema@3.25.0:
resolution: {integrity: sha512-HvWtU2UG41LALjajJrML6uQejQhNJx+JBO9IflpSja4R03iNWfKXrj6W2h7ljuLyc1nKS+9yDyL/9tD1U/yBnQ==}
peerDependencies:
@@ -4355,13 +4484,16 @@ packages:
zod@3.25.76:
resolution: {integrity: sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==}
zod@4.1.8:
resolution: {integrity: sha512-5R1P+WwQqmmMIEACyzSvo4JXHY5WiAFHRMg+zBZKgKS+Q1viRa0C1hmUKtHltoIFKtIdki3pRxkmpP74jnNYHQ==}
snapshots:
'@anthropic-ai/sdk@0.71.0(zod@3.25.76)':
'@anthropic-ai/sdk@0.71.0(zod@4.1.8)':
dependencies:
json-schema-to-ts: 3.1.1
optionalDependencies:
zod: 3.25.76
zod: 4.1.8
'@babel/generator@7.28.5':
dependencies:
@@ -4934,11 +5066,42 @@ snapshots:
- encoding
- supports-color
'@mcp-ui/server@5.12.0':
'@mcp-ui/server@5.16.3(hono@4.11.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(zod@4.1.8)':
dependencies:
'@modelcontextprotocol/sdk': 1.18.2
'@modelcontextprotocol/ext-apps': 0.2.2(@modelcontextprotocol/sdk@1.25.1(hono@4.11.1)(zod@4.1.8))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(zod@4.1.8)
'@modelcontextprotocol/sdk': 1.25.1(hono@4.11.1)(zod@4.1.8)
transitivePeerDependencies:
- '@cfworker/json-schema'
- hono
- react
- react-dom
- supports-color
- zod
'@modelcontextprotocol/ext-apps@0.2.2(@modelcontextprotocol/sdk@1.25.1(hono@4.11.1)(zod@4.1.8))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(zod@4.1.8)':
dependencies:
'@modelcontextprotocol/sdk': 1.25.1(hono@4.11.1)(zod@4.1.8)
prettier: 3.6.2
zod: 4.1.8
optionalDependencies:
'@oven/bun-darwin-aarch64': 1.3.5
'@oven/bun-darwin-x64': 1.3.5
'@oven/bun-darwin-x64-baseline': 1.3.5
'@oven/bun-linux-aarch64': 1.3.5
'@oven/bun-linux-aarch64-musl': 1.3.5
'@oven/bun-linux-x64': 1.3.5
'@oven/bun-linux-x64-baseline': 1.3.5
'@oven/bun-linux-x64-musl': 1.3.5
'@oven/bun-linux-x64-musl-baseline': 1.3.5
'@oven/bun-windows-x64': 1.3.5
'@oven/bun-windows-x64-baseline': 1.3.5
'@rollup/rollup-darwin-arm64': 4.55.1
'@rollup/rollup-darwin-x64': 4.55.1
'@rollup/rollup-linux-arm64-gnu': 4.55.1
'@rollup/rollup-linux-x64-gnu': 4.55.1
'@rollup/rollup-win32-x64-msvc': 4.55.1
react: 18.3.1
react-dom: 18.3.1(react@18.3.1)
'@modelcontextprotocol/inspector-cli@0.18.0(hono@4.11.1)(zod@3.25.76)':
dependencies:
@@ -5027,23 +5190,6 @@ snapshots:
- typescript
- utf-8-validate
'@modelcontextprotocol/sdk@1.18.2':
dependencies:
ajv: 6.12.6
content-type: 1.0.5
cors: 2.8.5
cross-spawn: 7.0.6
eventsource: 3.0.7
eventsource-parser: 3.0.6
express: 5.1.0
express-rate-limit: 7.5.1(express@5.1.0)
pkce-challenge: 5.0.0
raw-body: 3.0.1
zod: 3.25.76
zod-to-json-schema: 3.24.6(zod@3.25.76)
transitivePeerDependencies:
- supports-color
'@modelcontextprotocol/sdk@1.25.1(hono@4.11.1)(zod@3.25.76)':
dependencies:
'@hono/node-server': 1.19.7(hono@4.11.1)
@@ -5066,6 +5212,28 @@ snapshots:
- hono
- supports-color
'@modelcontextprotocol/sdk@1.25.1(hono@4.11.1)(zod@4.1.8)':
dependencies:
'@hono/node-server': 1.19.7(hono@4.11.1)
ajv: 8.17.1
ajv-formats: 3.0.1(ajv@8.17.1)
content-type: 1.0.5
cors: 2.8.5
cross-spawn: 7.0.6
eventsource: 3.0.7
eventsource-parser: 3.0.6
express: 5.1.0
express-rate-limit: 7.5.1(express@5.1.0)
jose: 6.1.3
json-schema-typed: 8.0.2
pkce-challenge: 5.0.0
raw-body: 3.0.1
zod: 4.1.8
zod-to-json-schema: 3.25.0(zod@4.1.8)
transitivePeerDependencies:
- hono
- supports-color
'@napi-rs/wasm-runtime@1.1.0':
dependencies:
'@emnapi/core': 1.7.1
@@ -5087,6 +5255,46 @@ snapshots:
'@nodelib/fs.scandir': 2.1.5
fastq: 1.19.1
'@opencode-ai/plugin@1.1.21':
dependencies:
'@opencode-ai/sdk': 1.1.21
zod: 4.1.8
'@opencode-ai/sdk@1.1.21': {}
'@oven/bun-darwin-aarch64@1.3.5':
optional: true
'@oven/bun-darwin-x64-baseline@1.3.5':
optional: true
'@oven/bun-darwin-x64@1.3.5':
optional: true
'@oven/bun-linux-aarch64-musl@1.3.5':
optional: true
'@oven/bun-linux-aarch64@1.3.5':
optional: true
'@oven/bun-linux-x64-baseline@1.3.5':
optional: true
'@oven/bun-linux-x64-musl-baseline@1.3.5':
optional: true
'@oven/bun-linux-x64-musl@1.3.5':
optional: true
'@oven/bun-linux-x64@1.3.5':
optional: true
'@oven/bun-windows-x64-baseline@1.3.5':
optional: true
'@oven/bun-windows-x64@1.3.5':
optional: true
'@oxc-project/types@0.101.0': {}
'@petamoriken/float16@3.9.2':
@@ -5468,9 +5676,15 @@ snapshots:
'@rollup/rollup-darwin-arm64@4.52.2':
optional: true
'@rollup/rollup-darwin-arm64@4.55.1':
optional: true
'@rollup/rollup-darwin-x64@4.52.2':
optional: true
'@rollup/rollup-darwin-x64@4.55.1':
optional: true
'@rollup/rollup-freebsd-arm64@4.52.2':
optional: true
@@ -5486,6 +5700,9 @@ snapshots:
'@rollup/rollup-linux-arm64-gnu@4.52.2':
optional: true
'@rollup/rollup-linux-arm64-gnu@4.55.1':
optional: true
'@rollup/rollup-linux-arm64-musl@4.52.2':
optional: true
@@ -5507,6 +5724,9 @@ snapshots:
'@rollup/rollup-linux-x64-gnu@4.52.2':
optional: true
'@rollup/rollup-linux-x64-gnu@4.55.1':
optional: true
'@rollup/rollup-linux-x64-musl@4.52.2':
optional: true
@@ -5525,6 +5745,9 @@ snapshots:
'@rollup/rollup-win32-x64-msvc@4.52.2':
optional: true
'@rollup/rollup-win32-x64-msvc@4.55.1':
optional: true
'@rtsao/scc@1.1.0': {}
'@standard-schema/spec@1.0.0': {}
@@ -5764,6 +5987,10 @@ snapshots:
dependencies:
valibot: 1.1.0(typescript@5.9.2)
'@valibot/to-json-schema@1.5.0(valibot@1.2.0(typescript@5.9.2))':
dependencies:
valibot: 1.2.0(typescript@5.9.2)
'@vercel/analytics@1.5.0(@sveltejs/kit@2.43.5(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.39.6)(vite@7.1.7(@types/node@24.5.2)(jiti@2.6.0)(tsx@4.20.6)(yaml@2.8.1)))(svelte@5.39.6)(vite@7.1.7(@types/node@24.5.2)(jiti@2.6.0)(tsx@4.20.6)(yaml@2.8.1)))(react@18.3.1)(svelte@5.39.6)':
optionalDependencies:
'@sveltejs/kit': 2.43.5(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.39.6)(vite@7.1.7(@types/node@24.5.2)(jiti@2.6.0)(tsx@4.20.6)(yaml@2.8.1)))(svelte@5.39.6)(vite@7.1.7(@types/node@24.5.2)(jiti@2.6.0)(tsx@4.20.6)(yaml@2.8.1))
@@ -6795,6 +7022,8 @@ snapshots:
globals@16.4.0: {}
globals@17.0.0: {}
globalthis@1.0.4:
dependencies:
define-properties: 1.2.1
@@ -8117,6 +8346,10 @@ snapshots:
optionalDependencies:
typescript: 5.9.2
valibot@1.2.0(typescript@5.9.2):
optionalDependencies:
typescript: 5.9.2
vary@1.1.2: {}
vite-plugin-devtools-json@1.0.0(vite@7.1.7(@types/node@24.5.2)(jiti@2.6.0)(tsx@4.20.6)(yaml@2.8.1)):
@@ -8298,12 +8531,14 @@ snapshots:
zimmerframe@1.1.4: {}
zod-to-json-schema@3.24.6(zod@3.25.76):
dependencies:
zod: 3.25.76
zod-to-json-schema@3.25.0(zod@3.25.76):
dependencies:
zod: 3.25.76
zod-to-json-schema@3.25.0(zod@4.1.8):
dependencies:
zod: 4.1.8
zod@3.25.76: {}
zod@4.1.8: {}

View File

@@ -5,8 +5,9 @@ packages:
catalogs:
ai:
'@anthropic-ai/sdk': ^0.71.0
'@mcp-ui/server': ^5.12.0
'@mcp-ui/server': ^5.16.3
'@modelcontextprotocol/inspector': ^0.18.0
'@opencode-ai/plugin': ^1.1.21
lint:
'@eslint/compat': ^2.0.0
'@eslint/js': ^9.36.0
@@ -18,7 +19,7 @@ catalogs:
eslint-plugin-import: ^2.32.0
eslint-plugin-pnpm: ^1.3.0
eslint-plugin-svelte: ^3.12.5
globals: ^16.0.0
globals: ^17.0.0
prettier: ^3.4.2
prettier-plugin-svelte: ^3.3.3
svelte-eslint-parser: ^1.4.0
@@ -44,6 +45,7 @@ catalogs:
'@svitejs/changesets-changelog-github-compact': ^1.2.0
'@types/estree': ^1.0.8
'@types/node': ^24.3.1
'@valibot/to-json-schema': ^1.5.0
'@vercel/analytics': ^1.5.0
dotenv: ^17.2.3
node-resolve-ts: ^1.0.2
@@ -52,7 +54,7 @@ catalogs:
ts-blank-space: ^0.6.2
tsdown: ^0.18.0
typescript: ^5.0.0
valibot: ^1.1.0
valibot: ^1.2.0
vite: ^7.0.4
vite-plugin-devtools-json: ^1.0.0
vitest: ^4.0.0