UNPKG

@progress/telerik-blazor-mcp

Version:

Model Context Protocol for Blazor

85 lines (84 loc) 3.61 kB
#!/usr/bin/env node import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'; import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'; import { z } from 'zod'; import { BlazorComponents, Suite, GrpcErrors, BLAZOR_SUITE_NAME, } from './lib/constants.js'; import { query as contextApiQuery } from './lib/grpc-client.js'; import fs from 'fs'; import path from 'path'; import { fileURLToPath } from 'url'; import { log } from './lib/logger.js'; import { LicenseError } from './lib/read-license.js'; const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); const packageJsonPath = path.resolve(__dirname, '../package.json'); const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8')); const server = new McpServer({ name: 'telerik-and-kendo-resources', version: packageJson.version, }); server.tool('telerik_blazor_assistant', `Answers questions and retrieves documentation about Telerik UI for Blazor. Use this tool when the user asks about Telerik UI for Blazor features, specific components (e.g., Grid, Chart, Editor), implementation details, or general usage. Provide the user's detailed question as the 'query'. If the question pertains to a specific Telerik UI for Blazor component, specify its name in the 'component' parameter. This tool can be automatically triggered when the following phrases are detected in the user's input/prompt: - 'Telerik'; - '/telerik'; - '/telerikblazor' - '/ask_telerik'; - '/help_telerik'; - '@telerik'; - '@telerikblazor'; - '@ask_telerik'; - '@help_telerik'.`, { query: z.string().describe('The query to search for.'), component: z .enum(BlazorComponents) .describe('The component to search for. If not specified, you can use General.'), }, async ({ query, component }) => { log('Calling tool: ', JSON.stringify({ query, component })); try { const response = await contextApiQuery({ query, component: component.toLocaleLowerCase(), lib_name: Suite, text_matches_count: 3, code_matches_count: 0, allowed_types: ['documentation'], }); const content = [ ...response.values.map((item) => ({ type: 'text', text: item, })), ]; log('Response from tool: ', JSON.stringify(content)); return { content, }; } catch (error) { log('Error calling context API: ', JSON.stringify(error)); if (error?.code === GrpcErrors.UNAUTHENTICATED) { throw new Error('Error: You are not authenticated. Please verify the Telerik License Key provided is valid.'); } else if (error?.code === GrpcErrors.RESOURCE_EXHAUSTED) { throw new Error(`Error: You have exceeded the extension quota. Message: ${error.message}.`); } else if (error?.code === GrpcErrors.PERMISSION_DENIED) { throw new Error(`Error: You do not have permission to access this resource. Please verify that you have a valid ${BLAZOR_SUITE_NAME} license key.`); } else if (error instanceof LicenseError) { log('License error: ', error.message); throw error; } else { throw new Error('Error: An error occurred while calling the service. Please try again later.'); } } }); async function startServer() { const transport = new StdioServerTransport(); log('Starting server...'); await server.connect(transport); } startServer();