bybreakingmind· 1 MCP server
LINE bot plugin for Claude Code — connect LINE messages to your Claude Code session via MCP
$git clone https://github.com/breakingmind/claude-external-plugins-lineInstalls into the current project.
Install claude-external-plugins-line by running `git clone https://github.com/breakingmind/claude-external-plugins-line`, then use it for the current task and follow its documentation at https://github.com/breakingmind/claude-external-plugins-line.
| 1 | # LINE Plugin for Claude Code |
| 2 | |
| 3 | [English](#english) | [繁體中文](#繁體中文) |
| 4 | |
| 5 | --- |
| 6 | |
| 7 | ## English |
| 8 | |
| 9 | Connect a LINE bot to your Claude Code with an MCP server. |
| 10 | |
| 11 | The MCP server receives LINE messages via webhook and provides tools to Claude to reply. When you message the bot, the server forwards the message to your Claude Code session. |
| 12 | |
| 13 |  |
| 14 | |
| 15 | ### Prerequisites |
| 16 | |
| 17 | - [Bun](https://bun.sh) — the MCP server runs on Bun. Install with `curl -fsSL https://bun.sh/install | bash`. |
| 18 | - A public HTTPS endpoint for the LINE webhook. Use a tunnel: |
| 19 | - [ngrok](https://ngrok.com): `npx ngrok http 3000` |
| 20 | - [Cloudflare Tunnel](https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/): `cloudflared tunnel --url http://localhost:3000` |
| 21 | |
| 22 | ### Quick Setup |
| 23 | |
| 24 | **1. Create a LINE Messaging API channel.** |
| 25 | |
| 26 | 1. Go to the [LINE Developers Console](https://developers.line.biz/console/) |
| 27 | 2. Create a Provider (if you don't have one) |
| 28 | 3. Create a **Messaging API** channel |
| 29 | 4. Under **Messaging API** tab: |
| 30 | - Disable "Auto-reply messages" |
| 31 | - Disable "Greeting messages" |
| 32 | - Note your **Channel access token** (issue a long-lived token) |
| 33 | 5. Under **Basic settings** tab: |
| 34 | - Note your **Channel secret** |
| 35 | |
| 36 | **2. Install the plugin manually.** |
| 37 | |
| 38 | Since this plugin is not yet on the official marketplace, follow these steps: |
| 39 | |
| 40 | ```sh |
| 41 | # 1. Create plugin cache directory |
| 42 | mkdir -p ~/.claude/plugins/cache/claude-plugins-official/line/0.0.1/.claude-plugin |
| 43 | |
| 44 | # 2. Copy plugin metadata (run from this repo's root) |
| 45 | cp .claude-plugin/plugin.json \ |
| 46 | ~/.claude/plugins/cache/claude-plugins-official/line/0.0.1/.claude-plugin/plugin.json |
| 47 | |
| 48 | # 3. Create MCP config (update the path to match your machine) |
| 49 | cat > ~/.claude/plugins/cache/claude-plugins-official/line/0.0.1/.mcp.json << 'EOF' |
| 50 | { |
| 51 | "mcpServers": { |
| 52 | "line": { |
| 53 | "command": "bun", |
| 54 | "args": ["--silent", "/path/to/claude_external_plugins_line/server.ts"] |
| 55 | } |
| 56 | } |
| 57 | } |
| 58 | EOF |
| 59 | |
| 60 | # 4. Remove orphan marker if it exists |
| 61 | rm -f ~/.claude/plugins/cache/claude-plugins-official/line/0.0.1/.orphaned_at |
| 62 | ``` |
| 63 | |
| 64 | Then add the plugin to `~/.claude/plugins/installed_plugins.json`: |
| 65 | |
| 66 | ```json |
| 67 | { |
| 68 | "line@claude-plugins-official": { |
| 69 | "pluginId": "line", |
| 70 | "marketplaceId": "claude-plugins-official", |
| 71 | "installedAt": "2026-01-01T00:00:00.000Z", |
| 72 | "sourceDir": "/path/to/claude_external_plugins_line" |
| 73 | } |
| 74 | } |
| 75 | ``` |
| 76 | |
| 77 | And enable it in `~/.claude/settings.json`: |
| 78 | |
| 79 | ```json |
| 80 | { |
| 81 | "enabledPlugins": { |
| 82 | "line@claude-plugins-official": true |
| 83 | } |
| 84 | } |
| 85 | ``` |
| 86 | |
| 87 | > Make sure the project-level `.mcp.json` in this repo is renamed or disabled to avoid conflicts: |
| 88 | > ```sh |
| 89 | > mv .mcp.json .mcp.json.disabled |
| 90 | > ``` |
| 91 | |
| 92 | **3. Save credentials.** |
| 93 | |
| 94 | ``` |
| 95 | /line:configure token <your-channel-access-token> |
| 96 | /line:configure secret <your-channel-secret> |
| 97 | ``` |
| 98 | |
| 99 | Both values are written to `~/.claude/channels/line/.env`. |
| 100 | |
| 101 | **4. Start a tunnel.** |
| 102 | |
| 103 | In a separate terminal: |
| 104 | |
| 105 | ```sh |
| 106 | npx ngrok http 3000 |
| 107 | ``` |
| 108 | |
| 109 | Note the HTTPS URL (e.g. `https://abc123.ngrok.io`). |
| 110 | |
| 111 | **5. Set the webhook URL in LINE Developers Console.** |
| 112 | |
| 113 | Under your channel's **Messaging API** tab: |
| 114 | - **Webhook URL**: `https://abc123.ngrok.io/webhook` |
| 115 | - Enable **Use webhook** |
| 116 | - Click **Verify** (Claude Code must be running with the channel flag for this to succeed) |
| 117 | |
| 118 | **6. Launch Claude Code with the LINE channel.** |
| 119 | |
| 120 | > This plugin is in local development and is not on Claude's approved channels allowlist. |
| 121 | > You must use the `--dangerously-load-development-channels` flag every time. |
| 122 | |
| 123 | Before launching, kill any leftover server processes to avoid port 3000 conflicts: |
| 124 | |
| 125 | ```sh |
| 126 | pkill -f "bun.*server" 2>/dev/null |
| 127 | sleep 2 |
| 128 | claude --dangerously-load-development-channels plugin:line@claude-plugins-official |
| 129 | ``` |
| 130 | |
| 131 | A successful startup shows: |
| 132 | ``` |
| 133 | Listening for channel messages from: plugin:line@claude-plugins-official |
| 134 | ``` |
| 135 | |
| 136 | > **Keep ngrok running between Claude restarts.** As long as ngrok stays up, the webhook URL does not change and you do not need to update the LINE Console. |
| 137 | |
| 138 | **7. Pair.** |
| 139 | |
| 140 | Message your LINE bot from the LINE app — it replies with a 6-character pairing code. In your Claude Code session: |
| 141 | |
| 142 | ``` |
| 143 | /line:access pair <code> |
| 144 | ``` |
| 145 | |
| 146 | Your next message reaches the assistant. |
| 147 | |
| 148 | **8. Lock it down.** |
| 149 | |
| 150 | Pairing is for capturing LINE user IDs. Once you're in, switch to `allowlist`: |
| 151 | |
| 152 | ``` |
| 153 | /line:access policy allowlist |
| 154 | ``` |
| 155 | |
| 156 | ### Configuration |
| 157 | |
| 158 | #### Changing the webhook port |
| 159 | |
| 160 | Default port is `3000`. To change it: |
| 161 | |
| 162 | ``` |
| 163 | /line:configure port 8080 |
| 164 | ``` |
| 165 | |
| 166 | Then update your tunnel and webhook URL accordingly. |
| 167 | |
| 168 | #### Environment variables |
| 169 | |
| 170 | All config lives in `~/.claude/channels/line/.env`: |
| 171 | |
| 172 | ``` |
| 173 | LINE_CHANNEL_ACCESS_TOKEN=<token> |
| 174 | LINE_CHANNEL_SECRET=<secret> |
| 175 | LINE_WEBHOOK_PORT=3000 |
| 176 | LINE_ACCESS_MODE=static # optional: pin config at boot, no runtime writes |
| 177 | ``` |
| 178 | |
| 179 | Shell environment variables take precedence over the `.env` file. |
| 180 | |
| 181 | ### Access control |
| 182 | |
| 183 | See **[ACCESS.md](./ACCESS.md)** for DM policies, group support, delivery config, and skill commands. |
| 184 | |
| 185 | Quick reference: |
| 186 | - User IDs start with `U` (e.g. `U4af4980dc9d2b...`) |