x-article-publisher について
Markdown 記事を X Articles 用の書式付き下書きにする Claude 向けスキルです。Python スクリプトでタイトル、HTML、画像位置を抽出し、ブラウザー自動化とクリップボードで入力します。公開は手動です。
主な機能
- 01Markdown を構造化データに変換
- 02本文を書式付き HTML に変換
- 03HTML と画像をクリップボードにコピー
- 04ブロックインデックスで画像を配置
- 05自動公開せず下書きを保存
活用シーン
- 01X Articles 向け Markdown 記事の準備
- 02見出し、リンク、リスト、太字の書式維持
- 03記事本文内の複数画像の配置
- 04手動公開前の下書き確認
MCP 対応
ブラウザーを自動操作して X Articles を開き編集するため、Playwright MCP が必要です。
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ mavscui/ agent-skills-hunter --skill x-article-publisherインストール後、Claude Code で/x-article-publisherを入力して読み込まれたか確認します。
詳細
X 記事パブリッシャー
Markdown コンテンツを X(Twitter)の記事エディターに公開します。リッチテキスト変換により書式を保持します。
前提条件
- ブラウザー自動化用の Playwright MCP
- Premium Plus サブスクリプションで X にログインしていること
- 依存関係をインストールした Python 3.9 以降:
pip install Pillow pyobjc-framework-Cocoa
スクリプト
~/.claude/skills/x-article-publisher/scripts/ にあります:
parse_markdown.py
Markdown を解析して構造化データを抽出します:
python parse_markdown.py <markdown_file> [--output json|html] [--html-only]
title、cover_image、content_images(位置指定用の block_index を含む)、html、total_blocks を含む JSON を返します。
copy_to_clipboard.py
画像または HTML をシステムのクリップボードにコピーします:
# Copy image (with optional compression)
python copy_to_clipboard.py image /path/to/image.jpg [--quality 80]
# Copy HTML for rich text paste
python copy_to_clipboard.py html --file /path/to/content.html
ワークフロー
方針:「先にテキスト、後から画像」
画像を複数含む記事では、最初にテキストコンテンツをすべて貼り付けてから、block_index を使って正しい位置に画像を挿入します。
- Python スクリプトで Markdown を解析 → title、block_index 付きの画像、HTML を取得
- X の記事エディターに移動
- カバー画像(最初の画像)をアップロード
- タイトルを入力
- HTML をクリップボードにコピー(Python) → Cmd+V で貼り付け
- block_index で指定された位置にコンテンツ画像を挿入
- 下書きとして保存(自動公開は絶対に行わない)
効率的な実行の原則
目標:操作間の待ち時間を最小限に抑え、スムーズな自動化を実現します。
1. 不要な browser_snapshot を避ける
ほとんどのブラウザー操作(click、type、press_key など)は、返却結果にページの状態を含みます。各操作の後に個別に browser_snapshot を呼び出す必要はありません。操作の返却結果に含まれるページの状態をそのまま使ってください。
❌ 错误做法:
browser_click → browser_snapshot → 分析 → browser_click → browser_snapshot → ...
✅ 正确做法:
browser_click → 从返回结果中获取页面状态 → browser_click → ...
2. 不要な browser_wait_for を避ける
browser_wait_for は次の場合にのみ使用してください:
- 画像のアップロード完了を待つ場合(
textGone="正在上传媒体") - ページの初期読み込みを待つ場合(まれなケース)
ボタンや入力欄が表示されるのを待つために browser_wait_for を使用しないでください。ページの読み込みが完了すれば、すぐに使用できます。
3. 独立した操作を並行して実行する
2 つの操作に依存関係がない場合は、同じメッセージ内で複数のツールを並行して呼び出せます:
✅ 可以并行:
- 填写标题 (browser_type) + 复制HTML到剪贴板 (Bash)
- 解析Markdown生成JSON + 生成HTML文件
❌ 不能并行(有依赖):
- 必须先点击create才能上传封面图
- 必须先粘贴内容才能插入图片
4. ブラウザー操作を連続して実行する
各ブラウザー操作が返すページの状態には、必要な要素参照がすべて含まれています。それらの参照をそのまま次の操作に使用してください:
# 理想流程(每步直接执行,不额外等待):
browser_navigate → 从返回状态找create按钮 → browser_click(create)
→ 从返回状态找上传按钮 → browser_click(上传) → browser_file_upload
→ 从返回状态找应用按钮 → browser_click(应用)
→ 从返回状态找标题框 → browser_type(标题)
→ 点击编辑器 → browser_press_key(Meta+v)
→ ...
5. 準備を事前に済ませる
ブラウザー操作を始める前に、すべての準備を済ませてください:
- Markdown を解析して JSON データを取得する
- HTML ファイルを /tmp/ に生成する
- title、cover_image、content_images などの情報を記録する
これにより、ブラウザー操作の段階では、途中で停止してデータを処理することなく連続して実行できます。
ステップ 1:Markdown を解析する(Python)
parse_markdown.py を使って、すべての構造化データを抽出します:
python ~/.claude/skills/x-article-publisher/scripts/parse_markdown.py /path/to/article.md
JSON 出力:
{
"title": "Article Title",
"cover_image": "/path/to/first-image.jpg",
"content_images": [
{"path": "/path/to/img2.jpg", "block_index": 5, "after_text": "context for debugging..."},
{"path": "/path/to/img3.jpg", "block_index": 12, "after_text": "another context..."}
],
"html": "<p>Content...</p><h2>Section</h2>...",
"total_blocks": 45
}
主なフィールド:
block_index:このインデックス(0 始まり)のブロック要素の後に画像を挿入しますtotal_blocks:HTML 内のブロック要素の合計数after_text:参照/デバッグ用にのみ保持され、位置指定には使用しません
クリップボード用に HTML を一時ファイルに保存します:
python parse_markdown.py article.md --html-only > /tmp/article_html.html
ステップ 2:X の記事エディターを開く
browser_navigate: https://x.com/compose/articles
重要:ページの読み込み後に表示されるのは下書き一覧であり、エディターではありません。次の手順が必要です:
- ページの読み込み完了を待つ:
browser_snapshotを使ってページの状態を確認します - すぐに「create」ボタンをクリックする:「添加标题」などのエディター要素を待たないでください。これらは create をクリックした後にのみ表示されます
- エディターの読み込みを待つ:create をクリックした後、エディター要素が表示されるまで待ちます
# 1. 导航到页面
browser_navigate: https://x.com/compose/articles
# 2. 获取页面快照,找到 create 按钮
browser_snapshot
# 3. 点击 create 按钮(通常 ref 类似 "create" 或带有 create 标签)
browser_click: element="create button", ref=<create_button_ref>
# 4. 现在编辑器应该打开了,可以继续上传封面图等操作
注意:browser_wait_for text="添加标题" をページの読み込み待ちに使用しないでください。このテキストは create をクリックした後にのみ表示されるため、タイムアウトします。
ログインが必要な場合は、手動でログインするようユーザーに促してください。
ステップ 3:カバー画像をアップロードする
- 「添加照片或视频」ボタンをクリックします
- カバー画像のパス(JSON 出力から取得)を指定して browser_file_upload を使用します
- 画像がアップロードされたことを確認します
ステップ 4:タイトルを入力する
- プレースホルダーが「添加标题」のテキストボックスを探します
- browser_type を使ってタイトル(JSON 出力から取得)を入力します
ステップ 5:テキストコンテンツを貼り付ける(Python クリップボード)
Python を使って HTML をシステムのクリップボードにコピーし、貼り付けます:
# Copy HTML to clipboard
python ~/.claude/skills/x-article-publisher/scripts/copy_to_clipboard.py html --file /tmp/article_html.html
次に、ブラウザーで:
browser_click on editor textbox
browser_press_key: Meta+v
これにより、すべてのリッチテキスト書式(H2、太字、リンク、リスト)が保持されます。
ステップ 6:コンテンツ画像を挿入する(block_index による位置指定)
重要な改善点:テキストとの一致に頼らず、block_index を使って正確な位置を指定します。
位置指定の原理
HTML を貼り付けた後、エディター内のコンテンツは、段落、見出し、引用などのブロック要素の連なりになります。各画像の block_index は、第 N ブロック要素の後に挿入することを示します。
操作手順
- すべてのブロック要素を取得する:browser_snapshot でエディターのコンテンツを取得し、テキストボックスの下にあるすべての子要素を探します
- インデックスで位置を指定する:
block_indexに基づいて該当するブロック要素をクリックします - 画像を貼り付ける:画像をクリップボードにコピーしてから貼り付けます
各コンテンツ画像(content_images 配列から)について:
# 1. Copy image to clipboard (with compression)
python ~/.claude/skills/x-article-publisher/scripts/copy_to_clipboard.py image /path/to/img.jpg --quality 85
# 2. Click the block element at block_index
# Example: if block_index=5, click the 6th block element (0-indexed)
browser_click on the element at position block_index in the editor
# 3. Paste image
browser_press_key: Meta+v
# 4. Wait for upload (use short time, returns immediately when done)
browser_wait_for textGone="正在上传媒体" time=2
位置指定の方法
browser_snapshot が返す構造では、エディターのコンテンツは通常、次のようになっています:
textbox [ref=xxx]:
generic [ref=block0]: # block_index 0
- paragraph content
heading [ref=block1]: # block_index 1
- h2 content
generic [ref=block2]: # block_index 2
- paragraph content
...
block_index=5 の後に画像を挿入するには:
- エディターのテキストボックスの下にある 6 番目の子要素を探します(インデックスは 0 から始まります)
- その要素をクリックします
- 画像を貼り付けます
注意:画像を 1 枚挿入するたびに、それ以降の画像の実際の位置がずれます。先に挿入した画像が後続画像のインデックスに影響しないよう、block_index の大きい順に画像を挿入することをおすすめします。
逆順で挿入する例
画像が 3 枚あり、block_index がそれぞれ 5、12、27 の場合:
- block_index=27 の画像を先に挿入します
- 次に block_index=12 の画像を挿入します
- 最後に block_index=5 の画像を挿入します
こうすることで、画像を挿入するたびに、すでに位置を指定した前の画像の位置に影響しません。
ステップ 7:下書きを保存する
- コンテンツが貼り付けられたことを確認します(単語数の表示を確認します)。
- 下書きは自動保存されます。必要に応じて「保存」ボタンをクリックします。
- 「预览」をクリックして書式を確認します。
- 次のように報告します:「下書きを保存しました。確認して手動で公開してください。」
重要なルール
- 絶対に公開しない — 下書きの保存のみ行います
- 最初の画像をカバー画像にする — 最初の画像をカバー画像としてアップロードします
- リッチテキストへの変換 — 貼り付ける前に、必ず Markdown を HTML に変換します
- クリップボード API を使用する — 適切な書式を保つため、クリップボード経由で貼り付けます
- ブロックインデックスで位置を指定する — 画像を正確に配置するため、block_index を使用します
- 逆順で挿入する — block_index の大きい順に画像を挿入します
- H1 タイトルの扱い — H1 はタイトルとしてのみ使用し、本文には含めません
対応する書式
- H2 見出し(## )
- 引用(> )
- コードブロック(
...)— X は<pre><code>に対応していないため、引用に変換されます - 太字(**)
- ハイパーリンク(text)
- 番号付きリスト(1. 2. 3.)
- 箇条書き(- )
- 段落
実行例
ユーザー:「/path/to/article.md を X に公開して」
# Step 1: Parse Markdown
python ~/.claude/skills/x-article-publisher/scripts/parse_markdown.py /path/to/article.md > /tmp/article.json
python ~/.claude/skills/x-article-publisher/scripts/parse_markdown.py /path/to/article.md --html-only > /tmp/article_html.html
- https://x.com/compose/articles に移動します
- カバー画像をアップロードします(カバー画像には browser_file_upload のみを使用します)
- タイトルを入力します(JSON の
titleから取得します) - HTML をコピーして貼り付けます:
次に、browser_press_key Meta+v を実行しますpython ~/.claude/skills/x-article-publisher/scripts/copy_to_clipboard.py html --file /tmp/article_html.html - コンテンツ画像ごとに、block_index の逆順で次の操作を行います:
python copy_to_clipboard.py image /path/to/img.jpg --quality 85block_indexの位置にあるブロック要素をクリックします- browser_press_key Meta+v を実行します
- アップロードが完了するまで待ちます
- プレビューで確認します
- 「下書きを保存しました。確認して手動で公開してください。」
ベストプラクティス
なぜ文字列の照合ではなく block_index を使うのですか?
- 正確な位置指定:文字列の内容に依存せず、似た文字列が複数箇所にあっても正しく位置を特定できます
- 信頼性:インデックスは決定的であり、文字列が似ているために混同することはありません
- デバッグが容易:
after_textは手動確認用として引き続き使用できます
なぜブラウザー内の JavaScript ではなく Python を使うのですか?
- ローカルでの処理がより信頼できます:Python は OS のクリップボードを直接操作でき、ブラウザーのサンドボックスによる制限を受けません
- 画像の圧縮:アップロード前に画像を圧縮する(--quality 85)ことで、アップロード時間を短縮します
- コードの再利用:スクリプトは固定されているため、変換ロジックを毎回書き直す必要がありません
- デバッグが容易:スクリプトを単独でテストでき、問題の特定も容易です
待機の戦略
重要なポイント:browser_wait_for の textGone パラメーターは、文字列が消えるとすぐに戻ります。time は最大待機時間であり、固定の待機時間ではありません。
- ❌ 余裕を持たせた待機:
time=5またはtime=10。アップロードに2秒しかかからない場合、残りの時間が無駄になります - ✅ 短い間隔でのポーリング:
time=2。条件を満たすとすぐに戻り、最大でも2秒待ちます
# 正确用法:短 time 值,条件满足立即返回
browser_wait_for textGone="正在上传媒体" time=2
# 错误用法:固定长时间等待
browser_wait_for time=5 # 无条件等待5秒,浪费时间
原則:「どれくらい待つ必要があるか」をあらかじめ決めるのではなく、妥当な最大値を設定して、条件をできるだけ早く検出できるようにします。
画像挿入の効率化
画像ごとのブラウザー操作を5ステップから2ステップに減らします:
- 旧:クリック → メディアを追加 → メディア → 写真を追加 → file_upload
- 新:段落をクリック → Meta+v
カバー画像とコンテンツ画像
- カバー画像:専用のアップロードボタンがあるため、browser_file_upload を使用します
- コンテンツ画像:Python のクリップボードから貼り付けます(より効率的です)