Skip to main content
Glama

notes_create

Create formatted Apple Notes with markdown-like syntax for headings, bold, italic, lists, and links directly from macOS applications.

Instructions

[Apple Notes operations] Create a new note with optional formatting

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
titleYesTitle of the note
contentYesContent of the note, can include markdown-like syntax for formatting
formatNoFormatting options for the note content

Implementation Reference

  • The core handler function for the 'notes_create' tool. It extracts title, content, and format from arguments, generates formatted HTML content, and returns the AppleScript code to create a new note in the Apple Notes app.
    script: (args) => {
      const { title = "New Note", content = "", format = {} } = args;
      const htmlContent = generateNoteHtml(args);
      
      return `
        tell application "Notes"
          make new note with properties {body:"${htmlContent}", name:"${title}"}
        end tell
      `;
  • Input schema defining parameters for the notes_create tool: title (string), content (string), and optional format object with booleans for various markdown-like formatting options. Requires title and content.
    schema: {
      type: "object",
      properties: {
        title: {
          type: "string",
          description: "Title of the note"
        },
        content: {
          type: "string",
          description: "Content of the note, can include markdown-like syntax for formatting"
        },
        format: {
          type: "object",
          description: "Formatting options for the note content",
          properties: {
            headings: {
              type: "boolean",
              description: "Enable heading formatting (# Heading)"
            },
            bold: {
              type: "boolean",
              description: "Enable bold formatting (**text**)"
            },
            italic: {
              type: "boolean",
              description: "Enable italic formatting (*text*)"
            },
            underline: {
              type: "boolean",
              description: "Enable underline formatting (~text~)"
            },
            links: {
              type: "boolean",
              description: "Enable link formatting ([text](url))"
            },
            lists: {
              type: "boolean",
              description: "Enable list formatting (- item or 1. item)"
            }
          }
        }
      },
      required: ["title", "content"]
    }
  • Helper function that converts plain text or markdown-like content into formatted HTML based on the format options provided in args. Used by the notes_create handler to process note content.
    function generateNoteHtml(args: any): string {
      const {
        title = "New Note",
        content = "",
        format = {
          headings: false,
          bold: false,
          italic: false,
          underline: false,
          links: false,
          lists: false
        }
      } = args;
    
      // Process content based on format options
      let processedContent = content;
      
      // If content contains markdown-like syntax and formatting is enabled, convert it
      if (format.headings) {
        // Convert # Heading to <h1>Heading</h1>, ## Heading to <h2>Heading</h2>, etc.
        processedContent = processedContent.replace(/^# (.+)$/gm, '<h1>$1</h1>');
        processedContent = processedContent.replace(/^## (.+)$/gm, '<h2>$1</h2>');
        processedContent = processedContent.replace(/^### (.+)$/gm, '<h3>$1</h3>');
      }
      
      if (format.bold) {
        // Convert **text** or __text__ to <b>text</b>
        processedContent = processedContent.replace(/\*\*(.+?)\*\*/g, '<b>$1</b>');
        processedContent = processedContent.replace(/__(.+?)__/g, '<b>$1</b>');
      }
      
      if (format.italic) {
        // Convert *text* or _text_ to <i>text</i>
        processedContent = processedContent.replace(/\*(.+?)\*/g, '<i>$1</i>');
        processedContent = processedContent.replace(/_(.+?)_/g, '<i>$1</i>');
      }
      
      if (format.underline) {
        // Convert ~text~ to <u>text</u>
        processedContent = processedContent.replace(/~(.+?)~/g, '<u>$1</u>');
      }
      
      if (format.links) {
        // Convert [text](url) to <a href="url">text</a>
        processedContent = processedContent.replace(/\[(.+?)\]\((.+?)\)/g, '<a href="$2">$1</a>');
      }
      
      if (format.lists) {
        // Handle unordered lists
        // Look for lines starting with - or * and convert to <li> items
        const listItems = processedContent.match(/^[*-] (.+)$/gm);
        if (listItems) {
          let listHtml = '<ul>';
          for (const item of listItems) {
            const content = item.replace(/^[*-] /, '');
            listHtml += `<li>${content}</li>`;
          }
          listHtml += '</ul>';
          
          // Replace the original list items with the HTML list
          for (const item of listItems) {
            processedContent = processedContent.replace(item, '');
          }
          processedContent = processedContent.replace(/\n+/g, '\n') + listHtml;
        }
        
        // Handle ordered lists (1. Item)
        const orderedItems = processedContent.match(/^\d+\. (.+)$/gm);
        if (orderedItems) {
          let listHtml = '<ol>';
          for (const item of orderedItems) {
            const content = item.replace(/^\d+\. /, '');
            listHtml += `<li>${content}</li>`;
          }
          listHtml += '</ol>';
          
          // Replace the original list items with the HTML list
          for (const item of orderedItems) {
            processedContent = processedContent.replace(item, '');
          }
          processedContent = processedContent.replace(/\n+/g, '\n') + listHtml;
        }
      }
      
      // Wrap paragraphs in <p> tags if they aren't already wrapped in HTML tags
      const paragraphs = processedContent.split('\n\n');
      processedContent = paragraphs
        .map((p: string) => {
          if (p.trim() && !p.trim().startsWith('<')) {
            return `<p>${p}</p>`;
          }
          return p;
        })
        .join('\n');
      
      return processedContent;
    }
  • Registration of tool listing handler which dynamically generates tool names as '{category.name}_{script.name}', resulting in 'notes_create' for the notes category's create script. This is how the tool is exposed in MCP.
    this.server.setRequestHandler(ListToolsRequestSchema, async () => ({
      tools: this.categories.flatMap((category) =>
        category.scripts.map((script) => ({
          name: `${category.name}_${script.name}`, // Changed from dot to underscore
          description: `[${category.description}] ${script.description}`,
          inputSchema: script.schema || {
            type: "object",
            properties: {},
          },
        })),
      ),
    }));
  • src/index.ts:12-35 (registration)
    Import and registration of the notesCategory, which contains the 'create' script, making it available to the framework for tool generation as 'notes_create'.
    import { notesCategory } from "./categories/notes.js";
    
    const server = new AppleScriptFramework({
      name: "applescript-server",
      version: "1.0.4",
      debug: false,
    });
    
    // Log startup information using stderr (server isn't connected yet)
    console.error(`[INFO] Starting AppleScript MCP server - PID: ${process.pid}`);
    
    // Add all categories
    console.error("[INFO] Registering categories...");
    server.addCategory(systemCategory);
    server.addCategory(calendarCategory);
    server.addCategory(finderCategory);
    server.addCategory(clipboardCategory);
    server.addCategory(notificationsCategory);
    server.addCategory(itermCategory);
    server.addCategory(mailCategory);
    server.addCategory(pagesCategory);
    server.addCategory(shortcutsCategory);
    server.addCategory(messagesCategory);
    server.addCategory(notesCategory);

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/joshrutkowski/applescript-mcp'

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