fix(ui): use stored-credentials endpoint for tools fetch on MCP edit page

The edit page was calling POST /mcp-rest/test/tools/list (the temp-session
endpoint that requires inline credentials) on mount. Since fetchTools
deliberately omits credentials from the request body, any server with
auth_type api_key/bearer_token/basic/authorization would 422.

Switch to GET /mcp-rest/tools/list?server_id=... which looks up stored
credentials on the backend — no inline creds needed for saved servers.
This commit is contained in:
Ryan Crabbe 2026-04-17 22:42:07 -07:00
parent 850fe595ac
commit a125ae697e
No known key found for this signature in database
2 changed files with 8 additions and 32 deletions

View file

@ -7,7 +7,7 @@ import NotificationsManager from "../molecules/notifications_manager";
vi.mock("../networking", () => ({
updateMCPServer: vi.fn(),
testMCPToolsListRequest: vi.fn().mockResolvedValue({ tools: [], error: null }),
listMCPTools: vi.fn().mockResolvedValue({ tools: [], error: null }),
}));
vi.mock("../molecules/notifications_manager", () => ({

View file

@ -3,7 +3,7 @@ import { Form, Select, Button as AntdButton, Tooltip, Input, InputNumber } from
import { InfoCircleOutlined } from "@ant-design/icons";
import { Button, TabGroup, TabList, Tab, TabPanels, TabPanel } from "@tremor/react";
import { AUTH_TYPE, OAUTH_FLOW, MCPServer, MCPServerCostInfo, TRANSPORT } from "./types";
import { updateMCPServer, testMCPToolsListRequest } from "../networking";
import { updateMCPServer, listMCPTools } from "../networking";
import MCPServerCostConfig from "./mcp_server_cost_config";
import MCPPermissionManagement from "./MCPPermissionManagement";
import MCPToolConfiguration from "./mcp_tool_configuration";
@ -271,47 +271,23 @@ const MCPServerEdit: React.FC<MCPServerEditProps> = ({
}
}, [mcpServer]);
// Fetch tools when component mounts or when OAuth token is received
// But only if the server has been properly saved (has a permanent server_id)
// Fetch tools when component mounts for a saved server
useEffect(() => {
// Don't fetch if server hasn't been saved yet (no permanent server_id)
if (!mcpServer.server_id || mcpServer.server_id.trim() === "") {
return;
}
fetchTools();
}, [mcpServer, accessToken, oauthAccessToken]);
}, [mcpServer, accessToken]);
const fetchTools = async () => {
if (!accessToken) return;
// HTTP/SSE requires a URL (unless spec_path is set); stdio does not.
if (mcpServer.transport !== "stdio" && !mcpServer.url && !mcpServer.spec_path) return;
const isM2M = mcpServer.auth_type === AUTH_TYPE.OAUTH2 && !!mcpServer.token_url;
if (mcpServer.auth_type === AUTH_TYPE.OAUTH2 && !isM2M && !oauthAccessToken) {
return;
}
if (!accessToken || !mcpServer.server_id) return;
setIsLoadingTools(true);
try {
// Prepare the MCP server config from existing server data
const mcpServerConfig = {
server_id: mcpServer.server_id,
server_name: mcpServer.server_name,
url: mcpServer.url,
transport: mcpServer.transport,
auth_type: mcpServer.auth_type,
mcp_info: mcpServer.mcp_info,
authorization_url: mcpServer.authorization_url,
token_url: mcpServer.token_url,
registration_url: mcpServer.registration_url,
command: mcpServer.command,
args: mcpServer.args,
env: mcpServer.env,
};
const toolsResponse = await testMCPToolsListRequest(accessToken, mcpServerConfig, oauthAccessToken);
// Use the GET endpoint which looks up stored credentials by server_id,
// rather than POST /test/tools/list which requires inline credentials.
const toolsResponse = await listMCPTools(accessToken, mcpServer.server_id);
if (toolsResponse.tools && !toolsResponse.error) {
setTools(toolsResponse.tools);