diff --git a/client/src/App.tsx b/client/src/App.tsx index 054a4f69..26eb44c5 100644 --- a/client/src/App.tsx +++ b/client/src/App.tsx @@ -347,9 +347,10 @@ const App = () => { useEffect(() => { const headers: HeadersInit = {}; - const proxyAuthToken = getMCPProxyAuthToken(config); + const { token: proxyAuthToken, header: proxyAuthTokenHeader } = + getMCPProxyAuthToken(config); if (proxyAuthToken) { - headers["Authorization"] = `Bearer ${proxyAuthToken}`; + headers[proxyAuthTokenHeader] = `Bearer ${proxyAuthToken}`; } fetch(`${getMCPProxyAddress(config)}/config`, { headers }) diff --git a/client/src/__tests__/App.config.test.tsx b/client/src/__tests__/App.config.test.tsx index 9b0dedcd..b2e03d36 100644 --- a/client/src/__tests__/App.config.test.tsx +++ b/client/src/__tests__/App.config.test.tsx @@ -1,7 +1,8 @@ -import React from "react"; import { render, waitFor } from "@testing-library/react"; import App from "../App"; import { DEFAULT_INSPECTOR_CONFIG } from "../lib/constants"; +import { InspectorConfig } from "../lib/configurationTypes"; +import * as configUtils from "../utils/configUtils"; // Mock auth dependencies first jest.mock("@modelcontextprotocol/sdk/client/auth.js", () => ({ @@ -24,7 +25,7 @@ jest.mock("../lib/auth", () => ({ jest.mock("../utils/configUtils", () => ({ ...jest.requireActual("../utils/configUtils"), getMCPProxyAddress: jest.fn(() => "http://localhost:6277"), - getMCPProxyAuthToken: jest.fn((config) => ({ + getMCPProxyAuthToken: jest.fn((config: InspectorConfig) => ({ token: config.MCP_PROXY_AUTH_TOKEN.value, header: "X-MCP-Proxy-Auth", })), @@ -36,6 +37,11 @@ jest.mock("../utils/configUtils", () => ({ saveInspectorConfig: jest.fn(), })); +// Get references to the mocked functions +const mockGetMCPProxyAuthToken = configUtils.getMCPProxyAuthToken as jest.Mock; +const mockInitializeInspectorConfig = + configUtils.initializeInspectorConfig as jest.Mock; + // Mock other dependencies jest.mock("../lib/hooks/useConnection", () => ({ useConnection: () => ({ @@ -87,10 +93,9 @@ describe("App - Config Endpoint", () => { afterEach(() => { jest.clearAllMocks(); - + // Reset getMCPProxyAuthToken to default behavior - const { getMCPProxyAuthToken } = require("../utils/configUtils"); - getMCPProxyAuthToken.mockImplementation((config) => ({ + mockGetMCPProxyAuthToken.mockImplementation((config: InspectorConfig) => ({ token: config.MCP_PROXY_AUTH_TOKEN.value, header: "X-MCP-Proxy-Auth", })); @@ -106,8 +111,7 @@ describe("App - Config Endpoint", () => { }; // Mock initializeInspectorConfig to return our test config - const { initializeInspectorConfig } = require("../utils/configUtils"); - initializeInspectorConfig.mockReturnValue(mockConfig); + mockInitializeInspectorConfig.mockReturnValue(mockConfig); render(); @@ -118,7 +122,7 @@ describe("App - Config Endpoint", () => { headers: { "X-MCP-Proxy-Auth": "Bearer test-proxy-token", }, - } + }, ); }); }); @@ -133,8 +137,7 @@ describe("App - Config Endpoint", () => { }; // Mock initializeInspectorConfig to return our test config - const { initializeInspectorConfig } = require("../utils/configUtils"); - initializeInspectorConfig.mockReturnValue(mockConfig); + mockInitializeInspectorConfig.mockReturnValue(mockConfig); render(); @@ -143,7 +146,7 @@ describe("App - Config Endpoint", () => { "http://localhost:6277/config", { headers: {}, - } + }, ); }); }); @@ -158,12 +161,11 @@ describe("App - Config Endpoint", () => { }; // Mock to return a custom header name - const { getMCPProxyAuthToken, initializeInspectorConfig } = require("../utils/configUtils"); - getMCPProxyAuthToken.mockReturnValue({ + mockGetMCPProxyAuthToken.mockReturnValue({ token: "test-proxy-token", header: "X-Custom-Auth", }); - initializeInspectorConfig.mockReturnValue(mockConfig); + mockInitializeInspectorConfig.mockReturnValue(mockConfig); render(); @@ -174,7 +176,7 @@ describe("App - Config Endpoint", () => { headers: { "X-Custom-Auth": "Bearer test-proxy-token", }, - } + }, ); }); }); @@ -188,10 +190,9 @@ describe("App - Config Endpoint", () => { }, }; - const { initializeInspectorConfig } = require("../utils/configUtils"); - initializeInspectorConfig.mockReturnValue(mockConfig); + mockInitializeInspectorConfig.mockReturnValue(mockConfig); - const { container } = render(); + render(); await waitFor(() => { expect(global.fetch).toHaveBeenCalledTimes(1); @@ -204,7 +205,7 @@ describe("App - Config Endpoint", () => { headers: expect.objectContaining({ "X-MCP-Proxy-Auth": "Bearer test-proxy-token", }), - }) + }), ); }); @@ -217,8 +218,7 @@ describe("App - Config Endpoint", () => { }, }; - const { initializeInspectorConfig } = require("../utils/configUtils"); - initializeInspectorConfig.mockReturnValue(mockConfig); + mockInitializeInspectorConfig.mockReturnValue(mockConfig); // Mock fetch to reject (global.fetch as jest.Mock).mockRejectedValue(new Error("Network error")); @@ -231,10 +231,10 @@ describe("App - Config Endpoint", () => { await waitFor(() => { expect(consoleErrorSpy).toHaveBeenCalledWith( "Error fetching default environment:", - expect.any(Error) + expect.any(Error), ); }); consoleErrorSpy.mockRestore(); }); -}); \ No newline at end of file +}); diff --git a/client/src/lib/hooks/useConnection.ts b/client/src/lib/hooks/useConnection.ts index 9c578fba..81112b8a 100644 --- a/client/src/lib/hooks/useConnection.ts +++ b/client/src/lib/hooks/useConnection.ts @@ -243,10 +243,11 @@ export function useConnection({ const checkProxyHealth = async () => { try { const proxyHealthUrl = new URL(`${getMCPProxyAddress(config)}/health`); - const proxyAuthToken = getMCPProxyAuthToken(config); + const { token: proxyAuthToken, header: proxyAuthTokenHeader } = + getMCPProxyAuthToken(config); const headers: HeadersInit = {}; if (proxyAuthToken) { - headers["X-MCP-Proxy-Auth"] = `Bearer ${proxyAuthToken}`; + headers[proxyAuthTokenHeader] = `Bearer ${proxyAuthToken}`; } const proxyHealthResponse = await fetch(proxyHealthUrl, { headers }); const proxyHealth = await proxyHealthResponse.json(); @@ -332,10 +333,11 @@ export function useConnection({ } // Add proxy authentication - const proxyAuthToken = getMCPProxyAuthToken(config); + const { token: proxyAuthToken, header: proxyAuthTokenHeader } = + getMCPProxyAuthToken(config); const proxyHeaders: HeadersInit = {}; if (proxyAuthToken) { - proxyHeaders["X-MCP-Proxy-Auth"] = `Bearer ${proxyAuthToken}`; + proxyHeaders[proxyAuthTokenHeader] = `Bearer ${proxyAuthToken}`; } // Create appropriate transport diff --git a/client/src/utils/__tests__/configUtils.test.ts b/client/src/utils/__tests__/configUtils.test.ts index 38ce163b..86dccbdf 100644 --- a/client/src/utils/__tests__/configUtils.test.ts +++ b/client/src/utils/__tests__/configUtils.test.ts @@ -57,7 +57,7 @@ describe("configUtils", () => { ...DEFAULT_INSPECTOR_CONFIG, MCP_PROXY_AUTH_TOKEN: { ...DEFAULT_INSPECTOR_CONFIG.MCP_PROXY_AUTH_TOKEN, - value: null as any, + value: null as unknown as string, }, }; @@ -69,4 +69,4 @@ describe("configUtils", () => { }); }); }); -}); \ No newline at end of file +}); diff --git a/client/src/utils/configUtils.ts b/client/src/utils/configUtils.ts index 3e4d3e9b..40e47a94 100644 --- a/client/src/utils/configUtils.ts +++ b/client/src/utils/configUtils.ts @@ -28,8 +28,16 @@ export const getMCPServerRequestMaxTotalTimeout = ( return config.MCP_REQUEST_MAX_TOTAL_TIMEOUT.value as number; }; -export const getMCPProxyAuthToken = (config: InspectorConfig): string => { - return config.MCP_PROXY_AUTH_TOKEN.value as string; +export const getMCPProxyAuthToken = ( + config: InspectorConfig, +): { + token: string; + header: string; +} => { + return { + token: config.MCP_PROXY_AUTH_TOKEN.value as string, + header: "X-MCP-Proxy-Auth", + }; }; const getSearchParam = (key: string): string | null => {