mirror of
https://github.com/windmill-labs/windmill.git
synced 2026-09-21 00:02:30 +00:00
feat: let plan mode search and read connected mcp servers (#11205)
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
a571117f3f
commit
5371519f0f
@@ -127,6 +127,12 @@ describe('read/write split', () => {
|
||||
expect(getTool('call_mcp_write_tool').requiresConfirmation).toBe(true)
|
||||
})
|
||||
|
||||
it('admits search and reads in plan mode, never writes', () => {
|
||||
expect(getTool('search_mcp_tools').planModeSafe).toBe(true)
|
||||
expect(getTool('call_mcp_read_tool').planModeSafe).toBe(true)
|
||||
expect(getTool('call_mcp_write_tool').planModeSafe).toBeFalsy()
|
||||
})
|
||||
|
||||
// The rejection sends the model to the write tool, which classifies from the
|
||||
// same cached listing: without dropping it, that retry is refused too and the
|
||||
// model has nowhere to go until the entry expires.
|
||||
|
||||
@@ -345,8 +345,9 @@ const callMcpToolSchema = z.object({
|
||||
|
||||
/**
|
||||
* The read and write call tools differ only in which side of the `readOnlyHint`
|
||||
* split they accept, and that check is what keeps a mutating call behind the
|
||||
* user's confirmation — building both from one body keeps them from drifting.
|
||||
* split they accept, and that check is what keeps a mutating call out of plan
|
||||
* mode and behind the user's confirmation — building both from one body keeps
|
||||
* them from drifting.
|
||||
*/
|
||||
function createCallTool(servers: McpServer[], mode: 'read' | 'write'): Tool<{}> {
|
||||
const isRead = mode === 'read'
|
||||
@@ -360,7 +361,7 @@ function createCallTool(servers: McpServer[], mode: 'read' | 'write'): Tool<{}>
|
||||
),
|
||||
showDetails: true,
|
||||
...(isRead
|
||||
? {}
|
||||
? { planModeSafe: true }
|
||||
: {
|
||||
requiresConfirmation: true,
|
||||
confirmationMessage: (args: any) => `Call ${args?.tool ?? ''} on ${args?.server ?? ''}`
|
||||
@@ -429,6 +430,7 @@ export function createMcpTools(servers: McpServer[]): Tool<{}>[] {
|
||||
'search_mcp_tools',
|
||||
'Search the tools exposed by the MCP servers connected to this workspace (listed in the system prompt). Returns server + tool names to pass to call_mcp_read_tool or call_mcp_write_tool, each with the input schema its arguments must follow.'
|
||||
),
|
||||
planModeSafe: true,
|
||||
fn: async ({ args, workspace, toolId, toolCallbacks }) => {
|
||||
const parsed = searchMcpToolsSchema.parse(args)
|
||||
toolCallbacks.setToolStatus(toolId, { content: 'Searching MCP tools...' })
|
||||
|
||||
Reference in New Issue
Block a user