apfel: macOS 26 の FoundationModels を UNIX ツールと OpenAI 互換サーバーにする
The free AI already on your Mac. CLI tool, OpenAI-compatible server, and interactive chat — all on-device via Apple Intelligence. No API keys, no cloud, no downloads.
ひと目でわかる
- これは何?
- apfel は Apple Silicon に同梱される Apple FoundationModels を、パイプで使える CLI と localhost:11434 の OpenAI 互換エンドポイントとして露出させる MIT ライセンスの Swift 製ツール。モデルの入手も API キーも不要な代わりに、対応 OS とハードウェア、そして 4096 トークンのコンテキストという境界をどう扱うかが導入判断の中心になる。
- 誰に向いている?
- macOS 26 Tahoe と Apple Silicon が揃っていて、クラウドに出せないテキストの要約や分類、シェルスクリプトへの組み込みをしたいなら apfel は候補になる。逆に Intel Mac、macOS 25 以前、長文の一括処理、精度が要件になる用途では動かないか力不足になる。
- 商用利用できる?
- できます。MIT は寛容なライセンスで、著作権表示とライセンス表示を残せば、使用・改変・販売が可能です。
- 今もメンテナンスされている?
- されています。最後のコミットは 1 日前です。
- 何の言語で書かれている?
- 主に Swift です(GitHub の言語統計による)。
回答はプロジェクトの GitHub データ(最終同期:2026年9月15日)と当サイトの分析に基づくもので、法的助言ではありません。
オープンソース詳細解説
apfel が埋めるのはどの隙間か
ローカル LLM を試すときの手間は、モデルの重みをダウンロードして、推論ランタイムを入れて、メモリに載せて、という手順そのものにある。apfel はこの手順を丸ごと省く。macOS 26 Tahoe と Apple Silicon の Mac には Apple FoundationModels 経由の LLM がすでに入っており、apfel はそれを呼び出す薄い層として動く。README の表現を借れば「The free AI already on your Mac」であり、配布物はモデルではなくインターフェースだ。
想定している利用者は 2 種類いる。ひとつはシェルで完結させたい人で、apfel "prompt" や echo "text" | apfel のように既存のパイプラインへ差し込める。もうひとつは OpenAI SDK で書いたコードをそのままローカルに向けたい人で、apfel --serve が http://localhost:11434/v1 を立てる。どちらも API キーを要求しない。クラウドに送れないテキストを扱いたい場合や、従量課金を避けたい場合に効く。
ただしこれは「無料の GPT 代替」ではない。後述するようにコンテキストは macOS 26 で 4096 トークン、macOS 27 で 8192 トークンとされ、モデルの選択肢も存在しない。apfel が提供するのは選択の自由ではなく、すでに手元にあるモデルへのアクセス経路である。
CLI とサーバーが同じバイナリに同居する構成
apfel の実体は単一の Swift バイナリで、起動時のフラグによって 3 つの顔を使い分ける。引数にプロンプトを渡せばワンショットの UNIX ツール、--chat なら REPL、--serve なら HTTP サーバーになる。モードごとに別のデーモンを立てる設計ではないため、インストールは brew install apfel の一度で済む。
サーバーモードのデータフローは素直だ。curl や OpenAI SDK が localhost:11434 に POST し、apfel がリクエストを FoundationModels の呼び出しに変換し、応答を OpenAI の chat.completions 形式に整形して返す。README の例では model に "apple-foundationmodel" を指定する。api_key は "unused" で通る。つまりクライアント側のコードは base_url を差し替えるだけでよく、既存の OpenAI 向け実装をほぼそのまま流用できる。
ツール呼び出しは CLI でもサーバーでも動くと README は説明している。--mcp に Model Context Protocol のサーバーを渡すと、apfel がツールを検出し、呼び出し、結果をモデルに戻す。README の実行例では、利用可能なツール一覧と multiply の呼び出し結果が stderr に出て、最終的な回答だけが stdout に流れる。この分離は重要で、パイプの下流に渡るのは自然文だけになる。
インストールと最初の数コマンド
前提は macOS 26 Tahoe 以降、Apple Silicon(M1 以降)、そして Apple Intelligence が有効になっていることの 3 つ。インストールは Homebrew 経由が最短で、brew install apfel、更新は brew upgrade apfel になる。ソースからビルドする場合は Xcode 不要で、Command Line Tools の macOS 26.4 SDK と Swift 6.3 があれば git clone したあと make install が通ると README は述べている。
よく使う形を並べておく。単発の質問は apfel "What is the capital of Austria?"。ファイルを添付するなら apfel -f README.md "Summarize this project" で、PDF や画像も渡せる。パイプ入力は echo "Summarize: $(cat README.md)" | apfel のように書く。スクリプトに組み込むときは apfel -q で余計な出力を落とし、result=$(apfel -q "Capital of France? One word.") のように受け取る。
出力の形を制御するフラグも揃っている。-o json で構造化出力、--schema person.schema.json でスキーマ適合を強制、--code でコードだけを取り出し、空なら終了コード 7 を返す。--count-tokens は実行前に入力トークン数を見積もるので、長いファイルを渡す前に使う。--permissive は創作や長いプロンプトでガードレールの誤検知を減らすためのフラグで、通常モードで弾かれたときに試す価値がある。
常駐させる場合は brew services start apfel を使う。README では APFEL_TOKEN=$(uuidgen) APFEL_MCP=/path/to/tools.py brew services start apfel という例が示されており、トークン認証と MCP サーバーの指定を環境変数で渡せる。停止は brew services stop apfel。
4096 トークンという境界と、そこから来る設計上の制約
apfel を使う上で最初にぶつかる壁はコンテキスト長だ。README はオンデバイスのコンテキストウィンドウを macOS 26 で 4096 トークン、macOS 27 で 8192 トークンとし、これは実行時に読み取ると書いている。つまり OS のバージョンによって使える幅が変わり、アプリ側で決められない。
4096 トークンは、日本語であれば数千文字程度、コードであれば中規模のファイル 1 本で埋まる。README の例にある apfel -f old.swift -f new.swift "What changed between these two files?" のような使い方は、2 ファイルの合計がこの範囲に収まっていることが前提になる。git diff HEAD~1 を丸ごと渡すような使い方も、差分が小さいうちは成立するが、大きくなれば切れる。だからこそ --count-tokens が用意されているわけで、長い入力を渡す前に見積もる習慣には実利的な意味がある。
--chat ではコンテキストが自動的にトリミングされると README は説明しており、詳細は docs/context-strategies.md に分離されている。会話が長引いても落ちない代わりに、古いやり取りは黙って捨てられる。何が残るかを制御したいなら、このドキュメントを読む必要がある。
もうひとつの制約はハードウェアと OS の固定だ。Intel Mac では動かない。macOS 25 以前でも動かない。Apple Intelligence を無効にしている環境でも動かない。apfel の問題というより FoundationModels の提供条件そのものだが、導入検討では apfel の品質と同じ重さで効いてくる。
ガードレールという不確定要素
オンデバイス推論はプライバシー面で有利だが、モデル側の安全機構から自由ではない。README は --permissive を「reduces guardrail false positives for creative/long prompts」と説明しており、通常モードでは正当なプロンプトが拒否される場合があることを認めている。
これは実務では無視できない。同じプロンプトが OS のバージョンや設定によって通ったり通らなかったりする可能性があり、CI に組み込むような用途では再現性の問題になる。apfel 側でガードレールを無効化する方法は README には書かれていない。--permissive は緩和であって解除ではない。
業務システムに組み込む前に、実際に流すプロンプトを通常モードと --permissive の両方で試し、どちらで通るかを確認しておくべき理由がここにある。モデルの挙動が Apple 側の更新で変わりうる以上、apfel のバージョンを固定しても入力に対する出力の安定性は保証されない。
Ollama と同じポート、違う前提
apfel --serve が立てるのは http://localhost:11434/v1 で、これは Ollama が使うポートと同じ番号だ。README 自身が「like Ollama」と書いており、OpenAI 互換クライアントの base_url をそのまま流用することを意図している。
両者の違いはモデルの出所にある。Ollama はモデルの重みをダウンロードしてローカルに保持し、Llama や Mistral など複数のモデルを選べる。量子化の種類も自分で決められる。代わりにディスク容量とメモリを消費し、初回はダウンロードが発生する。apfel はモデルを一切持たず、OS に組み込まれた単一のモデルを呼ぶだけだ。選べるモデルは 1 つで、重みの更新は OS の更新に従う。
この差は用途を分ける。モデルを差し替えて精度を比較したい、特定のタスクに合わせてファインチューニングしたい、という要求には Ollama 側が答える。一方で、モデルの管理自体をしたくない、ディスクを使いたくない、とにかく今すぐシェルから LLM を呼びたい、という要求には apfel が合う。同じポートを使うので、開発中に両方を切り替えて比べることもできる。
デモと MCP が示す想定用途
apfel にはシェルスクリプトのデモが同梱されている。apfel demos ./apfel-demos を実行すると、実行可能なデモ一式と README.md が指定ディレクトリに書き出される。README によれば cmd、oneliner、mac-narrator、wtd、explain、naming、port、gitsum の 8 本で、リポジトリの clone は不要とされている。
cmd は英語の指示をシェルコマンドに変換する。./apfel-demos/cmd "find all .log files modified today" に対して $ find . -name "*.log" -type f -mtime -1 を返す例が README に載っている。-x を付ければ確認後に実行、-c ならクリップボードへコピーする。危険なコマンドを無確認で実行しない設計になっている点は評価できる。
注意すべきは更新のタイミングだ。デモはバイナリに埋め込まれているため、brew upgrade apfel の後は apfel demos を再実行して書き出し直す必要があると README は明記している。古いデモがディレクトリに残ったまま新しい apfel を使うと、挙動がずれる可能性がある。
MCP 対応も同様に、apfel を単体のチャットツールではなくツール呼び出しのハブとして使う想定を示している。apfel --mcp ./mcp/calculator/server.py "What is 15 times 27?" のように渡すと、検出したツールとその呼び出し結果が stderr に、最終回答が stdout に出る。パイプの下流を汚さないこの分離は、スクリプトに組み込む際に効いてくる。
MIT ライセンスと更新コストの実際
apfel は MIT ライセンスで公開されている。商用利用を含めて制限が少なく、改変や再配布も許される。ただし apfel 自体が MIT でも、呼び出している Apple FoundationModels は Apple のフレームワークであり、その利用条件は別に適用される。ライセンス文を読めば apfel の部分は解決するが、モデルの利用条件は解決しない。ここは法務ではなく Apple のドキュメントで確認する範囲だ。
更新コストは小さく見えて、OS に強く依存する。apfel 本体は brew upgrade apfel で済む。しかしコンテキスト長は macOS のバージョンで決まり、モデルの挙動も OS 更新で変わりうる。リリース履歴を見ると v1.9.0 から v1.9.1 が約 3 日、v1.9.1 から v1.10.0 が約 1 か月で、活発に動いている。追従する側は、apfel のバージョンだけでなく macOS のバージョンも固定しないと再現性が保てない。
CI に組み込むなら、macOS 26 のランナーと Apple Intelligence が有効な環境を用意できるかを先に確認したい。ここが用意できないなら、apfel は開発者個人のマシンで使うツールであって、パイプラインの構成要素にはならない。
編集部の結論
macOS 26 Tahoe と Apple Silicon が揃っていて、クラウドに出せないテキストの要約や分類、シェルスクリプトへの組み込みをしたいなら apfel は候補になる。逆に Intel Mac、macOS 25 以前、長文の一括処理、精度が要件になる用途では動かないか力不足になる。導入前に確認すべきは 3 点で、Apple Intelligence が有効か、apfel --count-tokens -f <ファイル> で自分の入力が 4096 トークンに収まるか、そして本番で使うプロンプトを apfel --permissive と通常モードの両方で試してガードレールに弾かれないかどうか。この 3 つを自分のデータで確かめてから、brew services start apfel で常駐させるかどうかを決めればよい。
コミュニティノート