🚦 feat: Auto-reinitialize MCP Servers on Request (#9226)

This commit is contained in:
Danny Avila 2025-08-23 03:27:05 -04:00
parent ac608ded46
commit c827fdd10e
No known key found for this signature in database
GPG key ID: BF31EEB2C5CA0956
28 changed files with 871 additions and 312 deletions

View file

@ -45,7 +45,7 @@ describe('getUserMCPAuthMap', () => {
},
];
const tools = testCases.map((testCase) =>
const toolInstances = testCases.map((testCase) =>
createMockTool(testCase.normalizedToolName, testCase.originalName),
);
@ -54,7 +54,7 @@ describe('getUserMCPAuthMap', () => {
await getUserMCPAuthMap({
userId: 'user123',
tools,
toolInstances,
findPluginAuthsByKeys: mockFindPluginAuthsByKeys,
});
@ -69,7 +69,7 @@ describe('getUserMCPAuthMap', () => {
describe('Edge Cases', () => {
it('should return empty object when no tools have mcpRawServerName', async () => {
const tools = [
const toolInstances = [
createMockTool('regular_tool', undefined, false),
createMockTool('another_tool', undefined, false),
createMockTool('test_mcp_Server_no_raw_name', undefined),
@ -77,7 +77,7 @@ describe('getUserMCPAuthMap', () => {
const result = await getUserMCPAuthMap({
userId: 'user123',
tools,
toolInstances,
findPluginAuthsByKeys: mockFindPluginAuthsByKeys,
});
@ -104,14 +104,14 @@ describe('getUserMCPAuthMap', () => {
});
it('should handle database errors gracefully', async () => {
const tools = [createMockTool('test_mcp_Server1', 'Server1')];
const toolInstances = [createMockTool('test_mcp_Server1', 'Server1')];
const dbError = new Error('Database connection failed');
mockGetPluginAuthMap.mockRejectedValue(dbError);
const result = await getUserMCPAuthMap({
userId: 'user123',
tools,
toolInstances,
findPluginAuthsByKeys: mockFindPluginAuthsByKeys,
});
@ -119,18 +119,119 @@ describe('getUserMCPAuthMap', () => {
});
it('should handle non-Error exceptions gracefully', async () => {
const tools = [createMockTool('test_mcp_Server1', 'Server1')];
const toolInstances = [createMockTool('test_mcp_Server1', 'Server1')];
mockGetPluginAuthMap.mockRejectedValue('String error');
const result = await getUserMCPAuthMap({
userId: 'user123',
tools,
toolInstances,
findPluginAuthsByKeys: mockFindPluginAuthsByKeys,
});
expect(result).toEqual({});
});
it('should handle mixed null/undefined values in tools array', async () => {
const tools = [
'test_mcp_Server1',
null,
'test_mcp_Server2',
undefined,
'regular_tool',
'test_mcp_Server3',
];
mockGetPluginAuthMap.mockResolvedValue({
mcp_Server1: { API_KEY: 'key1' },
mcp_Server2: { API_KEY: 'key2' },
mcp_Server3: { API_KEY: 'key3' },
});
const result = await getUserMCPAuthMap({
userId: 'user123',
tools: tools as (string | undefined)[],
findPluginAuthsByKeys: mockFindPluginAuthsByKeys,
});
expect(mockGetPluginAuthMap).toHaveBeenCalledWith({
userId: 'user123',
pluginKeys: ['mcp_Server1', 'mcp_Server2', 'mcp_Server3'],
throwError: false,
findPluginAuthsByKeys: mockFindPluginAuthsByKeys,
});
expect(result).toEqual({
mcp_Server1: { API_KEY: 'key1' },
mcp_Server2: { API_KEY: 'key2' },
mcp_Server3: { API_KEY: 'key3' },
});
});
it('should handle mixed null/undefined values in servers array', async () => {
const servers = ['Server1', null, 'Server2', undefined, 'Server3'];
mockGetPluginAuthMap.mockResolvedValue({
mcp_Server1: { API_KEY: 'key1' },
mcp_Server2: { API_KEY: 'key2' },
mcp_Server3: { API_KEY: 'key3' },
});
const result = await getUserMCPAuthMap({
userId: 'user123',
servers: servers as (string | undefined)[],
findPluginAuthsByKeys: mockFindPluginAuthsByKeys,
});
expect(mockGetPluginAuthMap).toHaveBeenCalledWith({
userId: 'user123',
pluginKeys: ['mcp_Server1', 'mcp_Server2', 'mcp_Server3'],
throwError: false,
findPluginAuthsByKeys: mockFindPluginAuthsByKeys,
});
expect(result).toEqual({
mcp_Server1: { API_KEY: 'key1' },
mcp_Server2: { API_KEY: 'key2' },
mcp_Server3: { API_KEY: 'key3' },
});
});
it('should handle mixed null/undefined values in toolInstances array', async () => {
const toolInstances = [
createMockTool('test_mcp_Server1', 'Server1'),
null,
createMockTool('test_mcp_Server2', 'Server2'),
undefined,
createMockTool('regular_tool', undefined, false),
createMockTool('test_mcp_Server3', 'Server3'),
];
mockGetPluginAuthMap.mockResolvedValue({
mcp_Server1: { API_KEY: 'key1' },
mcp_Server2: { API_KEY: 'key2' },
mcp_Server3: { API_KEY: 'key3' },
});
const result = await getUserMCPAuthMap({
userId: 'user123',
toolInstances: toolInstances as (GenericTool | null)[],
findPluginAuthsByKeys: mockFindPluginAuthsByKeys,
});
expect(mockGetPluginAuthMap).toHaveBeenCalledWith({
userId: 'user123',
pluginKeys: ['mcp_Server1', 'mcp_Server2', 'mcp_Server3'],
throwError: false,
findPluginAuthsByKeys: mockFindPluginAuthsByKeys,
});
expect(result).toEqual({
mcp_Server1: { API_KEY: 'key1' },
mcp_Server2: { API_KEY: 'key2' },
mcp_Server3: { API_KEY: 'key3' },
});
});
});
describe('Integration', () => {
@ -138,7 +239,7 @@ describe('getUserMCPAuthMap', () => {
const originalServerName = 'Connector: Company';
const toolName = 'test_auth_mcp_Connector__Company';
const tools = [createMockTool(toolName, originalServerName)];
const toolInstances = [createMockTool(toolName, originalServerName)];
const mockCustomUserVars = {
'mcp_Connector: Company': {
@ -151,7 +252,7 @@ describe('getUserMCPAuthMap', () => {
const result = await getUserMCPAuthMap({
userId: 'user123',
tools,
toolInstances,
findPluginAuthsByKeys: mockFindPluginAuthsByKeys,
});