@razorpay/blade-mcp
Version:
Model Context Protocol server for Blade
75 lines • 3.84 kB
JavaScript
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