Skip to main content
Glama

Vibe Check MCP

shared.ts3.45 kB
import { promises as fsPromises, constants as fsConstants } from 'node:fs'; import { dirname, join, resolve } from 'node:path'; import os from 'node:os'; import { isDeepStrictEqual } from 'node:util'; const { access, mkdir, readFile, rename, writeFile } = fsPromises; export type JsonRecord = Record<string, unknown>; export type MergeOpts = { id: string; sentinel: string; transport: 'stdio' | 'http'; httpUrl?: string; dev?: { watch?: boolean; debug?: string; }; }; export type MergeResult = { next: JsonRecord; changed: boolean; reason?: string; }; export interface ClientAdapter { locate(custom?: string): Promise<string | null>; read(path: string, raw?: string): Promise<JsonRecord>; merge(config: JsonRecord, entry: JsonRecord, options: MergeOpts): MergeResult; writeAtomic(path: string, data: JsonRecord): Promise<void>; describe(): { name: string; pathHint: string; notes?: string }; } export function isRecord(value: unknown): value is JsonRecord { return typeof value === 'object' && value !== null && !Array.isArray(value); } export async function pathExists(path: string): Promise<boolean> { try { await access(path, fsConstants.F_OK); return true; } catch { return false; } } export function expandHomePath(path: string): string { if (!path.startsWith('~')) { return resolve(path); } const home = os.homedir(); if (path === '~') { return home; } const remainder = path.slice(1); if (remainder.startsWith('/') || remainder.startsWith('\\')) { return resolve(join(home, remainder.slice(1))); } return resolve(join(home, remainder)); } export async function readJsonFile(path: string, raw?: string, context = 'Client configuration'): Promise<JsonRecord> { const payload = raw ?? (await readFile(path, 'utf8')); const parsed = JSON.parse(payload); if (!isRecord(parsed)) { throw new Error(`${context} must be a JSON object.`); } return parsed; } export async function writeJsonFileAtomic(path: string, data: JsonRecord): Promise<void> { await mkdir(dirname(path), { recursive: true }); const tempPath = `${path}.${process.pid}.${Date.now()}.tmp`; const payload = `${JSON.stringify(data, null, 2)}\n`; await writeFile(tempPath, payload, { mode: 0o600 }); await rename(tempPath, path); } export function mergeIntoMap( config: JsonRecord, entry: JsonRecord, options: MergeOpts, mapKey: string, ): MergeResult { const baseConfig = isRecord(config) ? config : {}; const existingMap = isRecord(baseConfig[mapKey]) ? { ...(baseConfig[mapKey] as JsonRecord) } : {}; const currentEntry = isRecord(existingMap[options.id]) ? ({ ...(existingMap[options.id] as JsonRecord) } as JsonRecord) : null; if (currentEntry && currentEntry.managedBy !== options.sentinel) { return { next: baseConfig, changed: false, reason: `Existing entry "${options.id}" is not managed by ${options.sentinel}.`, }; } const sanitizedEntry = { ...entry } as JsonRecord; delete sanitizedEntry.managedBy; const nextEntry: JsonRecord = { ...sanitizedEntry, managedBy: options.sentinel }; const nextMap = { ...existingMap, [options.id]: nextEntry }; const nextConfig: JsonRecord = { ...baseConfig, [mapKey]: nextMap }; if (currentEntry && isDeepStrictEqual(currentEntry, nextEntry)) { return { next: baseConfig, changed: false }; } return { next: nextConfig, changed: true }; }

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/PV-Bhat/vibe-check-mcp-server'

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