xurl — X (Twitter) API 公式CLI
xurlは、Xデベロッパープラットフォームが提供するX APIの公式CLIです。一般的なアクションのためのショートカットコマンドと、あらゆるv2エンドポイントへのcurlライクなRAWアクセスの両方をサポートしています。すべてのコマンドはJSONを標準出力に返します。
このスキルは以下の用途に使用します。
- 投稿、返信、引用リポスト、削除
- 生ポストの検索(操作可能なIDを含む実際のポストJSON)およびタイムライン/メンションの読み取り
- いいね、リポスト、ブックマーク
- フォロー、アンフォロー、ブロック、ミュート
- ダイレクトメッセージ
- メディアアップロード(画像と動画)
- 任意のX API v2エンドポイントへのRAWアクセス
- マルチアプリ/マルチアカウントワークフロー
このスキルは、従来のxitterスキル(サードパーティのPython CLIをラップしていたもの)を置き換えます。xurlはXデベロッパープラットフォームチームによってメンテナンスされており、OAuth 2.0 PKCE(自動リフレッシュ対応)をサポートし、はるかに広いAPI範囲をカバーしています。
シークレットの安全性(必須)
エージェント/LLMセッション内で操作する場合の重要なルール:
- 決して
~/.xurlを読み取り、表示、解析、要約、アップロード、またはLLMコンテキストに送信しないでください。 - 決して ユーザーにチャット内で認証情報/トークンを貼り付けさせないでください。
- ユーザーは自分自身のマシンで手動で
~/.xurlにシークレットを入力する必要があります。Dockerでは、これはHermesツールサブプロセスが認識する~でなければなりません。以下のDockerの注意を参照してください。 - 決して エージェントセッション内でインラインシークレットを含む認証コマンドを推奨または実行しないでください。
- 決して エージェントセッション内で
--verbose/-vを使用しないでください — 認証ヘッダー/トークンが露出する可能性があります。 - 認証情報が存在することを確認するには、以下のコマンドのみを使用してください:
xurl auth status
エージェントコマンドでの禁止フラグ(インラインシークレットを受け入れるため):
--bearer-token, --consumer-key, --consumer-secret, --access-token, --token-secret, --client-id, --client-secret
アプリの認証情報登録と認証情報のローテーションは、ユーザーがエージェントセッション外で手動で行う必要があります。認証情報が登録された後、ユーザーは xurl auth oauth2 で認証します — これもエージェントセッション外で行います。トークンはYAML形式で ~/.xurl に永続化されます。各アプリには独立したトークンがあります。OAuth 2.0トークンは自動リフレッシュされます。
インストール
いずれか一つの方法を選んでください。Linuxでは、シェルスクリプトまたは go install が最も簡単です。
# シェルスクリプト(~/.local/binにインストール、sudo不要、Linux + macOSで動作)
curl -fsSL https://raw.githubusercontent.com/xdevplatform/xurl/main/install.sh | bash
# Homebrew(macOS)
brew install --cask xdevplatform/tap/xurl
# npm
npm install -g @xdevplatform/xurl
# Go
go install github.com/xdevplatform/xurl@latest
確認:
xurl --help
xurl auth status
xurl がインストールされていても auth status でアプリやトークンが表示されない場合、ユーザーは手動で認証を完了する必要があります — 次のセクションを参照してください。
初回ユーザー設定(ユーザーがエージェント外で実行)
これらの手順はエージェントではなくユーザーが直接実行する必要があります。シークレットの貼り付けが含まれるためです。ユーザーをこのブロックに誘導し、代わりに実行しないでください。
-
https://developer.x.com/en/portal/dashboard でアプリを作成または開きます。
-
リダイレクトURIを
http://localhost:8080/callbackに設定します。 -
アプリのクライアントIDとクライアントシークレットをコピーします。
-
アプリをローカルに登録します(ユーザーが実行):
xurl auth apps add my-app --client-id YOUR_CLIENT_ID --client-secret YOUR_CLIENT_SECRET -
認証します(
--appを指定してトークンをアプリにバインド):xurl auth oauth2 --app my-app(ブラウザが開き、OAuth 2.0 PKCEフローが開始されます。)
XがOAuth後の
/2/users/meルックアップでUsernameNotFoundエラーまたは403を返す場合は、ハンドルを明示的に渡してください(xurl v1.1.0以降):xurl auth oauth2 --app my-app YOUR_USERNAMEこれによりトークンがハンドルにバインドされ、壊れた
/2/users/me呼び出しをスキップします。 -
アプリをデフォルトに設定して、すべてのコマンドで使用されるようにします:
xurl auth default my-app -
確認:
xurl auth status xurl whoami
この後、エージェントは以下の任意のコマンドを追加設定なしで使用できます。OAuth 2.0トークンは自動リフレッシュされます。
よくある落とし穴:
xurl auth oauth2から--app my-appを省略すると、OAuthトークンはビルトインのdefaultアプリプロファイルに保存されます — このプロファイルにはclient-idやclient-secretがありません。OAuthフローが成功したように見えても、コマンドは認証エラーで失敗します。この問題が発生した場合は、xurl auth oauth2 --app my-appとxurl auth default my-appを再実行してください。
Docker HOMEの落とし穴: 公式Hermes Docker構成では、
/opt/dataがHERMES_HOMEですが、Hermesツールサブプロセスは/opt/data/homeをHOMEとして使用します。つまり、Hermesが実行するxurlコマンドでは、~/.xurlは/opt/data/.xurlではなく/opt/data/home/.xurlに解決されます。同じHOMEでユーザー設定を実行してください:HOME=/opt/data/home xurl auth apps add my-app --client-id YOUR_CLIENT_ID --client-secret YOUR_CLIENT_SECRET HOME=/opt/data/home xurl auth oauth2 --app my-app YOUR_USERNAME HOME=/opt/data/home xurl auth default my-app YOUR_USERNAME HOME=/opt/data/home xurl auth status
HOME=/opt/data xurl auth statusが成功してもHOME=/opt/data/home xurl auth statusがアプリやトークンを表示しない場合、Hermesツール呼び出しは認証情報を認識しません。
クイックリファレンス
| アクション | コマンド |
|---|---|
| 投稿 | xurl post "Hello world!" |
| 返信 | xurl reply POST_ID "Nice post!" |
| 引用 | xurl quote POST_ID "My take" |
| 投稿を削除 | xurl delete POST_ID |
| 投稿を読む | xurl read POST_ID |
| 投稿を検索 | xurl search "QUERY" -n 10 |
| 自分の情報 | xurl whoami |
| ユーザーを検索 | xurl user @handle |
| ホームタイムライン | xurl timeline -n 20 |
| メンション | xurl mentions -n 10 |
| いいね / いいね解除 | xurl like POST_ID / xurl unlike POST_ID |
| リポスト / 取り消し | xurl repost POST_ID / xurl unrepost POST_ID |
| ブックマーク / 削除 | xurl bookmark POST_ID / xurl unbookmark POST_ID |
| ブックマーク / いいね一覧 | xurl bookmarks -n 10 / xurl likes -n 10 |
| フォロー / アンフォロー | xurl follow @handle / xurl unfollow @handle |
| フォロー中 / フォロワー | xurl following -n 20 / xurl followers -n 20 |
| ブロック / ブロック解除 | xurl block @handle / xurl unblock @handle |
| ミュート / ミュート解除 | xurl mute @handle / xurl unmute @handle |
| DMを送信 | xurl dm @handle "message" |
| DM一覧 | xurl dms -n 10 |
| メディアアップロード | xurl media upload path/to/file.mp4 |
| メディアステータス | xurl media status MEDIA_ID |
| アプリ一覧 | xurl auth apps list |
| アプリ削除 | xurl auth apps remove NAME |
| デフォルトアプリ設定 | xurl auth default APP_NAME [USERNAME] |
| リクエストごとのアプリ指定 | xurl --app NAME /2/users/me |
| 認証状態確認 | xurl auth status |
注意:
POST_IDは完全なURLも受け付けます(例:https://x.com/user/status/1234567890) — xurlがIDを抽出します。- ユーザー名は先頭の
@があってもなくても動作します。
コマンド詳細
投稿
xurl post "Hello world!"
xurl post "Check this out" --media-id MEDIA_ID
xurl post "Thread pics" --media-id 111 --media-id 222
xurl reply 1234567890 "Great point!"
xurl reply https://x.com/user/status/1234567890 "Agreed!"
xurl reply 1234567890 "Look at this" --media-id MEDIA_ID
xurl quote 1234567890 "Adding my thoughts"
xurl delete 1234567890
読み取りと検索
xurl search は認証されたアカウントとしてXのインデックスをクエリし、生のポストオブジェクト(ID、著者、全文)を返します。そのため、結果に即座にアクション(返信、いいね、リポスト、引用)を実行できます。トピックの要約ではなく、実際のポストが必要な場合に使用します。
xurl read 1234567890
xurl read https://x.com/user/status/1234567890
xurl search "golang"
xurl search "from:elonmusk" -n 20
xurl search "#buildinpublic lang:en" -n 15
X Articlesについては、read ショートカットの代わりにRAW APIモードを使用してください。xurl read はポストIDまたはポストURLを期待します。/2/tweets/... エンドポイントの前に read を置かないでください。article ツイートフィールドをリクエストし、JSONレスポンスから data.article.plain_text を取り出します:
xurl --app APP_NAME '/2/tweets/2057909493250539891?expansions=author_id,attachments.media_keys,referenced_tweets.id&tweet.fields=created_at,lang,public_metrics,context_annotations,entities,possibly_sensitive,conversation_id,in_reply_to_user_id,referenced_tweets,article'
ユーザー、タイムライン、メンション
xurl whoami
xurl user elonmusk
xurl user @XDevelopers
xurl timeline -n 25
xurl mentions -n 20
エンゲージメント
xurl like 1234567890
xurl unlike 1234567890
xurl repost 1234567890
xurl unrepost 1234567890
xurl bookmark 1234567890
xurl unbookmark 1234567890
xurl bookmarks -n 20
xurl likes -n 20
ソーシャルグラフ
xurl follow @XDevelopers
xurl unfollow @XDevelopers
xurl following -n 50
xurl followers -n 50
# 他のユーザーのグラフ
xurl following --of elonmusk -n 20
xurl followers --of elonmusk -n 20
xurl block @spammer
xurl unblock @spammer
xurl mute @annoying
xurl unmute @annoying
ダイレクトメッセージ
xurl dm @someuser "Hey, saw your post!"
xurl dms -n 25
メディアアップロード
# 自動検出
xurl media upload photo.jpg
xurl media upload video.mp4
# 明示的なタイプ/カテゴリ
xurl media upload --media-type image/jpeg --category tweet_image photo.jpg
# 動画はサーバーサイド処理が必要 — ステータスを確認(またはポーリング)
xurl media status MEDIA_ID
xurl media status --wait MEDIA_ID
# 完全なワークフロー
xurl media upload meme.png # メディアIDを返す
xurl post "lol" --media-id MEDIA_ID
RAW APIアクセス
ショートカットは一般的な操作をカバーしています。その他の操作には、任意のX API v2エンドポイントに対してcurlライクなRAWモードを使用してください:
# GET
xurl /2/users/me
# JSONボディ付きPOST
xurl -X POST /2/tweets -d '{"text":"Hello world!"}'
# DELETE / PUT / PATCH
xurl -X DELETE /2/tweets/1234567890
# カスタムヘッダー
xurl -H "Content-Type: application/json" /2/some/endpoint
# 強制ストリーミング
xurl -s /2/tweets/search/stream
# 完全なURLも使用可能
xurl https://api.x.com/2/users/me
グローバルフラグ
| フラグ | 省略形 | 説明 |
|---|---|---|
--app | 特定の登録済みアプリを使用(デフォルトを上書き) | |
--auth | 認証タイプを強制: oauth1, oauth2, または app | |
--username | -u | 使用するOAuth2アカウント(複数存在する場合) |
--verbose | -v | エージェントセッションでは禁止 — 認証ヘッダーを漏洩 |
--trace | -t | X-B3-Flags: 1 トレースヘッダーを追加 |
ストリーミング
ストリーミングエンドポイントは自動検出されます。既知のものは以下の通りです:
/2/tweets/search/stream/2/tweets/sample/stream/2/tweets/sample10/stream
任意のエンドポイントで -s を使用してストリーミングを強制します。
出力形式
すべてのコマンドはJSONを標準出力に返します。構造はX API v2に準拠しています:
{ "data": { "id": "1234567890", "text": "Hello world!" } }
エラーもJSON形式です:
{ "errors": [ { "message": "Not authorized", "code": 403 } ] }
一般的なワークフロー
画像付き投稿
xurl media upload photo.jpg
xurl post "Check out this photo!" --media-id MEDIA_ID
会話に返信
xurl read https://x.com/user/status/1234567890
xurl reply 1234567890 "Here are my thoughts..."
検索してエンゲージ
xurl search "topic of interest" -n 10
xurl like POST_ID_FROM_RESULTS
xurl reply POST_ID_FROM_RESULTS "Great point!"
アクティビティを確認
xurl whoami
xurl mentions -n 20
xurl timeline -n 20
複数アプリ(認証情報は手動で事前設定)
xurl auth default prod alice # prodアプリ、aliceユーザー
xurl --app staging /2/users/me # stagingに対して一時的に使用
エラーハンドリング
- エラー時はゼロ以外の終了コードを返します。
- APIエラーもJSONとして標準出力に出力されるため、解析可能です。
- 認証エラー → ユーザーにエージェントセッション外で
xurl auth oauth2を再実行してもらいます。 - 呼び出し元のユーザーIDが必要なコマンド(いいね、リポスト、ブックマーク、フォローなど)は、
/2/users/me経由で自動的に取得します。そこで認証に失敗すると、認証エラーとして表示されます。
エージェントワークフロー
- 前提条件を確認:
xurl --helpとxurl auth status。 xurl searchを使用する前に、意図を確認します。タスクが実際のポストオブジェクト、認証されたアカウントコンテキストを必要とする場合、またはXへの書き込みアクションに繋がる場合に使用します — これはユーザーがエンゲージできるポストを必要とする場合の適切な手段です。- デフォルトアプリに認証情報があるか確認します。
auth statusの出力を解析します。デフォルトアプリは▸でマークされます。デフォルトアプリがoauth2: (none)と表示しているが、別のアプリに有効なoauth2ユーザーがいる場合、ユーザーにxurl auth default <that-app>を実行して修正するよう伝えてください。これが最も一般的な設定ミスです — ユーザーがカスタム名でアプリを追加したが、デフォルトに設定しなかったため、xurlが空のdefaultプロファイルを使い続けます。 - 認証が完全に欠落している場合は、停止してユーザーを「初回ユーザー設定」セクションに誘導してください — 自分でアプリを登録したりシークレットを渡そうとしないでください。
- 低コストの読み取りコマンド(
xurl whoami、xurl user @handle、xurl search ... -n 3)から始めて、到達可能性を確認します。 - 書き込みアクション(投稿、返信、いいね、リポスト、DM、フォロー、ブロック、削除)の前に、対象のポスト/ユーザーとユーザーの意図を確認します。
- 状態を変更するXアクションが実行されたことを証明できるのは、
xurlコマンドの出力(またはRAW X APIのレスポンス)のみです。検索結果、要約、または以前のコンテキストなど、他のソースに基づいて書き込みが完了したと報告しないでください。 - JSON出力を直接使用してください — すべてのレスポンスはすでに構造化されています。
~/.xurlの内容を会話に貼り付けないでください。
トラブルシューティング
| 症状 | 原因 | 修正 |
|---|---|---|
| OAuthフロー成功後の認証エラー | トークンが名前付きアプリではなく default アプリ(client-id/secretなし)に保存された | xurl auth oauth2 --app my-app を実行し、次に xurl auth default my-app を実行 |
OAuth中の unauthorized_client | Xダッシュボードでアプリタイプが「ネイティブアプリ」に設定されている | ユーザー認証設定で「ウェブアプリ、自動化アプリ、またはボット」に変更 |
OAuth直後の /2/users/me での UsernameNotFound または403 | Xが /2/users/me からユーザー名を確実に返さない | xurl auth oauth2 --app my-app YOUR_USERNAME を再実行(xurl v1.1.0以降)してハンドルを明示的に渡す |
| すべてのリクエストで401 | トークンの期限切れ、または間違ったデフォルトアプリ | xurl auth status を確認 — デフォルトアプリが oauth2: (none) と表示している場合、別のアプリをデフォルトに設定する必要があるかもしれません |