line-cua-mcp
A macOS MCP server for LINE that reads encrypted local database snapshots to fetch chat history and sends messages via LINE UI without cursor movement.
README
line-cua-mcp
語言:繁體中文(台灣)|English README
macOS 專用的 LINE Desktop MCP server。讀取訊息時,直接讀 LINE 本機加密資料庫的唯讀快照;這條讀取路徑完全在背景執行,不碰 UI:不移動游標、不切換視窗焦點、不用 OCR、不捲動畫面,而且 LINE 關閉時也可以讀。送訊息時則必須透過 LINE UI,由 cua-driver 以不移動游標的方式操作;送出前會用 OCR 讀取聊天標題,並用本機資料庫交叉比對目標聊天。
實驗性警告
這是一個實驗性個人工具,不是成熟產品,也不是可以放心給一般使用者安裝的正式產品。它會讀取你本機 LINE Desktop 的加密資料庫,並且在你明確要求時透過 LINE 介面送出訊息。請把它當成研究用/自用的原型工具:
- 只在你自己的 Mac、你自己的 LINE 帳號、你自己的資料上使用。
- 首次設定需要擷取本機 LINE 資料庫金鑰;這通常會啟動一個重新簽章的 LINE 副本並要求你登入,可能會讓原本的 LINE Desktop 被登出。
- 送訊息雖然有 OCR 和本機資料庫交叉比對來降低風險,但仍不應視為零風險;預設會先留下草稿(
auto: false),建議確認後再送出。 - LINE 更新、macOS 權限、OCR 結果、資料庫格式或
cua-driver行為改變,都可能讓它失效。 - 你必須自行確認使用方式符合 LINE 服務條款與所在地法律。本專案與 LINE/NAVER 無關,也不代表 LINE/NAVER 認可或支持。
兩條資料路徑
- 讀取是資料庫路徑。 macOS 版 LINE Desktop 是 Qt6/QML app,訊息文字由 GPU 繪製,accessibility tree 裡拿不到;但歷史訊息存在本機 wxSQLite3 / QtCipherSqlitePlugin AES-128-CBC 加密 SQLite DB(
…/Data/db/qwb*.edb)。read_history/list_chats會用 macOS keychain 裡的帳號金鑰解開唯讀快照,回傳本機 DB 內現有的歷史紀錄(每一則本機已存的訊息,含 sender、timestamp、direction),並附上涵蓋範圍(本機則數、最舊/最新時間)。本機 DB 只存有 LINE Desktop 已同步到這台 Mac 的訊息;從未載入到本機的較舊訊息不在其中(可用sync_older_messages回補)。這條路徑完全背景執行,不碰 UI。舊版曾用 OCR 讀螢幕,只能看到目前畫面;那條路徑已移除。 - 送訊息是 UI 路徑,但不移動游標。 不能靠改 DB 送訊息,所以
send_message會透過 cua-driver 操作 LINE UI:CGEvent 會送到指定座標/按鍵,但不 warp 可見游標;LINE 可能短暫跳到前景開啟目標聊天,完成後會把原本的前景 app 切回來。
MCP 工具
| Tool | 功能 |
|---|---|
line_status |
回報 LINE UI 是否可用,以及本機 DB/金鑰/解密狀態。DB-backed 讀取(list_chats / read_history)不需要 LINE 正在執行;只有 UI 工具需要。 |
list_chats |
從本機 DB 列出最近聊天(name、chatId、最後活動時間、是否群組)。完全背景執行。 |
read_history |
依名稱或 chatId 從已解密的本機 DB 讀取聊天本機已存的歷史紀錄:文字、direction、絕對時間戳,並附本機涵蓋範圍。不移動游標、不切前景、不用 OCR。 |
sync_older_messages |
盡力而為、走 UI(非背景): 讓 LINE 跳到前景並把聊天往上捲,促使 LINE 把較舊訊息回補進本機 DB。不移動游標、會還原焦點,並回報前後涵蓋範圍。需要 LINE 正在執行。 |
select_chat |
透過 UI 開啟指定聊天(搜尋 → pixel-click 第一筆結果)。供 send_message 使用。不移動游標;會還原焦點。 |
send_message |
透過 UI 對指定聊天送出或留下草稿。送出前有 anchored name、1:1-only、DB cross-check 等防護。 |
本機資料庫與金鑰
src/linedb.py(透過專案 venv 與 apsw-sqlite3mc 執行)負責解密。它會建立唯讀快照:把 qwb*.edb、-wal、-shm 複製到暫存資料夾,再開啟那份複本,所以不會鎖住或改動 LINE 正在寫入的檔案。cipher 參數是:
PRAGMA cipher='aes128cbc';
PRAGMA kdf_iter=1;
PRAGMA key='<32-hex>';
這是 wxSQLite3 AES-128,不是 SQLCipher;SQLCipher 的 PRAGMA/AES-256 開不起來。
金鑰
32-hex 金鑰不會由本專案寫進 repo 或明文檔案。linedb.py 會從 $LINE_DB_KEY 或 macOS login keychain service line-cua-mcp-dbkey 讀取:
security find-generic-password -s line-cua-mcp-dbkey -w # 讀回金鑰
擷取金鑰(第一次設定)
在有 SIP 的 Mac 上,不能直接 attach 到 hardened、sandboxed 的 LINE app 讀記憶體。可行的一次性流程(不需要關 SIP):
- 把
LINE.app複製到暫存資料夾;對副本執行xattr -cr。 - 對副本做 ad-hoc re-sign,加入
com.apple.security.get-task-allow(同時會移除 hardened-runtime flag),例如:codesign -f -s - --deep --entitlements ent.plist LINEcopy.app。 - 啟動這個副本並登入你的帳號。這通常會讓原本的 LINE Desktop 被登出;擷取完再登入回去即可。金鑰跟帳號穩定相關,所以副本中的金鑰可解開真實 DB。
- 用
lldbattach 到副本(get-task-allow讓它可被 debug);在 writable memory 裡找encryption_key=/mse附近的 32-hex token。 - 用真實 DB 驗證後存進 keychain:
然後刪掉這個 LINE 副本。security add-generic-password -a "$USER" -s line-cua-mcp-dbkey -w <key> -U
如果 LINE 之後 rotate key,linedb.py status 會回報 decryptOk: false,需要重做一次擷取。
快速檢查
.venv/bin/python src/linedb.py status # db found, key, decryptOk, counts
.venv/bin/python src/linedb.py list-chats --limit 20
.venv/bin/python src/linedb.py read "<chat name>" # 完整歷史(JSON)
.venv/bin/python src/linedb.py export-md --name "<chat>" --thread "<Name>" --out out.md
送訊息安全機制
send_message 是唯一會改變外部狀態的操作,所以加了多層防護:
- 重新選擇指定聊天,不會送到「目前剛好打開的聊天室」。
- Anchored name match(不是 substring):OCR 讀到的聊天標題正規化後必須等於目標名稱,只容許尾端多一個非英數字元(LINE header icon 造成的 OCR 雜訊)。例如短目標
明不會通過小明子/陳明婷;Alice不會通過Alice2。 - 預設只允許 1:1:如果開啟的聊天標題有 member-count badge
(N),視為群組,拒絕送出。需要送群組時必須明確傳allowGroup: true。 - DB 交叉比對(
crossCheckSendTarget):本機 DB 是聊天 identity 與 group status 的權威來源,不只相信 OCR。目標會先用聊天列表解析;如果目標是群組、名稱有歧義,或 OCR 標題指向不同聊天,就拒絕。 - 真正按 Return 前會再驗一次。
auto: false是預設值,只會把文字放進輸入框當草稿,不會送出。
ocr.ts(透過 src/ocr.swift 使用 macOS Vision)現在只用於送訊息前驗證聊天標題;讀訊息已不再用 OCR。
純 matcher / 交叉比對邏輯有 unit tests(yarn test)。DB 交叉比對補上 header OCR 可能 fail-open 的兩類問題:
- 把群組誤當 1:1:即使
(N)badge 被裁掉或 OCR 錯讀,仍會用 DB 的isGroup拒絕。isGroup是 fail-closed:只要不是u開頭的 1:1 聯絡人(例如群組、多人聊天室、LINE Square community、未知未來類型),都視為 group。 - 送錯對象,包含兩個方向:extension — OCR 標題解析成另一個已知聊天(例如目標
小明,實際開到小明華);truncation — 標題是另一個已知聊天名稱的嚴格前綴(可能是 OCR 把長名字裁短)。兩者都拒絕;目標名稱有歧義也拒絕。
殘餘限制與取捨: 交叉比對需要本機 DB(金鑰在 keychain);如果 DB 不可用,會降級成只靠 OCR 的保護機制並寫 log。若某個 1:1 名稱剛好是另一個聊天名稱的嚴格前綴,會被 truncation guard 拒絕;請改用完整名稱或精確 chatId。因為目前沒有獨立訊號能知道畫面上實際是哪個 chat,以下狀況無法只靠名稱完全解掉:兩個聊天顯示名稱完全相同(其中一個是群組);或某個新聊天還沒寫進本機 DB,而它的較長標題剛好被 OCR 裁短成目標名稱。預設仍是 auto: false,送出前請先檢查草稿。
需求
- macOS,已安裝並登入 LINE desktop app。
- Python venv,包含
apsw-sqlite3mc(DB 讀取路徑):python3 -m venv .venv && .venv/bin/pip install apsw-sqlite3mc PATH上的python3需要能 import Pillow (PIL);send-path header crop 會在ocr.tsshell out 使用它(pip install Pillow)。讀取路徑不需要 Pillow。- DB 金鑰已放進 keychain service
line-cua-mcp-dbkey(見上方)。 - 安裝 cua-driver,並授權 Accessibility / Screen Recording(
select_chat/send_message需要):/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/trycua/cua/main/libs/cua-driver/scripts/install.sh)" - Node 18+。
建置與執行
yarn install
yarn build # tsc + 複製 ocr.swift / linedb.py 到 dist/
node dist/server.js # MCP stdio server
Register with Claude Code:
claude mcp add --transport stdio line-cua -- node /absolute/path/to/line-cua-mcp/dist/server.js
調整參數
DB 路徑與 cipher 參數在 src/linedb.py。送訊息用的 OCR crop 區域與 composer click point 是 window-fraction 常數:src/ocr.ts 的 HEADER,以及 src/line.ts 的 composer 0.72, 0.89。如果 LINE 改 UI layout,要調這些值。
法律與免責
這是用來存取你自己的 LINE 帳號與資料、並且只在你自己的機器上使用的個人工具。使用前請理解:
- 你必須自行遵守 LINE 服務條款與所在地法律。讀本機資料庫、操作 desktop client,可能違反 LINE 的 ToS;金鑰擷取流程修改的是 app 的副本,不是你安裝的
LINE.app。只在自己的帳號/資料上使用。 - 本軟體以 AS IS 提供,沒有任何保證,作者不負任何責任;見
LICENSE。 - 這不是法律意見。如果你不確定某種使用方式是否合法,請尋求所在地法律意見。
商標:「LINE」是 LINE Corporation/NAVER 的商標。本專案是獨立專案,與 LINE/NAVER 無關,也不代表 LINE/NAVER 認可或支持。
隱私與金鑰處理說明請見 SECURITY.md。
Recommended Servers
playwright-mcp
A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.
Magic Component Platform (MCP)
An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.
Audiense Insights MCP Server
Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.
VeyraX MCP
Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.
graphlit-mcp-server
The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.
Kagi MCP Server
An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.
E2B
Using MCP to run code via e2b.
Neon Database
MCP server for interacting with Neon Management API and databases
Exa Search
A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.
Qdrant Server
This repository is an example of how to create a MCP server for Qdrant, a vector search engine.