Skip to main content
Glama
push-based

Angular Toolkit MCP

by push-based
get-ds-component-data.tool.ts6.39 kB
import { ToolSchemaOptions } from '@push-based/models'; import { createHandler, BaseHandlerOptions, } from '../shared/utils/handler-helpers.js'; import { COMMON_ANNOTATIONS } from '../shared/models/schema-helpers.js'; import { getComponentPathsInfo } from './utils/paths-helpers.js'; import { getComponentDocPathsForName } from './utils/doc-helpers.js'; import { validateComponentName, componentNameToKebabCase, } from '../shared/utils/component-validation.js'; import { resolveCrossPlatformPath } from '../shared/utils/cross-platform-path.js'; import * as fs from 'fs'; import * as path from 'path'; interface DsComponentDataOptions extends BaseHandlerOptions { componentName: string; sections?: string[]; } interface DsComponentData { componentName: string; implementation: string[]; documentation: string[]; stories: string[]; importPath: string; } export const getDsComponentDataToolSchema: ToolSchemaOptions = { name: 'get-ds-component-data', description: `Return comprehensive data for a DS component including implementation files, documentation files, stories files, and import path.`, inputSchema: { type: 'object', properties: { componentName: { type: 'string', description: 'The class name of the component to get data for (e.g., DsBadge)', }, sections: { type: 'array', items: { type: 'string', enum: ['implementation', 'documentation', 'stories', 'all'], }, description: 'Sections to include in the response. Options: "implementation", "documentation", "stories", "all". Defaults to ["all"] if not specified.', default: ['all'], }, }, required: ['componentName'], }, annotations: { title: 'Get Design System Component Data', ...COMMON_ANNOTATIONS.readOnly, }, }; function getAllFilesInDirectory(dirPath: string): string[] { const files: string[] = []; function walkDirectory(currentPath: string) { try { const items = fs.readdirSync(currentPath); for (const item of items) { const fullPath = path.join(currentPath, item); const stat = fs.statSync(fullPath); if (stat.isDirectory()) { walkDirectory(fullPath); } else { files.push(fullPath); } } } catch { return; } } if (fs.existsSync(dirPath)) { walkDirectory(dirPath); } return files; } function findStoriesFiles(componentPath: string): string[] { const storiesFiles: string[] = []; try { if (fs.existsSync(componentPath)) { const items = fs.readdirSync(componentPath); for (const item of items) { const fullPath = path.join(componentPath, item); const stat = fs.statSync(fullPath); if (stat.isFile() && item.endsWith('.stories.ts')) { storiesFiles.push(fullPath); } } } } catch { return storiesFiles; } return storiesFiles; } export const getDsComponentDataHandler = createHandler< DsComponentDataOptions, DsComponentData >( getDsComponentDataToolSchema.name, async ( { componentName, sections = ['all'] }, { cwd, uiRoot, storybookDocsRoot }, ) => { try { validateComponentName(componentName); const includeAll = sections.includes('all'); const includeImplementation = includeAll || sections.includes('implementation'); const includeDocumentation = includeAll || sections.includes('documentation'); const includeStories = includeAll || sections.includes('stories'); const pathsInfo = getComponentPathsInfo(componentName, uiRoot, cwd); let implementationFiles: string[] = []; if (includeImplementation) { const srcFiles = getAllFilesInDirectory(pathsInfo.srcPath); implementationFiles = srcFiles.map((file) => `file://${file}`); } const documentationFiles: string[] = []; let storiesFilePaths: string[] = []; if (storybookDocsRoot) { const docsBasePath = resolveCrossPlatformPath(cwd, storybookDocsRoot); if (includeDocumentation) { const docPaths = getComponentDocPathsForName( docsBasePath, componentName, ); if (fs.existsSync(docPaths.paths.api)) { documentationFiles.push(`file://${docPaths.paths.api}`); } if (fs.existsSync(docPaths.paths.overview)) { documentationFiles.push(`file://${docPaths.paths.overview}`); } } if (includeStories) { const componentFolderName = componentNameToKebabCase(componentName); const storiesComponentFolderPath = path.join( docsBasePath, componentFolderName, ); const storiesFiles = findStoriesFiles(storiesComponentFolderPath); storiesFilePaths = storiesFiles.map((file) => `file://${file}`); } } return { componentName, implementation: implementationFiles, documentation: documentationFiles, stories: storiesFilePaths, importPath: pathsInfo.importPath, }; } catch (ctx) { throw new Error( `Error retrieving component data: ${(ctx as Error).message}`, ); } }, (result) => { const messages: string[] = []; if (result.implementation && result.implementation.length > 0) { messages.push('Implementation'); messages.push(''); result.implementation.forEach((file: string) => { messages.push(file); }); messages.push(''); } if (result.documentation && result.documentation.length > 0) { messages.push('Documentation'); messages.push(''); result.documentation.forEach((file: string) => { messages.push(file); }); messages.push(''); } if (result.stories && result.stories.length > 0) { messages.push('Stories'); messages.push(''); result.stories.forEach((file: string) => { messages.push(file); }); messages.push(''); } if (result.importPath) { messages.push('Import path'); messages.push(''); messages.push(result.importPath); } return messages; }, ); export const getDsComponentDataTools = [ { schema: getDsComponentDataToolSchema, handler: getDsComponentDataHandler, }, ];

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/push-based/angular-toolkit-mcp'

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