feat(ui/): display the MCP extra headers on the UI

allow user to see what extra headers they set
This commit is contained in:
Krrish Dholakia
2025-10-03 18:43:41 -07:00
parent 562e7a4e03
commit c00cedcf26
5 changed files with 47 additions and 31 deletions
@@ -1,11 +1,12 @@
import React, { useState } from "react"
import React, { useState, useEffect } from "react"
import { Form, Select, Tooltip, Collapse } from "antd"
import { InfoCircleOutlined } from "@ant-design/icons"
import { MCPServer } from "./types"
const { Panel } = Collapse
interface MCPPermissionManagementProps {
availableAccessGroups: string[]
mcpServer: MCPServer | null
searchValue: string
setSearchValue: (value: string) => void
getAccessGroupOptions: () => Array<{
@@ -16,10 +17,24 @@ interface MCPPermissionManagementProps {
const MCPPermissionManagement: React.FC<MCPPermissionManagementProps> = ({
availableAccessGroups,
mcpServer,
searchValue,
setSearchValue,
getAccessGroupOptions,
}) => {
const form = Form.useFormInstance()
// Set initial values when mcpServer changes
useEffect(() => {
if (mcpServer) {
// Set extra_headers if they exist
if (mcpServer.extra_headers) {
form.setFieldValue('extra_headers', mcpServer.extra_headers)
}
}
}, [mcpServer, form])
return (
<Collapse
className="bg-gray-50 border border-gray-200 rounded-lg"
@@ -75,13 +90,22 @@ const MCPPermissionManagement: React.FC<MCPPermissionManagementProps> = ({
<Tooltip title="Forward custom headers from incoming requests to this MCP server (e.g., Authorization, X-Custom-Header, User-Agent)">
<InfoCircleOutlined className="ml-2 text-blue-400 hover:text-blue-600 cursor-help" />
</Tooltip>
{mcpServer?.extra_headers && mcpServer.extra_headers.length > 0 && (
<span className="ml-2 text-xs bg-blue-100 text-blue-700 px-2 py-1 rounded-full">
{mcpServer.extra_headers.length} configured
</span>
)}
</span>
}
name="extra_headers"
>
<Select
mode="tags"
placeholder="Enter header names (e.g., Authorization, X-Custom-Header)"
placeholder={
mcpServer?.extra_headers && mcpServer.extra_headers.length > 0
? `Currently: ${mcpServer.extra_headers.join(', ')}`
: "Enter header names (e.g., Authorization, X-Custom-Header)"
}
className="rounded-lg"
size="large"
tokenSeparators={[","]}
@@ -388,6 +388,7 @@ const CreateMCPServer: React.FC<CreateMCPServerProps> = ({
<div className="mt-8">
<MCPPermissionManagement
availableAccessGroups={availableAccessGroups}
mcpServer={null}
searchValue={searchValue}
setSearchValue={setSearchValue}
getAccessGroupOptions={getAccessGroupOptions}
@@ -4,6 +4,7 @@ import { Button, TextInput, TabGroup, TabList, Tab, TabPanels, TabPanel } from "
import { MCPServer, MCPServerCostInfo } from "./types";
import { updateMCPServer, testMCPToolsListRequest } from "../networking";
import MCPServerCostConfig from "./mcp_server_cost_config";
import MCPPermissionManagement from "./MCPPermissionManagement";
import { MinusCircleOutlined, PlusOutlined, InfoCircleOutlined } from "@ant-design/icons";
import { validateMCPServerUrl, validateMCPServerName } from "./utils";
import NotificationsManager from "../molecules/notifications_manager";
@@ -114,7 +115,7 @@ const MCPServerEdit: React.FC<MCPServerEditProps> = ({ mcpServer, accessToken, o
// Ensure access groups is always a string array
const accessGroups = (values.mcp_access_groups || []).map((g: any) => typeof g === 'string' ? g : g.name || String(g));
// Prepare the payload with cost configuration
// Prepare the payload with cost configuration and permission fields
const payload = {
...values,
server_id: mcpServer.server_id,
@@ -125,6 +126,10 @@ const MCPServerEdit: React.FC<MCPServerEditProps> = ({ mcpServer, accessToken, o
},
mcp_access_groups: accessGroups,
alias: values.alias,
// Include permission management fields
extra_headers: values.extra_headers || [],
allowed_tools: values.allowed_tools || [],
disallowed_tools: values.disallowed_tools || [],
};
const updated = await updateMCPServer(accessToken, payload);
@@ -179,34 +184,15 @@ const MCPServerEdit: React.FC<MCPServerEditProps> = ({ mcpServer, accessToken, o
</Select>
</Form.Item>
<Form.Item
label={
<span className="text-sm font-medium text-gray-700 flex items-center">
MCP Access Groups
<Tooltip title="Define access groups for this MCP server. Each group represents a set of permissions.">
<InfoCircleOutlined className="ml-2 text-blue-400 hover:text-blue-600 cursor-help" />
</Tooltip>
</span>
}
name="mcp_access_groups"
getValueFromEvent={value => value}
>
<Select
mode="tags"
style={{ width: '100%' }}
showSearch
placeholder="Add or select access groups"
tokenSeparators={[',']}
optionFilterProp="value"
filterOption={(input, option) =>
(option?.value ?? '').toLowerCase().includes(input.toLowerCase())
}
onSearch={(value) => setSearchValue(value)}
options={getAccessGroupOptions()}
// Ensure value is always an array of strings
getPopupContainer={trigger => trigger.parentNode}
{/* Permission Management / Access Control Section */}
<div className="mt-6">
<MCPPermissionManagement
availableAccessGroups={availableAccessGroups}
searchValue={searchValue}
setSearchValue={setSearchValue}
getAccessGroupOptions={getAccessGroupOptions}
/>
</Form.Item>
</div>
<div className="flex justify-end gap-2">
<AntdButton onClick={onCancel}>Cancel</AntdButton>
@@ -221,6 +221,10 @@ export const MCPServerView: React.FC<MCPServerViewProps> = ({
<Text className="font-medium">Transport</Text>
<div>{handleTransport(mcpServer.transport)}</div>
</div>
<div>
<Text className="font-medium">Extra Headers</Text>
<div>{mcpServer.extra_headers?.join(", ")}</div>
</div>
<div>
<Text className="font-medium">Auth Type</Text>
<div>{handleAuth(mcpServer.auth_type)}</div>
@@ -138,6 +138,7 @@ export interface MCPServer {
created_by: string
updated_at: string
updated_by: string
extra_headers?: string[] | null
status?: "healthy" | "unhealthy" | "unknown"
last_health_check?: string | null
health_check_error?: string | null