bear_toggle_todo
Toggle the completion status of a specific TODO item in a Bear note, identified by its 1-based index.
Instructions
Toggle a specific TODO item in a Bear note between complete and incomplete. The item_index is 1-based — use bear_get_todos first to see the list with index numbers.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | Note ID (uniqueIdentifier) | |
| item_index | Yes | 1-based index of the TODO item to toggle |
Implementation Reference
- mcp-server/src/tools.ts:413-445 (registration)Registration and schema definition for bear_toggle_todo tool. Defines the tool metadata, input schema (id and item_index), annotations, and buildArgs that construct the CLI command: ['todo', id, '--toggle', item_index, '--json'].
bear_toggle_todo: { tool: { name: "bear_toggle_todo", description: "Toggle a specific TODO item in a Bear note between complete and incomplete. The item_index is 1-based — use bear_get_todos first to see the list with index numbers.", inputSchema: { type: "object" as const, properties: { id: { type: "string", description: "Note ID (uniqueIdentifier)", }, item_index: { type: "number", description: "1-based index of the TODO item to toggle", }, }, required: ["id", "item_index"], }, annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: false, }, }, buildArgs: (input) => [ "todo", String(input.id), "--toggle", String(input.item_index), "--json", ], }, - mcp-server/src/index.ts:33-121 (handler)Generic handler that dispatches all tool calls. When bear_toggle_todo is invoked, the handler looks up the tool by name from the tools registry, calls buildArgs to construct the CLI arguments, then executes the command via execBcliWithReauth (or execBcliWithStdinAndReauth). The result is parsed as JSON and returned.
server.setRequestHandler(CallToolRequestSchema, async (request) => { const { name, arguments: input } = request.params; const handler = tools[name]; if (!handler) { return { content: [{ type: "text", text: `Unknown tool: ${name}` }], isError: true, }; } const params = (input ?? {}) as Record<string, unknown>; // Validate bear_edit_note: need at least one edit operation if (name === "bear_edit_note") { const hasAppend = params.append_text !== undefined; const hasBody = params.body !== undefined; const hasSetFm = params.set_frontmatter !== undefined && Object.keys(params.set_frontmatter as object).length > 0; const hasRemoveFm = Array.isArray(params.remove_frontmatter) && (params.remove_frontmatter as unknown[]).length > 0; const hasFm = hasSetFm || hasRemoveFm; if (!hasAppend && !hasBody && !hasFm) { return { content: [ { type: "text", text: "Provide 'append_text', 'body', 'set_frontmatter', or 'remove_frontmatter'.", }, ], isError: true, }; } if (hasAppend && hasBody) { return { content: [ { type: "text", text: "Provide either 'append_text' or 'body', not both.", }, ], isError: true, }; } } try { const args = handler.buildArgs(params); let result: { stdout: string; stderr: string }; // Check if this tool needs stdin piping const stdinData = handler.usesStdin?.(params) ?? null; if (stdinData !== null) { result = await execBcliWithStdinAndReauth(args, stdinData); } else { result = await execBcliWithReauth(args); } // Parse JSON output from bcli const stdout = result.stdout.trim(); if (!stdout) { return { content: [{ type: "text", text: "Command completed successfully." }], }; } // Validate it's JSON and pretty-print try { const parsed = JSON.parse(stdout); return { content: [ { type: "text", text: JSON.stringify(parsed, null, 2) }, ], }; } catch { // If bcli returned non-JSON, pass it through return { content: [{ type: "text", text: stdout }], }; } } catch (error) { const message = error instanceof BcliError ? error.message : String(error); return { content: [{ type: "text", text: message }], isError: true, }; } - mcp-server/src/bcli.ts:256-268 (helper)The execBcliWithReauth function is the execution helper that runs the bcli CLI command. For bear_toggle_todo, it executes: bcli todo <id> --toggle <item_index> --json. If auth fails, it automatically triggers re-authentication and retries.
export async function execBcliWithReauth( args: string[], ): Promise<{ stdout: string; stderr: string }> { try { return await execBcli(args); } catch (error) { if (error instanceof AuthError) { await performReauth(); return await execBcli(args); } throw error; } } - mcp-server/src/tools.ts:418-431 (schema)Input schema for bear_toggle_todo: requires 'id' (string, note uniqueIdentifier) and 'item_index' (number, 1-based index of the TODO item to toggle).
inputSchema: { type: "object" as const, properties: { id: { type: "string", description: "Note ID (uniqueIdentifier)", }, item_index: { type: "number", description: "1-based index of the TODO item to toggle", }, }, required: ["id", "item_index"], },