Skip to main content
Glama
index.test.ts5.87 kB
import { describe, it, expect, jest } from '@jest/globals'; // Mock the entire index module to avoid import issues const mockServer = { setRequestHandler: jest.fn(), connect: jest.fn(), }; jest.mock('@modelcontextprotocol/sdk/server/index.js', () => ({ Server: jest.fn().mockImplementation(() => mockServer) })); jest.mock('@modelcontextprotocol/sdk/server/stdio.js', () => ({ StdioServerTransport: jest.fn() })); jest.mock('@modelcontextprotocol/sdk/types.js', () => ({ CallToolRequestSchema: 'mocked-call-tool-schema', ListToolsRequestSchema: 'mocked-list-tools-schema', })); jest.mock('../n8n-client.js', () => ({ N8nClient: jest.fn().mockImplementation(() => ({ listWorkflows: jest.fn(), getWorkflow: jest.fn(), createWorkflow: jest.fn(), updateWorkflow: jest.fn(), deleteWorkflow: jest.fn(), activateWorkflow: jest.fn(), deactivateWorkflow: jest.fn(), listCredentials: jest.fn(), resolveCredentialAlias: jest.fn(), getNodeTypes: jest.fn(), getNodeTypeByName: jest.fn(), getNodeTypeExamples: jest.fn(), validateNodeConfiguration: jest.fn(), sourceControlPull: jest.fn(), listVariables: jest.fn(), createVariable: jest.fn(), updateVariable: jest.fn(), deleteVariable: jest.fn(), listExecutions: jest.fn(), getExecution: jest.fn(), deleteExecution: jest.fn(), getWebhookUrls: jest.fn(), runOnce: jest.fn(), listWorkflowTags: jest.fn(), setWorkflowTags: jest.fn(), transferWorkflow: jest.fn(), transferCredential: jest.fn(), })) })); describe('N8nMcpServer', () => { beforeEach(() => { // Set environment variables for testing process.env.N8N_BASE_URL = 'http://test-n8n.local:5678'; process.env.N8N_API_KEY = 'test-api-key'; }); describe('module import', () => { it('should be able to import the module', async () => { // Dynamic import to avoid top-level import issues const { N8nMcpServer } = await import('../index'); expect(N8nMcpServer).toBeDefined(); }); it('should handle constructor with valid config', async () => { const { N8nMcpServer } = await import('../index'); expect(() => new N8nMcpServer()).not.toThrow(); }); it('should warn when no auth configured', async () => { delete process.env.N8N_API_KEY; delete process.env.N8N_USERNAME; delete process.env.N8N_PASSWORD; const { N8nMcpServer } = await import('../index'); const server = new N8nMcpServer(); expect(server).toBeDefined(); }); }); describe('MCP tools', () => { describe('list tools', () => { it('should include new tools in the tools list', async () => { const { N8nMcpServer } = await import('../index'); new N8nMcpServer(); const listHandlers = mockServer.setRequestHandler.mock.calls.find( (call: any) => call[0] === 'mocked-list-tools-schema' ); expect(listHandlers).toBeDefined(); const handler = listHandlers![1]; const result = await (handler as any)(); const toolNames = result.tools.map((tool: any) => tool.name); expect(toolNames).toContain('webhook_urls'); expect(toolNames).toContain('run_once'); expect(toolNames).toContain('list_workflow_tags'); expect(toolNames).toContain('set_workflow_tags'); expect(toolNames).toContain('get_credential_schema'); expect(toolNames).toContain('list_variables'); expect(toolNames).toContain('create_variable'); expect(toolNames).toContain('update_variable'); expect(toolNames).toContain('delete_variable'); expect(toolNames).toContain('source_control_pull'); expect(toolNames).toContain('list_node_types'); expect(toolNames).toContain('get_node_type'); expect(toolNames).toContain('examples'); expect(toolNames).toContain('validate_node_config'); // Execution tools expect(toolNames).toContain('list_executions'); expect(toolNames).toContain('get_execution'); expect(toolNames).toContain('delete_execution'); }); }); }); describe('MCP Tools', () => { it('should register node type metadata tools', async () => { const { N8nMcpServer } = await import('../index.js'); const server = new N8nMcpServer(); // Check that setRequestHandler was called with the expected schemas expect(mockServer.setRequestHandler).toHaveBeenCalledWith( 'mocked-list-tools-schema', expect.any(Function) ); expect(mockServer.setRequestHandler).toHaveBeenCalledWith( 'mocked-call-tool-schema', expect.any(Function) ); }); it('should include new tools in list_tools response', async () => { const { N8nMcpServer } = await import('../index.js'); new N8nMcpServer(); // Get the list tools handler const listToolsCall = mockServer.setRequestHandler.mock.calls.find( call => call[0] === 'mocked-list-tools-schema' ); expect(listToolsCall).toBeDefined(); if (listToolsCall) { const listToolsHandler = listToolsCall[1] as () => Promise<any>; const response = await listToolsHandler(); expect(response.tools).toBeDefined(); expect(Array.isArray(response.tools)).toBe(true); const toolNames = response.tools.map((tool: any) => tool.name); expect(toolNames).toContain('list_node_types'); expect(toolNames).toContain('get_node_type'); expect(toolNames).toContain('examples'); expect(toolNames).toContain('validate_node_config'); expect(toolNames).toContain('list_executions'); expect(toolNames).toContain('get_execution'); expect(toolNames).toContain('delete_execution'); } }); }); });

Latest Blog Posts

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/get2knowio/n8n-mcp'

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