bear_attach_file
Attach a file or image to a Bear note, uploading to iCloud and embedding in markdown. Control placement: append, prepend, or insert before or after specific text.
Instructions
Attach a file or image to an existing Bear note. The file is uploaded to iCloud and embedded in the note's markdown. Supports common image formats (jpg, png, gif, webp, heic) and other file types (pdf, zip, etc.). By default the attachment is appended to the end. Use 'after' or 'before' to place it relative to text in the note, or 'prepend' to put it right after the title.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | Note ID (uniqueIdentifier) | |
| file_path | Yes | Absolute path to the file to attach | |
| after | No | Insert after the line containing this text | |
| before | No | Insert before the line containing this text | |
| prepend | No | Insert after the title line instead of at the end |
Implementation Reference
- mcp-server/src/tools.ts:447-500 (registration)The 'bear_attach_file' tool is registered in the tools record. It defines the tool name, description, inputSchema (id, file_path, after, before, prepend), and the buildArgs() function that constructs the CLI args array for the 'bcli attach' command.
bear_attach_file: { tool: { name: "bear_attach_file", description: "Attach a file or image to an existing Bear note. The file is uploaded to iCloud and embedded in the note's markdown. Supports common image formats (jpg, png, gif, webp, heic) and other file types (pdf, zip, etc.). By default the attachment is appended to the end. Use 'after' or 'before' to place it relative to text in the note, or 'prepend' to put it right after the title.", inputSchema: { type: "object" as const, properties: { id: { type: "string", description: "Note ID (uniqueIdentifier)", }, file_path: { type: "string", description: "Absolute path to the file to attach", }, after: { type: "string", description: "Insert after the line containing this text", }, before: { type: "string", description: "Insert before the line containing this text", }, prepend: { type: "boolean", description: "Insert after the title line instead of at the end", }, }, required: ["id", "file_path"], }, annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: false, }, }, buildArgs: (input) => { const args = [ "attach", String(input.id), String(input.file_path), "--json", ]; if (input.after) args.push("--after", String(input.after)); if (input.before) args.push("--before", String(input.before)); if (input.prepend) args.push("--prepend"); return args; }, }, - mcp-server/src/tools.ts:488-499 (handler)The handler logic for bear_attach_file: buildArgs constructs the CLI command 'attach <id> <file_path> --json' with optional --after, --before, and --prepend flags. The actual execution is in index.ts via execBcliWithReauth.
buildArgs: (input) => { const args = [ "attach", String(input.id), String(input.file_path), "--json", ]; if (input.after) args.push("--after", String(input.after)); if (input.before) args.push("--before", String(input.before)); if (input.prepend) args.push("--prepend"); return args; }, - mcp-server/src/tools.ts:452-481 (schema)The input schema for bear_attach_file. Requires 'id' (string) and 'file_path' (string). Optional fields: 'after' (string), 'before' (string), 'prepend' (boolean).
inputSchema: { type: "object" as const, properties: { id: { type: "string", description: "Note ID (uniqueIdentifier)", }, file_path: { type: "string", description: "Absolute path to the file to attach", }, after: { type: "string", description: "Insert after the line containing this text", }, before: { type: "string", description: "Insert before the line containing this text", }, prepend: { type: "boolean", description: "Insert after the title line instead of at the end", }, }, required: ["id", "file_path"], }, - mcp-server/src/index.ts:33-121 (handler)The generic tool handler in index.ts that dispatches all tools including bear_attach_file. It calls handler.buildArgs(params) and then execBcliWithReauth to run the 'bcli' command.
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, }; }