0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

OpenClaw × X-mcp-server で Xに投稿&検索

0
Posted at

始めに 🚀

OpenClaw から X(旧Twitter)へ投稿・検索できる構成を構築します。
構成はこんな感じです。
Gemini_Generated_Image_vvteftvvteftvvte.png

それと自分がハマった部分

  • ポート衝突
    OpenClaw Studioの開発UIが今回紹介するMCPサーバーと同様の3000を使うため衝突
  • トークン自動リフレッシュ対応
  • トークン参照ズレ

についても記録として残します。

上記のcallback ポート衝突(3000/3001)や refresh token 同期ズレについては対応済みです。反映済みコードは以下です。
https://github.com/nahrun1682/x-mcp-server

※注意
現在OpenClawのセキュリティ面については色々と問題起きておりますので、こちら自己責任です。ご了承ください。

このMCPサーバー導入でできること 🎯

機能 内容 備考
post_tweet 📝 ツイート投稿(テキスト) ポストのidを指定することで返信も可能
post_tweet(画像付き) 🖼️ 画像・GIF付き投稿 OAuth2 + メディアアップロード対応
search_tweets 🔎 キーワード検索 APIプランによっては制限あり
delete_tweet 🗑️ ツイート削除 投稿済みツイートのみ

念のためですが、使用するたびに料金発生しますので注意です。

すると、このようにOpenCLawから画像付きポストや検索が可能になります。
image.png

※ただし、まだ完全自動返信には対応してません。(誰かからポストが来た時に自動で返信するのような)
OpenClawに「x-mcp-serverで~~~して」といったときのみ投稿/検索/削除が可能です。
実際は半自動ってところですね。


関連OSSリポジトリ 🔗🙇‍♂️

今回検討したMCPサーバーのリポジトリURLは以下の通りです。

今回は OAuth完成度・v2対応・拡張性 を理由に
x-mcp-server を採用しました。
※ただしこれでも完全に安全とは言えませんので注意(トークン流出とか)


この記事で使うコアOSS 🧩

x-mcp-server(mbelinky版)

  • OAuth 2.0 対応

  • X API v2 対応

  • 画像・GIF付き投稿可能

  • stdio型 MCP サーバ

mcporter

OpenClaw から MCP サーバーを呼び出すための実行・設定管理ツール。
公式の AGENTS.default でも mcporter は「外部 Skill backend を管理する runtime/CLI」としてコアスキル扱いのため、これを使う前提となります。


前提 🛠️

  • Windows(wsl2)

  • X Developer アカウント

  • Node.js:v24.13.1

  • OpenClaw + mcporter

  • PM2(任意、常駐化のため)


Phase 1: X Developer Portal 設定 🏗️

  1. Developer Portal でアプリ作成ボタンをクリック

  2. 以下記入して「新しいクライアントアプリケーション」をクリック

    1. アプリケーション名:(任意)

    2. Environment:Development
      Pasted image 20260217182954.png

  3. 以下のキーを保存

    1. コンシューマーキー

    2. secret key

    3. ベアラートークン

  4. アプリ画面から「ユーザー認証設定」の「セットアップ」をクリック

    1. アプリ権限
      読み取りと書き込みを選択
      image.png

    2. アプリの種類
      webアプリ、自動化アプリまたはボットを選択
      Pasted image 20260217183410.png

    3. アプリ情報に以下を記載

      1. コールバックURI:http://localhost:3001/callback
      2. ウェブサイトURL:https://x.com/home
        Pasted image 20260217183458.png

5.「アクセストークンを生成」からアクセストークンとアクセストークンシークレットを生成し、アクセストークン/Client ID / Client Secret を保存


Phase 2: x-mcp-server の clone と初期セットアップ 📥

$ git clone https://github.com/nahrun1682/x-mcp-server.git

#もしもopenclaw以外で使う際は以下の本家をおすすめします
#git clone https://github.com/mbelinky/x-mcp-server
$ cd x-mcp-server

x-mcp-server$ cp .env.example .env

このあと.envに以下の値をセット

# OAuth 1.0a Configuration
#API_KEY=your_api_key_here
#API_SECRET_KEY=your_api_secret_key_here
#ACCESS_TOKEN=your_access_token_here
#ACCESS_TOKEN_SECRET=your_access_token_secret_here

# OAuth 2.0 Configuration (uncomment to use)
AUTH_TYPE=oauth2
OAUTH2_CLIENT_ID=your_client_id_here
OAUTH2_CLIENT_SECRET=your_client_secret_here
# ポートを3001に
OAUTH2_CALLBACK_PORT=3001
OAUTH2_ACCESS_TOKEN=your_access_token_here
#リフレッシュトークンは最初は空で良いです
OAUTH2_REFRESH_TOKEN=

# Optional: Enable debug logging
# DEBUG=true

次にビルドします

x-mcp-server$ npm install
x-mcp-server$ npm run build

Phase 3: OAuth2セットアップ 🔑

ここまで来たら以下のコマンドでOAuthのセットアップを行います

x-mcp-server$ node scripts/oauth2-setup.js

すると以下の画面に遷移するので認証を通します

Pasted image 20260217184054.png

ブラウザで認可を通すと .env にトークンが保存されます。
確認コマンド

x-mcp-server$ cat .env

Phase 4: callbackポート衝突の確認(OpenClaw Studioの:3000と競合) ⚠️

今回の構成では OAuth callback を最初から3001にしています 
理由は、自分の環境ではOpenClaw Studio(開発UI)が開発サーバとして 
http://localhost:3000を使っており、OAuth callback の待受が3000と衝突したためです。

「本当に3000が埋まっているか」を確認したい場合だけ、以下でプロセスを特定できます。

確認方法:

x-mcp-server$ lsof -i :3000

以降は3001を前提に進めます(Phase 2 で設定済み)。


Phase 5: mcporter登録と疎通確認 🔌

自分はここでハマりましたので記録しておきます。

  1. mcporter config add で Node本体に渡す引数は --arg を使い(--args だとダメ )
    以下のコマンドでmcporter側の固定envを同期させておきます

    x-mcp-server$ mcporter config add x-mcp-server \
      --scope home \
      --command "/home/<ユーザー>/.nvm/versions/node/v24.13.1/bin/node" \
      --arg "/home/<ユーザー>/.../x-mcp-server/build/index.js" \
      --env AUTH_TYPE=oauth2 \
      --env OAUTH2_CLIENT_ID="..." \
      --env OAUTH2_CLIENT_SECRET="..." \
      --env OAUTH2_ACCESS_TOKEN="..." \
      --env OAUTH2_REFRESH_TOKEN="..." \
      --env OAUTH2_TOKEN_EXPIRES_AT="..."
    
  2. 登録内容を確認

    x-mcp-server$ mcporter config get x-mcp-server
    

    成功するとENV情報が表示されます。

  3. ツールスキーマを確認(接続確認)

    x-mcp-server$ mcporter list --schema
    

    成功すると以下のようなMCPサーバーリストが表示されます。

    x-mcp-server$ mcporter list --schema
    mcporter 0.7.3 — Listing 1 server(s) (per-server timeout: 30s)
    - x-mcp-server (3 tools, 0.1s)
    ✔ Listed 1 servers (1 healthy).
    
  4. 検索テスト
    では検索ツールでテストしてみます。

    x-mcp-server$ mcporter call x-mcp-server.search_tweets query="OpenClaw" count=10
    

    以下のように検索結果が表示されたら成功です。

    X SEARCH RESULTS
    Query: "OpenClaw"
    Found 10 tweets
    =
    Tweet #1
    From: @Ujjwalabhi99
    Content: RT @tanayj: Peter Steinberger (@steipete) built 40+ projects over the last
    few years before OpenClaw went viral.
    Classic "overnight succes…
    Metrics: 0 likes, 74 retweets
    URL: https://x.com/Ujjwalabhi99/status/2023753658283012470
    =
    
  5. 最後にOpenClaw から「XをOpenclawで検索して」等と投げかけ、
    結果が返ることを確認します。


Phase 6: PM2で常駐化 ♻️

最後にPM2でサーバーを常駐化させたら完了です。

x-mcp-server$ pm2 start build/index.js --name x-mcp-server
x-mcp-server$ pm2 status
x-mcp-server$ pm2 save

Phase 7: 最終動作確認 ✅

最後に以下のような質問をOpenClawにして動作すれば完了です。

  • 「Xを~~~というキーワードで検索して」
  • 「Xに~~~という文面で投稿して」
    ※Discordなら画像を添付しながら指示することで画像付きポストが可能です。

また最後に専用Skillを作成することでよりスムーズに動作するかと思います。
まあOpenClawにこのMCPサーバーのことを相談すれば彼がSkillを作成してくれますが、
一応自分はこんなSkill使ってます。ご参考までに。

---
name: x-mcp-server
description: Operate the x-mcp-server MCP server through mcporter commands to search, 
post, and delete tweets on X safely, including schema verification, 
auth checks, and confirmation rules for destructive actions.
---

## 前提と初期チェック
1. `mcporter` がインストールされていること(`mcporter --version`)。
2. `x-mcp-srver` サーバーが登録済みで、OAuth 2.0 の認証情報が設定済み。
3. 作業開始時は **必ず** ツールスキーマを確認する:
    mcporter list x-mcp-server --schema
     

## アカウント情報
**自分のアカウント: XXXX**

- このアカウントで投稿・検索・削除を行う
- 自分の投稿を確認する際は `from:XXXXX` で検索

## 基本ワークフロー
1. 使うツールを決める(`search_tweets` / `post_tweet` / `delete_tweet`)。
2. すべて **mcporter形式** で実行する:`mcporter call x-mcp-server.<tool> key=value`
3. 投稿・削除のような変更系操作は、実行前にユーザー意図を再確認する。

## 代表コマンド例
- **検索**:
  mcporter call x-mcp-server.search_tweets query="OpenAI" count=10
- **特定ユーザーの投稿を拾う(URL直読み失敗時の代替)**:
  mcporter call x-mcp-server.search_tweets query="from:ebikani_hasami" count=10
  - Xの投稿URL(`https://x.com/<user>/status/<tweet_id>`)がWeb取得で失敗する場合でも、`from:<user>` 検索で該当投稿を取得できることがある。
  - 取得結果の `URL` / `status/<tweet_id>` を照合して対象ポストを特定する。
  - 自分の投稿に限定されず、公開投稿であれば他ユーザー投稿の確認にも使える。
- **投稿(テキストのみ)**:
  mcporter call x-mcp-server.post_tweet text="テスト投稿です"
- **返信投稿**:
  ```bash
  mcporter call x-mcp-server.post_tweet text="返信です" reply_to_tweet_id="1234567890123456789"
- **削除**:
  mcporter call x-mcp-server.delete_tweet tweet_id="1234567890123456789"

### 承認ルール(厳格運用)
- `delete_tweet` は **必ず承認を得てから実行**。
- `post_tweet` は外部公開の変更操作であり、**無承認投稿を絶対禁止**とする。
- **ツイート投稿前に必ず草稿を提出すること。**
- **`post_tweet` を実行してよい承認文は、ユーザーの単独メッセージ `承認`(2文字)だけとする。**
  - 有効:`承認`
  - 無効:`承認します` / `承認!` / `ok` / `OK` / スタンプ / 絵文字のみ / 文脈上の同意
- **承認メッセージに他の文字列が1文字でも含まれる場合は未承認扱い**とし、投稿しない。
- 承認が無効・曖昧な場合は、**「`承認` のみで再送してください」**と案内して待機する。
- **いかなるテスト目的でも、上記条件を満たす前の投稿は禁止。**

## 利用可能ツール一覧(参考)
1. **search_tweets** — ツイート検索
2. **post_tweet** — ツイート投稿(任意で返信・メディア)
3. **delete_tweet** — ツイート削除

参考: トークン自動リフレッシュ同期ずれ 🔄

基本的には大丈夫ですが、もしも使用中にトークン同期ずれが起きた場合は以下のコマンドをお試しください。
これの原因は.env と ~/.mcporter/mcporter.json のトークン不一致。でした。
つまり、.env だけ新しくても、mcporter側に古い OAUTH2_ACCESS_TOKEN が残っていると401になります。

確認:

cat .env
cat ~/.mcporter/mcporter.json

以下のコマンドで同期:

mcporter config remove x-mcp-server
mcporter config add x-mcp-server ...
pm2 restart x-mcp-server --update-env
0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?