Skip to main content
Glama

notes

Search, retrieve, and create notes in the Apple Notes app through the Apple MCP server to manage your notes directly from Claude AI and Cursor.

Instructions

Search, retrieve and create notes in Apple Notes app

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
operationYesOperation to perform: 'search', 'list', or 'create'
searchTextNoText to search for in notes (required for search operation)
titleNoTitle of the note to create (required for create operation)
bodyNoContent of the note to create (required for create operation)
folderNameNoName of the folder to create the note in (optional for create operation, defaults to 'Claude')

Implementation Reference

  • Definition of the 'notes' tool including name, description, and input schema specifying operations: search, list, create.
    const NOTES_TOOL: Tool = { name: "notes", description: "Search, retrieve and create notes in Apple Notes app", inputSchema: { type: "object", properties: { operation: { type: "string", description: "Operation to perform: 'search', 'list', or 'create'", enum: ["search", "list", "create"] }, searchText: { type: "string", description: "Text to search for in notes (required for search operation)" }, title: { type: "string", description: "Title of the note to create (required for create operation)" }, body: { type: "string", description: "Content of the note to create (required for create operation)" }, folderName: { type: "string", description: "Name of the folder to create the note in (optional for create operation, defaults to 'Claude')" } }, required: ["operation"] } };
  • tools.ts:308-308 (registration)
    Registration of the NOTES_TOOL in the exported tools array for MCP server.
    const tools = [CONTACTS_TOOL, NOTES_TOOL, MESSAGES_TOOL, MAIL_TOOL, REMINDERS_TOOL, WEB_SEARCH_TOOL, CALENDAR_TOOL, MAPS_TOOL];
  • Helper function to retrieve all notes from the Apple Notes application (used for 'list' operation).
    async function getAllNotes() { const notes: Note[] = await run(() => { const Notes = Application('Notes'); const notes = Notes.notes(); return notes.map((note: any) => ({ name: note.name(), content: note.plaintext() })); }); return notes; }
  • Helper function to search for notes containing the given text in name or content (used for 'search' operation).
    async function findNote(searchText: string) { const notes: Note[] = await run((searchText: string) => { const Notes = Application('Notes'); const notes = Notes.notes.whose({_or: [ {name: {_contains: searchText}}, {plaintext: {_contains: searchText}} ]})() return notes.length > 0 ? notes.map((note: any) => ({ name: note.name(), content: note.plaintext() })) : []; }, searchText); if (notes.length === 0) { const allNotes = await getAllNotes(); const closestMatch = allNotes.find(({name}) => name.toLowerCase().includes(searchText.toLowerCase()) ); return closestMatch ? [{ name: closestMatch.name, content: closestMatch.content }] : []; } return notes; }
  • Helper function to create a new note with title, body, and optional folder (used for 'create' operation), handles folder creation for 'Claude'.
    async function createNote(title: string, body: string, folderName: string = 'Claude'): Promise<CreateNoteResult> { try { // Format the body with proper markdown const formattedBody = body .replace(/^(#+)\s+(.+)$/gm, '$1 $2\n') // Add newline after headers .replace(/^-\s+(.+)$/gm, '\n- $1') // Add newline before list items .replace(/\n{3,}/g, '\n\n') // Remove excess newlines .trim(); const result = await run((title: string, body: string, folderName: string) => { const Notes = Application('Notes'); // Create the note let targetFolder; let usedDefaultFolder = false; let actualFolderName = folderName; try { // Try to find the specified folder const folders = Notes.folders(); for (let i = 0; i < folders.length; i++) { if (folders[i].name() === folderName) { targetFolder = folders[i]; break; } } // If the specified folder doesn't exist if (!targetFolder) { if (folderName === 'Claude') { // Try to create the Claude folder if it doesn't exist Notes.make({new: 'folder', withProperties: {name: 'Claude'}}); usedDefaultFolder = true; // Find it again after creation const updatedFolders = Notes.folders(); for (let i = 0; i < updatedFolders.length; i++) { if (updatedFolders[i].name() === 'Claude') { targetFolder = updatedFolders[i]; break; } } } else { throw new Error(`Folder "${folderName}" not found`); } } // Create the note in the specified folder or default folder let newNote; if (targetFolder) { newNote = Notes.make({new: 'note', withProperties: {name: title, body: body}, at: targetFolder}); actualFolderName = folderName; } else { // Fall back to default folder newNote = Notes.make({new: 'note', withProperties: {name: title, body: body}}); actualFolderName = 'Default'; } return { success: true, note: { name: title, content: body }, folderName: actualFolderName, usedDefaultFolder: usedDefaultFolder }; } catch (scriptError) { throw new Error(`AppleScript error: ${scriptError.message || String(scriptError)}`); } }, title, formattedBody, folderName); return result; } catch (error) { return { success: false, message: `Failed to create note: ${error instanceof Error ? error.message : String(error)}` }; } }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/jxnl/apple-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server