UNPKG

@razorpay/blade-mcp

Version:

Model Context Protocol server for Blade

75 lines 3.84 kB
import { join, basename } from 'path'; import { existsSync } from 'fs'; import { z } from 'zod'; import { CONSUMER_CURSOR_RULES_RELATIVE_PATH, analyticsToolCallEventName, } from '../utils/tokens.js'; import { hasOutDatedRules, getBladeDocsList } from '../utils/generalUtils.js'; import { handleError, sendAnalytics } from '../utils/analyticsUtils.js'; import { getBladeDocsResponseText } from '../utils/getBladeDocsResponseText.js'; import { createBladeCursorRulesToolName } from './createBladeCursorRules.js'; const bladeComponentsList = getBladeDocsList('components'); const bladeComponentsListString = bladeComponentsList.join(', '); const getBladeComponentDocsToolName = 'get_blade_component_docs'; const getBladeComponentDocsToolDescription = `Fetch the Blade Design System docs for the given list of components. Use this to get information about the components and their props while adding or changing a component.`; const getBladeComponentDocsToolSchema = { componentsList: z .string() .describe(`Comma separated list of semantic blade component names. E.g. "Button, Accordion". Make sure to use the semantic components (like PasswordInput for passwords). Possible values: ${bladeComponentsListString}`), currentProjectRootDirectory: z .string() .describe("The working root directory of the consumer's project. Do not use root directory, do not use '.', only use absolute path to current directory"), }; const getBladeComponentDocsToolCallback = ({ componentsList, currentProjectRootDirectory, }) => { const components = componentsList.split(',').map((s) => s.trim()); const invalidComponents = components.filter((comp) => !bladeComponentsList.includes(comp)); const invalidComponentsString = invalidComponents.join(', '); if (invalidComponents.length > 0) { return handleError({ toolName: getBladeComponentDocsToolName, mcpErrorMessage: `Invalid argument componentsList. Invalid values: ${invalidComponentsString}. Valid component docs values: ${bladeComponentsListString}. Make sure to call the parent component name (e.g. instead of calling ListViewFilters, call ListView)`, }); } const ruleFilePath = join(currentProjectRootDirectory, CONSUMER_CURSOR_RULES_RELATIVE_PATH); if (!existsSync(ruleFilePath)) { return handleError({ toolName: getBladeComponentDocsToolName, mcpErrorMessage: `Cursor rules do not exist. Call \`${createBladeCursorRulesToolName}\` first.`, }); } if (hasOutDatedRules(ruleFilePath)) { return handleError({ toolName: getBladeComponentDocsToolName, mcpErrorMessage: `Cursor rules are outdated. Call \`${createBladeCursorRulesToolName}\` first to update cursor rules`, }); } try { const responseText = getBladeDocsResponseText({ docsList: componentsList, documentationType: 'components', }); // Return the formatted response sendAnalytics({ eventName: analyticsToolCallEventName, properties: { toolName: getBladeComponentDocsToolName, componentsList, rootDirectoryName: basename(currentProjectRootDirectory), }, }); return { content: [ { type: 'text', text: responseText.trim(), }, ], }; } catch (error) { return handleError({ toolName: getBladeComponentDocsToolName, errorObject: error, }); } }; export { getBladeComponentDocsToolName, getBladeComponentDocsToolDescription, getBladeComponentDocsToolSchema, getBladeComponentDocsToolCallback, }; //# sourceMappingURL=getBladeComponentDocs.js.map