Skip to main content
Glama

macOS Automator MCP Server

by steipete
kbPathProcessor.ts4.77 kB
import fs from 'node:fs/promises'; import path from 'node:path'; import matter from 'gray-matter'; import { report, logErrorToReport, logWarningToReport } from './kbReport.js'; import { validateTipFile, validateSharedHandlerFile } from './kbFileValidator.js'; // Constants moved from validate-kb.ts that are relevant here const SHARED_HANDLERS_DIR_NAME = '_shared_handlers'; async function validateTipFilesRecursively( currentPath: string, categoryId: string, kbPathToUse: string, isLocalKbScan: boolean, recursive = true ): Promise<void> { try { const entries = await fs.readdir(currentPath, { withFileTypes: true }); for (const entry of entries) { const entryPath = path.join(currentPath, entry.name); if (entry.isDirectory() && recursive) { if (!entry.name.startsWith('_')) { await validateTipFilesRecursively(entryPath, categoryId, kbPathToUse, isLocalKbScan); } } else if (entry.isFile() && entry.name.endsWith('.md') && !entry.name.startsWith('_')) { await validateTipFile(entryPath, categoryId, kbPathToUse, isLocalKbScan); } } } catch (error) { if (!isLocalKbScan || (error as NodeJS.ErrnoException)?.code !== 'ENOENT') { logErrorToReport(currentPath, `Failed to read directory: ${(error as Error).message}`, isLocalKbScan); } else { // console.debug(`Optional category directory not found in local KB: ${currentPath}`); } } } export async function processKnowledgeBasePath(basePathToScan: string, isLocal: boolean): Promise<void> { console.info(`Validating knowledge base in: ${basePathToScan} ${isLocal ? '(Local)' : '(Embedded)'}`); try { const categoryDirEntries = await fs.readdir(basePathToScan, { withFileTypes: true }); for (const categoryDirEntry of categoryDirEntries) { if (categoryDirEntry.isDirectory()) { const categoryId = categoryDirEntry.name; const categoryPath = path.join(basePathToScan, categoryId); if (categoryId === SHARED_HANDLERS_DIR_NAME) { try { const handlerFiles = await fs.readdir(categoryPath, { withFileTypes: true }); for (const handlerFile of handlerFiles) { if (handlerFile.isFile() && (handlerFile.name.endsWith('.applescript') || handlerFile.name.endsWith('.js'))) { await validateSharedHandlerFile(path.join(categoryPath, handlerFile.name), isLocal); } } } catch (error) { if (!isLocal || (error as NodeJS.ErrnoException)?.code !== 'ENOENT') { logErrorToReport(categoryPath, `Failed to read _shared_handlers directory: ${(error as Error).message}`, isLocal); } else { // console.debug(`Optional _shared_handlers directory not found in local KB: ${categoryPath}`); } } continue; } const catInfoPath = path.join(categoryPath, '_category_info.md'); try { await fs.access(catInfoPath, fs.constants.R_OK); report.totalFilesChecked++; const catInfoContent = await fs.readFile(catInfoPath, 'utf-8'); const { data: catFm } = matter(catInfoContent); if (!catFm.description || typeof catFm.description !== 'string' || catFm.description.trim() === "") { logWarningToReport(catInfoPath, "Missing or empty 'description' in _category_info.md frontmatter.", isLocal); } } catch { if (!isLocal) { logWarningToReport(categoryPath, "_category_info.md not found or not readable. Category description will be default.", false); } } await validateTipFilesRecursively(categoryPath, categoryId, basePathToScan, isLocal); } } } catch (error: unknown) { if (error instanceof Error && 'code' in error && (error as NodeJS.ErrnoException).code === 'ENOENT') { if (!isLocal) { console.error(`Required knowledge base directory NOT FOUND at ${basePathToScan}.`); logErrorToReport(basePathToScan, `Failed to read knowledge base structure: ${error.message}`, false); } else { console.warn(`Local knowledge base directory not found at ${basePathToScan}. Skipping.`); logWarningToReport(basePathToScan, `Local KB directory not found. This is okay if not using one.`, true); } } else if (error instanceof Error) { logErrorToReport(basePathToScan, `Failed to read knowledge base structure: ${error.message}`, isLocal); } else { logErrorToReport(basePathToScan, `Failed to read knowledge base structure: Unknown error occurred`, isLocal); } } }

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/steipete/macos-automator-mcp'

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