Sezzlee Local LLM について
Sezzlee Local LLMは、Codex、Claude Code、Cursorなどの計画エージェントが、範囲を限定した言語タスクをOllamaモデルに委ねるためのMCPサーバーです。ファイル内容を呼び出し元エージェントのコンテキストに入れず、入出力にも上限を設けます。
主な機能
- 01分類、抽出、要約、変換などの限定タスク
- 02スキーマ準拠のJSONまたはテキスト出力
- 03local_mapによるCSV行のラベル付け
- 04ワークスペース内に限定したファイルアクセス
- 05入出力上限と無切り捨て処理
- 06モデルの到達性とキュー状態の確認
活用シーン
- 01ワークスペースのファイルを要約・抽出し、エージェントのコンテキストへの読み込みを回避
- 02ローカルモデルによる範囲限定テキストの分類や変換
- 03CSV行にラベルを付け、別の出力ファイルに保存
MCP 対応
MCPクライアントにlocal_task、local_map、local_statusを提供します。Ollamaに接続し、呼び出し元エージェントのコンテキスト外でモデルリクエストを実行します。
設定
ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。
npx -y @sezzlee/llm-mcpSEZZLEE_LLM_MODELOllama model to callSEZZLEE_LLM_BASE_URLOllama base URLSEZZLEE_LLM_NUM_CTXContext window in tokensSEZZLEE_LLM_TIMEOUT_MSPer-call timeout in millisecondsSEZZLEE_LLM_KEEP_ALIVEHow long Ollama keeps the model loadedSEZZLEE_LLM_ROOTWorkspace folder paths resolve againstSEZZLEE_LLM_OUTPUT_DIRFolder local_map writes its CSV intoローカルサーバーにはマシン上の実行環境(Node.js 18 以上など)が必要です。設定ファイルの場所はクライアントごとに異なります。
ツール
3掲載時のツール一覧 · 3 週間前に更新
このツールにパラメーターはありません。
詳細
@sezzlee/llm-mcp
プランニングエージェント(Codex、Claude Code、Cursor)が、範囲を限定した言語タスクをローカルモデルに委任できるMCP サーバーです。@sezzlee/mcp-coreを基盤としており、他の@sezzlee/*パッケージには依存しません。
クイックスタート
{
"mcpServers": {
"local": {
"command": "npx",
"args": ["-y", "@sezzlee/llm-mcp"],
"env": {
"SEZZLEE_LLM_BASE_URL": "http://127.0.0.1:11434",
"SEZZLEE_LLM_MODEL": "qwen3:8b"
}
}
}
}
Codexでは、同じブロックをmcp_servers.localの下に配置します。approval_policy = "never"で実行する場合は、default_tools_approval_mode = "auto"も必要です。そうでないと、Codexは呼び出しを拒否します。
ツール
ツールは3つあります。うち2つは読み取り専用です。local_mapは、サーバー独自の出力ディレクトリに新しいファイルを追加するだけです。
| ツール | 機能 | 主な引数 |
|---|---|---|
local_task | ローカルモデルで、classify、extract、summarize、transform、freeのいずれかの、範囲を限定した言語タスクを1つ実行します。ファイル引数はサーバー自身が読み取るため、その内容が呼び出し元のエージェントのコンテキストに入ることはありません。jsonSchemaを指定すると、そのスキーマに一致するJSONが回答となり(resultとして返されます)。指定しない場合はテキストとなり(answerとして返されます)。summarizeとextractでは、入力が大きすぎる場合にチャンクに分割してすべて読み取ります(最大32チャンク、合計1 MiB)。それ以外の種類では、入力が大きすぎるとinput_too_largeとして拒否します。黙って切り詰められることはありません。 | kind、instruction、text?、files?(最大8件、作業ディレクトリからの相対パス)、jsonSchema? |
local_map | CSVファイルの各行に、指定されたラベルのいずれかを付与します。エージェントに行の内容は表示されません。エージェントがパスを渡すと、サーバーは出力ディレクトリに新しいファイル(元の列にラベル列を追加したもの)を書き込み、そのファイルのパス、ラベルごとの件数、ラベルごとに最大4行のサンプルを返します。最大2,000行です。 | file、instruction、labels(2~50)、labelColumn?(デフォルトはlabel) |
local_status | ローカルモデルに接続可能か、読み込み済みか、コンテキストウィンドウのサイズ、1回の呼び出しで使用できる入力の上限、キューに入っている呼び出しの数を報告します。ローカルモデルを利用できるかどうか不明な場合は、委任する前に呼び出してください。 | なし |
設定
SEZZLEE_LLM_MODEL=qwen3:8b
SEZZLEE_LLM_ROOT=. # default: the working directory
SEZZLEE_LLM_OUTPUT_DIR=.llm-mcp/out # default; relative to root, must stay inside it
SEZZLEE_LLM_BASE_URL=http://127.0.0.1:11434 # default
SEZZLEE_LLM_NUM_CTX=16384 # default; at least 4096
SEZZLEE_LLM_KEEP_ALIVE=30m # default
SEZZLEE_LLM_TIMEOUT_MS=300000 # default; one request
npx -y @sezzlee/llm-mcp
| 変数 | デフォルト | 意味 |
|---|---|---|
SEZZLEE_LLM_MODEL | なし — 必須 | Ollama のモデル名です。組み込みのデフォルト値はありません。明示的に設定する必要があります(モデルの選択を参照)。 |
SEZZLEE_LLM_ROOT | 作業ディレクトリ | ワークスペースのルートです。ツールが受け付けるすべてのファイル引数は、このルートを基準に解決されます。 |
SEZZLEE_LLM_OUTPUT_DIR | .llm-mcp/out | local_map が出力を書き込む場所です。ルートからの相対パスであり、ルート内にとどめる必要があります。 |
SEZZLEE_LLM_BASE_URL | http://127.0.0.1:11434 | Ollama ホストのベース URL です。 |
SEZZLEE_LLM_NUM_CTX | 16384 | トークン単位のコンテキストウィンドウです。4096 以上の整数を指定する必要があります。 |
SEZZLEE_LLM_KEEP_ALIVE | 30m | Ollama の keep_alive に渡される値です。 |
SEZZLEE_LLM_TIMEOUT_MS | 300000 | モデルへの単一リクエストのタイムアウトです。 |
必須なのはモデル名だけです。設定の解析に失敗すると致命的ですが、ホストへの接続は必須ではありません。ホストが停止していても、サーバーは起動し、tools/list に応答します。また、local_status は reachable: false を報告します。サーバーがリクエストの受け付けを開始した直後に、モデルがウォームアップされます。
GPU で実際に利用できる値に合わせて SEZZLEE_LLM_NUM_CTX を設定してください。Ollama はサイズ超過の入力を拒否せず、先頭部分を黙って切り捨てます。また、入力予算はこの値から算出されます。
制限
| 制限 | 値 | 理由 |
|---|---|---|
| 入力予算 | コンテキストウィンドウの45% | Ollamaは、上限を超えたプロンプトを拒否せずに先頭部分を黙って削除するため、サーバー側で先に拒否します。 |
| 出力予算 | コンテキストウィンドウの40% | 応答の暴走を抑えます。IDを含むスキーマがない場合、モデルが12,600トークン分の無意味な出力を繰り返すことが確認されています。 |
| トークンあたりの文字数の推定値 | 約1.8 | トルコ語のテキストで測定しました。英語では1トークンあたり約4文字のため、切り詰めるよりも拒否する方向に推定値を調整しています。 |
local_task の files | 最大8個 | 1回の呼び出しで指定できるファイル引数の上限です。 |
local_task の長い入力(summarize/extract) | 最大32チャンク、合計1 MiB | それ以外の種類では、予算を超える入力は input_too_large として即座に拒否されます。 |
| チャンクのマージ回数 | 最大3回 | 3回のマージ後も収まらない場合は、input_too_large として失敗します。 |
local_map の行数 | 最大2,000行 | ラベル付けは1行あたり約270 msかかると測定されました。2,000行では約9分となり、Codexが許可するツールのタイムアウト900秒以内です。 |
local_map のファイルサイズ | 最大8 MiB | 何も書き込まれないまま途中でタイムアウトするのを避けるため、処理開始前に拒否します。 |
ルール
- Lint で強制される 3 つのレイヤーと、ルートのエントリーポイント 3 つ。
srcはplatform/(mcp-core と Node の境界)、backend/(モデルホスト)、tools/(MCP のインターフェース)に分かれています。tools/がホストにアクセスできるのはbackend/port.ts経由のみで、具体的なバックエンドはcli.tsで接続されます。 - ネットワークにアクセスするのは
src/backend/ollama.tsのみで、グローバルのfetch経由に限られます。このグローバルとnode:http/net/tls系は、それ以外のすべての場所で lint により禁止されています。 process.envを読み取るのはcli.tsのみで、各変数は名前を指定してアクセスします。- ファイルパスはワークスペースを基準に解決されます。 要求されたパスと、その
realpathは個別に検証されるため、ワークスペース外を指すシンボリックリンクも拒否されます。readTextが受け取れるのは、両方の検証を通過したWorkspacePathブランド付きのパスのみです。エラーエンベロープでは、ワークスペースの絶対パスは.として示されます。 - トークンを数えるのはサーバーであり、モデルではありません。
num_ctx × 0.45を超える入力はホストに届かず、どのような場合でも収まらない入力は、読み取る前に拒否されます。回答はnum_ctx × 0.4に制限されます。 - ファイルシステムに触れるのは
src/platform/workspace.tsのみで、lint により強制されています。書き込みを行うのはcreateOutputのみです。出力ディレクトリのrealpathを再確認し、ファイル名はサーバー自身が選び、安全な文字セットに変換して拡張子を.csvに固定したうえでwxで開きます。そのため、既存ファイルやシンボリックリンクを上書きすることはなく、ファイルが削除されることもありません(mcp-core)。 local_mapは行番号をモデルに渡し、モデルから受け取ります。 ID のない形式では行の順序が失われていました。行がスキップされた場合は一度だけ再度要求し、それでも欠けていれば、推測せずラベルなしとしてカウントします。- 分割した入力も切り捨てられません。 チャンクは段落、次に行の境界で分割されます。各チャンクからメモを生成し、それらを統合して、最後に指示を適用します。統合したメモが予算に収まらない場合は、統合のラウンドを繰り返します(最大 3 回)。それでも収まらない場合は、
input_too_largeとして呼び出しを拒否します。 - ホストあたり同時に処理するリクエストは 1 件です。
createSerialBackendはリクエストをキューに入れます。GPU はリクエストを並列実行せず、Codex は呼び出しを並行して送信します。probeはキューを経由しません。 - 新しいバックエンド種別を追加するには、
Backendインターフェースの別の実装を用意するだけです。 サーバーの残りの部分は変更されません。
設計メモ
以下の測定値は、上記のルールの基礎となっています。
Codex を Ollama に直接接続するのではなく、MCP サーバーを使う理由
Codex をローカルモデルに接続する方法を 4 つ試しましたが、動作したのは MCP サーバーだけでした。
| 方法 | 結果 |
|---|---|
| Codex から Ollama に直接接続 | Ollama 0.34.2 は /v1/responses を提供しており、接続には成功しますが、ローカルモデルは Codex のツールプロトコルを理解できません。存在しない Read ツールを呼び出し、Ollama は次のリクエストに no user query found と応答しました。本当の障害は、Codex が各ターンを約 37k トークンの基本コストで開始することで、16k のコンテキストには収まらない点です |
Codex のシェルで curl を実行 | サンドボックスによってネットワークアクセスが遮断されます。これを開放すると、ローカルモデルだけでなく、Codex にあらゆる場所へのネットワークアクセスを許可することになります |
Codex の spawn_agent | OpenAI モデルのみを受け付けます |
| MCP サーバー | サンドボックスの外部で実行され、Ollama に直接アクセスします。ローカルモデルに渡されるのはプロンプトだけです(実測値:196 トークン)。Codex の約 37k トークンのターンオーバーヘッドが Codex の外に出ることはありません |
サーバーの作業ディレクトリは Codex のワークスペースです。ツールが受け付けるすべてのファイル引数はこのディレクトリを基準に解決され、ワークスペースの外部を指すパスは拒否されます。
モデルの選択
gpt-oss:20b は、ID を含む JSON スキーマ local_map で 0/100 点と測定されました。また、構造化された local_task 呼び出しもこのスキーマに依存しますが、このモデルはスキーマを保持できませんでした。このリポジトリの測定には qwen3 モデル(上記の例では qwen3:8b)を使用しました。SEZZLEE_LLM_MODEL に組み込みのデフォルト値はないため、明示的に設定する必要があります。
表形式のデータで Codex だけを使う場合
明確な手がかりがある 400 行のラベリングタスクでは、Codex 単独での作業は委任した場合と同じ精度(14/14 件正解)で、約 3.5 倍高速でした。local_map 経由の 166 秒に対して 48 秒でした。このため、DELEGATION_INSTRUCTIONS(products/chat/api/src/codex/delegation-instructions.ts)では、データが明確なパターンを持つ表形式の場合、Codex が委任せずにスクリプトを書くことを認めています。委任が効果を発揮するのは、長文や非構造化テキストの場合だけであり、スクリプトで解析できる行には必要ありません。
採用しなかった案
ollama-mcpという名前。 バックエンドをプラグインで切り替えられるようになると、範囲が狭すぎます。llm-mcpは、現在のバックエンドではなく、その背後にあるリソースにちなんでサーバー名を付けるというリポジトリの慣例に沿っています。- コンシューマー向け製品内の専用ワーカー。 このサーバーにはチャットに特化した機能はありません。ツールにはファイルパスと指示を渡し、スキーマは MCP のインターフェース上で標準の JSON Schema です。1つの製品の中に閉じ込めると、外部からの貢献を受け入れられず、
@sezzlee/mcp-coreがすでに提供しているペイロード予算を一から作り直すことになります。 - 既存のオープンソースリポジトリを使う。 調査したもののほとんどは Python 製で、うち1つは改変を禁じるライセンスが適用されています。また、Codex の承認モード、ワークスペースの境界、ペイロード予算を把握しているものはありません。役立つアイデアは採用しました。種類ごとに用意されたプロンプト(
ollama-handoffより)、ファイルパスを受け取るツールとフェイルオーバー(LocalTokensより)、そして「ワーカーが出力を一定範囲内に収め、性能の高い側がそれを受け入れる」という考え方(Shahriar/ollama-mcp-server より)です。 - ジョブの種類ごとにツールを1つ用意する。 ツールスキーマが1つ増えるごとに、Codex の各ターンでトークンコストが発生します。
kind列挙型を持つ1つのlocal_taskツールで、同じ範囲をより少ないコストでカバーできます。 - キューに入れる代わりに同時実行数を増やす。 1つの GPU への4件の並列リクエストは、4件を順番に実行した場合より速くなったのはわずか1.1倍でした。GPU はリクエストを並列処理できないため、呼び出しをそれぞれのタイムアウト内に収めるには、キューに入れるしかありません。
対象外(意図的)
- ローカルモデルのエージェントループ。 調査したリポジトリの小規模モデルを本格的なエージェントハーネスで動かすと、単純なタスクに5~7分かかり、実際には行っていない作業を完了したと報告したこともありました。エージェントの処理には、すでに Codex 独自の
spawn_agentがあります。 - 埋め込み。 ホストでは
bge-m3を利用できますが、まだ使っていません。検索の必要が生じたら追加してください。 .xlsxの直接読み込み。 v1 では CSV とプレーンテキストのみを読み込みます。.xlsxの入力は呼び出し側で@sezzlee/excel-mcpを経由させます。このサーバーに直接フォーマットを処理させることは、現時点では対象外です。
測定結果
以下の Codex 実行はすべて、low の推論レベルで gpt-5.6-luna を使用し、num_ctx を 16,384 に設定した Ollama 0.34.2 に対して実行しました。「キャッシュなし」は input_tokens − cached_input_tokens です。
| 実行 | データ | セットアップ | 時間 | キャッシュなし入力 | 出力 | 結果 |
|---|---|---|---|---|---|---|
| S0 | 400 行、手がかりあり | Codex のみ | 53 s | 31.1k | 1.8k | 14/14 日 |
| S1 | 400 行、手がかりあり | local_task のみ | 68 s | 32.5k | 2.4k | 14/14(ローカル呼び出しで input_too_large が発生し、Codex は Python にフォールバック) |
| S2 | 400 行、手がかりあり | local_map、自動承認 | 155 s | 41.4k | 1.5k | 14/14、Codex は行を一度も読みませんでした |
| H0 | 400 行、手がかりなし | Codex のみ | 48 s | 25.8k | 1.9k | 14/14(200 行を読み、ルールを作成) |
| H2 | 400 行、手がかりなし | local_map、説明のみ | 162 s | 18.4k | 1.7k | 2/14(376/400 行にラベル付け) |
| H3 | 400 行、手がかりなし | local_map、サンプル+検証 | 166 s | 24.5k | 2.2k | 14/14(400/400 行にラベル付け) |
| D0 | 17 件のドキュメント | Codex のみ | 65 s | 34.1k | 2.9k | 17 件のレコード(各ドキュメントの最初の 240 行のみ読み込み) |
| D2 | 17 件のドキュメント | local_task +チャンク分割 | 226 s | 25.7k | 3.0k | 17 件のレコード。Codex はドキュメントを自ら読み込まず、17 回の呼び出しが同時に到着し、キューは 157 s で処理され、タイムアウトなし |
開発
pnpm turbo run test --filter=@sezzlee/llm-mcp
このためにローカルモデルは不要です。fetch は偽装されています。
test/live.spec.ts は実際の Ollama インスタンスに対して実行されます。
SEZZLEE_LLM_LIVE=1 SEZZLEE_LLM_BASE_URL=http://127.0.0.1:11434 SEZZLEE_LLM_MODEL=qwen3:8b \
pnpm turbo run test --filter=@sezzlee/llm-mcp -- test/live.spec.ts
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。