Skip to content

Commit c00cedc

Browse files
feat(ui/): display the MCP extra headers on the UI
allow user to see what extra headers they set
1 parent 562e7a4 commit c00cedc

File tree

5 files changed

+47
-31
lines changed

5 files changed

+47
-31
lines changed

ui/litellm-dashboard/src/components/mcp_tools/MCPPermissionManagement.tsx

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
1-
import React, { useState } from "react"
1+
import React, { useState, useEffect } from "react"
22
import { Form, Select, Tooltip, Collapse } from "antd"
33
import { InfoCircleOutlined } from "@ant-design/icons"
4-
4+
import { MCPServer } from "./types"
55
const { Panel } = Collapse
66

77
interface MCPPermissionManagementProps {
88
availableAccessGroups: string[]
9+
mcpServer: MCPServer | null
910
searchValue: string
1011
setSearchValue: (value: string) => void
1112
getAccessGroupOptions: () => Array<{
@@ -16,10 +17,24 @@ interface MCPPermissionManagementProps {
1617

1718
const MCPPermissionManagement: React.FC<MCPPermissionManagementProps> = ({
1819
availableAccessGroups,
20+
mcpServer,
1921
searchValue,
2022
setSearchValue,
2123
getAccessGroupOptions,
2224
}) => {
25+
const form = Form.useFormInstance()
26+
27+
// Set initial values when mcpServer changes
28+
useEffect(() => {
29+
if (mcpServer) {
30+
// Set extra_headers if they exist
31+
if (mcpServer.extra_headers) {
32+
form.setFieldValue('extra_headers', mcpServer.extra_headers)
33+
}
34+
35+
}
36+
}, [mcpServer, form])
37+
2338
return (
2439
<Collapse
2540
className="bg-gray-50 border border-gray-200 rounded-lg"
@@ -75,13 +90,22 @@ const MCPPermissionManagement: React.FC<MCPPermissionManagementProps> = ({
7590
<Tooltip title="Forward custom headers from incoming requests to this MCP server (e.g., Authorization, X-Custom-Header, User-Agent)">
7691
<InfoCircleOutlined className="ml-2 text-blue-400 hover:text-blue-600 cursor-help" />
7792
</Tooltip>
93+
{mcpServer?.extra_headers && mcpServer.extra_headers.length > 0 && (
94+
<span className="ml-2 text-xs bg-blue-100 text-blue-700 px-2 py-1 rounded-full">
95+
{mcpServer.extra_headers.length} configured
96+
</span>
97+
)}
7898
</span>
7999
}
80100
name="extra_headers"
81101
>
82102
<Select
83103
mode="tags"
84-
placeholder="Enter header names (e.g., Authorization, X-Custom-Header)"
104+
placeholder={
105+
mcpServer?.extra_headers && mcpServer.extra_headers.length > 0
106+
? `Currently: ${mcpServer.extra_headers.join(', ')}`
107+
: "Enter header names (e.g., Authorization, X-Custom-Header)"
108+
}
85109
className="rounded-lg"
86110
size="large"
87111
tokenSeparators={[","]}

ui/litellm-dashboard/src/components/mcp_tools/create_mcp_server.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -388,6 +388,7 @@ const CreateMCPServer: React.FC<CreateMCPServerProps> = ({
388388
<div className="mt-8">
389389
<MCPPermissionManagement
390390
availableAccessGroups={availableAccessGroups}
391+
mcpServer={null}
391392
searchValue={searchValue}
392393
setSearchValue={setSearchValue}
393394
getAccessGroupOptions={getAccessGroupOptions}

ui/litellm-dashboard/src/components/mcp_tools/mcp_server_edit.tsx

Lines changed: 14 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { Button, TextInput, TabGroup, TabList, Tab, TabPanels, TabPanel } from "
44
import { MCPServer, MCPServerCostInfo } from "./types";
55
import { updateMCPServer, testMCPToolsListRequest } from "../networking";
66
import MCPServerCostConfig from "./mcp_server_cost_config";
7+
import MCPPermissionManagement from "./MCPPermissionManagement";
78
import { MinusCircleOutlined, PlusOutlined, InfoCircleOutlined } from "@ant-design/icons";
89
import { validateMCPServerUrl, validateMCPServerName } from "./utils";
910
import NotificationsManager from "../molecules/notifications_manager";
@@ -114,7 +115,7 @@ const MCPServerEdit: React.FC<MCPServerEditProps> = ({ mcpServer, accessToken, o
114115
// Ensure access groups is always a string array
115116
const accessGroups = (values.mcp_access_groups || []).map((g: any) => typeof g === 'string' ? g : g.name || String(g));
116117

117-
// Prepare the payload with cost configuration
118+
// Prepare the payload with cost configuration and permission fields
118119
const payload = {
119120
...values,
120121
server_id: mcpServer.server_id,
@@ -125,6 +126,10 @@ const MCPServerEdit: React.FC<MCPServerEditProps> = ({ mcpServer, accessToken, o
125126
},
126127
mcp_access_groups: accessGroups,
127128
alias: values.alias,
129+
// Include permission management fields
130+
extra_headers: values.extra_headers || [],
131+
allowed_tools: values.allowed_tools || [],
132+
disallowed_tools: values.disallowed_tools || [],
128133
};
129134

130135
const updated = await updateMCPServer(accessToken, payload);
@@ -179,34 +184,15 @@ const MCPServerEdit: React.FC<MCPServerEditProps> = ({ mcpServer, accessToken, o
179184
</Select>
180185
</Form.Item>
181186

182-
<Form.Item
183-
label={
184-
<span className="text-sm font-medium text-gray-700 flex items-center">
185-
MCP Access Groups
186-
<Tooltip title="Define access groups for this MCP server. Each group represents a set of permissions.">
187-
<InfoCircleOutlined className="ml-2 text-blue-400 hover:text-blue-600 cursor-help" />
188-
</Tooltip>
189-
</span>
190-
}
191-
name="mcp_access_groups"
192-
getValueFromEvent={value => value}
193-
>
194-
<Select
195-
mode="tags"
196-
style={{ width: '100%' }}
197-
showSearch
198-
placeholder="Add or select access groups"
199-
tokenSeparators={[',']}
200-
optionFilterProp="value"
201-
filterOption={(input, option) =>
202-
(option?.value ?? '').toLowerCase().includes(input.toLowerCase())
203-
}
204-
onSearch={(value) => setSearchValue(value)}
205-
options={getAccessGroupOptions()}
206-
// Ensure value is always an array of strings
207-
getPopupContainer={trigger => trigger.parentNode}
187+
{/* Permission Management / Access Control Section */}
188+
<div className="mt-6">
189+
<MCPPermissionManagement
190+
availableAccessGroups={availableAccessGroups}
191+
searchValue={searchValue}
192+
setSearchValue={setSearchValue}
193+
getAccessGroupOptions={getAccessGroupOptions}
208194
/>
209-
</Form.Item>
195+
</div>
210196

211197
<div className="flex justify-end gap-2">
212198
<AntdButton onClick={onCancel}>Cancel</AntdButton>

ui/litellm-dashboard/src/components/mcp_tools/mcp_server_view.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,10 @@ export const MCPServerView: React.FC<MCPServerViewProps> = ({
221221
<Text className="font-medium">Transport</Text>
222222
<div>{handleTransport(mcpServer.transport)}</div>
223223
</div>
224+
<div>
225+
<Text className="font-medium">Extra Headers</Text>
226+
<div>{mcpServer.extra_headers?.join(", ")}</div>
227+
</div>
224228
<div>
225229
<Text className="font-medium">Auth Type</Text>
226230
<div>{handleAuth(mcpServer.auth_type)}</div>

ui/litellm-dashboard/src/components/mcp_tools/types.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,7 @@ export interface MCPServer {
138138
created_by: string
139139
updated_at: string
140140
updated_by: string
141+
extra_headers?: string[] | null
141142
status?: "healthy" | "unhealthy" | "unknown"
142143
last_health_check?: string | null
143144
health_check_error?: string | null

0 commit comments

Comments
 (0)