mirror of
https://github.com/tiennm99/litellm.git
synced 2026-07-17 10:17:46 +00:00
feat(ui/): display the MCP extra headers on the UI
allow user to see what extra headers they set
This commit is contained in:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user