Skip to main content
Glama
yomi

yomi

Official
by RikaiDev

Yomi(読み)— 個人用LINE MCPサーバー

Yomiは、あなたの個人アカウント向けのオープンソースLINE MCPサーバーです。ブラウザもボットアカウントもLINE公式クライアントも使わずに、Claudeや任意のローカルAIエージェントから、すべての会話の読み取り、返信、画像送信、検索ができます。

この名前には複数の読み方があります。読み(yomi)— 読むこと:メッセージを解析するだけでなく、あなたのように状況を読むこと。詠み(yomi)— 詠むこと:黙って読むのではなく、あなたに読み返してくれること。そして**黄泉*(yomi)— 到達不能な領域。黄泉帰り(yomigaeri)の「yomi」そのものです。「黄泉から帰る」という意味です。二つの領域を行き来する使者のように、Yomiは封印と静寂を通過して、会話の奥深くにまだ読めるメッセージを光の下に引き出します。失われた歴史を呼び起こすのではなく、まだ消えていないものを再び見えるようにするのです。*

LINEの公式Bot MCPサーバーがMessaging APIを通じてAIエージェントをLINE公式アカウントに接続するのとは異なり、Yomiは既存の個人LINEアカウントと会話にセカンダリデバイスとして接続します。

YomiはLINEのTCompact-over-HTTPSプロトコルを直接話し、Letter-Sealing(E2EE)メッセージとメディアを復号し、その結果を小さなstdio MCPサーバーを通じて任意のAIエージェントに公開します。Claude Desktop(または任意のMCPクライアント)でそれを指定すると、エージェントはあなたと同じようにLINEを追跡できます。読み取り、返信、画像送信、メンション、ローカルでの全履歴検索が可能で、get_insightを使えば状況を読むこともできます。どの会話があなたの返信を待っているか、誰があなたの世界をつなげているか、何が期限切れになっているか。

公式APIもボットアカウントもウェブフックも不要です。Yomiはあなた自身のアカウントにセカンダリデバイスとしてログインします。

ガイド: LINE MCPサーバーとは? · LINE MCP 是什麼?Yomi、官方 Bot 與桌面自動化的差異.

license runtime protocol npm

非公式。 Yomiは独立した個人プロジェクトであり、LINEとは提携・承認されていません。使用するとLINEの利用規約に違反する可能性があり、アカウントに追加のクライアントを実行するとレート制限や停止のリスクがあります。これはあなた自身のアカウントを読むことを目的としています。自己責任で使用してください。免責事項を参照してください。


はじめに

ネイティブデスクトッププレビュー

Yomi Desktopは、LINEの受信トレイとローカルエージェントのワークスペースを1つのネイティブアプリにまとめます。独自のランタイムをバンドルしているため、ユーザーはNodeのインストール、ターミナルの起動、このリポジトリのクローン、YOMI_RUN_MJSの設定は不要です。 ネイティブデスクトップは、後述のClaude Desktop MCPB拡張機能とは別物です。

プラットフォーム

一般ユーザー向けパッケージ

署名状況

インストール体験

macOS 14+、Apple Silicon

Yomi-Desktop-macOS-arm64-<version>.dmg

Developer ID署名およびApple公証済み

DMGを開く → Yomiをアプリケーションにドラッグ → Yomiを開く

Windows 10/11 x64

Yomi-Desktop-Windows-x64-<version>-Setup.exe

信頼されたOSS署名アプリケーションの申請中

署名とインストーラのスモークテストが通るまでダウンロードは利用できません

macOSパッケージは実際のダウンロードアプリの経路でテスト済みです。検疫されたDMG、/Applicationsへのインストール、Gatekeeper評価、初回起動、バンドルランタイムのメッセージ更新、ターミナル不要のLINEログインフォーム。Windowsインストーラには同等のアプリ内電話/PINログインフローが含まれており、リリース前にネイティブWindowsランナーでテストされています。

デスクトップビルドは実験的かつ非公式です。LINEの変更で壊れる可能性があり、追加のクライアントを実行するとアカウントが危険にさらされる可能性があります。テストアカウントを推奨し、最新のバックアップを保持してください。プレビューインストーラは、プラットフォームの署名が利用可能になった後にのみGitHubプレリリースとして公開されます。

デスクトップリリースプロセス、コード署名ポリシー、プライバシーポリシーを参照してください。

MCPサーバーとデスクトップ拡張機能

Node.jsとLINEアカウントが必要です。Yomiはnpxを通じてローカルで実行されます。このリポジトリをクローンしたり、Bunをインストールしたり、何かをビルドする必要はありません。最初にnode --versionを実行し、コマンドがない場合やバージョンがサポートされていない場合は、現在のLTSをインストールしてください。

Yomiのローカル検索インデックスはNode組み込みのnode:sqliteを使用するため、v22.13以降(ただしv23.0〜v23.3を除く) が必要です。v23.0〜v23.3はv22.13より新しいのに、そのモジュールがまだありません(22.13.0と23.4.0の両方でフラグが解除されました)。現在のLTSならどれでも問題ありません。これはpackage.jsonのengines.nodeです。Yomiの他の部分は古いNodeでも動作しますが、検索、スコープ、キャプチャは動作しません。

⚠️ Yomiには、自分のマシンで実行するクライアントが必要です。 クラウド専用ツール(ChatGPT、Claude.aiウェブ)ではYomiを実行できません。Claude DesktopまたはClaude CodeでYomiを設定すると、チャットとCoworkの両方で動作します。DesktopはあなたのマシンでYomiを起動し、Coworkのローカルセッションがそれを読み込むためです。CoworkにYomiをインストールしてもらわないでください。Coworkのシェルは使い捨てVM内で実行され、あなたのマシンではないため、そこでインストールされたものはセッション終了時に消えます。以下の手順は、自分のターミナルで自分で実行してください。

実際に使用するクライアントを選択し、そのセクションだけに従ってください。Claude CodeとClaude Desktopは別々のMCP設定を持っています。一方を設定しても他方は設定されません。

最も簡単な方法であり、コマンドラインが一切不要な唯一の方法です。Claude Desktopには独自のNodeランタイムが同梱されているため、他に何もインストールする必要はありません。

  1. 最新リリースから、お使いのマシン用のバンドルをダウンロードします。

    マシン

    ファイル

    Windows (Intel/AMD)

    yomi-win32-x64.mcpb

    Mac (Apple Silicon)

    yomi-darwin-arm64.mcpb

    Linux (x64)

    yomi-linux-x64.mcpb

  2. Claude Desktopで設定 → 拡張機能を開き、ダウンロードしたファイルをそのページにドラッグします(またはファイルをダブルクリックするだけでも構いません)。

  3. 要求内容を確認し、インストールをクリックします。

  4. 会話を開始して*「LINEにログイン」*と言います。Yomiがフォームを表示するので、電話番号を入力し、電話で確認します。どの時点でもターミナルは不要です。

これにより設定ファイルが完全にスキップされ、後述のWindows MSIXバグも回避されます。

Coworkユーザーへの注意: CoworkにYomiをインストールしてもらわないでください。Coworkのシェルは使い捨てVM内で実行されます。あなたのマシンではなく、実際のターミナルに入力することはありません。上記の3クリックで自分でバンドルをインストールしてください。インストール後、Coworkのローカルセッションは他のツールと同様にYomiを使用できます。

  1. npxの完全なパスを見つけます。

macOS / Linux: which npx
Windows:       where npx
  1. Claude Desktopの設定ファイルを開きます。

macOS:   ~/Library/Application Support/Claude/claude_desktop_config.json
Windows: %APPDATA%\Claude\claude_desktop_config.json

⚠️ Windows: ドキュメントに記載されたパスは、Claudeが実際に読み取るパスではない可能性があります。 Claude DesktopはMSIXパッケージとして配布されており、そのファイルシステムは仮想化されています。アプリは設定を

%LOCALAPPDATA%\Packages\Claude_pzs8sxrjxfjjc\LocalCache\Roaming\Claude\claude_desktop_config.json

から読み取りますが、設定 → 開発者 → 設定を編集は仮想化されていない%APPDATA%\Claude\ファイルを開きます。これらは同期されない別々のファイルであるため、ドキュメントに記載されたパスに正しいYomi設定を書いても静かに無視されます。エラーもログもなく、Yomiは単に表示されません。これはclaude-code#26073で、まだ未解決です。再起動後もYomiが表示されない場合は、同じ設定を上記のLocalCacheパスにも書いてください。(Claude Codeや、MSIX外にインストールされたDesktopには該当しません。)

  1. mcpServersの下にYomiを追加し、例のcommandを手順1で出力された完全なパスに置き換えます。Windowsでは、JSONのパス内の各\は\\と記述する必要があります。

{
  "mcpServers": {
    "yomi": {
      "command": "/opt/homebrew/bin/npx",
      "args": ["@rikaidev/yomi"]
    }
  }
}

たとえば、Windowsのパスは"C:\\Program Files\\nodejs\\npx.cmd"のようになります。どちらの例も盲目的にコピーせず、自分のマシンで報告されたパスを使用してください。

⚠️ ここで指定するnpxは、Yomiを実行するNodeを決定しません。 macOSとLinuxではnpxは#!/usr/bin/env nodeで始まるスクリプトであるため、Claude DesktopのPATHで最初に見つかるnodeを実行します。あなたが指定したnpxの隣にインストールされたNodeではありません。DesktopはデスクトップセッションからPATHを継承しますが、それは多くの場合あなたのターミナルのものとは異なります。また、バージョンマネージャ(nvm、fnm、asdf、voltaなど)は独自のnodeを他のすべてより優先させます。そのため、which npxが完全に最新のインストールを報告しても、Yomiは古いNodeで起動する可能性があります。

症状は明確です。ログイン、読み取り、送信はすべて機能しますが、検索、スコープ、キャプチャが失敗し、ログにNo such built-in module: node:sqliteと表示されます。Yomiはそのエラーで実際に取得したランタイムを出力します。推測せずにそれを読んでください。

修正方法は、サーバーにPATHを与え、その最初のエントリにサポートされているnodeを置くことです。

"yomi": {
  "command": "<the npx path from step 1>",
  "args": ["-y", "@rikaidev/yomi"],
  "env": { "PATH": "<dir holding a supported node><sep><a base PATH>" }
}

区切り文字: macOS/Linuxでは:、Windowsでは;。その後に使用可能なベースを残してください(/usr/local/bin:/usr/bin:/binまたはお使いのプラットフォームの同等物)。これはサーバーのPATHを先頭に追加するのではなく置き換えるため、npxは通常のツールを必要とします。

commandに絶対パスのnodeを指定しても機能しません。どれほどもっともらしく見えてもです。npxはパッケージ自身のbinを子プロセスとして起動し、そのために再びPATHからnodeを解決するため、commandは誰がnpxを実行するかを選ぶだけで、誰がYomiを実行するかは選びません。PATHを設定することが実際にサーバーに届く方法です。

AIエージェントで設定していますか? MCP設定は現在、手書きではなくエージェントによって書かれることがほとんどです。そのため、上記の手順は自分のマシンを読む人間向けに書かれています。エージェントはプレースホルダを出力するのではなく値を解決すべきです。また、この設定には明確に述べる価値のある落とし穴が1つあります。commandにnpxを指定してもランタイムは固定されません。手順:

  1. 実際にYomiのインデックスが必要とするモジュールを持つNodeを見つける — バージョン番号から推測しないこと:

    node -e 'require("node:sqlite")' && command -v node    # POSIX
    node -e "require('node:sqlite')" && where node         # Windows

    これが例外を投げる場合、そのNodeは検索/スコープ/キャプチャには使えません。他のインストール(which -a node、nvm ls、fnm list、…)を試して、成功するものを見つけてから先に進んでください。

  2. 上記のJSONに従って、そのNodeのディレクトリをenv.PATHに書き込み、その後にベースとなるPATHを維持してください。ディレクトリはターゲットマシン上で解決してください(ステップ1のパスのdirname)。このREADMEの例をコピーしないでください — それらはApple Silicon Homebrewのパスであり、ほぼどこでも間違っています。

    代わりにcommandに絶対パスのnodeを入れないでください。それはより強力な修正のように見えますが、実際はそうではありません。npxはパッケージのbinを子プロセスとして起動し、その子プロセスに対してPATHからnodeを再解決するため、commandは誰がnpxを実行するかを決めるだけです。これは推測ではなく測定に基づいています — PATHの先頭にNode 20がある場合、commandで固定してもサーバーにはNode 20が渡されました。

    command -vもラッパーを返すことがあり、実際のバイナリではない場合があります — ヒープシム、ローカル優先のnpxラッパー、バージョンマネージャーのスタブはすべて一般的で、クライアントの作業ディレクトリによって動作が異なるものもあります。「本当の」ものを見つけようと推論しないでください。ステップ3で解決します。

  3. インデックスに触れるツールで検証してください。yomi versionは検証ではありません — SQLiteを開かずに文字列を出力するだけなので、検索を実行できないNodeでも成功します。get_scope_policyを呼び出してください。SQLiteが必要で、LINEログインは不要です。ポリシーテキストが返れば、ランタイムは正しいです。失敗した場合、エラーは実際に実行されたNodeと、そのNodeが必要としたものを示します。

  4. Claude Desktopを完全に終了して再起動してください。他の何よりも先に、Settings → DeveloperでYomiが読み込まれていることを確認してください。Yomiがそこにリストされていない場合、Claudeは設定を読んでいません — Windowsの場合は、ステップ2のMSIX警告を参照してください。リストされれば、ツールはチャットとCoworkのローカルセッションの両方で利用可能です。

このセットアップにClaude Codeをインストールする必要はありません。

claude mcp add yomi -- npx @rikaidev/yomi

新しいclaudeセッションを開始してください。Yomiツールが自動的に表示されるはずです。このコマンドはClaude Codeのみを設定します。Claude Desktopは設定しません。

この形式はランタイムをPATHに任せます。claudeセッションが解決するnodeがサポートされているものであれば問題ありません — これはClaude Desktopのものとは異なり、表示されているのと同じPATHです。node -e 'require("node:sqlite")'で確認してください。例外が発生する場合、またはPATHに依存したくない場合は、Nodeを明示的に指定してください:

claude mcp add yomi -e PATH="$(dirname "$(command -v node)"):$PATH" -- npx -y @rikaidev/yomi

どちらの場合も、yomi versionではなくget_scope_policyで検証してください。バージョンコマンドはSQLiteを開かずに文字列を出力するため、検索を実行できないNodeでも成功します。

このリポジトリのクローン内でClaude Codeを実行していますか? スペックを@rikaidev/yomi@latestと指定してください。タグがない場合、npxは最初にローカルbinを探します。このリポジトリではpackage.jsonが"bin": {"yomi": ...}を宣言していますが、node_modules/.binにはリンクされていません — そのためnpxはインストールをスキップしてsh: yomi: command not foundで終了します。明示的なタグを指定すると、公開されたパッケージを取得します。これはYomi自体の作業コピーにのみ影響します。他の場所ではタグなしの形式で問題ありません。

この標準設定はほとんどのMCPクライアントで動作します:

{
  "mcpServers": {
    "yomi": {
      "command": "npx",
      "args": ["@rikaidev/yomi"]
    }
  }
}

Cursor Settings → MCP → Add new MCP Server → 名前をyomiにし、コマンドタイプ、値: npx @rikaidev/yomi

または、プロジェクトルートの.cursor/mcp.jsonに追加してください。

.vscode/mcp.jsonに追加:

{
  "servers": {
    "yomi": {
      "command": "npx",
      "args": ["@rikaidev/yomi"]
    }
  }
}

~/.config/opencode/opencode.jsonに追加:

{
  "mcp": {
    "yomi": {
      "type": "local",
      "command": ["npx", "@rikaidev/yomi"],
      "enabled": true
    }
  }
}
codex mcp add yomi npx @rikaidev/yomi

または~/.codex/config.tomlに追加:

[mcp_servers.yomi]
command = "npx"
args = ["@rikaidev/yomi"]

cline_mcp_settings.jsonに追加:

{
  "mcpServers": {
    "yomi": {
      "type": "stdio",
      "command": "npx",
      "args": ["-y", "@rikaidev/yomi"]
    }
  }
}

~/.codeium/windsurf/mcp_config.jsonに追加 — 標準設定と同じJSONです。

amp mcp add yomi -- npx @rikaidev/yomi

Advanced settings → Extensions → Add custom extension → 名前yomi、タイプSTDIO、コマンド: npx @rikaidev/yomi

grok mcp add yomi -- npx @rikaidev/yomi

初回ログイン

接続後、エージェントに伝えてください:

"LINEにログインして — 私の番号は+8869XXXXXXXXです。"

携帯電話でデバイスを承認し(ログインを参照)、次のように伝えてください:

"未読のLINEを要約して、返信待ちの相手を教えて。"


Related MCP server: line-desktop-mcp

できること

YomiはMCP上で20のツールを公開しています(名前を挙げる価値のあるものは表を参照)。大きな読み取り結果はトークン効率の良いTOONを使用し、小さなステータスと書き込み結果はコンパクトなJSONを使用します。エラーはプレーンテキストのままで、メディアはネイティブのMCP画像/音声/リソースコンテンツを使用します。 以下で「正直なエラー」とは、問題を明示する明示的な失敗(例: missing_decrypt_material)を意味します — Yomiはフォールバック、プレースホルダー、偽の成功を決して作り出しません。

読み取り

ツール

機能

get_unread_digest

ワンショット: 未読メッセージがあるすべての会話について、それぞれの最新メッセージ、E2EE復号済み、送信者名を解決して返します。「未読を要約して次のステップを提案」のために作られています。読み取り専用 — 何も既読にしません。

list_conversations

未読数と復号済みの最終メッセージプレビュー付きのチャット/グループ/ルーム。新しいアクティビティが先頭。

get_chat_messages

1つの会話を復号済みで取得。beforeカーソルでさらに深くページングできます。各メッセージには生のMENTIONメタデータが含まれ、誰が@メンションされたかがわかります(テキスト内のリテラルな@nameはメンションではありません)。

get_message_media / get_message_image

復号済みの添付ファイル(画像/動画/音声/ファイル)。非メディアの場合は正直なエラー。

find_contact / list_contacts

名前の部分一致による友達リスト検索、または全リスト。生のLINEデータ — ファジースコアリングや親密度ランキングはありません。

get_group_members

永続グループのメンバー。グループレコードのないアドホックルームは、偽の空リストを返すのではなく正直に失敗します。

洞察(メッセージだけでなく状況を読む)

ツール

機能

get_insight

ローカルインデックス上のコンパクトなコンテキストネットワーク — エージェントが推論する構造であり、メッセージのダンプではありません。connectors(あなたのチャットのうち2つ以上に登場する人々、およびそれらの削除でコンタクトグラフが分割される構造的ブリッジ)、relationships(会話ごとのエンゲージメントと、そこでのあなたの典型的な返信リズム)、open(最新メッセージがあなたのものではない会話で、そのリズムに対してどれだけ遅延しているかでランク付けされ、それぞれプレビュー付き)を返します。構造と統計のみを計算します。メッセージが誰に宛てられているか、オープンなリクエストか締めくくりの承認か、ニックネームの実際の正体かを判断することは意図的にしません — それはエージェントが各プレビューから読み取る言語であり、スレッドを判断する価値がある場合にのみget_chat_messagesを逆参照します。TOONでエンコードされ、同等のJSONの約¼のトークンです。

書き込み(これらは実際に送信します — 下書きではありません)

ツール

機能

send_message

今すぐE2EEテキストメッセージを送信します(1:1はペアワイズキー、グループ/ルームはグループキー)。オプションのmentionsで実際の@メンションを添付でき、LINEがハイライトして通知します。省略すると、リテラルな@nameは誰にも通知しない単なるテキストです。1回の呼び出しで1送信、リトライなし。

send_image

暗号化し、LINE OBSにアップロードし、E2EE画像を今すぐ送信します。1:1、グループ、ルームで動作します。1回の呼び出しで1送信。キーを解決できない場合やアップロードが拒否された場合は正直に失敗します。

mark_read

相手が見える既読通知を送信します。明示的な場合のみ — メッセージの読み取りやバックグラウンドキャプチャは何も既読にしません。

検索(ローカル、会話横断 — LINEにはそのようなプリミティブはありません)

ツール

機能

search_messages

インデックス化されたすべての会話に対するハイブリッド検索。初回使用時に自動収集し、チャット間で結果を多様化し、各ヒットの周囲の小さなコンテキストウィンドウを返します。何も隠されないよう mode(hybrid/semantic/keyword)を返します。

collect_messages

ローカルDBへの明示的な一括インデックス化+セマンティック検索用の埋め込み。一括フェッチが許可されている唯一のツールで、呼び出しごとに1回だけ実行され、タイマーでは実行されません。

スコープとプライバシー(すべてオフラインで動作、LINEセッション不要)

ツール

機能

exclude_chats

会話を拒否リストに追加し、すでにインデックス化されたデータをパージします。将来のキャプチャだけではありません — 古いデータをインデックスに残したままの拒否リストは偽りのプライバシーです。

include_chats

会話を再度許可します(パージされたデータは復元されません)。

list_excluded_chats / get_scope_policy

拒否リスト/完全なプライバシーポリシーを表示します(PRIVACY.md から読み込み)。

セッション

ツール

機能

login / login_complete

パスワードレスなセカンダリデバイスログイン。下記参照。login は既存セッションなしで呼び出せる唯一のツールです。


ログイン

前提条件: プライマリのスマートフォンで、設定 › 我的帳號 › 允許自其他裝置登入 (設定 › アカウント › 他のデバイスからのログインを許可)を有効にしてください。これがないとLINEはこのデバイスにサインインプロンプトを一切表示しません — 初回ログインがハングしているように見える最も一般的な原因はこれです。

⚠️ デスクトップセッションは同時に1つのみ: LINEではアカウントごとにデスクトップクライアントセッションは同時に1つだけ許可されています。Yomiはデスクトップのセカンダリデバイス(DESKTOPMAC)として接続するため、Yomiにログインすると公式LINEデスクトップアプリはサインアウトされます(そしてLINEデスクトップにサインインし直すとYomiのセッションは無効になります)。Yomiと公式LINEデスクトップクライアントを同時に使用することはできません。

エージェントにE.164形式の電話番号を渡すだけで済みます — ツールを呼び出す際にリージョン自体はエージェントが提供します(例: +886 番号の場合は TW)。

YomiはLINEの**パスワードレス(セカンダリデバイス)**フローを駆動します。ログインがどのように表示されるかはMCPクライアントによって異なります:

  • MCP elicitation 機能を持つクライアント — login は電話番号/リージョンの入力を求め、ダイアログにPINを表示し、完了までブロックします。1回の呼び出しで、PINがモデルを経由することはありません。電話番号がトランスクリプトに入ることはありません。

  • それを持たないクライアント(例: 現在のClaude Desktop) — 2回の呼び出し。login(電話番号+リージョン付き)は結果にPINを返します。プライマリのスマートフォンのLINEでそれを入力し、デバイスを承認します。その後 login_complete を呼び出します。これは電話が確認するまでブロックします。エージェントは login_complete をすぐに呼び出すべきです — 待機処理はそちらが行うため、あなたが報告することは何もありません。

  • ターミナルから — npx @rikaidev/yomi login はPINも含めてフロー全体をstdoutで実行します。常にフォールバックとして利用可能です。

唯一重要となる期限はLINE側のものです: PINが表示されてから入力してデバイスを承認するまで約3分です。Yomi自身のクライアントはその後も数分間リッスンし続けるため、スマートフォンが遅いことが失敗の原因になることは決してありません — LINEの3分間のコード有効期限だけが問題です。

ログインすると、ログイン証明書を含むセッションが永続化され(下記参照)、今後のログインではPINが完全にスキップされます。

インタラクティブビューをレンダリングするクライアント向けに、実験的なMCP Apps UI(ui://yomi/login カード)もあります。これは仕様に準拠しておりMCP Inspectorでレンダリングされますが、一部のホストはビューハンドシェイクを完了せずにリソースをフェッチするため、表示専用でありクリティカルパス上には決してありません — 上記のフローは常に機能します。

セッションと認証情報

Yomiは独自のログインを所有しています。起動時に resumeSession() を1回呼び出し、macOSキーチェーン(サービス dev.rikai.yomi.credentials、アカウント line)からLINEセッションを読み取り、必要に応じてトークンを静かに更新します。

  • ファーストパーティ認証情報。 パスワードレスログインは認証トークン、リフレッシュトークン、証明書、MID、そしてE2EE鍵ペア自体を永続化し、その後それらを読み戻して書き込みが実際に完了したことを検証します。永続化できないログインは、次の再起動時に静かに失敗するのではなく、ログイン時に明示的に失敗します。

  • 共有セッション。 セッションは標準の dev.rikai.yomi.credentials キーチェーンエントリ(またはローカル認証情報ストア)に保存され、Yomi MCPとYomi Desktopがまったく同じLINEログインセッションをシームレスに共有できます。

  • プラットフォームに関する注意。 macOSではセッションはログインキーチェーンに保存されます。LinuxとWindowsでは、Yomiは現在ローカルJSONファイルにフォールバックします — 機能はしますが、OSのシークレットストアほど保護されておらず、macOSのパスほどテストもされていません。ネイティブのセキュアストレージバックエンド(libsecret / DPAPI)が計画されています。それまでは、非macOSインストールはそれに応じて扱ってください。

login とオフラインのスコープ/検索ツールを除くすべてのツールは、セッションがない場合に正直なエラーを返します。Yomiはそれ以外は純粋なクエリサーバーです — ポーリングもバックグラウンドでのバックフィルも行わず、各ツール呼び出しは必要なLINEリクエストだけを行い、collect_messages だけが一度に多くのチャットにまたがってフェッチする唯一の経路です。


検索

LINEには会話をまたいだ検索はありません。Yomiはローカルに検索を構築します。インデックスはリポジトリ内のgitignoreされたSQLiteデータベース(data/search-index.db)です — あなたのマシンから何も出て行きません。

検索は設計上ハイブリッドです。常にFTS5キーワード検索(bigram前処理されたテキストに対するbm25。これにより単語境界のないCJK部分文字列もカバーされます)を実行し、埋め込みが存在する場合はセマンティック検索も実行して、2つのランクリストをReciprocal Rank Fusionで融合します。純粋なセマンティック検索は埋め込まれていないメッセージにある完全一致を静かに落とし、純粋なキーワード検索は言い換えを見逃します。両方を融合することで、正確な用語と意味の一致が一緒に表面化します。レスポンスの mode フィールドは常にどの手法が寄与したかを報告します。

セマンティックランキングは各メッセージを独自のベクトルとして保持します。実際にインデックス化されたLINE会話に対するテストでは、重複する会話ウィンドウを埋め込むと中央のメッセージが希釈され、検索品質が低下することがわかりました。そのためコンテキストはランキング後にのみ追加されます: Yomiは1つのチャットが上位結果を埋め尽くすのを制限し、各勝者を両側2メッセージずつ展開して、エージェントがヒットに意味を与えたやり取りを見られるようにします。埋め込み自体を弱めることはありません。

セマンティックランキングは**Xenova/bge-small-zh-v1.5(BAAI汎用埋め込み、小型、中国語プライマリだが多言語)をtransformers.js経由で使用します。埋め込み推論は完全にプロセス内でCPU上で実行されます — メッセージテキストが外部に送信されることは決してありません。**

唯一の注意点は一度だけのモデルダウンロードです: 最初の collect_messages または search_messages で、transformers.jsがモデル(約90MB)を**huggingface.co**からフェッチしてローカルにキャッシュします。以降の実行は完全にオフラインです。その最初のフェッチはモデル重みのためのHuggingFaceへの送信HTTPSリクエストです — あなたのIPとどのモデルがダウンロードされているかは伝わりますが、メッセージコンテンツもLINEデータも含まれません。Yomiを完全にエアギャップ環境で使用する必要がある場合は、最初の検索の前にtransformers.jsキャッシュを事前に投入(またはローカルのモデルディレクトリを指定)して、ネットワーク呼び出しが一切行われないようにしてください。


セカンダリデバイスの現実(「古いメッセージを取得できない」を信頼する前に読んでください)

Yomiはアカウントのセカンダリデバイスとして動作します。これが何を見られるかを形作ります:

  • Letter SealingのないグループチャットはLINEサーバー上で平文です — 完全な履歴とメディア、制限なし。

  • Letter SealingのあるグループチャットはE2EEであり、そこではエポックが重要です。 そのようなグループは共有のグループキーで暗号化されており、これは(メンバーシップの変更時、またはクライアントが新しいものをプロビジョニングしたときに)ローテーションします。LINEはデバイスに現在のグループキーしか渡しません — 置き換えられたキーをフェッチするAPIはありません。したがって、セカンダリデバイスは保持しているキーのエポック以降のメッセージを復号できます。Yomiが現在のキーを取得する前の古いエポックで送信されたメッセージは、以前の履歴を読めるグループであっても、復号不能で返ってくることがあります。これはLetter Sealingのエポックごとのグループキーに固有のものであり、ここでのバグではありません。横方向にも影響します: あなたのスマートフォンが保持するエポックとYomiが保持するエポックは同じである必要はないため、2つのデバイスは同じグループの異なるスライスをそれぞれ読むことができます。

  • Yomiのインストール自体は何もローテーションしないため、「Yomiをインストールする前」は正しい境界ではありません。 Yomiは既存のグループキーを解決するだけで、キーを登録(発行)することは決してありません。発行はグループの共有シークレットをすべてのメンバーに対してローテーションし、以前のキーで暗号化されたすべてのメッセージを孤立させるからです。したがって、新規インストールは現在のキーを取得し、最後のローテーションまで読み戻します — これはインストールより数か月前かもしれません。境界はインストール日ではなく、最後の再キーイングです。そしてYomiは一度エポックを見るとそのキーを保持するため、インストール後のローテーションでは両側を読むことができます。グループが今日まで完全に復号不能で返ってくる場合、それはこの制限ではありません — 報告してください。

  • 1:1メディアはアカウントレベルのE2EEキーチェーンを使用します。これはセカンダリデバイスが完全に保持します(LINEはペアリング中に同期します)— Yomiは見える1:1の画像/ファイルを復号できます。

  • 1:1履歴のバックフィルが唯一の実際の制限です。 LINEはセカンダリデバイスにグループの場合のように過去の1:1メッセージ履歴を渡しません。Yomiが接続中に受信したメッセージは正常に復号されます。ペアリングより前の1:1履歴を深くスクロールすると空で返ってくることがあります。これはLINEサーバー側の制限であり、ここでのバグではありません。

復号が本当に失敗した場合、Yomiは明示的な missing_decrypt_material エラーを返します — 偽のカードやプレースホルダーは決してありません。沈黙は正直です。捏造された結果はそうではありません。


開発

Yomiのソースコードに取り組むコントリビューター向け(bun またはNode.js 24+が必要 — .nvmrc はCIがインストールするのと同じ24を固定しているため、このディレクトリで nvm use するとそれを取得します。nvmは engines を読まないため、2つは別々に記載され、テストで保護されていることに注意してください):

bun install                 # install dependencies (or npm install)
bun run.mjs                 # run the stdio MCP server
bun run.mjs login           # run the login flow in a terminal
npm run build               # tsc --noEmit — type-check only (Yomi ships & runs from src/)
npm test                    # bun test

ビルドは型チェックとコンパイルのみを行います。このリポジトリは自身のビルドの一部としてライブのLINEサーバーと通信しません。MCPクライアントを接続して login を呼び出すことが、実際にセッションを開始する方法です。

src/
  line/     LINE protocol core: TCompact/Thrift codec, E2EE (Letter-Sealing,
            group keys, media), Talk/Auth/Sync service clients, session state,
            passwordless login flow.
  auth/     Credential store (macOS Keychain, JSON-file fallback off-darwin).
  search/   Local cross-conversation index (SQLite + FTS5) and the offline
            embedding pipeline (transformers.js).
  mcp/      The stdio server: tool schemas, handlers, the privacy-policy loader,
            and the experimental MCP Apps login view (mcp/ui/).
  util/     [TAG]-prefixed logger (stderr only — stdout is the MCP JSON-RPC stream).

Yomiが人間向けに書き出すものはすべてstderrに出力されます。stdoutはMCP JSON-RPCストリーム用に予約されています。うっかり console.log を入れるとプロトコルが破損します — サーバーが到達できるパスには追加しないでください。


プライバシー

デフォルトでは、Yomi はすべての会話をローカルのオンデバイス検索インデックスに登録し、エージェントがそれらを横断検索できるようにします — 全取得がデフォルトで、チャットごとにオプトアウト可能です。アップロードされるものは一切なく、デバイスから送信されるデータは、エージェント自身が返信の中で提示するものだけです。(Yomi 自身が行う唯一の非 LINE ネットワーク呼び出しは、初回検索時のHuggingFace からの一回限りの埋め込みモデルダウンロードです — モデルの重みは入りますが、メッセージ内容は出ません。検索を参照)。PRIVACY.md が正式なポリシーであり、Yomi は接続時(および get_scope_policy 経由)に同じテキストをエージェントに提示するため、一括読み取りの前にデフォルトを開示できます。


免責事項

Yomi は独立した非公式の個人プロジェクトであり、学習と自身の LINE アカウントへのアクセスを目的として構築されています。LINE コーポレーションとは提携、承認、または推奨の関係はありません。「LINE」は各権利所有者の商標です。

Yomi の実行は LINE の利用規約に違反する可能性があり、アカウントで追加クライアントを操作すると、レート制限やアカウント停止につながる可能性があります。Yomi はご自身のアカウントとデータにアクセスすることを目的としています。使用方法については、すべて利用者の責任となります。本ソフトウェアは、いかなる保証もなく「現状のまま」提供されます — LICENSE を参照してください。

謝辞

Yomi の LINE プロトコル実装は、3 つのオープンソースプロジェクトを参考に作成されました。これらのフィールドレイアウト、E2EE チャンク順序、リクエスト形状、および Thrift 定義が、この独立した実装の基盤となっています:

  • evex-dev/linejs (MIT) — リクエスト形状と Letter-Sealing E2EE ペイロードレイアウト。

  • DeachSword/CHRLINE (BSD-3-Clause) — プロトコルのフィールドレイアウトとパスワードレスログインフロー。

  • er1ce/LINE-Protocol (Apache-2.0) — Thrift 列挙型定義 (ContentType、MessageRelationType、ServiceCode)。

それらのライセンスが要求する通り、各プロジェクトの著作権表示と完全なライセンス文は NOTICE に転載されています。

ライセンス

MIT

Available Tools

41 tools
accept_invitationA

Accepts a group/chat invitation for your LINE account — you join the chat. Use for a group you were invited to (its chatId appears with invited status). One accept per call.

NameRequiredDescriptionDefault
chatIdYesLINE group/room MID whose invitation to accept, as returned by list_conversations.
add_friendA

Adds a person to your LINE friends by their MID (e.g. from get_group_members or find_contact). One add per call.

NameRequiredDescriptionDefault
midYesMID of the person to add as a friend, e.g. from get_group_members.
block_contactA

Blocks a contact for your LINE account — they can no longer message you. Reversible with unblock_contact. One block per call.

NameRequiredDescriptionDefault
midYesMID of the contact to block.
cancel_reactionA

Removes this account's reaction from a LINE message. Undoes a react_message. One cancellation per call.

NameRequiredDescriptionDefault
messageIdYesLINE message id whose reaction to remove, as returned by get_chat_messages.
collect_messagesA

Bulk-fetch recent messages from LINE conversations into Yomi's local cross-conversation search index (LINE has no native cross-chat search). Fetches up to perChat per chat (default 100) for chatIds, or all conversations when omitted, and best-effort embeds them for semantic search — re-running also repairs any messages still missing a vector. A background capture loop keeps the index current on its own, so call this only to force a reconcile or backfill specific chats. Undecryptable messages are skipped, not fabricated.

NameRequiredDescriptionDefault
chatIdsNoLINE chat/group/room MIDs to collect from, as returned by list_conversations. Omit to collect from all conversations.
perChatNoMaximum recent messages to fetch per chat (default 100).
create_groupA

Creates a new LINE group/room immediately with the given members (no message is sent). chatType 0 = group (invitees must accept before joining), 1 = room (members added directly); default 1. Provide name and mids (initial members, e.g. from find_contact). One create per call.

NameRequiredDescriptionDefault
midsYesMIDs of the initial members to add.
nameYesName for the new group.
chatTypeNoLINE chat type: 0 = group (invite-based), 1 = room (direct add). Default 1.
exclude_chatsA

Add conversations to Yomi's privacy denylist. Excluded chats are (1) skipped by future collect_messages/search_messages auto-collect — never fetched or indexed — and (2) PURGED now: their already-indexed messages and embeddings are deleted from the local index in the same call. A real privacy action, not just a future filter. Local-index operation; works without a live LINE session.

NameRequiredDescriptionDefault
chatIdsYesLINE chat/group/room MIDs to exclude, as returned by list_conversations.
find_contactA

Find LINE friends whose display name contains name (case-insensitive substring). Returns each match's mid for send_message. Raw friend-list lookup — no ranking, no fuzzy scoring.

NameRequiredDescriptionDefault
nameYesSubstring to match against friends' display names, case-insensitive.
get_chat_messagesA

Fetch messages from one LINE conversation. Text is E2EE-decrypted when keys are available; each message has fromName (resolved sender), a mediaType flag (image/video/audio/file) plus messageId for get_message_media, and mentions (LINE's raw contentMetadata.MENTION, or null — a literal "@name" in text is not itself a mention). Without before, returns the most recent count. With before (id/deliveredTime of the oldest message already seen), returns one older page — repeat to page further back.

NameRequiredDescriptionDefault
countNoMaximum number of messages to return (default 50).
beforeNoCursor to fetch messages older than this point. Use the id and/or deliveredTime of the oldest message already seen.
chatIdYesLINE chat/group/room MID, as returned by list_conversations.
get_group_membersA

List the members of one LINE group (mid + displayName each). Resolves persistent groups (c...); ad-hoc rooms (r...) without a group record return an honest error, never a fabricated empty list.

NameRequiredDescriptionDefault
chatIdYesLINE group chat MID, as returned by list_conversations.
get_insightA

A compact "what needs my attention" context network over the local index — you make the final call, this assembles the evidence cheaply. Nodes: connectors (people across ≥2 of your chats, with structural bridges) and relationships (per-conversation engagement, reply rhythm, recency). open: conversations whose latest message is NOT yours, ranked by how overdue they are relative to your usual reply rhythm there, each with fromName (last speaker), a preview of the latest message, overdueRatio/typicality, and a lastMessageId pointer. It carries NO message threads and makes NO judgement about addressee, nicknames, or open-request vs closing-ack — those are language understanding you do by reading each preview (a group message may be addressed to someone else, who then owns it), fetching the full thread with get_chat_messages only for the few worth it. Reads across all conversations (denylist-excluded dropped). Empty only when the index is empty.

NameRequiredDescriptionDefault
chatIdNoOptional focus: restrict `relationships` and `pending` to this chat (as returned by list_conversations). Omit to scan all conversations.
sinceHoursNoLookback window in hours, measured back from the newest captured message (not wall-clock). Default 504 (21 days).
get_message_imageA

Download and decrypt one LINE image message. Legacy alias of get_message_media restricted to images; prefer get_message_media for video/audio/file.

NameRequiredDescriptionDefault
chatIdYesLINE chat/group/room MID the message belongs to. Required to locate E2EE key material.
previewNoFetch the smaller preview object instead of the full-resolution original.
messageIdYesLINE message id, as returned by get_chat_messages.
get_message_mediaA

Download and decrypt one LINE media message of any downloadable type (image, video, audio, file). Returns image/audio MCP content, or an embedded resource blob (with filename when known) for video/file. Non-media messages (text, sticker refs, unsupported types) return an honest error naming the content type — never fabricated bytes.

NameRequiredDescriptionDefault
chatIdYesLINE chat/group/room MID the message belongs to. Required to locate E2EE key material.
previewNoFetch the smaller preview object instead of the full-resolution original (images/video only).
messageIdYesLINE message id, as returned by get_chat_messages.
get_scope_policyA

Return Yomi's data-capture privacy policy (the disclosure to show the user) plus the current list of excluded conversations. Call this to show the user, in concrete terms, what Yomi captures by default and how to exclude conversations.

NameRequiredDescriptionDefault

No parameters

get_unread_digestA

One-shot unread digest: every LINE conversation with unread messages (all pages of the inbox, newest activity first), each with its most recent messages (default 10), E2EE-decrypted, with resolved sender names. Saves calling list_conversations then get_chat_messages per chat. Read-only: never marks anything read, never touches the search index; denylist-excluded conversations are omitted. Returns an empty list when nothing is unread — never fabricated.

NameRequiredDescriptionDefault
limitNoMaximum number of unread conversations to return, most recently active first (default: all of them).
perChatNoMaximum recent messages to include per unread conversation (default 10).
include_chatsA

Remove conversations from Yomi's denylist, re-allowing future capture. Does NOT restore data purged when the chat was excluded — capture resumes from empty history going forward. Local-index operation; works without a live LINE session.

NameRequiredDescriptionDefault
chatIdsYesLINE chat/group/room MIDs to re-include.
invite_memberA

Invites members into a LINE group immediately. Invitees must accept before joining. Provide mids (from find_contact or get_group_members). One call per invite batch.

NameRequiredDescriptionDefault
midsYesMIDs of the people to invite.
chatIdYesLINE group/room MID to invite into, as returned by list_conversations.
kick_memberA

Removes (kicks) members from a LINE group immediately — they lose access at once (re-adding needs a fresh invite); visible to every member. Provide mids (from get_group_members). One call per removal batch.

NameRequiredDescriptionDefault
midsYesMIDs of the members to remove.
chatIdYesLINE group/room MID to remove members from, as returned by list_conversations.
leave_groupA

Makes THIS LINE account leave a group immediately — it loses access to the group and its history. One leave per call.

NameRequiredDescriptionDefault
chatIdYesLINE group/room MID to leave, as returned by list_conversations.
list_contactsA

List the authenticated user's full LINE friend list as-is (mid + displayName). No ranking, no interaction-frequency ordering.

NameRequiredDescriptionDefault

No parameters

list_conversationsA

List LINE conversations (chats, groups, rooms) with unread counts, a preview of the last message, and a human-readable name (group title, or the other party's display name for a 1:1).

NameRequiredDescriptionDefault
limitNoMaximum number of conversations to return (default 20).
list_excluded_chatsA

List the conversations currently on Yomi's privacy denylist. Returns [{ chatId, name }]; name is best-effort resolved when a live LINE session exists, otherwise null — never a fabricated placeholder. Local-index operation; works without a live LINE session.

NameRequiredDescriptionDefault

No parameters

list_stickersA

List the sticker packages this LINE account OWNS — the only stickers it can send. Returns each package's packageId (STKPKGID), title, and version (STKVER). Get individual sticker ids via search_stickers, then send_sticker. Read-only.

NameRequiredDescriptionDefault
languageNoLocale for package titles, e.g. 'en' or 'zh-Hant'. Defaults to 'en'.
loginA

Log in to LINE via the passwordless secondary-device flow. Requires 設定 > 我的帳號 > 允許自其他裝置登入 enabled on the primary phone — with it off LINE never prompts that phone and NO login can succeed, so raise this with the human up front rather than after a failure. On MCP clients with form elicitation, this call first confirms that setting, then prompts for phone/region and PIN and completes login by itself; if the human says the setting is off, it returns the enabling steps without starting a login (relay them verbatim, then call login again). On clients without it (e.g. Claude Desktop), phone/region come from the arguments or a persisted login, and this returns as soon as LINE issues the PIN (or reports none needed) — then call login_complete IMMEDIATELY (do not wait for the human). LINE gives ~3 minutes from PIN display to confirm on the phone; login_complete blocks past that, so calling it late only wastes that window.

NameRequiredDescriptionDefault
phoneNoPhone number in E.164 form, e.g. +8869XXXXXXXX. Omit to be prompted (elicitation) or to reuse a persisted number.
regionNoRegion code, e.g. TW, JP, TH, ID, US. Omit to be prompted (elicitation) or to reuse a persisted region.
login_completeA

Finish a passwordless login that login started on a client without form elicitation (not needed on form-elicitation-capable clients). No arguments. Call immediately after login returns — do not wait for the human. Blocks while they enter the PIN (skipped if a stored certificate is valid) and approve the device, then returns the profile. LINE's real deadline is ~3 minutes from PIN display. Errors if no login is pending.

NameRequiredDescriptionDefault

No parameters

mark_readA

Send a LINE read receipt (mark a conversation read up to messageId, or the latest when omitted) — a real action the other party can see. Use ONLY when the user explicitly wants to mark a chat read; reading (get_chat_messages, get_unread_digest) and background capture never mark read. Fails honestly if there is nothing to mark.

NameRequiredDescriptionDefault
chatIdYesLINE chat/group/room MID to mark read, as returned by list_conversations.
messageIdNoOptional message id to mark read up to. Omit to mark read up to the latest message.
preview_stickerA

Show sticker preview images (MCP image content from the public sticker CDN) so you and the user can SEE them before sending. Give a packageId (from list_stickers/search_stickers) to preview its first stickers, or add a stickerId to preview just one. Each image is labeled with its stickerId + packageId for send_sticker. Read-only.

NameRequiredDescriptionDefault
limitNoMax stickers to preview when no stickerId is given (default 8).
packageIdYesSticker package id (STKPKGID) to preview.
stickerIdNoOptional specific sticker id (STKID) to preview just that sticker.
react_messageA

Adds a reaction to a LINE message, visible to the conversation. reactionType: 2 = 👍 LIKE, 3 = ❤️ LOVE, 4 = 😆 LAUGH, 5 = 😮 SURPRISE, 6 = 😢 SAD, 7 = 😡 ANGRY (default 2). One reaction per call.

NameRequiredDescriptionDefault
messageIdYesLINE message id to react to, as returned by get_chat_messages.
reactionTypeNoPredefined reaction: 2=👍LIKE, 3=❤️LOVE, 4=😆LAUGH, 5=😮SURPRISE, 6=😢SAD, 7=😡ANGRY. Default 2.
rename_groupA

Renames a LINE group/chat immediately; the new name is visible to every member. Works on groups/rooms (chatId starting with c/r). One rename per call.

NameRequiredDescriptionDefault
nameYesNew group name.
chatIdYesLINE group/room MID to rename, as returned by list_conversations.
search_messagesA

Search across your LINE messages. Hybrid ranking: FTS5 keyword search (covers every indexed message, so exact matches are never dropped) fused with semantic similarity when embeddings are available — the mode field reports which contributed (hybrid | semantic | keyword). If the index is empty and a session is live, it auto-collects all conversations first; a populated index searches locally with no network. Empty index with no session returns an honest notice, never a fabricated match list.

NameRequiredDescriptionDefault
limitNoMaximum number of results to return (default 20).
queryYesSearch query. Plain keywords and natural-language descriptions both work — keyword matching catches exact terms, semantic matching catches paraphrases.
search_stickersA

Search the account's OWNED sticker packages by title and expand each match into its individual sticker ids (STKID), ready for send_sticker. Case-insensitive substring match on the package title. Read-only.

NameRequiredDescriptionDefault
limitNoMax matching packages to expand with sticker ids (default 8).
queryYesSubstring to match against owned package titles (case-insensitive).
languageNoLocale for package titles to match against, e.g. 'en' or 'zh-Hant'. Defaults to 'en'.
send_audioA

Sends an E2EE audio message to a LINE conversation immediately (same pipeline as send_file). Provide exactly one of filePath or audioBase64; optional durationMs sets the recipient player length. Works for 1:1/group/room. One send per call.

NameRequiredDescriptionDefault
chatIdYesLINE chat/group/room MID to send to, as returned by list_conversations.
fileNameNoOptional original filename (used for the upload name; defaults to the basename of filePath or audio.m4a).
filePathNoLocal filesystem path to the audio file. Mutually exclusive with audioBase64.
durationMsNoOptional audio duration in milliseconds, for the recipient player progress bar.
audioBase64NoBase64-encoded audio bytes. Mutually exclusive with filePath.
send_contactA

Shares a LINE contact card to a conversation immediately — the recipient sees a tappable card for contactMid (e.g. from find_contact or get_group_members). displayName is optional (resolved from the mid when omitted). Works for 1:1/group/room. One send per call.

NameRequiredDescriptionDefault
chatIdYesLINE chat/group/room MID to send to, as returned by list_conversations.
contactMidYesMID of the person whose contact card to share, as returned by find_contact or get_group_members.
displayNameNoOptional display name for the card. Resolved from contactMid when omitted.
send_fileA

Sends an E2EE file attachment (any type — .docx, .pdf, .zip, …) to a LINE conversation immediately (same pipeline as send_image; the original filename is sealed end-to-end). Works for 1:1/group/room; fails honestly if the key cannot be resolved or the upload is rejected. One send per call. Provide exactly one of filePath or fileBase64; fileName is required with fileBase64 (and overrides the basename when given with filePath).

NameRequiredDescriptionDefault
chatIdYesLINE chat/group/room MID to send to, as returned by list_conversations.
fileNameNoOriginal filename shown to the recipient (sealed E2EE). Required with fileBase64; optional with filePath (defaults to its basename).
filePathNoLocal filesystem path to the file. Mutually exclusive with fileBase64.
fileBase64NoBase64-encoded file bytes. Mutually exclusive with filePath; requires fileName.
send_imageA

Sends an E2EE image to a LINE conversation immediately (encrypt → upload to OBS → send). Works for 1:1/group/room; fails honestly if the key cannot be resolved or the upload is rejected. One send per call. Provide exactly one of imagePath or imageBase64.

NameRequiredDescriptionDefault
chatIdYesLINE chat/group/room MID to send to, as returned by list_conversations.
imagePathNoLocal filesystem path to the image file. Mutually exclusive with imageBase64.
imageBase64NoBase64-encoded image bytes. Mutually exclusive with imagePath.
send_locationA

Sends a location (map pin) to a LINE conversation immediately — latitude/longitude plus optional title (place name) and address. Works for 1:1/group/room. One send per call.

NameRequiredDescriptionDefault
titleNoOptional place name shown on the pin.
chatIdYesLINE chat/group/room MID to send to, as returned by list_conversations.
addressNoOptional address shown under the pin.
latitudeYesLatitude in decimal degrees.
longitudeYesLongitude in decimal degrees.
send_messageA

Sends a text message to a LINE conversation immediately (not a draft). Always E2EE (pairwise for 1:1, group key for group/room); fails honestly rather than sending plaintext if the key cannot be resolved. One send per call. To @mention someone, put the visible "@name " into text AND pass a matching mentions entry — without mentions, "@name" is plain text and notifies no one. Resolve MIDs via get_group_members or find_contact first.

NameRequiredDescriptionDefault
textYesPlain-text message body, including the literal "@name" text for any mentions — mentions only mark up text that is already there.
chatIdYesLINE chat/group/room MID to send to, as returned by list_conversations.
mentionsNoOptional @mentions. Each entry marks a span of `text` as a mention of one user, which LINE highlights and notifies. Omit to send `text` as plain, non-notifying text.
replyToMessageIdNoOptional message id (from get_chat_messages) this replies to — LINE renders a quoted reply. Omit for a normal message.
send_stickerA

Sends a LINE sticker to a conversation immediately, named by stickerId (STKID) + packageId (STKPKGID). Only OWNED stickers can be sent — get ids from search_stickers/list_stickers. Works for 1:1/group/room. One send per call.

NameRequiredDescriptionDefault
chatIdYesLINE chat/group/room MID to send to, as returned by list_conversations.
versionNoSticker version (STKVER). Defaults to "1".
packageIdYesLINE sticker package id (STKPKGID).
stickerIdYesLINE sticker id (STKID).
send_videoA

Sends an E2EE video to a LINE conversation immediately (same pipeline as send_file; uses LINE chunked video encryption so it plays and integrity-verifies on official clients). Provide exactly one of filePath or videoBase64; optional durationMs sets the scrubber length. Works for 1:1/group/room. One send per call.

NameRequiredDescriptionDefault
chatIdYesLINE chat/group/room MID to send to, as returned by list_conversations.
fileNameNoOptional original filename (used for the upload name; defaults to the basename of filePath or video.mp4).
filePathNoLocal filesystem path to the video file. Mutually exclusive with videoBase64.
durationMsNoOptional video duration in milliseconds, for the recipient player scrubber.
videoBase64NoBase64-encoded video bytes. Mutually exclusive with filePath.
unblock_contactA

Unblocks a previously blocked contact for your LINE account. Undoes block_contact. One unblock per call.

NameRequiredDescriptionDefault
midYesMID of the contact to unblock.
unsend_messageA

Retracts (unsends) one of YOUR OWN LINE messages for everyone — deletes it from the conversation for all participants and CANNOT be undone. LINE allows unsending only your own messages. SAFETY GATE: you must pass confirm: true, or the call refuses so it can never fire by accident. One unsend per call.

NameRequiredDescriptionDefault
confirmYesMust be true to proceed. Retraction is irreversible; the call refuses unless this is explicitly true.
messageIdYesLINE message id to retract (must be your own), as returned by get_chat_messages.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 1 tool updatev0.6.2
    • Changedget_unread_digest1 field changed
      • changedInput schema / properties / limit / description
        Previous value: -"Maximum number of conversations to scan for unread (default 20)."New value: +"Maximum number of unread conversations to return, most recently active first (default: all of them)."
  2. 39 tool updatesv0.4.1
    • Addedaccept_invitation
    • Addedadd_friend
    • Addedcancel_reaction
    • Addedcollect_messages
    • Addedcreate_group
    • Addedexclude_chats
    • Addedfind_contact
    • Addedget_chat_messages
    • Addedget_group_members
    • Addedget_insight
    • Addedget_message_image
    • Addedget_message_media
    • Addedget_scope_policy
    • Addedget_unread_digest
    • Addedinclude_chats
    • Addedinvite_member
    • Addedkick_member
    • Addedleave_group
    • Addedlist_contacts
    • Addedlist_conversations
    • Addedlist_excluded_chats
    • Addedlist_stickers
    • Addedlogin_complete
    • Addedmark_read
    • Addedpreview_sticker
    • Addedreact_message
    • Addedrename_group
    • Addedsearch_messages
    • Addedsearch_stickers
    • Addedsend_audio
    • Addedsend_contact
    • Addedsend_file
    • Addedsend_image
    • Addedsend_location
    • Addedsend_message
    • Addedsend_sticker
    • Addedsend_video
    • Addedunblock_contact
    • Addedunsend_message
  3. 38 tool updatesv0.3.0
    • Removedaccept_invitation
    • Removedadd_friend
    • Removedcancel_reaction
    • Removedcollect_messages
    • Removedcreate_group
    • Removedexclude_chats
    • Removedfind_contact
    • Removedget_chat_messages
    • Removedget_group_members
    • Removedget_message_image
    • Removedget_message_media
    • Removedget_scope_policy
    • Removedget_unread_digest
    • Removedinclude_chats
    • Removedinvite_member
    • Removedkick_member
    • Removedleave_group
    • Removedlist_contacts
    • Removedlist_conversations
    • Removedlist_excluded_chats
    • Removedlist_stickers
    • Removedlogin_complete
    • Removedmark_read
    • Removedpreview_sticker
    • Removedreact_message
    • Removedrename_group
    • Removedsearch_messages
    • Removedsearch_stickers
    • Removedsend_audio
    • Removedsend_contact
    • Removedsend_file
    • Removedsend_image
    • Removedsend_location
    • Removedsend_message
    • Removedsend_sticker
    • Removedsend_video
    • Removedunblock_contact
    • Removedunsend_message
  4. 40 tool updatesv0.2.0
    • First observedaccept_invitation
    • First observedadd_friend
    • First observedblock_contact
    • First observedcancel_reaction
    • First observedcollect_messages
    • First observedcreate_group
    • First observedexclude_chats
    • First observedfind_contact
    • First observedget_chat_messages
    • First observedget_group_members
    • First observedget_message_image
    • First observedget_message_media
    • First observedget_scope_policy
    • First observedget_unread_digest
    • First observedinclude_chats
    • First observedinvite_member
    • First observedkick_member
    • First observedleave_group
    • First observedlist_contacts
    • First observedlist_conversations
    • First observedlist_excluded_chats
    • First observedlist_stickers
    • First observedlogin
    • First observedlogin_complete
    • First observedmark_read
    • First observedpreview_sticker
    • First observedreact_message
    • First observedrename_group
    • First observedsearch_messages
    • First observedsearch_stickers
    • First observedsend_audio
    • First observedsend_contact
    • First observedsend_file
    • First observedsend_image
    • First observedsend_location
    • First observedsend_message
    • First observedsend_sticker
    • First observedsend_video
    • First observedunblock_contact
    • First observedunsend_message

TDQS

A4.1/5.0

Scored across 41 tools

Disambiguation4/5

Most tools target a distinct resource+action, and descriptions actively disambiguate the tricky clusters (get_unread_digest vs list_conversations vs get_insight; find_contact vs list_contacts; search_stickers vs list_stickers). The only real overlaps are the explicitly-flagged legacy alias get_message_image vs get_message_media and collect_messages vs search_messages' auto-collect, both of which are documented so an agent won't misselect.

Naming Consistency5/5

Nearly every tool follows a clean snake_case verb_noun pattern (get_*, list_*, send_*, search_*, create_/rename_/invite_/kick_/leave_group, block_/unblock_contact). The send_* family, group-management family, and privacy family are each internally uniform. Only 'login' / 'login_complete' deviate slightly, which is negligible.

Tool Count3/5

41 tools is heavy and sits well above the comfortable 3-15 range, largely because seven distinct send_* variants (message/image/file/audio/video/location/contact/sticker) plus a full login pair inflate the surface. Each tool is genuinely distinct and earns its place in a rich LINE domain, but some consolidation (e.g. a single send_media with a type param) would be reasonable.

Completeness5/5

The surface covers the full lifecycle: auth (login/login_complete), conversation listing/search/digest/insight, message fetch and media download, all outbound message types, group CRUD and membership, contact add/block/find, reactions/unsend, stickers, and a complete privacy denylist lifecycle (exclude/include/list/policy). No obvious dead ends for the stated purpose.

Maintenance

ActivityNo data
ResponsivenessOutdated data

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    D
    maintenance
    Enables AI tools to read and send messages through LINE Desktop via MCP, supporting manual or automatic sending without official LINE API tokens.
    118 npm
    127
    MIT
  • A
    license
    Not graded
    quality
    D
    maintenance
    Enables AI tools to read and send LINE messages by automating the LINE Desktop application, with macOS OCR-based reading and idle-aware scheduling.
    118 npm
    1
    MIT
  • A
    license
    Not graded
    quality
    B
    maintenance
    Enables AI assistants to read, search, and reply to personal LINE messages, including end-to-end-encrypted chats and media, all decrypted locally.
    MIT