( permissionPromptToolName: string | undefined, structuredIO: StructuredIO, getMcpTools: () => Tool[], onPermissionPrompt?: (details: RequiresActionDetails) => void, )
| 4265 | // Exported for testing — regression: this used to crash at construction when |
| 4266 | // getMcpTools() was empty (before per-server connects populated appState). |
| 4267 | export function getCanUseToolFn( |
| 4268 | permissionPromptToolName: string | undefined, |
| 4269 | structuredIO: StructuredIO, |
| 4270 | getMcpTools: () => Tool[], |
| 4271 | onPermissionPrompt?: (details: RequiresActionDetails) => void, |
| 4272 | ): CanUseToolFn { |
| 4273 | if (permissionPromptToolName === 'stdio') { |
| 4274 | return structuredIO.createCanUseTool(onPermissionPrompt) |
| 4275 | } |
| 4276 | if (!permissionPromptToolName) { |
| 4277 | return async ( |
| 4278 | tool, |
| 4279 | input, |
| 4280 | toolUseContext, |
| 4281 | assistantMessage, |
| 4282 | toolUseId, |
| 4283 | forceDecision, |
| 4284 | ) => |
| 4285 | forceDecision ?? |
| 4286 | (await hasPermissionsToUseTool( |
| 4287 | tool, |
| 4288 | input, |
| 4289 | toolUseContext, |
| 4290 | assistantMessage, |
| 4291 | toolUseId, |
| 4292 | )) |
| 4293 | } |
| 4294 | // Lazy lookup: MCP connects are per-server incremental in print mode, so |
| 4295 | // the tool may not be in appState yet at init time. Resolve on first call |
| 4296 | // (first permission prompt), by which point connects have had time to finish. |
| 4297 | let resolved: CanUseToolFn | null = null |
| 4298 | return async ( |
| 4299 | tool, |
| 4300 | input, |
| 4301 | toolUseContext, |
| 4302 | assistantMessage, |
| 4303 | toolUseId, |
| 4304 | forceDecision, |
| 4305 | ) => { |
| 4306 | if (!resolved) { |
| 4307 | const mcpTools = getMcpTools() |
| 4308 | const permissionPromptTool = mcpTools.find(t => |
| 4309 | toolMatchesName(t, permissionPromptToolName), |
| 4310 | ) as PermissionPromptTool | undefined |
| 4311 | if (!permissionPromptTool) { |
| 4312 | const error = `Error: MCP tool ${permissionPromptToolName} (passed via --permission-prompt-tool) not found. Available MCP tools: ${mcpTools.map(t => t.name).join(', ') || 'none'}` |
| 4313 | process.stderr.write(`${error}\n`) |
| 4314 | gracefulShutdownSync(1) |
| 4315 | throw new Error(error) |
| 4316 | } |
| 4317 | if (!permissionPromptTool.inputJSONSchema) { |
| 4318 | const error = `Error: tool ${permissionPromptToolName} (passed via --permission-prompt-tool) must be an MCP tool` |
| 4319 | process.stderr.write(`${error}\n`) |
| 4320 | gracefulShutdownSync(1) |
| 4321 | throw new Error(error) |
| 4322 | } |
| 4323 | resolved = createCanUseToolWithPermissionPrompt(permissionPromptTool) |
| 4324 | } |
no test coverage detected