Skip to main content
Glama

Vibe Check MCP

claude-config.test.ts4.49 kB
import { promises as fs } from 'node:fs'; import { dirname, join } from 'node:path'; import os from 'node:os'; import { afterEach, describe, expect, it, vi } from 'vitest'; import { locateClaudeConfig, readClaudeConfig, writeClaudeConfigAtomic, } from '../src/cli/clients/claude.js'; const ORIGINAL_ENV = { ...process.env }; describe('Claude config helpers', () => { afterEach(() => { vi.restoreAllMocks(); process.env = { ...ORIGINAL_ENV }; }); it('expands custom paths with a tilde', async () => { const tmpHome = await fs.mkdtemp(join(os.tmpdir(), 'claude-home-')); vi.spyOn(os, 'homedir').mockReturnValue(tmpHome); const result = await locateClaudeConfig('~/config.json'); expect(result).toBe(join(tmpHome, 'config.json')); }); it('expands custom paths with a tilde and backslash', async () => { const tmpHome = await fs.mkdtemp(join(os.tmpdir(), 'claude-home-')); vi.spyOn(os, 'homedir').mockReturnValue(tmpHome); const result = await locateClaudeConfig('~\\config.json'); expect(result).toBe(join(tmpHome, 'config.json')); }); it('locates the default macOS path when present', async () => { const tmpHome = await fs.mkdtemp(join(os.tmpdir(), 'claude-home-')); vi.spyOn(os, 'homedir').mockReturnValue(tmpHome); const platformSpy = vi.spyOn(process, 'platform', 'get').mockReturnValue('darwin'); const candidate = join( tmpHome, 'Library', 'Application Support', 'Claude', 'claude_desktop_config.json', ); await fs.mkdir(dirname(candidate), { recursive: true }); await fs.writeFile(candidate, '{}', 'utf8'); const result = await locateClaudeConfig(); expect(result).toBe(candidate); platformSpy.mockRestore(); }); it('locates the config via APPDATA on Windows', async () => { const tmpDir = await fs.mkdtemp(join(os.tmpdir(), 'claude-appdata-')); const platformSpy = vi.spyOn(process, 'platform', 'get').mockReturnValue('win32'); const originalAppData = process.env.APPDATA; process.env.APPDATA = join(tmpDir, 'AppData'); const candidate = join(process.env.APPDATA, 'Claude', 'claude_desktop_config.json'); await fs.mkdir(dirname(candidate), { recursive: true }); await fs.writeFile(candidate, '{}', 'utf8'); const result = await locateClaudeConfig(); expect(result).toBe(candidate); if (originalAppData === undefined) { delete process.env.APPDATA; } else { process.env.APPDATA = originalAppData; } platformSpy.mockRestore(); }); it('prefers XDG config directories on Linux', async () => { const tmpHome = await fs.mkdtemp(join(os.tmpdir(), 'claude-home-')); const platformSpy = vi.spyOn(process, 'platform', 'get').mockReturnValue('linux'); vi.spyOn(os, 'homedir').mockReturnValue(tmpHome); const xdgDir = await fs.mkdtemp(join(os.tmpdir(), 'claude-xdg-')); process.env.XDG_CONFIG_HOME = xdgDir; const candidate = join(xdgDir, 'Claude', 'claude_desktop_config.json'); await fs.mkdir(dirname(candidate), { recursive: true }); await fs.writeFile(candidate, '{}', 'utf8'); const result = await locateClaudeConfig(); expect(result).toBe(candidate); platformSpy.mockRestore(); }); it('returns null when no candidates exist', async () => { const platformSpy = vi.spyOn(process, 'platform', 'get').mockReturnValue('linux'); const tmpHome = await fs.mkdtemp(join(os.tmpdir(), 'claude-home-')); vi.spyOn(os, 'homedir').mockReturnValue(tmpHome); process.env.XDG_CONFIG_HOME = ''; const result = await locateClaudeConfig(); expect(result).toBeNull(); platformSpy.mockRestore(); }); it('writes configs atomically with 0600 permissions', async () => { const tmpDir = await fs.mkdtemp(join(os.tmpdir(), 'claude-write-')); const target = join(tmpDir, 'config.json'); await writeClaudeConfigAtomic(target, { hello: 'world' }); const stat = await fs.stat(target); expect(stat.mode & 0o777).toBe(0o600); const content = await fs.readFile(target, 'utf8'); expect(JSON.parse(content)).toEqual({ hello: 'world' }); }); it('throws when config JSON is not an object', async () => { const tmpDir = await fs.mkdtemp(join(os.tmpdir(), 'claude-read-')); const target = join(tmpDir, 'config.json'); await fs.writeFile(target, '"string"', 'utf8'); await expect(readClaudeConfig(target)).rejects.toThrow('Claude config must be a JSON object.'); }); });

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