Skip to main content
Glama
mednabouli

MCP Multi-Context Hook Generator

by mednabouli
components.ts3.81 kB
import fs from 'fs'; import path from 'path'; import { Project, SyntaxKind } from 'ts-morph'; export interface ComponentInfo { name: string; filePath: string; props: { defaultValue: string; description: string; name: string; type: string; optional: boolean; }[]; isDefaultExport?: boolean; } function isComponentFile(file: string): boolean { return /\.(tsx|jsx)$/.test(file); } export function crawlComponents(rootDir = process.cwd(), baseDir = 'components'): ComponentInfo[] { const dir = path.join(rootDir, baseDir); if (!fs.existsSync(dir)) return []; const results: ComponentInfo[] = []; const project = new Project({ tsConfigFilePath: path.join(rootDir, 'tsconfig.json'), skipAddingFilesFromTsConfig: false, }); function walk(currentDir: string) { const entries = fs.readdirSync(currentDir, { withFileTypes: true }); for (const entry of entries) { const fullPath = path.join(currentDir, entry.name); if (entry.isDirectory()) { walk(fullPath); } else if (isComponentFile(entry.name)) { project.addSourceFileAtPath(fullPath); } } } walk(dir); // Analyze each file project.getSourceFiles().forEach((sourceFile) => { sourceFile.getExportedDeclarations().forEach((decls, exportName) => { decls.forEach((decl) => { if ( decl.getKind() === SyntaxKind.FunctionDeclaration || decl.getKind() === SyntaxKind.VariableDeclaration ) { const name = exportName; const props: { name: string; type: string; optional: boolean; defaultValue: string; description: string; }[] = []; // Try to extract props from first parameter if (decl.getKind() === SyntaxKind.FunctionDeclaration) { const func = decl.asKindOrThrow(SyntaxKind.FunctionDeclaration); const param = func.getParameters()[0]; if (param) { const paramType = param.getType(); paramType.getProperties().forEach((prop) => { props.push({ name: prop.getName(), type: prop.getTypeAtLocation(param).getText(), optional: prop.isOptional(), defaultValue: '', // or provide logic to extract default value if available description: '', // or provide logic to extract description if available }); }); } } if (decl.getKind() === SyntaxKind.VariableDeclaration) { const variable = decl.asKindOrThrow(SyntaxKind.VariableDeclaration); const initializer = variable.getInitializer(); if (initializer && initializer.getKind() === SyntaxKind.ArrowFunction) { const arrowFunc = initializer.asKindOrThrow(SyntaxKind.ArrowFunction); const param = arrowFunc.getParameters()[0]; if (param) { const paramType = param.getType(); paramType.getProperties().forEach((prop) => { props.push({ name: prop.getName(), type: prop.getTypeAtLocation(param).getText(), optional: prop.isOptional(), defaultValue: '', // or provide logic to extract default value if available description: '', // or provide logic to extract description if available }); }); } } } results.push({ name, filePath: sourceFile.getFilePath(), props, isDefaultExport: name === 'default', }); } }); }); }); return results; }

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/mednabouli/MCPV2'

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