@razorpay/blade-mcp
Version:
Model Context Protocol server for Blade
74 lines • 3.9 kB
JavaScript
import { existsSync, readFileSync } from 'fs';
import { join, basename } from 'path';
import { z } from 'zod';
import { CONSUMER_CURSOR_RULES_RELATIVE_PATH, analyticsToolCallEventName, PATTERNS_KNOWLEDGEBASE_DIRECTORY, } from '../utils/tokens.js';
import { getBladeDocsList, hasOutDatedRules } from '../utils/generalUtils.js';
import { handleError, sendAnalytics } from '../utils/analyticsUtils.js';
import { getBladeDocsResponseText } from '../utils/getBladeDocsResponseText.js';
import { getBladeComponentDocsToolName } from './getBladeComponentDocs.js';
const bladePatternsList = getBladeDocsList('patterns');
const whichPatternToUseGuide = readFileSync(join(PATTERNS_KNOWLEDGEBASE_DIRECTORY, 'index.md'), 'utf8');
const getBladePatternDocsToolName = 'get_blade_pattern_docs';
const getBladePatternDocsToolDescription = `Fetch the Blade Design System pattern docs. Use this to get information about design patterns, best practices, and implementation guidelines.`;
const getBladePatternDocsToolSchema = {
patternsList: z
.string()
.describe(`Comma separated list of blade pattern names. E.g. "ListView, DetailedView". Possible values: ${bladePatternsList.join(', ')}. Here is guide on how to decide which pattern to use: ${whichPatternToUseGuide}`),
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 getBladePatternDocsToolCallback = ({ patternsList, currentProjectRootDirectory, }) => {
const components = patternsList.split(',').map((s) => s.trim());
const invalidComponents = components.filter((comp) => !bladePatternsList.includes(comp));
if (invalidComponents.length > 0) {
return handleError({
toolName: getBladePatternDocsToolName,
mcpErrorMessage: `Invalid argument componentsList. Invalid values: ${invalidComponents.join(', ')}. Valid component docs values: ${bladePatternsList.join(', ')}. 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: getBladePatternDocsToolName,
mcpErrorMessage: 'Cursor rules do not exist. Call create_blade_cursor_rules first.',
});
}
if (hasOutDatedRules(ruleFilePath)) {
return handleError({
toolName: getBladePatternDocsToolName,
mcpErrorMessage: 'Cursor rules are outdated. Call create_blade_cursor_rules first.',
});
}
try {
const responseText = getBladeDocsResponseText({
docsList: patternsList,
documentationType: 'patterns',
});
// Return the formatted response
sendAnalytics({
eventName: analyticsToolCallEventName,
properties: {
toolName: getBladePatternDocsToolName,
patternsList,
rootDirectoryName: basename(currentProjectRootDirectory),
},
});
return {
content: [
{
type: 'text',
text: `Below is the documentation for Patterns. After this, call ${getBladeComponentDocsToolName} to get documentation for components that are used in patterns.:\n ${responseText}`,
},
],
};
}
catch (error) {
return handleError({
toolName: getBladePatternDocsToolName,
errorObject: error,
});
}
};
export { getBladePatternDocsToolName, getBladePatternDocsToolDescription, getBladePatternDocsToolSchema, getBladePatternDocsToolCallback, };
//# sourceMappingURL=getBladePatternDocs.js.map