get_user_decision
Request user decisions remotely during AFK mode by sending prompts for confirmations, choices, text input, or code diff approvals to mobile devices.
Instructions
Sends a decision request to the mobile client and blocks until the user responds or timeout expires. Only call when AFK mode is active. Use type 'confirm' for yes/no, 'choice' for selecting from options, 'text' for free-text input, 'diff' for approving code changes.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| sessionId | Yes | The session ID | |
| prompt | Yes | The question for the user | |
| type | Yes | The type of decision | |
| options | No | For "choice" type: list of options | |
| diff | No | For "diff" type: file diff information | |
| defaultValue | No | Default value used if timeout fires | |
| timeoutSeconds | No | Timeout in seconds (default: 300) |
Implementation Reference
- src/server/mcp-tools.ts:167-211 (handler)Main handler function for get_user_decision tool. Creates a decision request, sends it to the mobile client via WebSocket, and blocks until the user responds or timeout expires. Returns { decision: string | null, timedOut: boolean }.
async (args) => { const id = crypto.randomUUID(); const timestamp = new Date().toISOString(); const timeoutMs = (args.timeoutSeconds ?? 300) * 1000; const result = await new Promise<{ decision: string | null; timedOut: boolean; }>((resolve) => { const timer = setTimeout(() => { const session = getSession(); session.pendingDecisions.delete(id); clearCurrentDecision(id); resolve({ decision: args.defaultValue ?? null, timedOut: true }); }, timeoutMs); addPendingDecision({ id, resolve, timer }); const request: DecisionRequestMessage = { type: "decision_request", id, timestamp, prompt: args.prompt, decisionType: args.type, options: args.options ?? null, diff: args.diff ?? null, defaultValue: args.defaultValue ?? null, timeoutSeconds: args.timeoutSeconds ?? 300, }; sendDecisionRequest(request); // Push notification for decision requests sendPushNotification("🔔 Decision Needed", args.prompt); }); return { content: [ { type: "text" as const, text: JSON.stringify(result), }, ], }; }, - src/server/mcp-tools.ts:138-166 (schema)Zod schema definition for get_user_decision input parameters. Defines sessionId, prompt, type (confirm/choice/text/diff), options, diff, defaultValue, and timeoutSeconds with validation rules.
{ sessionId: z.string().describe("The session ID"), prompt: z.string().describe("The question for the user"), type: z.enum(["confirm", "choice", "text", "diff"]).describe("The type of decision"), options: z .array(z.string()) .nullable() .optional() .describe('For "choice" type: list of options'), diff: z .object({ filePath: z.string(), before: z.string(), after: z.string(), }) .nullable() .optional() .describe('For "diff" type: file diff information'), defaultValue: z .string() .nullable() .optional() .describe("Default value used if timeout fires"), timeoutSeconds: z .number() .optional() .default(300) .describe("Timeout in seconds (default: 300)"), }, - src/server/mcp-tools.ts:135-136 (registration)Tool registration with MCP server using server.tool() method. Registers the tool name 'get_user_decision' with its description and handler.
server.tool( "get_user_decision", - src/shared/types.ts:108-116 (schema)TypeScript interface GetUserDecisionInput defining the type-safe input structure for the tool, including sessionId, prompt, type, options, diff, defaultValue, and timeoutSeconds.
export interface GetUserDecisionInput { sessionId: string; prompt: string; type: DecisionType; options?: string[] | null; diff?: DiffInfo | null; defaultValue?: string | null; timeoutSeconds?: number; } - src/server/session.ts:85-87 (helper)Helper function addPendingDecision that stores the pending decision request in the session's pendingDecisions Map, allowing the WebSocket handler to resolve it when the user responds.
export function addPendingDecision(pending: PendingDecision): void { getSession().pendingDecisions.set(pending.id, pending); }