feat(ui/): allow user to edit allowed tools for an mcp server

This commit is contained in:
Krrish Dholakia
2025-10-03 19:05:56 -07:00
parent 6691d0bc85
commit aa1b690494
3 changed files with 45 additions and 6 deletions
@@ -406,6 +406,7 @@ const CreateMCPServer: React.FC<CreateMCPServerProps> = ({
accessToken={accessToken}
formValues={formValues}
allowedTools={allowedTools}
existingAllowedTools={null}
onAllowedToolsChange={setAllowedTools}
/>
</div>
@@ -5,6 +5,7 @@ import { MCPServer, MCPServerCostInfo } from "./types";
import { updateMCPServer, testMCPToolsListRequest } from "../networking";
import MCPServerCostConfig from "./mcp_server_cost_config";
import MCPPermissionManagement from "./MCPPermissionManagement";
import MCPToolConfiguration from "./mcp_tool_configuration";
import { MinusCircleOutlined, PlusOutlined, InfoCircleOutlined } from "@ant-design/icons";
import { validateMCPServerUrl, validateMCPServerName } from "./utils";
import NotificationsManager from "../molecules/notifications_manager";
@@ -23,7 +24,8 @@ const MCPServerEdit: React.FC<MCPServerEditProps> = ({ mcpServer, accessToken, o
const [tools, setTools] = useState<any[]>([]);
const [isLoadingTools, setIsLoadingTools] = useState(false);
const [searchValue, setSearchValue] = useState<string>("");
const [aliasManuallyEdited, setAliasManuallyEdited] = useState(false)
const [aliasManuallyEdited, setAliasManuallyEdited] = useState(false);
const [allowedTools, setAllowedTools] = useState<string[]>([]);
// Initialize cost config from existing server data
useEffect(() => {
@@ -32,6 +34,13 @@ const MCPServerEdit: React.FC<MCPServerEditProps> = ({ mcpServer, accessToken, o
}
}, [mcpServer]);
// Initialize allowed tools from existing server data
useEffect(() => {
if (mcpServer.allowed_tools) {
setAllowedTools(mcpServer.allowed_tools);
}
}, [mcpServer]);
// Transform string array to object array for initial form values
useEffect(() => {
if (mcpServer.mcp_access_groups) {
@@ -128,7 +137,7 @@ const MCPServerEdit: React.FC<MCPServerEditProps> = ({ mcpServer, accessToken, o
alias: values.alias,
// Include permission management fields
extra_headers: values.extra_headers || [],
allowed_tools: values.allowed_tools || [],
allowed_tools: allowedTools.length > 0 ? allowedTools : null,
disallowed_tools: values.disallowed_tools || [],
};
@@ -195,6 +204,24 @@ const MCPServerEdit: React.FC<MCPServerEditProps> = ({ mcpServer, accessToken, o
/>
</div>
{/* Tool Configuration Section */}
<div className="mt-6">
<MCPToolConfiguration
accessToken={accessToken}
formValues={{
server_id: mcpServer.server_id,
server_name: mcpServer.server_name,
url: mcpServer.url,
transport: mcpServer.transport,
auth_type: mcpServer.auth_type,
mcp_info: mcpServer.mcp_info,
}}
allowedTools={allowedTools}
existingAllowedTools={mcpServer.allowed_tools || null}
onAllowedToolsChange={setAllowedTools}
/>
</div>
<div className="flex justify-end gap-2">
<AntdButton onClick={onCancel}>Cancel</AntdButton>
<Button type="submit">Save Changes</Button>
@@ -8,6 +8,7 @@ interface MCPToolConfigurationProps {
accessToken: string | null
formValues: Record<string, any>
allowedTools: string[]
existingAllowedTools: string[] | null
onAllowedToolsChange: (tools: string[]) => void
}
@@ -15,6 +16,7 @@ const MCPToolConfiguration: React.FC<MCPToolConfigurationProps> = ({
accessToken,
formValues,
allowedTools,
existingAllowedTools,
onAllowedToolsChange,
}) => {
const previousToolsLengthRef = useRef(0)
@@ -25,19 +27,28 @@ const MCPToolConfiguration: React.FC<MCPToolConfigurationProps> = ({
enabled: true,
})
// Auto-select all tools when tools are first loaded
// Auto-select tools when tools are first loaded
useEffect(() => {
// Only auto-select if:
// 1. We have tools
// 2. Tools length changed (new tools loaded)
// 3. No tools are currently selected (initial state)
if (tools.length > 0 && tools.length !== previousToolsLengthRef.current && allowedTools.length === 0) {
const allToolNames = tools.map((tool) => tool.name)
onAllowedToolsChange(allToolNames)
if (existingAllowedTools && existingAllowedTools.length > 0) {
// If we have existing allowed tools, use those as the initial selection
// Filter to only include tools that are actually available from the server
const availableToolNames = tools.map((tool) => tool.name)
const validExistingTools = existingAllowedTools.filter(toolName => availableToolNames.includes(toolName))
onAllowedToolsChange(validExistingTools)
} else {
// If no existing allowed tools, auto-select all tools (create mode)
const allToolNames = tools.map((tool) => tool.name)
onAllowedToolsChange(allToolNames)
}
}
// Update ref to track tools length (will be 0 when tools clear)
previousToolsLengthRef.current = tools.length
}, [tools, allowedTools.length, onAllowedToolsChange])
}, [tools, allowedTools.length, existingAllowedTools, onAllowedToolsChange])
const handleToolToggle = (toolName: string) => {
if (allowedTools.includes(toolName)) {