mirror of
https://github.com/RooVetGit/Roo-Code.git
synced 2026-10-01 02:01:27 +00:00
Adds granular per-mode control over which MCP servers and tools are available, replacing the previous all-or-nothing 'mcp' group behavior.
Schema (packages/types/src/mode.ts): - Add mcpServerFilterSchema with disabled/allowedTools/disabledTools - Add mcpDefaultPolicy ('allow'|'deny') for deny-by-default support - Add mcpGroupOptionsSchema extending group options for MCP tuples - Add superRefine validation rejecting MCP options on non-mcp groups
Core filtering (src/utils/mcp-filter.ts): - getMcpFilterForMode() resolves MCP config for a mode - isMcpServerAllowedForMode() checks server access with policy - isMcpToolAllowedForMode() checks tool access with allowlist/blocklist - Inlined getGroupName to avoid vscode import chain (ISSUE-16)
Prerequisite fix (src/utils/mcp-name.ts): - Fix normalizeForComparison regex: /[-\s]+/g -> /[-\s]/g (ISSUE-10) - Add toLowerCase() for case-insensitive matching
Prompt-level filtering: - filter-tools-for-mode.ts: Filter MCP tools from system prompt - build-tools.ts: Filter MCP tools for Gemini native function calling - ISSUE-19: Document native tools remain unfiltered for Gemini
Execution-time guards: - validateToolUse.ts: Replace blanket MCP allow with filter checks - Server-level guard for use_mcp_tool/access_mcp_resource - Tool-level guard for dynamic mcp--server--tool names - ISSUE-21: Tool-level check for use_mcp_tool when tool_name available - presentAssistantMessage.ts mcp_tool_use: Add filter using cline.taskMode - ISSUE-17: validateToolUse call uses cline.taskMode (frozen at task start) instead of state.mode (live UI mode) - ISSUE-20: Remove dead ?? defaultModeSlug fallback
Defense-in-depth: - UseMcpToolTool.execute(): Server + tool level filter before execution - AccessMcpResourceTool.execute(): Server level filter before execution - FLAG-E: Document 10-second TTL cache in CustomModesManager
UI fix (webview-ui): - ModesView.tsx: Cache group tuple options on toggle-off, restore on toggle-on to prevent MCP config data loss (ISSUE-9/ISSUE-13) - Extract pure caching functions to groupOptionsCache.ts
Tests: 89 new tests across 11 files, all passing
33 lines
1.3 KiB
TypeScript
33 lines
1.3 KiB
TypeScript
import { useRef, useEffect, useCallback } from "react"
|
|
|
|
import type { GroupEntry, ToolGroup } from "@roo-code/types"
|
|
|
|
import { syncCacheFromGroups, removeGroupWithCache, addGroupWithCache } from "./groupOptionsCache"
|
|
|
|
/**
|
|
* Custom hook that caches group options (tuple second element) when
|
|
* groups are removed, and restores them when groups are re-added.
|
|
*
|
|
* This prevents data loss when toggling a group like "mcp" off and
|
|
* back on — without the cache, the MCP filter config (mcpServers,
|
|
* mcpDefaultPolicy) would be discarded on uncheck.
|
|
*/
|
|
export function useGroupOptionsCache(groups: GroupEntry[]) {
|
|
const groupOptionsCache = useRef<Map<string, object>>(new Map())
|
|
|
|
// Sync cache with external state: if external state has tuple
|
|
// entries, update the cache so that toggles preserve them.
|
|
useEffect(() => {
|
|
syncCacheFromGroups(groupOptionsCache.current, groups)
|
|
}, [groups])
|
|
|
|
const removeGroup = useCallback((currentGroups: GroupEntry[], groupName: string): GroupEntry[] => {
|
|
return removeGroupWithCache(groupOptionsCache.current, currentGroups, groupName)
|
|
}, [])
|
|
|
|
const addGroup = useCallback((currentGroups: GroupEntry[], groupName: ToolGroup): GroupEntry[] => {
|
|
return addGroupWithCache(groupOptionsCache.current, currentGroups, groupName)
|
|
}, [])
|
|
|
|
return { removeGroup, addGroup, cache: groupOptionsCache }
|
|
}
|