Sezzlee Local LLM

io.github.sezzlee由 GitHub 账号 sezzlee 发布v0.1.3更新于 Oct 24, 2026

Let a planning agent hand bounded language work to a local Ollama model.

概览

AI 生成的概览

让编程智能体把有界的语言任务(分类、抽取、摘要、转换、CSV 打标)交给本地 Ollama 模型处理,而不占用自身上下文。

可以做什么
  • 在本地模型上执行单个有界语言任务:classify、extract、summarize、transform 或 free,可按给定 schema 返回 JSON
  • 为该任务读取文本或最多 8 个工作区文件,超长输入会分块合并而非截断
  • 用 2–50 个标签为 CSV 的每一行打标,把新的带标签 CSV 写入输出目录,并返回各标签计数与样例行
  • 检查本地模型是否可达并已加载、上下文窗口、单次调用输入预算与排队数量
适用场景
适合让规划型智能体把长文本或非结构化文本工作(文档摘要、记录抽取、行分类)外包给本地模型,使大量内容不进入智能体自身上下文。对于模式清晰的小型表格任务收益不大,README 的实测显示智能体独自处理更快。
运行要求
通过 npx 以 stdio 在本地运行,需要 Node.js,以及可访问的 Ollama 主机(默认 为必填且无默认值;SEZZLEE_LLM_ROOT、SEZZLEE_LLM_OUTPUT_DIR、SEZZLEE_LLM_NUM_CTX、SEZZLEE_LLM_KEEP_ALIVE、SEZZLEE_LLM_TIMEOUT_MS 可选。仅限桌面端。
安装前请注意
local_map 会在工作区根目录内的输出目录(SEZZLEE_LLM_OUTPUT_DIR,默认 .llm-mcp/out)写入新的 CSV 文件;它不会覆盖或删除,但确实会创建文件。文件参数由服务器读取后发送到 Ollama 主机,请把 SEZZLEE_LLM_BASE_URL 指向可信主机。SEZZLEE_LLM_NUM_CTX 应设为 GPU 实际可提供的值,因为 Ollama 会静默丢弃超长提示的开头。在 Codex 中若 approval_policy 为 "never",还需设置 default_tools_approval_mode = "auto"。

安装

在 SourceWeft 中

  1. 打开 控制台中的 Sezzlee Local LLM,将其添加到工作区。
  2. 为需要使用其工具的对话启用该服务。

Desktop only,通过 STDIO。 STDIO 服务会启动本地进程,因此需要 SourceWeft 桌面宿主。

其他 MCP 客户端

参照 仓库 中的启动说明。

README

@sezzlee/llm-mcp

MCP server that lets a planning agent (Codex, Claude Code, Cursor) hand off bounded language work to a local model. It builds on @sezzlee/mcp-core and names no other @sezzlee/* package.

Quick start

json
{  "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"      }    }  }}

In Codex, the same block goes under mcp_servers.local. If it runs with approval_policy = "never", default_tools_approval_mode = "auto" is also required, or Codex refuses the call.

Tools

Three tools. Two are read-only; local_map only adds new files to the server's own output directory.

ToolWhat it doesKey arguments
local_taskRuns one bounded language task on the local model: classify, extract, summarize, transform, or free. The server reads any file arguments itself — their contents never enter the calling agent's context. With jsonSchema the answer is JSON matching that schema (returned as result); otherwise it is text (returned as answer). summarize and extract split an oversized input into chunks and read all of it (up to 32 chunks, 1 MiB total); every other kind refuses an oversized input as input_too_large. Nothing is ever silently truncated.kind, instruction, text?, files? (up to 8, paths relative to the working directory), jsonSchema?
local_mapLabels every row of a CSV file with one of the given labels. The agent never sees the rows: it passes a path, and the server writes a new file (the original columns plus one label column) under the output directory, returning that file's path, the per-label counts, and up to 4 sample rows per label. Up to 2,000 rows.file, instruction, labels (2–50), labelColumn? (defaults to label)
local_statusReports whether the local model is reachable and loaded, its context window, one call's input budget, and how many calls are queued. Call it when unsure the local model is available before delegating to it.none

Configuration

text
SEZZLEE_LLM_MODEL=qwen3:8bSEZZLEE_LLM_ROOT=.                            # default: the working directorySEZZLEE_LLM_OUTPUT_DIR=.llm-mcp/out           # default; relative to root, must stay inside itSEZZLEE_LLM_BASE_URL=http://127.0.0.1:11434   # defaultSEZZLEE_LLM_NUM_CTX=16384                     # default; at least 4096SEZZLEE_LLM_KEEP_ALIVE=30m                    # defaultSEZZLEE_LLM_TIMEOUT_MS=300000                 # default; one request
npx -y @sezzlee/llm-mcp
VariableDefaultMeaning
SEZZLEE_LLM_MODELnone — requiredThe Ollama model name. There is no built-in default; it must be set explicitly (see Model choice).
SEZZLEE_LLM_ROOTworking directoryWorkspace root. Every file argument a tool accepts is resolved against it.
SEZZLEE_LLM_OUTPUT_DIR.llm-mcp/outWhere local_map writes its output. Relative to the root, and must stay inside it.
SEZZLEE_LLM_BASE_URLhttp://127.0.0.1:11434Base URL of the Ollama host.
SEZZLEE_LLM_NUM_CTX16384Context window in tokens. Must be an integer of at least 4096.
SEZZLEE_LLM_KEEP_ALIVE30mValue forwarded to Ollama's keep_alive.
SEZZLEE_LLM_TIMEOUT_MS300000Timeout for a single request to the model.

Only the model name is required. Parsing is fatal, reaching the host is not: the server still starts and answers tools/list with the host down, and local_status reports reachable: false. The model is warmed up right after the server starts serving.

Set SEZZLEE_LLM_NUM_CTX to what the GPU actually delivers. Ollama does not refuse an oversized input — it silently drops the head — and the input budget is derived from this value.

Limits

LimitValueWhy
Input budget45% of the context windowOllama silently drops the head of an oversized prompt instead of refusing it, so the server refuses first.
Output budget40% of the context windowCaps a runaway completion; without an id-bearing schema the model was measured looping into 12,600 tokens of garbage.
Chars-per-token estimate~1.8Measured on Turkish text; English runs closer to 4 characters per token, so the estimate errs toward refusing rather than truncating.
local_task filesup to 8Per-call file argument cap.
local_task long input (summarize/extract)up to 32 chunks, 1 MiB totalOther kinds refuse an over-budget input outright as input_too_large.
Chunk merge roundsup to 3A merge that still does not fit after 3 rounds fails as input_too_large.
local_map rowsup to 2,000Labelling was measured at ~270 ms per row — about nine minutes for 2,000 rows, inside the 900 s tool timeout Codex allows.
local_map file sizeup to 8 MiBRefused up front rather than timed out halfway with nothing written.

Rules

  • Three lint-enforced layers, three root entrypoints. src splits into platform/ (the mcp-core and Node boundary), backend/ (the model host), and tools/ (the MCP surface). tools/ sees the host only through backend/port.ts; the concrete backend is wired in cli.ts.
  • Only src/backend/ollama.ts reaches the network, and only through the global fetch. That global and the node:http/net/tls family are lint-banned everywhere else.
  • process.env is read only in cli.ts, each variable accessed by name.
  • File paths are resolved against the workspace. The requested path and its realpath are checked separately, so a symlink pointing outside the workspace is refused too. readText accepts only a WorkspacePath-branded path that has passed both checks. In error envelopes, the workspace's absolute path appears as ..
  • The server counts tokens, not the model. An input over num_ctx × 0.45 never reaches the host; an input that could not fit under any circumstances is refused before it is even read. The answer is capped at num_ctx × 0.4.
  • Only src/platform/workspace.ts touches the filesystem, lint-enforced. The single writer is createOutput: it re-checks the output directory's realpath, the server itself picks the file name, lowers it to a safe alphabet and fixes the extension to .csv, and opens it wx — so it never overwrites an existing file or a symlink, and nothing is ever deleted (mcp-core).
  • local_map carries the row number to the model and back. An id-less format lost the row order. A skipped row is asked again once; if it is still missing, it is left unlabeled and counted — never guessed.
  • A chunked input is not truncated either. Chunks split on paragraph, then line, boundaries; each chunk yields notes, the notes are merged and the instruction applied one last time. If the merged notes still do not fit the budget, the merge round repeats (up to 3); if that still fails, the call is refused as input_too_large.
  • One request per host at a time. createSerialBackend queues requests: the GPU does not run them in parallel, while Codex fires calls concurrently. probe bypasses the queue.
  • A new backend kind is just another implementation of the Backend interface. The rest of the server does not change.

Design notes

The measurements below are what the rules above are built on.

Why an MCP server instead of pointing Codex at Ollama directly

Four ways of getting Codex to a local model were tried; only the MCP server worked.

ApproachResult
Codex straight to OllamaOllama 0.34.2 serves /v1/responses and the connection succeeds, but the local model does not know Codex's tool protocol — it called a Read tool that does not exist, and Ollama answered the next request with no user query found. The real blocker: Codex starts every turn with a ~37k-token base cost, which does not fit a 16k context
Codex shell runs curlThe sandbox cuts network access; opening it means giving Codex network access everywhere, not just to the local model
Codex's spawn_agentAccepts OpenAI models only
MCP serverRuns outside the sandbox and reaches Ollama itself. Only the prompt reaches the local model (measured: 196 tokens) — Codex's ~37k-token turn overhead never leaves Codex

The server's working directory is Codex's workspace: every file argument the tools accept is resolved against it, and a path that resolves outside it is refused.

Model choice

gpt-oss:20b was measured scoring 0/100 on the id-bearing JSON schema local_map and structured local_task calls depend on — the model could not hold the schema. A qwen3 model (qwen3:8b in the examples above) is what the measurements in this repository were run with; SEZZLEE_LLM_MODEL has no built-in default, so it must be set explicitly.

Codex alone on tabular data

On a 400-row labelling task with clear cues, Codex working alone was as accurate as delegating (14/14 correct) and about 3.5x faster: 48 s versus 166 s through local_map. This is why DELEGATION_INSTRUCTIONS (products/chat/api/src/codex/delegation-instructions.ts) allows Codex to write a script instead of delegating when the data is tabular with clear patterns — delegating only pays off on long or unstructured text, not on rows a script can already parse.

Rejected alternatives

  • The name ollama-mcp. Too narrow once the backend became pluggable; llm-mcp follows the repo's convention of naming a server after the resource behind it, not the current backend.
  • A private worker inside a consumer product. The server has nothing chat-specific in it — tools take a file path and an instruction, schemas are plain JSON Schema on the MCP surface. Keeping it inside one product would close it to outside contribution and force reinventing the payload budget that @sezzlee/mcp-core already provides.
  • Using an existing open-source repo. Most of the ones reviewed are Python, and one carries a license that forbids modification; none of them know Codex's approval mode, its workspace boundary, or the payload budget. Ideas were borrowed where they held up: per-kind ready-made prompts (from ollama-handoff), file-path-taking tools and failover (from LocalTokens), and "the worker produces bounded output, the strong side accepts it" (from Shahriar/ollama-mcp-server).
  • One tool per job kind. Every extra tool schema is token cost on every Codex turn; one local_task tool with a kind enum covers the same ground for less.
  • Raising concurrency instead of queueing. Four parallel requests to one GPU were only 1.1x faster than four sequential ones — the GPU does not run requests in parallel, so a queue is the only thing that keeps a call inside its own timeout.

Out of scope (deliberately)

  • An agent loop on the local model. A reviewed repo's small model, run through a full agent harness, took 5–7 minutes on a simple task and once reported having done work it had not done. Agent work already has Codex's own spawn_agent.
  • Embedding. bge-m3 is available on the host but unused; add it if a search need appears.
  • Reading .xlsx directly. v1 reads CSV and plain text only. An .xlsx input goes through @sezzlee/excel-mcp from the calling side; teaching this server the format directly is out of scope for now.

Measured runs

All Codex runs below used gpt-5.6-luna at low reasoning effort, against Ollama 0.34.2 with num_ctx 16,384. "Cache-free" is input_tokens − cached_input_tokens.

RunDataSetupTimeCache-free inputOutputResult
S0400 rows, with cuesCodex alone53 s31.1k1.8k14/14 days
S1400 rows, with cueslocal_task only68 s32.5k2.4k14/14 (local call hit input_too_large, Codex fell back to Python)
S2400 rows, with cueslocal_map, auto-approved155 s41.4k1.5k14/14, Codex never read the rows
H0400 rows, no cuesCodex alone48 s25.8k1.9k14/14 (read 200 rows and wrote a rule)
H2400 rows, no cueslocal_map, blind instruction162 s18.4k1.7k2/14 (376/400 rows labelled)
H3400 rows, no cueslocal_map, sample + verify166 s24.5k2.2k14/14 (400/400 rows labelled)
D017 documentsCodex alone65 s34.1k2.9k17 records (read only the first 240 lines of each document)
D217 documentslocal_task + chunking226 s25.7k3.0k17 records, Codex read no document itself; 17 calls arrived at once, the queue cleared in 157 s, no timeout

Development

text
pnpm turbo run test --filter=@sezzlee/llm-mcp

No local model is needed for this — fetch is faked.

test/live.spec.ts runs against a real Ollama instance:

text
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

来源:packages/servers/llm-mcp/README.md,提交 2614421

工具

0
SourceWeft 尚未在沙箱中启动过该软件包,因此其工具未知。

版本历史

1
  1. v0.1.3最新Oct 11, 2026

评分

已满足适用检查项的 50%

该评分衡量此收录条目的完整程度,依据注册中心条目、端点与公开来源计算得出。它不是对服务器本身的评价,也不表示服务器安全或当前可用:可连通性是带日期的检查结果,评分也不包含安装量或用户评价。

  • 近 30 天内可连通25 分

    请保持端点能够响应 MCP 握手;SourceWeft 每 30 天探测一次。

  • 已声明认证方式10 分

    请在注册中心条目中声明凭据请求头,或保持端点能够响应探测,以便判定其认证方式。

  • 已列出工具15 分

    请让服务器在无凭据时响应 tools/list,或发布可在沙箱中无凭据启动的软件包。

  • 描述必需15 分
  • 图标10 分
  • 文档15 分
  • 许可证10 分