Skip to main content
Glama

Firebase MCP

config.test.ts8.42 kB
import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest'; // Mock logger vi.mock('../utils/logger.js', () => ({ logger: { debug: vi.fn(), error: vi.fn(), info: vi.fn(), }, })); // Save original process properties to restore later const originalStdinIsTTY = process.stdin.isTTY; const originalStdoutIsTTY = process.stdout.isTTY; const originalEnv = { ...process.env }; describe('Config Module', () => { beforeEach(() => { vi.resetModules(); vi.clearAllMocks(); // Reset process properties process.stdin.isTTY = originalStdinIsTTY; process.stdout.isTTY = originalStdoutIsTTY; process.env = { ...originalEnv }; // Clear any environment variables that might affect tests delete process.env.FORCE_HTTP_TRANSPORT; delete process.env.MCP_TRANSPORT; delete process.env.SERVICE_ACCOUNT_KEY_PATH; delete process.env.FIREBASE_STORAGE_BUCKET; delete process.env.MCP_HTTP_PORT; delete process.env.MCP_HTTP_HOST; delete process.env.MCP_HTTP_PATH; }); afterEach(() => { // Restore original process properties process.stdin.isTTY = originalStdinIsTTY; process.stdout.isTTY = originalStdoutIsTTY; process.env = { ...originalEnv }; }); describe('isStdioContext', () => { it('should return true when in stdio context', async () => { // Set up stdio context process.stdin.isTTY = false; process.stdout.isTTY = false; delete process.env.FORCE_HTTP_TRANSPORT; // Import the module after setting up the context const { isStdioContext } = await import('../config'); // Test the function expect(isStdioContext()).toBe(true); }); it('should return false when not in stdio context', async () => { // Set up non-stdio context process.stdin.isTTY = true; process.stdout.isTTY = false; // Import the module after setting up the context const { isStdioContext } = await import('../config'); // Test the function expect(isStdioContext()).toBe(false); // Test with different TTY configuration process.stdin.isTTY = false; process.stdout.isTTY = true; expect(isStdioContext()).toBe(false); // Test with both TTYs true process.stdin.isTTY = true; process.stdout.isTTY = true; expect(isStdioContext()).toBe(false); }); it('should return false when FORCE_HTTP_TRANSPORT is set', async () => { // Set up stdio context but with FORCE_HTTP_TRANSPORT process.stdin.isTTY = false; process.stdout.isTTY = false; process.env.FORCE_HTTP_TRANSPORT = 'true'; // Import the module after setting up the context const { isStdioContext } = await import('../config'); // Test the function expect(isStdioContext()).toBe(false); }); }); describe('isHttpServerRunning', () => { it('should return true when server is running', async () => { // Mock successful fetch global.fetch = vi.fn().mockResolvedValue({ ok: true, }); // Import the module after setting up the mock const { isHttpServerRunning } = await import('../config'); // Test the function const result = await isHttpServerRunning('localhost', 3000); expect(result).toBe(true); // Verify fetch was called with correct URL expect(global.fetch).toHaveBeenCalledWith('http://localhost:3000', expect.any(Object)); }); it('should return false when server is not running', async () => { // Mock failed fetch global.fetch = vi.fn().mockRejectedValue(new Error('Connection refused')); // Import the module after setting up the mock const { isHttpServerRunning } = await import('../config'); // Test the function const result = await isHttpServerRunning('localhost', 3000); expect(result).toBe(false); }); it('should return false when fetch times out', async () => { // Mock fetch that times out (AbortController will abort it) global.fetch = vi.fn().mockImplementation(() => { throw new Error('AbortError'); }); // Import the module after setting up the mock const { isHttpServerRunning } = await import('../config'); // Test the function const result = await isHttpServerRunning('localhost', 3000); expect(result).toBe(false); }); }); describe('getConfig', () => { it('should return default configuration when no environment variables are set', async () => { // Save original environment variables const originalEnv = { ...process.env }; // Clear environment variables that might affect the test delete process.env.SERVICE_ACCOUNT_KEY_PATH; delete process.env.FIREBASE_STORAGE_BUCKET; try { // Import the module const { getConfig, TransportType } = await import('../config'); // Test the function const config = getConfig(); // Verify default values expect(config).toMatchObject({ transport: TransportType.STDIO, http: { port: 3000, host: 'localhost', path: '/mcp', }, name: 'firebase-mcp', }); // Verify version is a string expect(typeof config.version).toBe('string'); } finally { // Restore original environment variables process.env = { ...originalEnv }; } }); it('should use environment variables when set', async () => { // Set environment variables process.env.SERVICE_ACCOUNT_KEY_PATH = '/path/to/service-account.json'; process.env.FIREBASE_STORAGE_BUCKET = 'test-bucket'; process.env.MCP_TRANSPORT = 'http'; process.env.MCP_HTTP_PORT = '4000'; process.env.MCP_HTTP_HOST = '127.0.0.1'; process.env.MCP_HTTP_PATH = '/api/mcp'; // Import the module const { getConfig, TransportType } = await import('../config'); // Test the function const config = getConfig(); // Verify values from environment variables expect(config).toEqual({ serviceAccountKeyPath: '/path/to/service-account.json', storageBucket: 'test-bucket', transport: TransportType.HTTP, http: { port: 4000, host: '127.0.0.1', path: '/api/mcp', }, version: expect.any(String), name: 'firebase-mcp', }); }); it('should force stdio transport when in stdio context', async () => { // Set up stdio context process.stdin.isTTY = false; process.stdout.isTTY = false; process.env.MCP_TRANSPORT = 'http'; // This should be overridden // Import the module const { getConfig, TransportType } = await import('../config'); // Get the logger to verify debug calls const { logger } = await import('../utils/logger.js'); // Test the function const config = getConfig(); // Verify stdio transport was forced expect(config.transport).toBe(TransportType.STDIO); // Verify debug message was logged expect(logger.debug).toHaveBeenCalledWith('Detected stdio context, using stdio transport'); }); it('should default to stdio transport for invalid transport type', async () => { // Set invalid transport process.env.MCP_TRANSPORT = 'invalid'; // Import the module const { getConfig, TransportType } = await import('../config'); // Test the function const config = getConfig(); // Verify default to stdio expect(config.transport).toBe(TransportType.STDIO); }); it('should log debug message when using HTTP transport', async () => { // Set HTTP transport and non-stdio context process.env.MCP_TRANSPORT = 'http'; process.stdin.isTTY = true; // Not stdio context // Import the module const { getConfig, TransportType } = await import('../config'); // Get the logger to verify debug calls const { logger } = await import('../utils/logger.js'); // Test the function const config = getConfig(); // Verify HTTP transport was used expect(config.transport).toBe(TransportType.HTTP); // Verify debug messages were logged expect(logger.debug).toHaveBeenCalledWith('Using transport: http'); expect(logger.debug).toHaveBeenCalledWith('Configuring HTTP transport'); }); }); });

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/gannonh/firebase-mcp'

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