Skip to main content
Glama

create_note_with_link

Create and publish a Substack note with an attached link that displays as a rich card below the text. Use this tool to share content with embedded URL previews.

Instructions

Create a Substack Note with a link attachment. The link is displayed as a rich card below the note text. Publishes immediately.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
bodyYesNote content in markdown format
urlYesURL to attach as a link card

Implementation Reference

  • src/server.ts:300-334 (registration)
    Tool registration for 'create_note_with_link' using server.tool() with Zod schema (body: string, url: string.url()) and async handler that orchestrates attachment creation and note publishing
    server.tool(
      "create_note_with_link",
      "Create a Substack Note with a link attachment. The link is displayed as a rich card below the note text. Publishes immediately.",
      {
        body: z.string().describe("Note content in markdown format"),
        url: z.string().url().describe("URL to attach as a link card"),
      },
      async ({ body, url }) => {
        const attachment = await client.createNoteAttachment(url);
        const bodyJson = {
          type: "doc" as const,
          attrs: { schemaVersion: "v1" as const },
          content: markdownToProseMirrorContent(body),
        };
        const note = await client.createNote(bodyJson, [attachment.id]);
        return {
          content: [
            {
              type: "text",
              text: JSON.stringify(
                {
                  id: note.id,
                  body: note.body,
                  date: note.date,
                  attachment_id: attachment.id,
                  message: "Note with link published successfully.",
                },
                null,
                2,
              ),
            },
          ],
        };
      },
    );
  • Handler function that: (1) creates link attachment via client.createNoteAttachment(url), (2) converts markdown to ProseMirror JSON format, (3) creates note with attachment via client.createNote(bodyJson, [attachment.id]), (4) returns JSON result with note id, body, date, and attachment_id
    async ({ body, url }) => {
      const attachment = await client.createNoteAttachment(url);
      const bodyJson = {
        type: "doc" as const,
        attrs: { schemaVersion: "v1" as const },
        content: markdownToProseMirrorContent(body),
      };
      const note = await client.createNote(bodyJson, [attachment.id]);
      return {
        content: [
          {
            type: "text",
            text: JSON.stringify(
              {
                id: note.id,
                body: note.body,
                date: note.date,
                attachment_id: attachment.id,
                message: "Note with link published successfully.",
              },
              null,
              2,
            ),
          },
        ],
      };
    },
  • createNoteAttachment method - makes POST request to /api/v1/comment/attachment with {url, type: 'link'} payload, returns NoteAttachment with id
    async createNoteAttachment(url: string): Promise<NoteAttachment> {
      return this.request<NoteAttachment>(
        `${this.publicationUrl}/api/v1/comment/attachment`,
        {
          method: "POST",
          body: JSON.stringify({ url, type: "link" }),
        },
      );
    }
  • createNote method - makes POST request to /api/v1/comment/feed with bodyJson, tabId, surface, replyMinimumRole, and optional attachmentIds
    async createNote(
      bodyJson: NoteCreatePayload["bodyJson"],
      attachmentIds?: string[],
    ): Promise<SubstackNote> {
      const payload: NoteCreatePayload = {
        bodyJson,
        tabId: "for-you",
        surface: "feed",
        replyMinimumRole: "everyone",
      };
      if (attachmentIds?.length) {
        payload.attachmentIds = attachmentIds;
      }
      return this.request<SubstackNote>(
        `${this.publicationUrl}/api/v1/comment/feed`,
        {
          method: "POST",
          body: JSON.stringify(payload),
        },
      );
    }
  • markdownToProseMirrorContent helper function - converts markdown text to ProseMirror content array format used for Notes
    export function markdownToProseMirrorContent(markdown: string): PMNode[] {
      const doc = JSON.parse(markdownToProseMirror(markdown));
      return doc.content;
    }

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/conorbronsdon/substack-mcp'

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