fix(ui): expose the authorization MCP auth type in the create and edit forms

This commit is contained in:
Devin AI 2026-07-27 10:22:00 +00:00
parent 24123269cc
commit 153b17e98b
6 changed files with 94 additions and 4 deletions

View file

@ -355,6 +355,45 @@ describe("CreateMCPServer", () => {
expect(payload.credentials).toEqual({ auth_value: "my-secret-key" });
});
it("creates a server with the raw Authorization auth type and its header value", async () => {
await selectHttpTransport();
const user = userEvent.setup({ delay: null });
await user.type(getServerNameInput(), "Raw_Auth_Server");
await user.type(screen.getByPlaceholderText("https://your-mcp-server.com"), "https://example.com/mcp");
await selectAntOption("Authentication", "Authorization (raw header)");
const authInput = await screen.findByPlaceholderText("Enter token or secret");
await user.type(authInput, "ApiKey upstream-key");
vi.mocked(networking.createMCPServer).mockResolvedValue({
server_id: "new-server-1",
server_name: "Raw_Auth_Server",
alias: "Raw_Auth_Server",
url: "https://example.com/mcp",
transport: "http",
auth_type: "authorization",
created_at: "2024-01-01T00:00:00Z",
created_by: "user-1",
updated_at: "2024-01-01T00:00:00Z",
updated_by: "user-1",
});
await act(async () => {
fireEvent.click(screen.getByRole("button", { name: "Add MCP Server" }));
});
await waitFor(() => {
expect(networking.createMCPServer).toHaveBeenCalledTimes(1);
});
const [, payload] = vi.mocked(networking.createMCPServer).mock.calls[0];
expect(payload.auth_type).toBe("authorization");
expect(payload.credentials).toEqual({ auth_value: "ApiKey upstream-key" });
});
it("does not write the browser-authorized token into form.credentials for true_passthrough", async () => {
await selectHttpTransport();

View file

@ -56,7 +56,13 @@ interface CreateMCPServerProps {
onBackToDiscovery?: () => void;
}
const AUTH_TYPES_REQUIRING_AUTH_VALUE = [AUTH_TYPE.API_KEY, AUTH_TYPE.BEARER_TOKEN, AUTH_TYPE.TOKEN, AUTH_TYPE.BASIC];
const AUTH_TYPES_REQUIRING_AUTH_VALUE = [
AUTH_TYPE.API_KEY,
AUTH_TYPE.BEARER_TOKEN,
AUTH_TYPE.TOKEN,
AUTH_TYPE.BASIC,
AUTH_TYPE.AUTHORIZATION,
];
const AUTH_TYPES_REQUIRING_CREDENTIALS = [
...AUTH_TYPES_REQUIRING_AUTH_VALUE,
AUTH_TYPE.OAUTH2,
@ -1071,12 +1077,13 @@ const CreateMCPServer: React.FC<CreateMCPServerProps> = ({
children: (
<>
<Form.Item name="auth_type" rules={[{ required: true, message: "Please select an auth type" }]}>
<Select placeholder="Select auth type" className="rounded-lg" size="large">
<Select placeholder="Select auth type" className="rounded-lg" size="large" virtual={false}>
<Select.Option value="none">None</Select.Option>
<Select.Option value="api_key">API Key</Select.Option>
<Select.Option value="bearer_token">Bearer Token</Select.Option>
<Select.Option value="token">Token</Select.Option>
<Select.Option value="basic">Basic Auth</Select.Option>
<Select.Option value="authorization">Authorization (raw header)</Select.Option>
<Select.Option value="oauth2">OAuth</Select.Option>
<Select.Option value="oauth2_token_exchange">OAuth Token Exchange (OBO)</Select.Option>
<Select.Option value="aws_sigv4">AWS SigV4 (Bedrock AgentCore MCPs)</Select.Option>

View file

@ -432,6 +432,41 @@ describe("MCPServerEdit (auth type switch)", () => {
expect(payload.registration_url).toBeNull();
});
it("saves the raw Authorization auth type with its header value", async () => {
vi.mocked(networking.updateMCPServer).mockResolvedValue({
...interactiveOAuthServer,
auth_type: "authorization",
});
render(
<MCPServerEdit
mcpServer={{ ...interactiveOAuthServer, auth_type: "api_key" }}
accessToken="access-token"
onCancel={vi.fn()}
onSuccess={vi.fn()}
availableAccessGroups={[]}
/>,
);
await selectAntOption("Authentication", "Authorization (raw header)");
const authInput = await screen.findByPlaceholderText("Enter token or secret (leave blank to keep existing)");
await userEvent.setup({ delay: null }).type(authInput, "ApiKey upstream-key");
const saveButtons = screen.getAllByRole("button", { name: "Save Changes" });
await act(async () => {
fireEvent.click(saveButtons[0]);
});
await waitFor(() => {
expect(networking.updateMCPServer).toHaveBeenCalledTimes(1);
});
const [, payload] = vi.mocked(networking.updateMCPServer).mock.calls[0];
expect(payload.auth_type).toBe("authorization");
expect(payload.credentials).toEqual({ auth_value: "ApiKey upstream-key" });
});
it("keeps oauth2 endpoint overrides when the auth type is unchanged", async () => {
vi.mocked(networking.updateMCPServer).mockResolvedValue({ ...interactiveOAuthServer });

View file

@ -59,7 +59,13 @@ interface MCPServerEditProps {
availableAccessGroups: string[];
}
const AUTH_TYPES_REQUIRING_AUTH_VALUE = [AUTH_TYPE.API_KEY, AUTH_TYPE.BEARER_TOKEN, AUTH_TYPE.TOKEN, AUTH_TYPE.BASIC];
const AUTH_TYPES_REQUIRING_AUTH_VALUE = [
AUTH_TYPE.API_KEY,
AUTH_TYPE.BEARER_TOKEN,
AUTH_TYPE.TOKEN,
AUTH_TYPE.BASIC,
AUTH_TYPE.AUTHORIZATION,
];
const AUTH_TYPES_REQUIRING_CREDENTIALS = [
...AUTH_TYPES_REQUIRING_AUTH_VALUE,
AUTH_TYPE.OAUTH2,
@ -1111,12 +1117,13 @@ const MCPServerEdit: React.FC<MCPServerEditProps> = ({
{!isStdioTransport && (
<>
<Form.Item label="Authentication" name="auth_type" rules={[{ required: true }]}>
<Select>
<Select virtual={false}>
<Select.Option value="none">None</Select.Option>
<Select.Option value="api_key">API Key</Select.Option>
<Select.Option value="bearer_token">Bearer Token</Select.Option>
<Select.Option value="token">Token</Select.Option>
<Select.Option value="basic">Basic Auth</Select.Option>
<Select.Option value="authorization">Authorization (raw header)</Select.Option>
<Select.Option value="oauth2">OAuth</Select.Option>
<Select.Option value="oauth2_token_exchange">OAuth Token Exchange (OBO)</Select.Option>
<Select.Option value="aws_sigv4">AWS SigV4 (Bedrock AgentCore MCPs)</Select.Option>

View file

@ -108,6 +108,7 @@ describe("constants", () => {
expect(AUTH_TYPE.NONE).toBe("none");
expect(AUTH_TYPE.API_KEY).toBe("api_key");
expect(AUTH_TYPE.BEARER_TOKEN).toBe("bearer_token");
expect(AUTH_TYPE.AUTHORIZATION).toBe("authorization");
expect(AUTH_TYPE.OAUTH2).toBe("oauth2");
});

View file

@ -38,6 +38,7 @@ export const AUTH_TYPE = {
BEARER_TOKEN: "bearer_token",
TOKEN: "token",
BASIC: "basic",
AUTHORIZATION: "authorization",
OAUTH2: "oauth2",
OAUTH2_TOKEN_EXCHANGE: "oauth2_token_exchange",
AWS_SIGV4: "aws_sigv4",