Skip to main content
Glama

MCP Svelte Docs Server

import { Server } from '@modelcontextprotocol/sdk/server/index.js'; import { ReadResourceRequestSchema, ListResourcesRequestSchema, ListResourceTemplatesRequestSchema, McpError, ErrorCode, } from '@modelcontextprotocol/sdk/types.js'; import { Feature, Pattern, CommonMistake, features as docFeatures, patterns as docPatterns, mistakes as docMistakes } from '../types.js'; /** * Registers all resources with the MCP server * @param server The MCP server */ export function register_resources(server: Server): void { // Register direct resources server.setRequestHandler(ListResourcesRequestSchema, async () => ({ resources: [ { uri: 'svelte5://overview', name: 'Svelte 5 Overview', description: 'Overview of Svelte 5 features and changes', mimeType: 'text/plain', }, { uri: 'svelte5://runes/overview', name: 'Runes Overview', description: 'Overview of all runes in Svelte 5', mimeType: 'text/plain', }, { uri: 'svelte5://snippets/overview', name: 'Snippets Overview', description: 'Overview of snippets in Svelte 5', mimeType: 'text/plain', }, { uri: 'svelte5://global-state/overview', name: 'Global State Overview', description: 'Overview of global state approaches in Svelte 5', mimeType: 'text/plain', }, ], })); // Register resource templates server.setRequestHandler( ListResourceTemplatesRequestSchema, async () => ({ resourceTemplates: [ { uriTemplate: 'svelte5://runes/{rune_name}', name: 'Rune Reference', description: 'Detailed reference for a specific rune', mimeType: 'text/plain', }, { uriTemplate: 'svelte5://patterns/{category}/{pattern_name}', name: 'Pattern Reference', description: 'Reference for a specific Svelte pattern', mimeType: 'text/plain', }, { uriTemplate: 'svelte5://mistakes/{category}', name: 'Common Mistakes', description: 'Common mistakes for a specific category', mimeType: 'text/plain', }, ], }), ); // Register resource reader server.setRequestHandler( ReadResourceRequestSchema, async (request) => { const uri = request.params.uri; // Handle overview resources if (uri === 'svelte5://overview') { return { contents: [ { uri, mimeType: 'text/plain', text: generateSvelte5Overview(), }, ], }; } else if (uri === 'svelte5://runes/overview') { return { contents: [ { uri, mimeType: 'text/plain', text: generateRunesOverview(), }, ], }; } else if (uri === 'svelte5://snippets/overview') { return { contents: [ { uri, mimeType: 'text/plain', text: generateSnippetsOverview(), }, ], }; } else if (uri === 'svelte5://global-state/overview') { return { contents: [ { uri, mimeType: 'text/plain', text: generateGlobalStateOverview(), }, ], }; } // Handle rune resources const runeMatch = uri.match(/^svelte5:\/\/runes\/(.+)$/); if (runeMatch) { const runeName = runeMatch[1]; return { contents: [ { uri, mimeType: 'text/plain', text: generateRuneReference(runeName), }, ], }; } // Handle pattern resources const patternMatch = uri.match( /^svelte5:\/\/patterns\/(.+)\/(.+)$/, ); if (patternMatch) { const category = patternMatch[1]; const patternName = patternMatch[2]; return { contents: [ { uri, mimeType: 'text/plain', text: generatePatternReference(category, patternName), }, ], }; } // Handle mistake resources const mistakeMatch = uri.match(/^svelte5:\/\/mistakes\/(.+)$/); if (mistakeMatch) { const category = mistakeMatch[1]; return { contents: [ { uri, mimeType: 'text/plain', text: generateMistakeReference(category), }, ], }; } // Resource not found throw new McpError( ErrorCode.InvalidRequest, `Resource not found: ${uri}`, ); }, ); } /** * Generate Svelte 5 overview content * @returns Overview content */ function generateSvelte5Overview(): string { return `# Svelte 5 Overview Svelte 5 introduces a new reactivity system based on "runes" - special symbols that instruct the compiler to add reactivity to variables, derived values, and effects. ## Key Features ### Runes - $state - Declare reactive state - $derived - Compute values based on state - $effect - Run side effects when state changes - $props - Declare component props ### Snippets Snippets are a new feature that replaces slots, allowing for more flexible and powerful component composition. ### Event Handling Event handlers now use standard HTML attributes (onclick) instead of the directive syntax (on:click). ### Props Props are now declared using the $props rune instead of export let. ### Global State Svelte 5 provides several approaches to global state management, including function-based, object-based, class-based, and context-based approaches. ## Migration from Svelte 4 If you're migrating from Svelte 4, you'll need to: - Replace top-level let declarations with $state - Replace $: reactive declarations with $derived - Replace $: blocks with $effect - Replace on:event with onevent - Replace export let with $props - Replace createEventDispatcher with callback props For more details on specific features, see the relevant resources.`; } /** * Generate runes overview content * @returns Runes overview content */ function generateRunesOverview(): string { const features = docFeatures; const runeFeatures = features.filter( (f) => f.name.startsWith('$') || f.name === 'Runes' || f.description.includes('rune'), ); let content = `# Svelte 5 Runes Overview Runes are special symbols that instruct the compiler to add reactivity to variables, derived values, and effects. They are the foundation of Svelte 5's reactivity system. ## Available Runes `; for (const feature of runeFeatures) { content += `### ${feature.name}\n${feature.description}\n\n`; if (feature.bestPractices && feature.bestPractices.length > 0) { content += '**Best Practices:**\n'; for (const practice of feature.bestPractices) { content += `- ${practice}\n`; } content += '\n'; } } return content; } /** * Generate snippets overview content * @returns Snippets overview content */ function generateSnippetsOverview(): string { const features = docFeatures; const snippetsFeature = features.find((f) => f.name === 'Snippets'); let content = ''; if (snippetsFeature) { content += `# Svelte 5 Snippets ## ${snippetsFeature.name} ${snippetsFeature.description} `; if (snippetsFeature.examples && snippetsFeature.examples.length > 0) { content += `## Examples `; snippetsFeature.examples.forEach((example) => { content += `\`\`\`svelte ${example} \`\`\` `; }); } if (snippetsFeature.bestPractices && snippetsFeature.bestPractices.length > 0) { content += `## Best Practices `; snippetsFeature.bestPractices.forEach((practice) => { content += `- ${practice}\n`; }); } } return content; } /** * Generate global state overview content * @returns Global state overview content */ function generateGlobalStateOverview(): string { const patterns = docPatterns; let content = `# Svelte 5 Global State Overview Svelte 5 provides several approaches to global state management, each with its own advantages and trade-offs. ## Approaches `; for (const pattern of patterns) { content += `## ${pattern.name} ${pattern.description} `; if (pattern.examples && pattern.examples.length > 0) { pattern.examples.forEach((example) => { content += `\`\`\`svelte ${example} \`\`\` `; }); } } return content; } /** * Generate rune reference content * @param runeName Rune name * @returns Rune reference content */ function generateRuneReference(runeName: string): string { const features = docFeatures; const runeFeature = features.find( (f) => f.name.toLowerCase() === `$${runeName}`.toLowerCase() || f.name.toLowerCase() === runeName.toLowerCase(), ); let content = ''; if (runeFeature) { content += `# ${runeFeature.name} ${runeFeature.description} `; if (runeFeature.examples && runeFeature.examples.length > 0) { content += `## Examples `; runeFeature.examples.forEach((example) => { content += `\`\`\`svelte ${example} \`\`\` `; }); } if (runeFeature.bestPractices && runeFeature.bestPractices.length > 0) { content += `## Best Practices `; runeFeature.bestPractices.forEach((practice) => { content += `- ${practice}\n`; }); } } return content; } /** * Generate pattern reference content * @param category Pattern category * @param patternName Pattern name * @returns Pattern reference content */ function generatePatternReference( category: string, patternName: string, ): string { // This is a placeholder for now // In a real implementation, you would look up the pattern in the database return `# ${patternName} (${category}) This is a placeholder for the ${patternName} pattern in the ${category} category. ## Implementation \`\`\`svelte // Implementation details would go here \`\`\` ## Usage \`\`\`svelte // Usage examples would go here \`\`\` ## Notes Additional notes and considerations would go here. `; } /** * Generate mistake reference content * @param category Mistake category * @returns Mistake reference content */ function generateMistakeReference(category: string): string { const mistakes = docMistakes; const categoryMistakes = mistakes.filter( (m) => m.name.toLowerCase().includes(category.toLowerCase()) || m.description.toLowerCase().includes(category.toLowerCase()), ); if (categoryMistakes.length === 0) { throw new McpError( ErrorCode.InvalidRequest, `Mistake category not found: ${category}`, ); } let content = `# Common Mistakes: ${category} This resource lists common mistakes related to ${category} in Svelte 5 and how to correct them. `; for (const mistake of categoryMistakes) { content += `## ${mistake.name}\n${mistake.description}\n\n`; content += `**Mistake:**\n\`\`\`svelte\n${mistake.mistake}\n\`\`\`\n\n`; content += `**Correction:**\n\`\`\`svelte\n${mistake.correction}\n\`\`\`\n\n`; content += `**Explanation:**\n${mistake.explanation}\n\n`; } return content; }

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/spences10/mcp-svelte-docs'

If you have feedback or need assistance with the MCP directory API, please join our Discord server