# line-bot-ops-mcp MCP server for running your own LINE bot from Claude, Cursor or any MCP client. It covers the part generic LINE MCP servers can't: your bot's webhook queue. Ask *why* a message was never answered, see the failed jobs, and put them back in the queue. > "Why did the bot stop replying?" → `line_queue_health`, `line_failed_jobs`, `line_retry_job` > "How many followers did we gain yesterday, and how much push quota is left?" > "Switch user U123… to the seller menu." ## Tools | Tool | What it does | Needs | |---|---|---| | `line_bot_info` | Display name, basic ID, chat mode of the Official Account | LINE | | `line_message_quota` | Monthly push quota and how much is used | LINE | | `line_followers_insight` | Followers, targeted reaches and blocks for one day | LINE | | `line_get_profile` | Profile of one user who added the bot | LINE | | `line_richmenu_list` | All Rich Menus, and which is the default | LINE | | `line_push_text` | Send a text to one user, group or room | LINE | | `line_link_richmenu` | Show a specific Rich Menu to one user, or remove it | LINE | | `line_queue_health` | Jobs per status, age of the oldest pending job, jobs stuck in processing | Supabase | | `line_failed_jobs` | Most recent failed jobs with their error and message text | Supabase | | `line_retry_job` | Put a failed job back to pending | Supabase | | `line_find_users` | Search linked users by display name or role | Supabase | | `line_broadcast` | Send to every friend. Only registered when `LINE_MCP_ALLOW_BROADCAST=true` | LINE | The LINE tools work with any Messaging API channel. The queue tools expect the `line_jobs` and `line_users` tables in [`schema.sql`](schema.sql), which is the schema every project generated by [create-line-bot](https://github.com/MankhongGarden/create-line-bot) already has. If your bot doesn't use a queue, leave the Supabase variables unset and use the LINE tools only. ## Setup ```json { "mcpServers": { "line-bot-ops": { "command": "npx", "args": ["-y", "line-bot-ops-mcp"], "env": { "LINE_CHANNEL_ACCESS_TOKEN": "...", "SUPABASE_URL": "https://.supabase.co", "SUPABASE_SERVICE_ROLE_KEY": "..." } } } } ``` With Claude Code: ```bash claude mcp add line-bot-ops -e LINE_CHANNEL_ACCESS_TOKEN=... -e SUPABASE_URL=... -e SUPABASE_SERVICE_ROLE_KEY=... -- npx -y line-bot-ops-mcp ``` Or as a Claude Code plugin, which asks for the values below and adds a triage skill: ```bash claude plugin marketplace add MankhongGarden/line-bot-ops-mcp claude plugin install line-bot-ops@mankhonggarden ``` | Variable | Required | | |---|---|---| | `LINE_CHANNEL_ACCESS_TOKEN` | for LINE tools | Long-lived channel access token | | `SUPABASE_URL` | for queue tools | `NEXT_PUBLIC_SUPABASE_URL` is accepted too, so a Next.js `.env.local` works as is | | `SUPABASE_SERVICE_ROLE_KEY` | for queue tools | Server-side only. Never ship it to a browser | | `LINE_MCP_ALLOW_BROADCAST` | no | `true` to register `line_broadcast` | The server starts without any of these. A tool whose credentials are missing returns an error naming the variable. ## Safety - Broadcast is off unless you opt in, because it messages every friend and can't be undone. - Every tool declares all four MCP hints (read-only, destructive, idempotent, open-world). Only push, Rich Menu changes, retries and broadcast are marked as writes, and all but push are marked destructive. - LINE IDs are validated (`U`/`C`/`R` + 32 hex, `richmenu-` + 32 hex) before anything is sent, so tool input can't reach other LINE API paths. - The channel access token is only ever sent to `https://api.line.me`; the service role key only to your own `SUPABASE_URL`. - `line_retry_job` only moves jobs that are `failed`. Reply tokens expire soon after the event, so a retried job that replies may fail again; push is the fallback. ## Development ```bash npm install npm test # builds, then runs the tool contract tests with a mocked LINE API ``` ## Related - [create-line-bot](https://github.com/MankhongGarden/create-line-bot): scaffolds the bot this server is built to operate (fast-ack webhook, queue, idempotency, LIFF). - [Surviving LINE's 5-second webhook timeout on Vercel](https://github.com/MankhongGarden/line-webhook-fast-ack-dispatcher-worker): why the queue exists. ## Privacy Runs locally and collects nothing. See [PRIVACY.md](PRIVACY.md) for exactly what is sent where. ## License MIT