mirror of
https://github.com/RooVetGit/Roo-Code.git
synced 2026-09-07 08:26:51 +00:00
fix: update MCP configuration to use direct object format in YAML
- Updated schema to accept { mcp: { included: [...] } } directly as a GroupEntry
- Modified McpSelector to create the direct object format instead of tuple
- Updated getGroupName and getGroupOptions helpers to handle the new format
- Updated MCP server section to properly extract included list from both formats
This resolves the nested array issue in YAML generation when toggling MCP
checkbox and selecting specific servers. The YAML now correctly generates:
- mcp:
included: [...]
Instead of the previous nested structure.
This commit is contained in:
parent
7e92618e43
commit
b223d71a7f
5 changed files with 77 additions and 49 deletions
|
|
@ -40,7 +40,17 @@ export type GroupOptions = z.infer<typeof groupOptionsSchema>
|
|||
* GroupEntry
|
||||
*/
|
||||
|
||||
export const groupEntrySchema = z.union([toolGroupsSchema, z.tuple([toolGroupsSchema, groupOptionsSchema])])
|
||||
export const groupEntrySchema = z.union([
|
||||
toolGroupsSchema,
|
||||
z.tuple([toolGroupsSchema, groupOptionsSchema]),
|
||||
// Allow direct mcp configuration object
|
||||
z.object({
|
||||
mcp: z.object({
|
||||
included: z.array(z.string()),
|
||||
description: z.string().optional(),
|
||||
}),
|
||||
}),
|
||||
])
|
||||
|
||||
export type GroupEntry = z.infer<typeof groupEntrySchema>
|
||||
|
||||
|
|
|
|||
|
|
@ -54,18 +54,34 @@ export async function getMcpServersSection(
|
|||
if (currentMode) {
|
||||
// Find MCP group configuration
|
||||
const mcpGroup = currentMode.groups.find((group: GroupEntry) => {
|
||||
// Handle tuple format: ["mcp", { mcp: { included: [...] } }]
|
||||
if (Array.isArray(group) && group.length === 2 && group[0] === "mcp") {
|
||||
return true
|
||||
}
|
||||
// Handle direct object format: { mcp: { included: [...] } }
|
||||
if (typeof group === "object" && !Array.isArray(group) && "mcp" in group) {
|
||||
return true
|
||||
}
|
||||
return getGroupName(group) === "mcp"
|
||||
})
|
||||
|
||||
// If MCP group configuration is found, get mcpIncludedList from mcp.included
|
||||
if (mcpGroup && Array.isArray(mcpGroup) && mcpGroup.length === 2) {
|
||||
const options = mcpGroup[1] as { mcp?: { included?: unknown[] } }
|
||||
mcpIncludedList = Array.isArray(options.mcp?.included)
|
||||
? options.mcp.included.filter((item: unknown): item is string => typeof item === "string")
|
||||
: undefined
|
||||
// Extract mcpIncludedList based on the format
|
||||
if (mcpGroup) {
|
||||
let mcpOptions: { mcp?: { included?: unknown[] } } | undefined
|
||||
|
||||
if (Array.isArray(mcpGroup) && mcpGroup.length === 2) {
|
||||
// Tuple format
|
||||
mcpOptions = mcpGroup[1] as { mcp?: { included?: unknown[] } }
|
||||
} else if (typeof mcpGroup === "object" && !Array.isArray(mcpGroup) && "mcp" in mcpGroup) {
|
||||
// Direct object format
|
||||
mcpOptions = mcpGroup as { mcp?: { included?: unknown[] } }
|
||||
}
|
||||
|
||||
if (mcpOptions) {
|
||||
mcpIncludedList = Array.isArray(mcpOptions.mcp?.included)
|
||||
? mcpOptions.mcp.included.filter((item: unknown): item is string => typeof item === "string")
|
||||
: undefined
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -77,7 +93,7 @@ export async function getMcpServersSection(
|
|||
connectedServers = `${filteredServers
|
||||
.map((server) => {
|
||||
const tools = server.tools
|
||||
?.filter((tool) => tool.enabledForPrompt !== false)
|
||||
?.filter((tool) => tool.enabledForPrompt !== false)
|
||||
?.map((tool) => {
|
||||
const schemaStr = tool.inputSchema
|
||||
? ` Input Schema:
|
||||
|
|
|
|||
|
|
@ -23,13 +23,26 @@ export function getGroupName(group: GroupEntry): ToolGroup {
|
|||
if (typeof group === "string") {
|
||||
return group
|
||||
}
|
||||
|
||||
return group[0]
|
||||
if (Array.isArray(group)) {
|
||||
return group[0]
|
||||
}
|
||||
// Handle direct MCP object format
|
||||
if (typeof group === "object" && "mcp" in group) {
|
||||
return "mcp" as ToolGroup
|
||||
}
|
||||
return group as ToolGroup
|
||||
}
|
||||
|
||||
// Helper to get group options if they exist
|
||||
function getGroupOptions(group: GroupEntry): GroupOptions | undefined {
|
||||
return Array.isArray(group) ? group[1] : undefined
|
||||
if (Array.isArray(group)) {
|
||||
return group[1]
|
||||
}
|
||||
// Handle direct MCP object format - return the object itself as options
|
||||
if (typeof group === "object" && "mcp" in group) {
|
||||
return group as GroupOptions
|
||||
}
|
||||
return undefined
|
||||
}
|
||||
|
||||
// Helper to check if a file path matches a regex pattern
|
||||
|
|
|
|||
|
|
@ -69,45 +69,28 @@ const McpSelector: React.FC<McpSelectorProps> = ({
|
|||
setMcpIncludedList(included)
|
||||
}, [currentMode])
|
||||
// Handle save
|
||||
function updateMcpGroupOptions(groups: GroupEntry[] = [], group: string, mcpIncludedList: string[]): GroupEntry[] {
|
||||
let mcpGroupFound = false
|
||||
const newGroups = groups
|
||||
.map((g) => {
|
||||
if (Array.isArray(g) && g[0] === group) {
|
||||
mcpGroupFound = true
|
||||
return [
|
||||
group,
|
||||
{
|
||||
...(g[1] || {}),
|
||||
mcp: mcpIncludedList.length > 0 ? { included: mcpIncludedList } : undefined,
|
||||
},
|
||||
] as GroupEntry
|
||||
}
|
||||
if (typeof g === "string" && g === group) {
|
||||
mcpGroupFound = true
|
||||
return [
|
||||
group,
|
||||
{
|
||||
mcp: mcpIncludedList.length > 0 ? { included: mcpIncludedList } : undefined,
|
||||
},
|
||||
] as GroupEntry
|
||||
}
|
||||
return g
|
||||
})
|
||||
.filter((g) => g !== undefined)
|
||||
function updateMcpGroupOptions(groups: GroupEntry[] = [], _group: string, mcpIncludedList: string[]): GroupEntry[] {
|
||||
// Filter out any existing "mcp" entries (both string and object forms)
|
||||
const filteredGroups = groups.filter((g) => {
|
||||
if (typeof g === "string") {
|
||||
return g !== "mcp"
|
||||
}
|
||||
if (Array.isArray(g) && g[0] === "mcp") {
|
||||
return false
|
||||
}
|
||||
if (typeof g === "object" && g !== null && !Array.isArray(g) && "mcp" in g) {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
})
|
||||
|
||||
if (!mcpGroupFound && group === "mcp") {
|
||||
const groupsWithoutSimpleMcp = newGroups.filter((g) => g !== "mcp")
|
||||
groupsWithoutSimpleMcp.push([
|
||||
"mcp",
|
||||
{
|
||||
mcp: mcpIncludedList.length > 0 ? { included: mcpIncludedList } : undefined,
|
||||
},
|
||||
])
|
||||
return groupsWithoutSimpleMcp as GroupEntry[]
|
||||
} else {
|
||||
return newGroups as GroupEntry[]
|
||||
// Add the new MCP configuration if there are selected servers
|
||||
if (mcpIncludedList.length > 0) {
|
||||
// Directly add the mcp object without wrapping in an array
|
||||
return [...filteredGroups, { mcp: { included: mcpIncludedList } }] as GroupEntry[]
|
||||
}
|
||||
|
||||
return filteredGroups as GroupEntry[]
|
||||
}
|
||||
|
||||
// Handle save
|
||||
|
|
|
|||
|
|
@ -62,7 +62,13 @@ type ModesViewProps = {
|
|||
|
||||
// Helper to get group name regardless of format
|
||||
function getGroupName(group: GroupEntry): ToolGroup {
|
||||
return Array.isArray(group) ? group[0] : group
|
||||
if (Array.isArray(group)) {
|
||||
return group[0]
|
||||
}
|
||||
if (typeof group === "object" && "mcp" in group) {
|
||||
return "mcp" as ToolGroup
|
||||
}
|
||||
return group as ToolGroup
|
||||
}
|
||||
|
||||
const ModesView = ({ onDone }: ModesViewProps) => {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue