Skip to main content
Glama

line-approval-bridge

AI エージェント(Claude Code の定期タスク、シェルスクリプトなど)から あなたの LINE に通知し、返信・承認を待って、その答えで処理を分岐する ための小さなブリッジです。

Claude Code / スクリプト ──(MCP / CLI)──▶ Cloudflare Worker ──push──▶ あなたの LINE
          ▲                                   │  ▲                         │
          └──────── 結果をポーリング ───────────┘  └──── Webhook(返信)────────┘
  • notify(text, send_at?) … 一方向の通知。send_at を付けると サーバー側で予約し、Mac がスリープしていてもその時刻に届く

  • ask_approval(question, options, timeout) … 「承認 / 却下」などのボタン付きで質問し、回答が来るまで待つ

  • get_reply(id) … 回答の取得(待ちの再開)

公式 LINE Bot MCP Server との違い

公式 LINE Bot MCP Server は 送信専用 です。メッセージを送ることはできますが、ユーザーの返信を受け取ってエージェントに返す仕組みはありません。

line-approval-bridge は 人間の判断を待つ(human-in-the-loop) ことに特化しています。

公式 LINE Bot MCP Server

line-approval-bridge

メッセージ送信

できる

できる

返信の受信(Webhook)

なし

あり(署名検証つき)

承認ボタンを出して待つ

なし

ask_approval

返信内容で処理を分岐

なし

answer.value で分岐

自由入力の返信

なし

あり(#ID 指定で過去の依頼にも回答可)

受信者の制限

—

許可した userId のみ

Related MCP server: LINE Bot MCP Server

特徴

  • 無料で動く: Cloudflare Workers 無料プラン + Workers KV、LINE コミュニケーションプラン(無料・月 200 通)

  • 安全: X-Line-Signature(HMAC-SHA256)を検証。許可リストにない userId は無視。API は Bearer トークン必須

  • 返信は通数を消費しない: 「受け付けました」の返事は reply API(無料)で返す

  • MCP サーバー + CLI: Claude Code からはツールとして、シェルからは終了コードで分岐

  • ローカル開発モード: LINE に実際に送らず、署名付き Webhook をシミュレートして全フローを試せる

なぜ Cloudflare Workers か(Vercel ではなく)

  • KV ストアが Workers に標準で付いてくる(Vercel は外部の Redis 連携が必要で、設定項目が増える)

  • 無料枠で十分(1 日 10 万リクエスト、KV 読み取り 10 万回・書き込み 1,000 回)

  • Web Crypto がそのまま使えるので、署名検証が依存ライブラリなしで書ける

  • スリープ(コールドスタート)が実質なく、LINE の Webhook にすぐ応答できる


セットアップ

所要時間は 30 分ほどです。トークンやパスワードはすべてご自身で発行・入力してください。 このリポジトリやチャットに貼る必要はありません。

必要なもの

  • LINE アカウント(スマホの LINE アプリ)

  • Cloudflare アカウント(無料)

  • Node.js 20 以上、git

1. LINE 公式アカウントを作り、Messaging API を有効にする

  1. LINE Official Account Manager を開き、LINE アカウントでログイン

  2. 「アカウントを作成」から LINE 公式アカウントを作る(名前は何でもよい。例: My Agent)

  3. 作ったアカウントを開き、右上の 設定 → 左メニュー Messaging API → 「Messaging API を利用する」

  4. プロバイダーを選ぶ(なければ新規作成。名前は何でもよい)→ OK

  5. 同じ設定画面の左メニュー 応答設定 で次のようにする

    • 応答メッセージ: オフ(自動返信がブリッジの返事と混ざるのを防ぐ)

    • Webhook: オン

    • あいさつメッセージ: お好みで

2. トークンと自分の userId を確認する

LINE Developers コンソール を開き、手順 1 のプロバイダー → チャネル(公式アカウント名)を選びます。

確認する値

場所

このあと入れる先

チャネルシークレット

「チャネル基本設定」タブ → チャネルシークレット

Worker の secret LINE_CHANNEL_SECRET

あなたの userId(U で始まる 33 文字)

「チャネル基本設定」タブ → 一番下の「あなたのユーザーID」

Worker の secret ALLOWED_USER_IDS

チャネルアクセストークン(長期)

「Messaging API設定」タブ → 一番下「チャネルアクセストークン(長期)」の 発行

Worker の secret LINE_CHANNEL_ACCESS_TOKEN

続けて「Messaging API設定」タブにある QR コードを LINE アプリで読み取り、公式アカウントを友だち追加 してください(友だちでないと通知が届きません)。

3. Worker をデプロイする

git clone https://github.com/fumy98/line-approval-bridge.git
cd line-approval-bridge
npm install
cd api
npx wrangler login                 # ブラウザが開くので Cloudflare にログインして許可
npx wrangler kv namespace create KV

最後のコマンドが表示する id = "..." を、api/wrangler.toml の REPLACE_WITH_YOUR_KV_NAMESPACE_ID と置き換えます。

次に secret を 4 つ登録します。コマンドごとに入力を求められるので、値を貼り付けて Enter(画面には表示されません)。

npx wrangler secret put LINE_CHANNEL_SECRET        # 手順 2 のチャネルシークレット
npx wrangler secret put LINE_CHANNEL_ACCESS_TOKEN  # 手順 2 のチャネルアクセストークン(長期)
npx wrangler secret put ALLOWED_USER_IDS           # 手順 2 のあなたの userId(複数ならカンマ区切り)
openssl rand -hex 32                               # API_TOKEN 用のランダム文字列を作る(控えておく)
npx wrangler secret put API_TOKEN                  # ↑で作った文字列
npx wrangler deploy

deploy の最後に https://line-approval-bridge.<あなたのサブドメイン>.workers.dev が表示されます。これが Worker の URL です。

4. LINE に Webhook URL を登録する

LINE Developers コンソール →「Messaging API設定」タブ → Webhook URL の「編集」に

https://line-approval-bridge.<あなたのサブドメイン>.workers.dev/webhook

を入れて「更新」→「検証」で 成功 と出れば OK。その下の Webhook の利用 をオンにします。

(コンソールを開かなくても、手順 5 のあとで node client/dist/cli.js setup-webhook を実行すれば、LINE の API 経由で URL の登録と疎通テストまで行えます。)

5. クライアント(CLI / MCP)を準備する

cd ..                      # リポジトリ直下に戻る
npm run build

環境変数を 2 つ使います(.env.example 参照)。シェルで使う場合は ~/.zshrc などに書きます。

export LINE_APPROVAL_URL="https://line-approval-bridge.<あなたのサブドメイン>.workers.dev"
export LINE_APPROVAL_TOKEN="<手順 3 で作った API_TOKEN>"

動作確認:

node client/dist/cli.js notify "テスト通知です"
node client/dist/cli.js ask "承認テストです。どちらかを押してください" --wait 300 --print value

LINE に届いたメッセージの「承認」ボタンを押すと、ターミナルに 承認 と表示されます。

6. Claude Code に MCP サーバーとして登録する

claude mcp add line-approval --scope user \
  -e LINE_APPROVAL_URL="https://line-approval-bridge.<あなたのサブドメイン>.workers.dev" \
  -e LINE_APPROVAL_TOKEN="<API_TOKEN>" \
  -- node "$(pwd)/client/dist/mcp.js"

--scope user にすると、すべてのプロジェクトと定期タスクから使えます。値は手元の ~/.claude.json にだけ保存されます。claude mcp list で line-approval が Connected になっていれば完了です。

つまずきやすい点(実際に詰まったところ)

症状

原因と対処

LINE Developers コンソールで Messaging API のチャネルが作れない

先に LINE Official Account Manager で公式アカウントを作り、そこで「Messaging API を利用する」を押します(手順 1)。Developers コンソール側から始めると迷子になりがちです

自分の userId がどこにあるか分からない

「チャネル基本設定」タブの一番下の「あなたのユーザーID」(U で始まる 33 文字)。LINE アプリのプロフィールにある ID(@〜 や任意の ID)とは別物です

通知が届かない(エラーも出ない)

公式アカウントを友だち追加していないことが多いです。「Messaging API設定」タブの QR コードを LINE アプリで読み取ります

ボタンを押す前に「メッセージありがとうございます」等の自動返信が来る

応答設定の 応答メッセージをオフ にします(手順 1-5)。オンのままだとブリッジの返事と混ざります

PC / Mac 版の LINE でボタンが出ない

古い版はクイックリプライ(スマホのみ表示)だけでした。今の版はメッセージ内にボタンを出すので、npx wrangler deploy し直せば PC 版でも押せます

返信しても pending のまま

Webhook URL の登録漏れか「Webhook の利用」がオフです。node client/dist/cli.js setup-webhook を実行すると、登録と疎通テストをまとめて行い、オフなら警告を出します

wrangler secret put で貼り付けても何も表示されない

仕様です(入力は画面に出ません)。貼り付けて Enter を押せば登録されます。登録済みの名前は npx wrangler secret list で確認できます(値は出ません)

wrangler.toml の KV id を書き換え忘れた

deploy が KV のエラーで止まります。npx wrangler kv namespace list で id を確認して書き換えます

トークンを ~/.zshrc に直接書きたくない

別ファイル(例 ~/.config/line-approval-bridge/env、権限 600)に export 2 行を書き、~/.zshrc から source すると、設定ファイルを人に見せるときに安全です

Claude Code で line-approval のツールが見えない・古いまま

claude mcp add のあとや npm run build し直したあとは、Claude Code(デスクトップアプリ)を再起動します。定期タスクから確認なしで使うには、許可に mcp__line-approval__notify などを追加します

時刻を指定した通知がスリープ中に送られない

Mac 側で sleep や定期タスクで待つと、スリープ中は動きません。--at / send_at の予約送信を使うと Worker 側で送るので届きます(「予約送信」の節)

トークンの置き場所まとめ

値

置き場所

git に入るか

LINE_CHANNEL_SECRET / LINE_CHANNEL_ACCESS_TOKEN / ALLOWED_USER_IDS / API_TOKEN

Cloudflare の Worker secret(wrangler secret put)

入らない

LINE_APPROVAL_URL / LINE_APPROVAL_TOKEN

シェルの環境変数、または claude mcp add -e

入らない

ローカル開発用の値

api/.dev.vars(.gitignore 済み)

入らない

KV namespace id

api/wrangler.toml

入る(秘密情報ではない)


使い方

MCP ツール(Claude Code から)

ツール

引数

戻り値

notify

text, send_at?(ISO 8601・タイムゾーン付き。例 2026-10-18T07:00+09:00)

sent、予約時は scheduled for <時刻> [id=XXXXXX]

ask_approval

question, options?(既定 ["承認","却下"]、最大 13 個・各 20 文字), allow_free_text?(既定 true), timeout?(期限・秒、既定 86400), wait_seconds?(この呼び出しで待つ秒数、既定 600)

status(answered / expired / pending), answer.value, answer.kind(option / text), id

get_reply

id, wait_seconds?

同上

wait_seconds を過ぎても回答がなければ pending と id を返します。エージェントは get_reply(id) を呼べば待ちを再開できます(依頼そのものは timeout まで有効)。

例: 週の動画トピックを LINE で承認する

Claude Code の定期タスクのプロンプトに、次のように書きます。

1. 来週の動画トピックを 7 本考えて topics.md に書く。
2. line-approval の ask_approval を呼ぶ。
   question: 「来週のトピック案です」+ 7 本のタイトルを番号付きで
   options: ["承認", "却下"]
   timeout: 43200(12 時間)
3. 返ってきた answer で分岐する。
   - 「承認」: topics.md の状態を approved にしてコミットする。
   - 「却下」: 何もせず notify で「今週は見送りました」と送る。
   - 自由入力(例「3 番を別の話題に」): 指示どおり直して、もう一度 ask_approval する(最大 3 回)。
   - expired / pending: notify で「未承認のため保留しました」と送って終了する。

CLI(シェルスクリプトから)

line-approval notify "<text>" [--at 2026-10-18T07:00+09:00]   # --at でサーバー側に予約
line-approval scheduled      # 予約中の通知を一覧
line-approval cancel <id>    # 予約を取り消し
line-approval ask "<question>" [--options 承認,却下] [--no-free-text] [--timeout 秒] [--wait 秒 | --no-wait] [--print value|json]
line-approval get <id> [--wait 秒] [--print value|json]
line-approval quota          # 今月の送信数

(npm link -w client で line-approval コマンドとして使えます。そうしない場合は node client/dist/cli.js。)

予約送信(時刻指定の通知)

Mac 上のタイマー(sleep や cron)で時刻を待つと、スリープ中は送れません。--at / send_at を使うと予約が Worker の KV に保存され、Cloudflare の Cron Trigger(毎分)が時刻になったら送るので、手元の端末の状態に関係なく届きます。

line-approval notify "7時です。ゴミ出しの日" --at "2026-10-18T07:00+09:00"
# => 予約しました: #K7Q2MX 2026-10-17T22:00:00.000Z
line-approval scheduled
line-approval cancel K7Q2MX
  • 時刻は タイムゾーン付きの ISO 8601 で指定します(+09:00 か Z)。2026-10-18T07:00 のようにタイムゾーンがないものは 400 になります

  • 過去・現在の時刻を指定した場合は、その場ですぐ送ります

  • 送信は分単位です。指定した分の Cron 実行で送られるので、最大 1〜2 分ほど遅れることがあります

終了コード: 0 回答あり / 2 期限切れ / 3 まだ回答待ち(--wait 経過) / 1 エラー

answer=$(line-approval ask "本番にデプロイしますか?" --timeout 3600 --print value)
case "$?:$answer" in
  0:承認) ./deploy.sh ;;
  0:*)    echo "却下またはコメント: $answer" ;;
  *)      echo "回答なし" ;;
esac

LINE 側での答え方

  • ボタンを押す(いちばん確実)

  • ボタンと同じ文字を送る(例: 承認)→ 最新の依頼への回答

  • 自由に書いて送る(例: 3 番だけ差し替えて)→ 最新の依頼への自由入力回答(allow_free_text が true の場合)

  • #ID 内容 と送る(例: #K7Q2MX 却下)→ 古い依頼にも回答できる。ID はメッセージ内の #K7Q2MX

  • 回答は最初の 1 回だけ有効。期限切れ・回答済みの依頼にはそう返事します

HTTP API

すべて Authorization: Bearer <API_TOKEN> が必要です(/health と /webhook を除く)。

メソッド

パス

本文 / 結果

POST

/api/notify

{ "text": "...", "to"?: "U...", "sendAt"?: "2026-10-18T07:00+09:00" } → 200 { "ok": true }。sendAt が未来なら 202 { "ok": true, "scheduled": { id, text, sendAt, createdAt } }

GET

/api/scheduled

{ "scheduled": [{ id, text, sendAt, createdAt }, ...] }(送信予定順)

DELETE

/api/scheduled/:id

予約の取り消し → { "ok": true }(ないときは 404)

POST

/api/requests

{ "question": "...", "options"?: [...], "allowFreeText"?: true, "timeoutSeconds"?: 86400, "to"?: "U..." } → 201 依頼オブジェクト

GET

/api/requests/:id

依頼オブジェクト { id, status, question, options, answer: { kind, value, answeredAt } | null, ... }

GET

/api/quota

{ "limit": 200, "used": 12 }

POST

/webhook

LINE からの Webhook(署名検証)

GET

/health

{ "ok": true }

to を省略すると DEFAULT_TO(なければ ALLOWED_USER_IDS の先頭)に送ります。to に許可リスト外の userId を指定すると 400 になります。

制限と注意

  • 月 200 通: LINE の無料プランでは push(notify と ask_approval)が 1 回 1 通として数えられます。「受け付けました」の返事は reply なので数えられません。line-approval quota で確認できます

  • 反映に最大 1 分ほどかかることがあります: Workers KV は結果整合のため、ボタンを押してから answered が読めるまで遅れる場合があります。人の承認待ちという用途では問題にならない想定です

  • ボタンはメッセージ内(Flex Message)に表示されるので、スマホでも PC 版 LINE でも押せます。スマホでは入力欄の上にもクイックリプライのボタンが出ます(こちらは最新のメッセージのみ)

  • 予約送信の上限: 予約は同時に 100 件まで(超えると 409)、365 日先まで。予約はすべて KV の 1 キー(sched:index)にまとめて保存し、毎分の Cron は get 1 回だけ読みます(KV の list は無料枠で 1 日 1,000 回までのため使いません)。読み取りは 1 日 1,440 回、書き込みは予約・取り消し・送信のときだけです

  • 予約送信の注意: KV は結果整合のため、予約直後や送信直後に一覧へ反映されるまで遅れることがあり、まれに送信が 1 分ほど遅れたり、同じ予約が 2 回届いたりする可能性があります。LINE への送信が失敗した場合は次の分に再試行します(最大 5 回)。予約した通知も月 200 通に数えられます

  • 1 対 1 のトークのみ: グループ・複数人での承認は対象外です

ローカル開発

LINE に実際には送らず(LINE_DRY_RUN=true)、ログに出すだけのモードです。

cp api/.dev.vars.example api/.dev.vars
npm run dev                                   # http://localhost:8787

# 別のターミナルで
export LINE_APPROVAL_URL=http://localhost:8787 LINE_APPROVAL_TOKEN=local-dev-token
node client/dist/cli.js ask "テスト" --wait 120 --print value

# さらに別のターミナルで、LINE で返信したことにする(ID は dev サーバーのログの #XXXXXX)
npm run simulate -- tap XXXXXX 0              # ボタン 0 番を押す
npm run simulate -- text "承認"                # 文字で返信
npm run simulate -- text "hi" --user Uother   # 許可リスト外のユーザー(無視される)

テスト:

npm test          # 署名検証・許可リスト・依頼のライフサイクル・CLI・MCP
npm run typecheck

ディレクトリ構成

api/       Cloudflare Worker(Webhook 受信・HTTP API・KV)
client/    クライアントライブラリ、CLI(line-approval)、MCP サーバー(line-approval-mcp)
scripts/   ローカル開発用の Webhook シミュレータ

API(api/)とクライアント(client/)は分離しており、クライアントは HTTP 経由でのみ API を呼びます。


English summary

line-approval-bridge lets an AI agent (Claude Code scheduled tasks, scripts) send you a LINE message and wait for your reply or approval, then branch on it. The official LINE Bot MCP Server can only send; this project adds the receiving side: a Cloudflare Worker that verifies LINE webhook signatures, accepts replies only from allowlisted userIds, stores them in Workers KV, and exposes a bearer-token HTTP API. Scheduled notifications (sendAt / --at) are stored in a single KV key and sent by a per-minute Cron Trigger, so they arrive even while your machine sleeps. A stdio MCP server (notify, ask_approval, get_reply) and a CLI (exit codes for branching) wrap the API. Runs on free tiers (Cloudflare Workers + LINE's 200 messages/month plan; acknowledgements use the free reply API). Includes a local dry-run mode with a signed-webhook simulator and tests for signature verification, the allowlist and the request lifecycle.

License

MIT

Related MCP Connectors

Related MCP Servers

  • A
    license
    B
    quality
    D
    maintenance
    Enables AI agents to send messages, manage rich menus, and interact with users through LINE Official Accounts via the LINE Messaging API. Supports both individual messaging and broadcasting to all followers with text and customizable flex messages.
    18
    3,294 npm
    Apache 2.0
  • A
    license
    A
    quality
    C
    maintenance
    Enables an AI agent to connect to a LINE Official Account via the LINE Messaging API, sending push and broadcast text or flex messages, managing rich menus, and retrieving user profiles, message quotas, follower IDs, and group summaries.
    13
    Apache 2.0
  • A
    license
    A
    quality
    C
    maintenance
    Connects an AI agent to a LINE Official Account through the LINE Messaging API, enabling it to push and broadcast text or flex messages to users. It also supports retrieving user profiles, message quotas, follower IDs, and group summaries, plus creating and managing rich menus.
    13
    5 npm
    Apache 2.0
  • A
    license
    Not graded
    quality
    A
    maintenance
    Lets AI agents run one or many LINE Official Accounts through natural conversation, covering broadcasts, Flex and tappable Rich Messages, Thai-ready rich menus, coupons, audiences, insights, and LINE Shopping via 51 tools. It adds pre-flight quota and quiet-hour guardrails, multi-OA switching and fan-out, and delivers assets like images and rich-menu graphics without external hosting or setup.
    1,491 npm
    MIT