Skills Plugins MCP Prompt Model 博客 我的中心

publish-substack-article

Publish Markdown articles to Substack as drafts. Use when user wants to publish a Markdown file to Substack, or mentions "发布到 Substack", "Substack article", "publish to Substack". Handles Markdown-to-HTML conversion and saves as draft (never auto-publish).

DeepseekModel キュレーション済みスキル 品質 優秀 · 78 v1.0.0

取得

https://deepseekmodel.com/api/download.php?id=sugarforever-01coder-agent-skills-skills-publish-substack-article-skill-md&format=skill
ダウンロード .skill 標準形式。system_prompt と model_config を収録し、任意の Agent で利用可能
.skill ファイルの system_prompt フィールドの実際の内容。
name publish-substack-article description Publish Markdown articles to Substack as drafts. Use when user wants to publish a Markdown file to Substack, or mentions "发布到 Substack", "Substack article", "publish to Substack". Handles Markdown-to-HTML conversion and saves as draft (never auto-publish). Publish Substack Article Publish Markdown content to Substack post editor, converting Markdown to HTML and pasting as rich text. Saves as draft for user review before publishing. Prerequisites Browser automation MCP (either one): Chrome DevTools MCP ( mcp__chrome-devtools__* ) Playwright MCP ( mcp__playwright__* ) User logged into Substack Python 3 with markdown package ( pip install markdown ) copy_to_clipboard.py script (shared from publish-zsxq-article skill) Browser MCP Tool Mapping This skill works with both Chrome DevTools MCP and Playwright MCP: Action Chrome DevTools MCP Playwright MCP Navigate navigate_page browser_navigate Take snapshot take_snapshot browser_snapshot Take screenshot take_screenshot browser_take_screenshot Click element click browser_click Fill text fill browser_type Upload file upload_file browser_file_upload Press key press_key browser_press_key Evaluate JS evaluate_script browser_evaluate Priority : Default to Playwright MCP . Use Chrome DevTools MCP only when Playwright MCP is unavailable. Detection : At runtime, prefer mcp__playwright__browser_navigate . Fall back to mcp__chrome-devtools__navigate_page only if Playwright tools are not available. Key URLs Substack dashboard: https://{publication}.substack.com/publish Post editor: https://{publication}.substack.com/publish/post/{postId} Publication Resolution The Substack publication subdomain (e.g., verysmallwoods in verysmallwoods.substack.com ) is required to navigate to the dashboard. Do not hardcode a default. Before any navigation, resolve the publication in this order: Skill argument — if the user invoked the skill with a publication subdomain, use it. Environment variable — check SUBSTACK_PUBLICATION (optional, for users who publish repeatedly to the same publication). Prompt the user if neither is available: 请提供 Substack publication subdomain(例如 verysmallwoods.substack.com 里的 verysmallwoods )。 Do not proceed to Step 3 (Navigate) without a resolved publication subdomain. Editor Interface The Substack post editor uses Tiptap (ProseMirror-based WYSIWYG editor). Key Elements Title input: textbox "title" (placeholder: "Title") Subtitle input: textbox "Add a subtitle…" Content area: .ProseMirror (Tiptap editor, "Start writing...") Save status: button "Saved" (auto-saves) Preview button: button "Preview" Continue button: button "Continue" (publish flow - DO NOT USE) Settings sidebar: button "Settings" (title, description, thumbnail) Settings Sidebar (left panel) When "Settings" or "File Settings" is open: Title: textbox "Add a title..." Description: textbox "Add a description..." Thumbnail: Upload button (3:2 aspect ratio) Toolbar Bold, Italic, Strikethrough, Code, Link, Image, Audio, Video, Quote, Lists (bullet/ordered), Button, More (Code block, Divider, Footnote, LaTeX, etc.) Content Insertion Method CRITICAL: Use clipboard paste with HTML content , NOT direct fill or plain Markdown paste. The Tiptap editor handles HTML paste natively and renders it as rich content. The workflow is: Convert Markdown to HTML using Python's markdown library Copy HTML to system clipboard using copy_to_clipboard.py html Focus the editor content area Press Cmd+V (macOS) or Ctrl+V (Windows/Linux) to paste Why HTML paste? fill tool → Content treated as plain text, no formatting Plain Markdown paste → Tiptap does NOT parse Markdown on paste HTML paste → Tiptap renders HTML as rich content (headings, code blocks, links, bold, etc.) Known limitation : Substack's editor does NOT support HTML tables. Tables will be collapsed into plain text. See Step 0: Pre-Processing for converting tables to images. Main Workflow Step 0: Pre-Processing — Convert Tables to Images Substack does NOT render HTML tables. They collapse into plain text. Any Markdown table must be converted to a PNG image and uploaded separately. Workflow: Detect tables in the Markdown file (lines with | forming table structure) Convert each table to PNG using the diagram-to-image skill: # Extract table to temp file cat > /tmp/table1.md << 'TABLE_EOF' | Column 1 | Column 2 | Column 3 | |----------|----------|----------| | Data 1 | Data 2 | Data 3 | TABLE_EOF # Convert via diagramless.xyz API (auto-detects as table) node ~/.claude/skills/diagram-to-image/scripts/diagram-to-image.mjs /tmp/table1.md -o /tmp/table1.png Note the position of each table in the article for later insertion (after which heading/paragraph) Remove table Markdown from the content before HTML conversion (so it won't appear as plain text in the pasted content) Image upload happens after pasting the main content — see Step 7. Step 1: Prepare Content Read the Markdown file and extract: Title : from YAML frontmatter title field, or H1 header # Title , or filename Subtitle : from YAML frontmatter excerpt or description field Content : full Markdown body (strip YAML frontmatter and any cross-reference links) Step 2: Convert Markdown to HTML Use Python's markdown library with tables and fenced_code extensions: import markdown import re with open ( '/path/to/article.md' , 'r' ) as f: content = f.read() # Strip YAML frontmatter content = re.sub( r'^---\n.*?\n---\n' , '' , content, flags=re.DOTALL) # Strip cross-reference links (e.g., English version link) # Adjust pattern as needed for your articles content = re.sub( r'^> .* available at.*\n\n?' , '' , content, flags=re.MULTILINE) # Convert to HTML html = markdown.markdown(content, extensions=[ 'tables' , 'fenced_code' ]) # Write to temp file with open ( '/tmp/substack_article.html' , 'w' ) as f: f.write(html) IMPORTANT : Do NOT use nl2br extension - it converts single newlines to <br> tags, causing extra line breaks in the editor. Step 3: Navigate to Substack Navigate to the Substack dashboard and create a new post: # Navigate to Substack dashboard navigate to: https://{publication}.substack.com/publish If not logged in, prompt user to log in: 请先登录 Substack,登录完成后告诉我。 Please log in to Substack first, then let me know. Step 4: Create New Post From the dashboard, create a new text post: Click "Create new" in the sidebar Select "Text post" (or navigate directly to a new post URL) Alternatively, if the editor is already open with an empty post, proceed directly. Step 5: Fill Title and Subtitle Click the title textbox ( textbox "title" ) Type the article title Click the subtitle textbox ( textbox "Add a subtitle…" ) Type the subtitle/excerpt click: title textbox fill/type: article title click: subtitle textbox fill/type: article subtitle Step 6: Insert HTML Content (via Clipboard Paste) CRITICAL: Do NOT use fill tool - it inserts plain text without formatting. Copy HTML to system clipboard: python3 /path/to/copy_to_clipboard.py html --file /tmp/substack_article.html Click the editor content area ( .ProseMirror or paragraph element inside it) Press Cmd+V to paste: press_key: Meta+v (macOS) press_key: Control+v (Windows/Linux) This triggers Tiptap's HTML paste handler, which renders the content as rich text with proper formatting. Step 7: Insert Table Images If the article had tables converted to images in Step 0, insert them now: Navigate to the correct position in the editor — click on the paragraph or empty line where the table should appear (after the relevant heading/text) Click the Image toolbar button ( button "Image" ) — a dropdown menu appears with options: Image, Gallery, Stock photos, Generate image Click "Image" menuitem from the dropdown — a file chooser dialog opens Upload the image via file chooser: Playwright MCP: browser_file_upload with the image path Chrome DevTools MCP: upload_file with the image path Important notes: File path restriction : Playwright MCP only allows file uploads from within allowed roots (project directories). If your image is in /tmp/ , copy it to the project directory first Repeat for each table : Position cursor at the correct location, then upload each table image Delete residual text : If table content was pasted as plain text (because it wasn't removed in pre-processing), select it (triple-click to select paragraph) and delete before inserting the image Step 8: Verify Draft After pasting: Check the "Saved" status indicator (green dot + "Saved" text) Take a snapshot to verify content structure Optionally take a screenshot for visual verification The editor auto-saves, so no explicit save action is needed. Step 9: Report Completion 草稿已保存到 Substack。请在 Substack 中预览并手动发布。 Draft saved to Substack. Please preview and publish manually. Post URL: https://{publication}.substack.com/publish/post/{postId} Complete Example Flow User: "把 /path/to/my-article.md 发布到 Substack" 0. Pre-process tables (if any) - Detect Markdown tables - Create styled HTML for each table - Render to screenshots (open in browser, screenshot, close tab) - Remove table Markdown from content - Note insertion positions 1. Read /path/to/my-article.md - Extract title from frontmatter or H1 - Extract subtitle from frontmatter excerpt - Get full Markdown content (with tables removed) 2. Convert Markdown to HTML - Strip frontmatter - Use markdown.markdown() with ['tables', 'fenced_code'] - Write to /tmp/substack_article.html 3. Navigate to Substack dashboard or new post 4. Check if logged in - If not, prompt user to login 5. Fill title and subtitle 6. Copy HTML to clipboard + Paste - python3 copy_to_clipboard.py html --file /tmp/substack_article.html - Click editor content area - Press Cmd+V 7. Insert table images at correct positions - For each table: click position → Image button → Image menuitem → file upload 8. Verify draft saved - Check "Saved" status 9. Report success - "草稿已保存,请手动预览并发布" Critical Rules NEVER click "Continue" - This starts the publish flow. Only save as draft (auto-save handles this) Always convert to HTML first - Plain Markdown will not be parsed by the Tiptap editor Use clipboard paste - The only reliable way to insert formatted content Check login status - Prompt user to login if needed Preserve original file - Never modify the source Markdown file Report completion - Tell user the draft is saved and needs manual review No nl2br extension - Causes double line breaks Tables → images - Pre-process tables before pasting content; upload images after paste Playwright file paths - Playwright MCP restricts file uploads to allowed roots; copy temp files to project directory before uploading Resolve publication first - Never hardcode a publication subdomain. Resolve via skill argument, SUBSTACK_PUBLICATION env var, or user prompt before any navigation (see Publication Resolution) Prefer Playwright MCP - Default to Playwright MCP; only use Chrome DevTools MCP when Playwright is unavailable Troubleshooting Content Shows as Plain Text (No Formatting) If you see raw HTML tags or unformatted text: Cause : Content was inserted using fill tool instead of clipboard paste Solution : Use the copy_to_clipboard.py + Cmd+V method (see Step 6) Tables Not Rendering (Shows Plain Text) Substack's Tiptap editor does not support HTML tables. They collapse into inline plain text. Solution : Convert tables to PNG via diagram-to-image skill → upload as images (see Step 0 and Step 7) Alternative : Restructure simple tables as formatted lists If plain text already pasted : Triple-click the plain text paragraph to select it, press Backspace to delete, then insert the table image at that position Login Required If page shows login prompt: 请先登录 Substack: https://{publication}.substack.com 登录完成后告诉我。 Editor Not Loading If editor elements are not visible: Wait for page to fully load Take a new snapshot If still not loading, refresh the page Clipboard Copy Fails If copy_to_clipboard.py fails: Ensure dependencies: pip install pyobjc-framework-Cocoa (macOS) Check the HTML file exists and is readable Try copying a smaller test string first Element Reference Element Selector/Identifier Description Title input textbox "title" Post title Subtitle input textbox "Add a subtitle…" Post subtitle Content area .ProseMirror (Tiptap editor) Post content Save status button "Saved" Auto-save indicator Preview button button "Preview" Preview post Continue button button "Continue" DO NOT USE - starts publish flow Settings button button "Settings" Open settings sidebar Exit button button "Exit" Exit editor Image button button "Image" Opens image upload dropdown Image menuitem menuitem "Image" Opens file chooser for image upload Author button button "{PublicationName}" Author/publication selector Technical Details Editor Stack Tiptap : A headless, framework-agnostic rich-text editor built on ProseMirror ProseMirror : The underlying rich-text editing framework Paste handling : Tiptap natively parses HTML from clipboard and converts to its internal document model Content Conversion Pipeline Markdown file ↓ (Python markdown library) HTML string ↓ (copy_to_clipboard.py) System clipboard (text/html + text/plain) ↓ (Cmd+V keyboard shortcut) Tiptap ProseMirror editor ↓ (auto-save) Substack draft Supported Formatting The following Markdown elements are correctly rendered after HTML conversion and paste: | Markdown Element | Substack Support | Notes |
このスキルを起動するキーワード。クリックでコピーできます。

このスキルにはトリガーワードがありません。

ダウンロードした .skill に含まれるフィールド。
フィールド 説明
formatフォーマット識別子(skill/v1)
skill_idスキル固有 ID
nameスキル名
versionバージョン
description説明
categoryカテゴリ(配列)
trigger_wordsトリガーワード
tagsタグ
sourceソース
source_urlソース URL(本ページ)
exported_atエクスポート日時(ダウンロード毎)
system_promptシステムプロンプト本文
model_configモデル設定:provider / model / temperature / max_tokens / top_p
examplesサンプル
install_guide各プラットフォームの導入説明(Coze / Dify / Claude / カスタム)
同じスキルを各プラットフォーム形式で出力できます。
.skill 標準形式。system_prompt と model_config を収録し、任意の Agent で利用可能 ダウンロード
.skillpro 拡張形式。scripts / tools / dependencies / hooks を含む ダウンロード
.json 純粋な JSON 出力。system_prompt とモデル設定のみ ダウンロード
Coze frontmatter 付き Markdown。Coze へのインポート用 ダウンロード
Dify Dify DSL。アプリ作成後にそのままインポート ダウンロード

每日精选 Skill 推荐,免费送到你邮箱

输入邮箱,每天接收一个精选 AI Agent 技能推荐。完全免费,持续更新。

验证码 --

提交后我们会发送一封确认邮件,点击邮件里的链接才会开始收信。

完全免费,取消任意时间。我们不会发送垃圾邮件。