clef-mcp 0.3.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -10,9 +10,9 @@
10
10
  [![Official MCP Registry](https://img.shields.io/badge/MCP_Registry-io.github.HighlyLoadedEgo-blue)](https://registry.modelcontextprotocol.io)
11
11
  [![License: Apache-2.0](https://img.shields.io/badge/License-Apache_2.0-blue.svg)](LICENSE)
12
12
 
13
- **A "reflex" for AI coding agents: structured decisions with probabilities — not prose.**
13
+ **Local decisions for AI agents. Reusable classification for your datasets.**
14
14
 
15
- Local [MCP](https://modelcontextprotocol.io) server that gives agents (Claude Code, Codex, Cursor, ZCode, …) access to the **Clef-Flash** decision model (9B, Apache-2.0 by Cloudflare) through a single tool: `clef_decide`. Pass a `state` and typed questions, get a **probability distribution over your options** in one forward pass. Fully local, offline, no tokens burned.
15
+ Run **Clef-Flash** (9B, Apache-2.0 by Cloudflare) locally. Give coding agents a structured [MCP](https://modelcontextprotocol.io) decision tool, or classify JSONL/CSV datasets with YAML profiles. Get probabilities and explicit review results instead of generated prose. Inference stays on your machine.
16
16
 
17
17
  </div>
18
18
 
@@ -20,18 +20,133 @@ Local [MCP](https://modelcontextprotocol.io) server that gives agents (Claude Co
20
20
 
21
21
  ## Quick start
22
22
 
23
+ Requires Node.js 20+ and enough memory for the selected model (16 GB recommended for Q4_K_M). The default model download is approximately 6 GB; subsequent inference runs offline.
24
+
25
+ ```bash
26
+ npm install -g clef-mcp
27
+ clef-mcp install
28
+ ```
29
+
30
+ Choose your workflow:
31
+
32
+ | Workflow | Start here |
33
+ |---|---|
34
+ | Decisions inside Claude Code, Codex, Cursor or ZCode | `clef-mcp setup`, then restart your client; [client configuration](#register-with-your-mcp-client) |
35
+ | Classify tickets, documents or other records | [YAML profiles and dataset classification](#classify-jsonlcsv-with-a-yaml-profile) |
36
+ | Hooks, CI or shell scripts | [`clef-mcp decide`](#scripting--hooks) |
37
+
38
+ The MCP server starts with `clef-mcp` (stdio). Only `install` downloads model/runtime files. You can also use `npx -y clef-mcp` instead of a global install; `npx -y clef-mcp install --setup` combines model installation and client registration.
39
+
40
+ ## Classify JSONL/CSV with a YAML profile
41
+
42
+ Define a task once, then apply it to separate records. The model loads once for the whole batch; a separate daemon is not required.
43
+
44
+ Save this as `support-routing.yaml`:
45
+
46
+ ```yaml
47
+ schema_version: 1
48
+ name: support-routing
49
+ instructions: Classify the current support request into exactly one department.
50
+ labels:
51
+ billing: Payments, refunds, invoices and subscription charges
52
+ technical: Errors, outages, installation and integration problems
53
+ other: Requests outside billing and technical support
54
+ input:
55
+ id_field: id
56
+ fields: [subject, body]
57
+ policy:
58
+ min_probability: 0.80
59
+ min_margin: 0.15
60
+ ```
61
+
62
+ Save `tickets.jsonl` (one object per line):
63
+
64
+ ```jsonl
65
+ {"id":"001","subject":"Duplicate charge","body":"Please refund my duplicate subscription payment."}
66
+ {"id":"002","subject":"Checkout crashes","body":"The payment page returns an error."}
67
+ ```
68
+
69
+ Or use `tickets.csv` with a header row:
70
+
71
+ ```csv
72
+ id,subject,body
73
+ 001,Duplicate charge,Please refund my duplicate subscription payment.
74
+ 002,Checkout crashes,The payment page returns an error.
75
+ ```
76
+
77
+ ```bash
78
+ clef-mcp classify tickets.jsonl --profile support-routing.yaml --output results.jsonl
79
+ clef-mcp classify tickets.csv --profile support-routing.yaml --output csv-results.jsonl
80
+ # stdout carries JSONL; summaries and diagnostics go to stderr
81
+ cat tickets.jsonl | clef-mcp classify - --profile support-routing.yaml
82
+ # Extension override, including CSV on stdin
83
+ cat tickets.csv | clef-mcp classify - --format csv --profile support-routing.yaml
84
+ ```
85
+
86
+ Runnable files also ship in [`examples/classify/`](examples/classify/).
87
+
88
+ ### Profile fields
89
+
90
+ | Field | Meaning |
91
+ |---|---|
92
+ | `schema_version` | Required; currently `1` |
93
+ | `name` | Required profile ID, up to 64 letters/digits/underscores/hyphens, starting with a letter or digit |
94
+ | `instructions` | Required classification question |
95
+ | `labels` | Required map of 2–100 mutually exclusive label IDs to descriptions; include a fallback category where appropriate |
96
+ | `model` | Optional model ID; priority is CLI `--model` → profile → `CLEF_MODEL` → `clef-flash` |
97
+ | `input.fields` | Optional exact top-level field names to send to the model; otherwise use the full record |
98
+ | `input.id_field` | Optional string/numeric ID to copy to the result; missing or invalid IDs become row errors |
99
+ | `policy.min_probability` | Minimum winning probability, default `0.80` |
100
+ | `policy.min_margin` | Minimum difference between the two highest probabilities, default `0.15` |
101
+ | `policy.min_confidence` | Optional minimum runtime-reported confidence; missing confidence then requires review |
102
+ | `examples` | Optional list of up to 20 `{input: {...}, label: configured_label}` references |
103
+
104
+ Examples are data supplied alongside the current record; they do not train or modify model weights. Unknown fields, duplicate YAML keys, aliases, merge keys, unsupported tags and non-JSON values are rejected. Label IDs use the same character rules as profile names, with a 128-character limit; prototype-shaped reserved keys are rejected. Missing selected fields produce row errors.
105
+
106
+ ### Accepted results and `needs_review`
107
+
108
+ Illustrative results (actual probabilities depend on your data and runtime):
109
+
110
+ ```jsonl
111
+ {"row":1,"id":"001","profile":"support-routing","model":"clef-flash","status":"classified","label":"billing","suggested_label":"billing","probability":0.92,"margin":0.87,"probabilities":{"billing":0.92,"technical":0.05,"other":0.03},"review_reasons":[]}
112
+ {"row":2,"id":"002","profile":"support-routing","model":"clef-flash","status":"needs_review","label":null,"suggested_label":"technical","probability":0.48,"margin":0.06,"probabilities":{"billing":0.42,"technical":0.48,"other":0.10},"review_reasons":["low_probability","low_margin"]}
113
+ ```
114
+
115
+ `classified` means all configured thresholds passed. `needs_review` keeps the suggestion and full distribution but sets `label: null`. Reasons are `low_probability`, `low_margin`, `tie`, `low_confidence` or `missing_confidence`. Exact ties always require review, including when thresholds are zero. Comparisons are inclusive at the threshold. Results may include model `confidence` and token `usage` when available.
116
+
117
+ Winning probability, probability margin and model-reported confidence are different quantities. These thresholds are routing policy, not a calibrated accuracy guarantee. Check them on representative labeled data before automating decisions. Classification does not grant authorization or execute actions.
118
+
119
+ Invalid JSONL objects and missing fields produce `status: "error"` rows and processing continues. Runtime failures stop the run; they are never converted to review decisions. Output includes identifiers and results, not a copy of the original record.
120
+
121
+ ### Resume, formats and limits
122
+
23
123
  ```bash
24
- # 1. Detect hardware, download the model (~6 GB) + llama.cpp runtime, verify checksum + inference
25
- npx clef-mcp install
124
+ clef-mcp classify tickets.jsonl --profile support-routing.yaml --output results.jsonl --resume
125
+ ```
26
126
 
27
- # 2. Register the MCP server + agent skill in your clients (zcode, claude-code, codex, cursor)
28
- npx clef-mcp setup
127
+ File output creates private `results.jsonl` and `results.jsonl.meta.json` files. The sidecar fingerprints the full input, validated profile, effective model, runtime and format. Resume requires all of these to match. Use a new output path after changing data or thresholds; existing files are never silently overwritten. Input must stay unchanged while a run is active.
29
128
 
30
- # 3. Run the MCP server (stdio)
31
- npx clef-mcp
129
+ Resume skips the contiguous committed prefix, including committed error rows; it does not retry those errors. An incomplete final write is discarded, while corruption in a complete row is rejected. Resume requires regular file input and `--output`; stdin/stdout resume is unsupported. A local lock prevents simultaneous writers. Dead local writer locks can be reclaimed; active, foreign-host or unverifiable locks are preserved. A crash during lock acquisition may leave `.lock.claim`, which requires inspection before manual removal.
130
+
131
+ JSONL accepts objects, ignores blank lines and supports UTF-8 BOM/CRLF. CSV supports quoted commas, escaped quotes and multiline fields; headers must be nonempty and unique, with consistent column counts. CSV cells remain strings, preserving IDs such as `001`. Format defaults to `.jsonl`/`.csv`, or JSONL for stdin; other extensions need `--format`.
132
+
133
+ Profiles and logical records are limited to 1 MiB, YAML nesting to 64 levels, selected/CSV fields to 1000, and examples to 20. Existing instruction/criteria/state limits and the model's 16k-token context also apply; selected fields and examples share that context. Oversized JSONL rows are reported as row errors. Broken/oversized CSV syntax stops the run because record boundaries cannot be recovered reliably.
134
+
135
+ | Exit code | Meaning |
136
+ |---|---|
137
+ | `0` | Completed; review results are allowed |
138
+ | `1` | Row errors occurred in this invocation, or inference/output failed |
139
+ | `2` | Invalid options/profile/input structure or incompatible checkpoint |
140
+ | `3` / `4` | Model not installed / runtime missing |
141
+ | `130` | Interrupted; committed file output can be resumed |
142
+
143
+ ### Update
144
+
145
+ ```bash
146
+ npm install -g clef-mcp@latest
32
147
  ```
33
148
 
34
- `clef-mcp` (step 3) never downloads anything. If the model is missing, tool calls return a structured `MODEL_NOT_INSTALLED` error with a hint. Steps 1 and 2 combine: `npx clef-mcp install --setup`.
149
+ Restart MCP clients and any existing daemon after updating. An already installed model does not need another download.
35
150
 
36
151
  ## Why not just ask the LLM?
37
152
 
@@ -196,7 +311,11 @@ clef-mcp decide --questions questions.json --state state.json
196
311
 
197
312
  stdout carries the strict JSON result (same shape as the MCP tool, including `confidence` and `usage`); errors go to stderr as structured JSON with exit codes: `2` invalid input, `3` model not installed, `4` runtime missing. `decide` never downloads anything.
198
313
 
199
- Each plain `decide` invocation is a cold start (model load included, a few seconds) — fine for gates and triage. For repeated calls, start `clef-mcp daemon` once: it keeps the model warm on a permission-scoped unix socket in `CLEF_HOME` (no TCP port, unloads after `CLEF_DAEMON_IDLE` seconds, default 600), and `clef-mcp decide --daemon` answers in well under a second, falling back to a cold run when no daemon is running. See [`examples/hooks/`](examples/hooks/) for a PreToolUse guard and a GitHub Action recipe.
314
+ Model selection: `--model <id>` overrides the input document's `model`, which overrides `CLEF_MODEL` (default: `clef-flash`). The same precedence applies with `--daemon`.
315
+
316
+ Each plain `decide` invocation is a cold start (model load included, a few seconds) — fine for gates and triage. For repeated calls, start `clef-mcp daemon` once: it keeps the model warm on an owner-only (`0600`) unix socket in `CLEF_HOME` (no TCP port, unloads after `CLEF_DAEMON_IDLE` seconds of inactivity following the last completed decision, default 600). Active and queued requests prevent idle unloading. `clef-mcp decide --daemon` answers in well under a second, falling back to a cold run when no daemon is running. See [`examples/hooks/`](examples/hooks/) for a PreToolUse guard and a GitHub Action recipe.
317
+
318
+ The PreToolUse guard blocks a command when the model judges it destructive (p ≥ 0.9) and tells the agent to **ask the user** — a block is a pause plus escalation, not a wall; the gate is advisory by design and says so. First real firing on day one: caught a history-rewrite force push (p=0.94) and surfaced its own bypass vector, which is now fixed and documented in the recipe.
200
319
 
201
320
  ## Teach your agent (skill)
202
321
 
@@ -231,6 +350,7 @@ The `ClefRuntime` interface (`load / decide / unload / health`) isolates the eng
231
350
  ```bash
232
351
  clef-mcp # run the MCP server on stdio (default command)
233
352
  clef-mcp decide # one-shot decision (no MCP session): JSON in, JSON out — for hooks, CI, scripts
353
+ clef-mcp classify # apply a YAML profile to JSONL/CSV records; review uncertain results
234
354
  clef-mcp daemon # keep the model warm on a local unix socket; `decide --daemon` uses it
235
355
  clef-mcp install # detect hardware → download model + runtime → verify checksum → verify inference
236
356
  clef-mcp setup # register the MCP server + agent skill in zcode / claude-code / codex / cursor
@@ -295,10 +415,10 @@ Codes: `MODEL_NOT_INSTALLED`, `MODEL_LOAD_FAILED`, `RUNTIME_NOT_FOUND`, `RUNTIME
295
415
 
296
416
  ## Security & data handling
297
417
 
298
- - No network servers, no telemetry, no accounts; everything runs locally.
418
+ - No public network service, telemetry or accounts. MCP uses stdio; inference uses local loopback HTTP, and the optional daemon uses a local Unix socket.
299
419
  - The model downloads only on an explicit `install`, over HTTPS, checksum-verified.
300
420
  - `state` content is passed to the model as data; the server never executes or instruction-interprets it.
301
- - Filesystem access is limited to `CLEF_HOME` (plus reading standard MCP client config paths in `doctor`).
421
+ - Model/runtime storage stays in `CLEF_HOME`. Classification also reads the input/profile paths you supply and writes explicit output/checkpoint paths; setup/doctor inspect or update supported client configuration.
302
422
  - The managed runtime is the official llama.cpp build; pin it with `CLEF_LLAMA_RELEASE_TAG`.
303
423
 
304
424
  See [SECURITY.md](SECURITY.md) for the full policy.