import { describe, it, expect } from 'vitest'; import { generateMcpConfig } from '../src/services/mcp-config-generator.js'; import type { ProfileWithServer } from '../src/services/mcp-config-generator.js'; function makeProfile(overrides: Partial = {}): ProfileWithServer['profile'] { return { id: 'p1', name: 'default', serverId: 's1', permissions: [], envOverrides: {}, version: 1, createdAt: new Date(), updatedAt: new Date(), ...overrides, }; } function makeServer(overrides: Partial = {}): ProfileWithServer['server'] { return { id: 's1', name: 'slack', description: 'Slack MCP', packageName: '@anthropic/slack-mcp', dockerImage: null, transport: 'STDIO', repositoryUrl: null, envTemplate: [], version: 1, createdAt: new Date(), updatedAt: new Date(), ...overrides, }; } describe('generateMcpConfig', () => { it('returns empty mcpServers for empty profiles', () => { const result = generateMcpConfig([]); expect(result).toEqual({ mcpServers: {} }); }); it('generates config for a single profile', () => { const result = generateMcpConfig([ { profile: makeProfile(), server: makeServer() }, ]); expect(result.mcpServers['slack--default']).toBeDefined(); expect(result.mcpServers['slack--default']?.command).toBe('npx'); expect(result.mcpServers['slack--default']?.args).toEqual(['-y', '@anthropic/slack-mcp']); }); it('excludes secret env vars from output', () => { const server = makeServer({ envTemplate: [ { name: 'SLACK_BOT_TOKEN', description: 'Token', isSecret: true }, { name: 'SLACK_TEAM_ID', description: 'Team', isSecret: false, defaultValue: 'T123' }, ] as never, }); const result = generateMcpConfig([ { profile: makeProfile(), server }, ]); const config = result.mcpServers['slack--default']; expect(config?.env).toBeDefined(); expect(config?.env?.['SLACK_TEAM_ID']).toBe('T123'); expect(config?.env?.['SLACK_BOT_TOKEN']).toBeUndefined(); }); it('applies env overrides from profile (non-secret only)', () => { const server = makeServer({ envTemplate: [ { name: 'API_URL', description: 'URL', isSecret: false }, ] as never, }); const profile = makeProfile({ envOverrides: { API_URL: 'https://staging.example.com' } as never, }); const result = generateMcpConfig([{ profile, server }]); expect(result.mcpServers['slack--default']?.env?.['API_URL']).toBe('https://staging.example.com'); }); it('generates multiple server configs', () => { const result = generateMcpConfig([ { profile: makeProfile({ name: 'readonly' }), server: makeServer({ name: 'slack' }) }, { profile: makeProfile({ name: 'default', id: 'p2' }), server: makeServer({ name: 'github', id: 's2', packageName: '@anthropic/github-mcp' }) }, ]); expect(Object.keys(result.mcpServers)).toHaveLength(2); expect(result.mcpServers['slack--readonly']).toBeDefined(); expect(result.mcpServers['github--default']).toBeDefined(); }); it('omits env when no non-secret vars have values', () => { const server = makeServer({ envTemplate: [ { name: 'TOKEN', description: 'Secret', isSecret: true }, ] as never, }); const result = generateMcpConfig([ { profile: makeProfile(), server }, ]); expect(result.mcpServers['slack--default']?.env).toBeUndefined(); }); it('uses server name as fallback when packageName is null', () => { const server = makeServer({ packageName: null }); const result = generateMcpConfig([ { profile: makeProfile(), server }, ]); expect(result.mcpServers['slack--default']?.args).toEqual(['-y', 'slack']); }); });