create_note
Create Note. Create a new note draft or ready note.
| Group | Access | MCP name |
|---|---|---|
| Notes | Writes data | create_note |
Description
The description the MCP server sends to the model, word for word. Its rules apply to every call.
Create a new note draft or ready note. The content body must be in Markdown format. When generating new note content (not when the user already provided the full body), call get_writing_style first unless they pasted complete style instructions. If the content includes a link (https:// URL or bare domain like example.com), ask the user if they'd like a link preview before calling this tool; pass includePreviews: true only if they confirm. Prefer full https:// URLs in the content. To attach images, pass imageUrl as an array of remote image URLs (max 5) — WriteStack fetches and stores them like CSV import. You can also enable auto-restack by passing autoRestackAfterHours (1–168 hours) — the note will automatically be restacked that many hours after it's published. To cross-post to Buffer, call list_buffer_channels first and pass bufferChannelIds and/or bufferChannelPosts (per-channel text and images). Tags you assign also decide which reserved queue times this note can take later (OR match; untagged notes only use open or untagged-only times). Very important: New line MUST be with double newlines (
).
Arguments
| Argument | Type | Required | Description |
|---|---|---|---|
autoRestackAfterHours | integer | null | No | Optional auto-restack delay in hours (1–168). If set, after the note is published WriteStack will automatically restack (re-post) it the given number of hours later to boost visibility. Pass null or omit to disable auto-restack on the note. Requires the WriteStack browser extension v1.4.78 or higher to actually fire. Min 1. Max 168. |
bufferChannelIds | string[] | No | Optional array of Buffer channel IDs to cross-post this new note to once it publishes on Substack. Call list_buffer_channels first to get the valid IDs — only IDs returned by that tool are accepted. Maximum 20 channels per note — requests with more are rejected. Channel IDs from bufferChannelPosts are merged in automatically. Omit or pass an empty array to skip Buffer cross-posting unless you also pass bufferChannelPosts. Requires a connected Buffer account. Platform limits still apply: Instagram requires an image or video, and Instagram feed images must be between 4:5 and 1.91:1 aspect ratio for automatic posting (otherwise Buffer falls back to Notify Me). See https://support.buffer.com/article/622-instagrams-accepted-aspect-ratio-ranges |
bufferChannelPosts | object[] | No | Optional per-channel Buffer post overrides when a channel should have different text or images than the Substack note. Call list_buffer_channels first. Each item needs bufferChannelId and, unless reset is true, a plain-text body (max 5000). Those channel IDs are also selected on the note (merged with bufferChannelIds, still max 20). imageUrl attaches images to that channel only — they are not added to the Substack note. Omit imageUrl to keep existing channel images; pass [] to clear them. includePreviews adds a link card from the first URL in that channel's body (max 1). reset: true deletes the override so the channel falls back to the note. Removing a channel from bufferChannelIds does not delete a saved override. Platform limits still apply: Instagram requires an image or video, and Instagram feed images must be between 4:5 and 1.91:1 aspect ratio for automatic posting (otherwise Buffer falls back to Notify Me). See https://support.buffer.com/article/622-instagrams-accepted-aspect-ratio-ranges Max items 20. |
bufferChannelPosts[].body | string | No | Plain-text override for this channel (max 5000). Required unless reset is true. This is what Buffer publishes for this channel instead of the Substack note. Max length 5000. |
bufferChannelPosts[].bufferChannelId | string | Yes | Buffer channel ID from list_buffer_channels |
bufferChannelPosts[].imageUrl | string[] | No | Remote image URLs for this channel only (max 5). WriteStack fetches and stores them. They are not added to the Substack note. Omit to keep existing channel images; pass [] to clear them. Max items 5. |
bufferChannelPosts[].includePreviews | boolean | No | If true, attach a rich link-preview card from the first URL in this channel's body. Max 1 preview per channel. |
bufferChannelPosts[].reset | boolean | No | If true, delete this channel's custom post so it falls back to the Substack note. The channel stays selected. |
content | string | Yes | The note body text |
imageUrl | string[] | No | Optional remote image URLs to attach to the note (same as CSV import image_url). WriteStack fetches each URL and stores the image. Max 5. Pass full https:// URLs. Invalid or unreachable URLs are skipped. Max items 5. |
includePreviews | boolean | No | If the note's content contains a link (full https:// URL or bare domain like writestack.io), ask the user whether they want a rich link-preview card (image, title, description) attached before creating/updating the note - do not assume yes. If they confirm, pass includePreviews: true. Prefer writing links as full https:// URLs in the content so previews resolve reliably. Only one preview can be attached per note; if there are multiple links, the first link in the content is used. |
status | string | No | Note status One of: "draft", "ready". Default "draft". |
tags | string[] | No | Category/tag names to assign. Tags also decide which reserved queue times this note can take: a note matches a reserved slot if it shares ANY of the slot's tags. Untagged notes only use open or untagged-only times. Call list_tags first to show available names. |
Example call
The smallest valid request: required arguments only, with placeholder values.
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "create_note",
"arguments": {
"content": "…"
}
}
}Result
The result has structuredContent that matches this schema. The same data is also in content as JSON text.
| Field | Type | Required | Description |
|---|---|---|---|
attachments | any[] | No | |
autoRestackAfterHours | number | null | Yes | |
bufferChannelIds | string[] | No | |
bufferChannelPosts | object[] | No | |
bufferChannelPosts[].attachments | object[] | Yes | |
bufferChannelPosts[].attachments[].type | string | Yes | |
bufferChannelPosts[].attachments[].url | string | Yes | |
bufferChannelPosts[].body | string | Yes | |
bufferChannelPosts[].bufferChannelId | string | Yes | |
bufferChannelPosts[].reset | boolean | No | |
linkPreview | object | No | |
linkPreview.added | boolean | Yes | |
linkPreview.reason | string | No | |
linkPreview.url | string | No | |
message | string | Yes | |
noteId | string | Yes | |
status | string | Yes |
Annotations
| Hint | Value |
|---|---|
readOnlyHint | false |
destructiveHint | false |
openWorldHint | true |
The full input and output JSON Schemas for every tool are in /mcp-tools.json.