Skip to main content
Glama
inspectProject.js4.06 kB
import fs from 'fs/promises'; import path from 'path'; import { z } from 'zod'; import { detectLanguages, getSignatures } from '../detectors/language.js'; import { detectFrameworks, detectDatabaseHints } from '../detectors/framework.js'; import { detectEntryPoints } from '../detectors/entrypoint.js'; import { classifyProjectType } from '../detectors/projectType.js'; import { scanTree, getStructureSummary } from '../scanners/tree.js'; import { parseDependencies } from '../scanners/dependencies.js'; import { createError, ErrorCodes } from '../utils/errors.js'; /** * Input schema for inspect_project tool */ export const inspectProjectSchema = { path: z.string().describe("Path to the project directory to inspect"), maxDepth: z.number().optional().default(3).describe("Maximum depth to scan (default: 3)"), includeHidden: z.boolean().optional().default(false).describe("Include hidden files and directories") }; /** * Main inspect_project tool handler * Provides a complete snapshot of the project structure and stack */ export async function inspectProject({ path: projectPath, maxDepth = 3, includeHidden = false }) { // Validate path exists try { const stats = await fs.stat(projectPath); if (!stats.isDirectory()) { return createError(ErrorCodes.PATH_NOT_DIRECTORY); } } catch (err) { if (err.code === 'ENOENT') { return createError(ErrorCodes.PATH_NOT_FOUND); } if (err.code === 'EACCES') { return createError(ErrorCodes.ACCESS_DENIED); } return createError(ErrorCodes.SCAN_ERROR, err.message); } try { // Scan directory tree const { files, structure, truncated } = await scanTree(projectPath, { maxDepth, includeHidden }); // Parse dependencies const dependencies = await parseDependencies(projectPath, files); // Detect languages const languages = await detectLanguages(projectPath, files); // Detect frameworks const frameworks = await detectFrameworks(projectPath, files, languages, dependencies); // Detect entry points const entryPoints = await detectEntryPoints(projectPath, files, languages); // Classify project type const projectType = await classifyProjectType(frameworks, languages, files, projectPath); // Get structure summary const structureSummary = getStructureSummary(structure, files); // Find config files const sigs = await getSignatures(); const configFiles = files.filter(f => sigs.configFiles.some(cf => path.basename(f) === cf || f.endsWith(cf)) ); // Build result (omit empty fields) const result = { project: { language: languages.map(l => l.name), type: projectType.type, confidence: projectType.confidence } }; if (frameworks.length > 0) { result.frameworks = frameworks.map(f => ({ name: f.name, confidence: f.confidence })); } if (entryPoints.length > 0) { result.entryPoints = entryPoints; } if (Object.keys(structureSummary).length > 0) { result.structureSummary = structureSummary; } if (dependencies.primary.length > 0 || dependencies.dev.length > 0) { result.dependencies = {}; if (dependencies.primary.length > 0) { result.dependencies.primary = dependencies.primary; } if (dependencies.dev.length > 0) { result.dependencies.dev = dependencies.dev; } } if (configFiles.length > 0) { result.configFiles = configFiles; } if (truncated) { result.truncated = true; } return result; } catch (err) { return createError(ErrorCodes.SCAN_ERROR, err.message); } }

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/QoutaID/qoutaMcp'

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