Skip to main content
Glama
code-samples.ts10.2 kB
import { McpServer, ResourceTemplate } from "@modelcontextprotocol/sdk/server/mcp.js"; import fs from 'fs/promises'; import path from 'path'; /** * Register code sample resources for the Nylas API */ export async function registerCodeSamplesResources(server: McpServer) { // Path to the code samples directory const codeSamplesPath = path.join(process.cwd(), 'nylas-code-samples'); // Register a resource for each code sample category await registerCategories(server, codeSamplesPath); // Register a resource for specific code samples by path server.resource( "code-sample-by-path", new ResourceTemplate("nylas://code-samples/{path*}", { list: undefined }), async (uri, { path: samplePath }) => { try { // Replace slashes in the path parameter with the correct path separator const normalizedPath = typeof samplePath === 'string' ? samplePath.replace(/\//g, path.sep) : samplePath.join(path.sep); // Determine if it's a directory or a file const fullPath = path.join(codeSamplesPath, normalizedPath); const stats = await fs.stat(fullPath); if (stats.isDirectory()) { // If it's a directory, list the contents const files = await fs.readdir(fullPath); const mdFiles = files.filter(file => file.endsWith('.md')); // If there's an index.md file, use that if (mdFiles.includes('index.md')) { const indexContent = await fs.readFile(path.join(fullPath, 'index.md'), 'utf-8'); return { contents: [{ uri: uri.href, text: indexContent, mimeType: "text/markdown" }] }; } // Otherwise, create a directory listing const listing = `# ${path.basename(normalizedPath)} Code Samples\n\n` + `Available samples:\n\n` + mdFiles.map(file => `- [${file.replace('.md', '')}](nylas://code-samples/${samplePath}/${file})`).join('\n'); return { contents: [{ uri: uri.href, text: listing, mimeType: "text/markdown" }] }; } else { // If it's a file, return its contents const content = await fs.readFile(fullPath, 'utf-8'); return { contents: [{ uri: uri.href, text: content, mimeType: "text/markdown" }] }; } } catch (error) { // If the file doesn't exist, return a not found message return { contents: [{ uri: uri.href, text: `# Not Found\n\nThe requested code sample "${samplePath}" was not found.`, mimeType: "text/markdown" }] }; } } ); // Register a resource to get code samples by language server.resource( "code-samples-by-language", new ResourceTemplate("nylas://code-samples/language/{language}/{category?}", { list: undefined }), async (uri, { language, category }) => { try { // Normalize language name const normalizedLanguage = normalizeLanguageName(typeof language === 'string' ? language : language[0]); // If a category is specified, search only in that category if (category) { const categoryPath = path.join(codeSamplesPath, typeof category === 'string' ? category : category[0]); const samples = await findCodeSamplesByLanguage(categoryPath, normalizedLanguage); return { contents: [{ uri: uri.href, text: formatCodeSamplesForLanguage(normalizedLanguage, typeof category === 'string' ? category : category[0], samples), mimeType: "text/markdown" }] }; } else { // Search in all categories const categories = await fs.readdir(codeSamplesPath); // Store all found code samples const allSamples: Record<string, string[]> = {}; // Find code samples in each category for (const cat of categories) { const categoryPath = path.join(codeSamplesPath, cat); // Skip if not a directory const stats = await fs.stat(categoryPath); if (!stats.isDirectory()) continue; const samples = await findCodeSamplesByLanguage(categoryPath, normalizedLanguage); if (samples.length > 0) { allSamples[cat] = samples; } } return { contents: [{ uri: uri.href, text: formatAllCodeSamplesForLanguage(normalizedLanguage, allSamples), mimeType: "text/markdown" }] }; } } catch (error) { // If there's an error, return an error message return { contents: [{ uri: uri.href, text: `# Error\n\nAn error occurred while searching for ${language} code samples${category ? ` in ${category}` : ''}.`, mimeType: "text/markdown" }] }; } } ); } /** * Register resources for all categories of code samples */ async function registerCategories(server: McpServer, codeSamplesPath: string) { // Register a resource listing all categories server.resource( "code-samples-categories", "nylas://code-samples", async (uri) => { try { const categories = await fs.readdir(codeSamplesPath); const dirCategories = await Promise.all( categories.map(async (category) => { const categoryPath = path.join(codeSamplesPath, category); const stats = await fs.stat(categoryPath); return stats.isDirectory() ? category : null; }) ); const validCategories = dirCategories.filter(Boolean) as string[]; const content = `# Nylas API Code Samples This resource provides code samples for integrating with the Nylas API in various programming languages. ## Available Categories ${validCategories.map(category => `- [${category}](nylas://code-samples/${category})`).join('\n')} ## Samples by Language You can also view samples filtered by programming language: - [Node.js](nylas://code-samples/language/node) - [Python](nylas://code-samples/language/python) - [Java](nylas://code-samples/language/java) - [Ruby](nylas://code-samples/language/ruby) - [API (curl)](nylas://code-samples/language/api)`; return { contents: [{ uri: uri.href, text: content, mimeType: "text/markdown" }] }; } catch (error) { return { contents: [{ uri: uri.href, text: "# Error\n\nFailed to load code sample categories.", mimeType: "text/markdown" }] }; } } ); } /** * Recursively find code samples for a specific language in a directory */ async function findCodeSamplesByLanguage(dirPath: string, language: string): Promise<string[]> { const results: string[] = []; try { const entries = await fs.readdir(dirPath, { withFileTypes: true }); for (const entry of entries) { const fullPath = path.join(dirPath, entry.name); if (entry.isDirectory()) { // Recursively search in subdirectories const subResults = await findCodeSamplesByLanguage(fullPath, language); results.push(...subResults); } else if (entry.name.endsWith('.md')) { // Check if the file contains code samples for the specified language const content = await fs.readFile(fullPath, 'utf-8'); if (content.includes(`\`\`\`${language}`) || (language === 'Node' && content.includes('```Node')) || (language === 'API' && content.includes('```API'))) { // Store the relative path instead of the absolute path const relativePath = fullPath.replace(process.cwd() + path.sep + 'nylas-code-samples' + path.sep, ''); results.push(relativePath); } } } } catch (error) { // Ignore errors and return what we found so far } return results; } /** * Normalize language names to match code block markers in markdown files */ function normalizeLanguageName(language: string): string { const langMap: Record<string, string> = { 'node': 'Node', 'nodejs': 'Node', 'javascript': 'Node', 'js': 'Node', 'python': 'Python', 'py': 'Python', 'java': 'Java', 'ruby': 'Ruby', 'rb': 'Ruby', 'curl': 'API', 'api': 'API', 'rest': 'API' }; return langMap[language.toLowerCase()] || language; } /** * Format code samples for a specific language in a category */ function formatCodeSamplesForLanguage(language: string, category: string, samples: string[]): string { if (samples.length === 0) { return `# No ${language} Code Samples Found\n\nNo code samples for ${language} were found in the ${category} category.`; } return `# ${language} Code Samples for ${category}\n\n` + `Found ${samples.length} code sample(s) for ${language} in the ${category} category:\n\n` + samples.map(sample => `- [${path.basename(sample, '.md')}](nylas://code-samples/${sample.replace(/\\/g, '/')})`).join('\n'); } /** * Format all code samples for a specific language across all categories */ function formatAllCodeSamplesForLanguage(language: string, samples: Record<string, string[]>): string { const categories = Object.keys(samples); if (categories.length === 0) { return `# No ${language} Code Samples Found\n\nNo code samples for ${language} were found.`; } let content = `# ${language} Code Samples\n\n`; for (const category of categories) { content += `## ${category}\n\n`; content += samples[category] .map(sample => `- [${path.basename(sample, '.md')}](nylas://code-samples/${sample.replace(/\\/g, '/')})`).join('\n'); content += '\n\n'; } return content; }

Latest Blog Posts

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/nylas-samples/nylas-api-mcp'

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