手動セットアップ(Mac / Linux / Windows)
通常は1コマンドで完了します
このページは Windows や、手動で細かく構築したい場合の手順です。Mac / Linux は セットアップの流れ のワンライナーをおすすめします。
クイックスタート(Mac/Linux):
./setup.shを実行するだけで 依存導入 → Gemma 4 E4B 取得 → whisperモデルDL → .env生成(トークン自動発行)→ 起動 まで完了します。 以後の設定変更は 母艦設定画面http://localhost:8789(127.0.0.1 専用)またはcd server && npm run config -- set KEY VALUE。
「母艦(mothership)」= STT(whisper) と任意のローカル翻訳(Ollama) を動かし、iPhone から Tailscale 経由で叩かれるバックエンド PC。STT は常に母艦で行う(iPhone WebView の Web Speech はマイク権限が取れないため)。本書は Mac Studio や Windows PC 等、別マシンでゼロから立ち上げる手順。
対象: Apple Silicon Mac(Metal 利用)または Windows 10/11 PC。サーバ本体は Node.js 製で OS 非依存、Ollama・Tailscale・ffmpeg・whisper.cpp もすべて Mac / Windows 両対応。OS で異なるのは 導入コマンド・常駐化・スリープ抑止・パス表記のみで、各手順に両方を併記する。
STT の GPU アクセラレーション
Mac(Apple Silicon) は whisper.cpp が Metal を自動利用して高速。Windows の公式プリビルド (whisper-bin-x64.zip)は CPU 版で、large-v3-turbo でも実用域だが Mac より遅め。NVIDIA GPU 機なら CUDA/Vulkan ビルド(whisper-cublas-* / whisper-vulkan-*)を使うか、STT が重ければ小さめモデル (ggml-medium 等)に落とすと軽くなる。
表記: 以降のコマンドは Mac は Terminal(zsh/bash)、Windows は PowerShell を想定。
~は Mac のホーム、Windows は%USERPROFILE%(例C:\Users\<you>)に読み替える。
0. 全体像
iPhone(Even Hub WebView) ──Tailscale HTTPS──> 母艦 :8788 (Fastify)
├─ /stt → whisper-server :8181(常駐)
├─ /translate ┐ api: Claude(@anthropic-ai/sdk, アプリのキー)
└─ /replies ┘ subscription: Claude(agent-sdk)
│ local: Ollama :11434 (gemma4)- api: アプリ側で入力した Anthropic API キーをヘッダ
x-anthropic-api-keyで母艦へ。サーバは保存しない。 - subscription: 母艦の Claude Code ログイン資格情報(課金なし/やや遅い)。
- local: 母艦の Ollama(オフライン)。
1. 前提ツールの導入
Mac (Homebrew):
brew install node whisper-cpp ffmpeg ollama tailscale # tailscale は GUI アプリ版でも可Windows (PowerShell):
# Node / ffmpeg / Ollama / Tailscale は winget で導入(公式インストーラ版でも可)
winget install OpenJS.NodeJS.LTS
winget install Gyan.FFmpeg # 16kHz 以外の PCM リサンプル時のみ使用
winget install Ollama.Ollama # local モード用(api/subscription のみなら不要)
winget install tailscale.tailscalewhisper.cpp だけは winget に無いので、公式リリースの Windows プリビルドを手動配置する:
- https://github.com/ggml-org/whisper.cpp/releases から
whisper-bin-x64.zip(NVIDIA GPU ならwhisper-cublas-*-bin-x64.zip)をダウンロード。 - 任意のフォルダ(例
C:\whisper)へ解凍。whisper-server.exe/whisper-cli.exeが入っている。 - サーバに場所を教えるため
server\.envにWHISPER_BIN=C:\whisper\whisper-server.exeを設定 (PATH を通すなら不要)。
whisper-server/whisper-cli(Windows は.exe)→ STT 本体。ffmpeg→ 16kHz 以外の PCM リサンプル時のみ使用(16kHz はサーバ内で WAV 化)。ollama→ local モード用(api/subscription のみなら不要)。
2. リポジトリ取得 & 依存インストール
git clone https://github.com/aieo-product/evan-live-translate.git
cd evan-live-translate
npm --prefix server install
npm --prefix glasses-app install3. STT モデル取得(必須・~1.6GB / gitignore)
mkdir -p server/models
curl -L -o server/models/ggml-large-v3-turbo.bin \
https://huggingface.co/ggerganov/whisper.cpp/resolve/main/ggml-large-v3-turbo.bin別パスに置く場合は WHISPER_MODEL env で指定。
4. ローカル翻訳モデル(local モードを使う場合のみ)
gemma4 は Ollama 0.22 以上が必須(
ollama --versionで確認、古ければ更新)。E4B は約 9.6GB =実質 16GB 以上の RAM/VRAM を推奨。低スペック・旧 Ollama 環境ではgemma2:9bを使う。
Mac:
brew services start ollama # 常駐(再起動後も自動起動)
ollama pull gemma4 # 既定(Gemma 4 E4B・140言語・en/th/vi/zh/ko→ja 実測良好)
# 任意: ollama pull gemma2:9b # 軽量・旧 Ollama 可(gemma4 が重い環境向けフォールバック)Windows: インストーラを入れた時点で Ollama はバックグラウンド常駐+ログイン時自動起動 (localhost:11434)になっているので、brew services 相当の操作は不要。モデル取得だけ行う:
ollama pull gemma4 # 既定(Gemma 4 E4B・140言語・en/th/vi/zh/ko→ja 実測良好)
# 任意: ollama pull gemma2:9b # 軽量・旧 Ollama 可(gemma4 が重い環境向けフォールバック)モデルは OLLAMA_MODEL env か、アプリの「モデル」選択で切替。
5. サーバ設定 server/.env
cp server/.env.example server/.env # Maccopy server\.env.example server\.env # Windows主な項目(詳細は .env.example):
| env | 既定 | 説明 |
|---|---|---|
DEFAULT_BACKEND_MODE | (未設定→subscription) | 既定エンジン api/subscription/local/openai/gemini |
TRANSLATE_MODEL/REPLY_MODEL | claude-haiku-4-5 | Claude 既定モデル(アプリのモデル選択で上書き可) |
OLLAMA_MODEL | gemma4 | local 既定モデル(要 Ollama 0.22+。軽量にするなら gemma2:9b) |
OLLAMA_KEEP_ALIVE | 30m | 翻訳モデルの常駐時間。常用するなら -1m(無期限常駐)推奨 — 既定30分だとアイドル後の初回翻訳がモデル再ロードで5〜7秒待たされる(#87)。⚠️ -1(単位なし)は Ollama が 400 で拒否し local 翻訳が全部失敗する。負値は必ず -1m のように単位を付ける |
OPENAI_API_KEY/OPENAI_MODEL | (なし)/gpt-5.6-luna | openai 既定モデル(アプリ側でキー入力すればサーバ env は不要) |
GEMINI_API_KEY/GEMINI_MODEL | (なし)/gemini-3.5-flash-lite | gemini 既定モデル(アプリ側でキー入力すればサーバ env は不要) |
WHISPER_MODEL | server/models/ggml-large-v3-turbo.bin | STT モデルパス |
WHISPER_SERVER_PORT | 8181 | whisper-server ポート |
PORT | 8788 | バックエンド待受 |
CALLLOG_DIR | server/data | 通話ログバックアップ(/calllog/backup)の保存先。母艦ローカルのみ、外部送信なし |
鍵はできればファイルに直書きせず env 注入する(Mac は Keychain →
.zshrc、Windows はsetxかユーザー環境変数)。apiモードはアプリ側でキー入力するのでサーバ env のキーは 必須ではない(subscriptionは Claude Code ログインで可)。
6. 起動(ブリッジの起動方法)
npm --prefix server run devこれだけで以下が自動で立ち上がる:
- Fastify が
0.0.0.0:8788で待受(LAN/tailnet 双方)。 - whisper-server を detached で 1 度だけ spawn(
127.0.0.1:8181、モデル常駐)。 既に上がっていれば再利用(tsx watchの再読込でもモデルは温存)。 - プリウォーム(whisper・Ollama をメモリへロード、Ollama は
keep_aliveで常駐)。
確認:
curl -s localhost:8788/health
# {"ok":true,"backend":"subscription","defaultMode":"subscription","modes":["api","subscription","local","openai","gemini"]}7. Tailscale で HTTPS 公開(iOS の ATS 対策・必須)
iOS WebView は平文 HTTP の fetch を弾く。Tailscale Serve で母艦を HTTPS 公開する。
tailscale serve --bg --https=443 http://127.0.0.1:8788
tailscale serve status # https://<host>.<tailnet>.ts.net → :8788 を確認iPhone を同じ tailnet に入れれば、ネット越しに世界中どこからでもこの HTTPS 名で母艦に届く (同一 LAN 不要)。
8. iPhone アプリ(glasses-app)
npm --prefix glasses-app run build
npm --prefix glasses-app run pack # evan-livetranslate.ehpk を生成 → Even Hub に sideload- アプリの「バックエンド」に母艦の HTTPS MagicDNS 名(
https://<host>.<tailnet>.ts.net)を設定。 - 「翻訳エンジン」で api/subscription/local、「モデル」を選択。api 選択時は「APIキー」を入力。
9. 常駐化とスリープ抑止(母艦を建てっぱなしにする)
外出先から使うには、母艦がサーバ常駐・スリープしない状態である必要がある。まず本番用に ビルドしておく(dev の tsx watch ではなくビルド済み dist を走らせる):
npm --prefix server run build # dist/ を生成
npm --prefix server run start # = node --env-file-if-exists=.env dist/index.js常駐化
Mac: LaunchAgent + 監視ループで常駐(詳細は下の「実機セットアップ済み環境」)。ログイン時起動・ クラッシュ時 2 秒で自動再起動。
Windows: 次のいずれか。
タスクスケジューラ(標準機能・推奨): 「トリガー = ログオン時」で下のラッパー
.cmdを起動。 ラッパーが落ちても再起動するループにしておく。serverフォルダにrun-server.cmdを置く:bat@echo off cd /d %~dp0 :loop node --env-file-if-exists=.env dist\index.js timeout /t 2 /nobreak >nul goto loopタスクスケジューラで「最上位の特権で実行」「ユーザーがログオンしているかに関わらず実行」を 選ぶと、画面ロック中も動く。
NSSM(Windows サービス化)や pm2 + pm2-startup(Node 製・クロスプラットフォーム)でも可。
pm2 start "npm --prefix server run start" --name evan-lt && pm2 save && pm2-startup install。
スリープ抑止
Mac: nohup caffeinate -dimsu &>/dev/null &(再起動で消えるので再ログイン後に再実行)。
Windows: AC 電源時にスリープ/画面オフしない設定にする。
powercfg /change standby-timeout-ac 0 # スリープしない
powercfg /change hibernate-timeout-ac 0 # 休止状態にしない
powercfg /change monitor-timeout-ac 0 # 画面オフもしない(任意)ノート PC を母艦にするなら「カバーを閉じたときの動作=何もしない」も設定する (設定 → システム → 電源、または powercfg)。
⚠️ 別マシンへ移すときに変える所(移植性)
- 母艦 URL の既定値はソースにハードコードしない。
glasses-app/src/settings.tsはimport.meta.env.VITE_BACKEND_URLを読み、未指定ならhttp://localhost:8788にフォールバックする。- 手軽: アプリの「バックエンド」欄で自分の ts.net 名に変更(または
?backend=で起動時上書き)、 - 恒久(配布ビルド):
VITE_BACKEND_URL=https://YOUR_MOTHERSHIP.ts.net npm --prefix glasses-app run buildで母艦 URL を焼き込んでからパッケージング。
- 手軽: アプリの「バックエンド」欄で自分の ts.net 名に変更(または
glasses-app/app.jsonの network whitelist は["localhost", "127.0.0.1", "*.ts.net"]。 ts.net 経由なら追加設定なしで通る(個人 IP は焼かない)。
トラブルシュート
| 症状 | 原因/対処 |
|---|---|
アプリ status が 接続NG / Load failed | HTTPS 必須。Tailscale Serve(手順7) と iPhone の Tailscale 接続を確認 |
STT通信エラー: TypeError: Load failed(IP直叩きは通るのに ts.net 名だけ通らない) | iPhone の iCloud プライベートリレーがON。Safari/WebView の DNS を Apple が横取りし MagicDNS 名を解決できない。設定→AppleID→iCloud→プライベートリレーを恒久OFF("明日までオフ"は翌日復活するので不可)。切り分け: http://<tailnet-ip>:8788/health は通るが http://<name>:8788/health が真っ白=名前解決のみ失敗 |
/stt が遅い/失敗 | whisper-server が落ちている。curl 127.0.0.1:8181/ 確認、server/models/*.bin の存在確認 |
STT: マイク権限が必要 | 旧経路。実機は G2 マイク経由(v0.3.0+)。アプリを最新版に |
| local が遅い初回 | モデルのコールドロード。ollama ps で常駐確認、OLLAMA_KEEP_ALIVE 調整 |
api モードで APIキーが必要 | アプリの「APIキー」欄に入力(x-anthropic-api-key で母艦へ渡る) |
| アップデート後、母艦プロセスが起動直後に落ちる/クラッシュループする | OLLAMA_URL/WHISPER_SERVER_URL に外部(非ローカル)URL を設定したまま更新した場合に起きていた既知の不具合(起動時にSSRF検証がthrowしていた)。現在は遅延検証に変更済みで、プロセスは起動を続け /health も生きる(該当機能を使うリクエストのみ 502)。外部URLを意図しているなら ALLOW_EXTERNAL_BACKENDS=true を設定 |