Skip to content

Commit aa1b690

Browse files
feat(ui/): allow user to edit allowed tools for an mcp server
1 parent 6691d0b commit aa1b690

File tree

3 files changed

+45
-6
lines changed

3 files changed

+45
-6
lines changed

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
@@ -406,6 +406,7 @@ const CreateMCPServer: React.FC<CreateMCPServerProps> = ({
406406
accessToken={accessToken}
407407
formValues={formValues}
408408
allowedTools={allowedTools}
409+
existingAllowedTools={null}
409410
onAllowedToolsChange={setAllowedTools}
410411
/>
411412
</div>

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

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { MCPServer, MCPServerCostInfo } from "./types";
55
import { updateMCPServer, testMCPToolsListRequest } from "../networking";
66
import MCPServerCostConfig from "./mcp_server_cost_config";
77
import MCPPermissionManagement from "./MCPPermissionManagement";
8+
import MCPToolConfiguration from "./mcp_tool_configuration";
89
import { MinusCircleOutlined, PlusOutlined, InfoCircleOutlined } from "@ant-design/icons";
910
import { validateMCPServerUrl, validateMCPServerName } from "./utils";
1011
import NotificationsManager from "../molecules/notifications_manager";
@@ -23,7 +24,8 @@ const MCPServerEdit: React.FC<MCPServerEditProps> = ({ mcpServer, accessToken, o
2324
const [tools, setTools] = useState<any[]>([]);
2425
const [isLoadingTools, setIsLoadingTools] = useState(false);
2526
const [searchValue, setSearchValue] = useState<string>("");
26-
const [aliasManuallyEdited, setAliasManuallyEdited] = useState(false)
27+
const [aliasManuallyEdited, setAliasManuallyEdited] = useState(false);
28+
const [allowedTools, setAllowedTools] = useState<string[]>([]);
2729

2830
// Initialize cost config from existing server data
2931
useEffect(() => {
@@ -32,6 +34,13 @@ const MCPServerEdit: React.FC<MCPServerEditProps> = ({ mcpServer, accessToken, o
3234
}
3335
}, [mcpServer]);
3436

37+
// Initialize allowed tools from existing server data
38+
useEffect(() => {
39+
if (mcpServer.allowed_tools) {
40+
setAllowedTools(mcpServer.allowed_tools);
41+
}
42+
}, [mcpServer]);
43+
3544
// Transform string array to object array for initial form values
3645
useEffect(() => {
3746
if (mcpServer.mcp_access_groups) {
@@ -128,7 +137,7 @@ const MCPServerEdit: React.FC<MCPServerEditProps> = ({ mcpServer, accessToken, o
128137
alias: values.alias,
129138
// Include permission management fields
130139
extra_headers: values.extra_headers || [],
131-
allowed_tools: values.allowed_tools || [],
140+
allowed_tools: allowedTools.length > 0 ? allowedTools : null,
132141
disallowed_tools: values.disallowed_tools || [],
133142
};
134143

@@ -195,6 +204,24 @@ const MCPServerEdit: React.FC<MCPServerEditProps> = ({ mcpServer, accessToken, o
195204
/>
196205
</div>
197206

207+
{/* Tool Configuration Section */}
208+
<div className="mt-6">
209+
<MCPToolConfiguration
210+
accessToken={accessToken}
211+
formValues={{
212+
server_id: mcpServer.server_id,
213+
server_name: mcpServer.server_name,
214+
url: mcpServer.url,
215+
transport: mcpServer.transport,
216+
auth_type: mcpServer.auth_type,
217+
mcp_info: mcpServer.mcp_info,
218+
}}
219+
allowedTools={allowedTools}
220+
existingAllowedTools={mcpServer.allowed_tools || null}
221+
onAllowedToolsChange={setAllowedTools}
222+
/>
223+
</div>
224+
198225
<div className="flex justify-end gap-2">
199226
<AntdButton onClick={onCancel}>Cancel</AntdButton>
200227
<Button type="submit">Save Changes</Button>

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

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,15 @@ interface MCPToolConfigurationProps {
88
accessToken: string | null
99
formValues: Record<string, any>
1010
allowedTools: string[]
11+
existingAllowedTools: string[] | null
1112
onAllowedToolsChange: (tools: string[]) => void
1213
}
1314

1415
const MCPToolConfiguration: React.FC<MCPToolConfigurationProps> = ({
1516
accessToken,
1617
formValues,
1718
allowedTools,
19+
existingAllowedTools,
1820
onAllowedToolsChange,
1921
}) => {
2022
const previousToolsLengthRef = useRef(0)
@@ -25,19 +27,28 @@ const MCPToolConfiguration: React.FC<MCPToolConfigurationProps> = ({
2527
enabled: true,
2628
})
2729

28-
// Auto-select all tools when tools are first loaded
30+
// Auto-select tools when tools are first loaded
2931
useEffect(() => {
3032
// Only auto-select if:
3133
// 1. We have tools
3234
// 2. Tools length changed (new tools loaded)
3335
// 3. No tools are currently selected (initial state)
3436
if (tools.length > 0 && tools.length !== previousToolsLengthRef.current && allowedTools.length === 0) {
35-
const allToolNames = tools.map((tool) => tool.name)
36-
onAllowedToolsChange(allToolNames)
37+
if (existingAllowedTools && existingAllowedTools.length > 0) {
38+
// If we have existing allowed tools, use those as the initial selection
39+
// Filter to only include tools that are actually available from the server
40+
const availableToolNames = tools.map((tool) => tool.name)
41+
const validExistingTools = existingAllowedTools.filter(toolName => availableToolNames.includes(toolName))
42+
onAllowedToolsChange(validExistingTools)
43+
} else {
44+
// If no existing allowed tools, auto-select all tools (create mode)
45+
const allToolNames = tools.map((tool) => tool.name)
46+
onAllowedToolsChange(allToolNames)
47+
}
3748
}
3849
// Update ref to track tools length (will be 0 when tools clear)
3950
previousToolsLengthRef.current = tools.length
40-
}, [tools, allowedTools.length, onAllowedToolsChange])
51+
}, [tools, allowedTools.length, existingAllowedTools, onAllowedToolsChange])
4152

4253
const handleToolToggle = (toolName: string) => {
4354
if (allowedTools.includes(toolName)) {

0 commit comments

Comments
 (0)