tla-checker 0.3.11 → 0.4.1

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
@@ -253,6 +253,65 @@ if (result.dot) {
253
253
  | `export_dot` | bool | Include DOT graph in result |
254
254
  | `dot_mode` | string | DOT export mode: `full`, `trace`, `clean` (default), `choices` |
255
255
 
256
+ ## MCP Server
257
+
258
+ `tla-mcp` exposes the model checker as a Model Context Protocol server over stdio, so agentic clients (Claude Code, Cursor, etc.) can call it as a first-class tool.
259
+
260
+ ### Install
261
+
262
+ The fastest path — install the published crate from crates.io (no clone needed):
263
+
264
+ ```bash
265
+ cargo install tla-checker --bin tla-mcp
266
+ ```
267
+
268
+ Or download a pre-built binary from the [latest GitHub release](https://github.com/fabracht/tla-rs/releases/latest) (Linux, macOS Intel/Apple Silicon, Windows).
269
+
270
+ From a working copy:
271
+
272
+ ```bash
273
+ cargo install --path . --bin tla-mcp
274
+ ```
275
+
276
+ ### Register with your client
277
+
278
+ Add to your MCP client config (Claude Code example, `~/.claude/mcp.json` or `claude_desktop_config.json`):
279
+
280
+ ```json
281
+ {
282
+ "mcpServers": {
283
+ "tla": {
284
+ "command": "tla-mcp"
285
+ }
286
+ }
287
+ }
288
+ ```
289
+
290
+ ### Tools
291
+
292
+ All tools return a `schema_version: "1"` field — the contract is frozen at version 1 and will be bumped explicitly on breaking changes.
293
+
294
+ | Tool | Purpose |
295
+ |------|---------|
296
+ | `validate_spec` | Parse a `.tla` file and return a summary (vars, **constants with resolved values**, invariants, init/next presence). Returns a structured parse/config error with source span on failure. Inspect the `constants` array before every `check_spec` call — outlier values are the most common cause of timeouts. |
297
+ | `list_invariants` | Return the detected invariants (definitions matching `Inv*`, `TypeOK*`, `NotSolved*`, plus anything declared in a cfg `INVARIANT` directive). |
298
+ | `check_spec` | Run full model checking. **Requires** `max_states`, `max_depth`, AND `max_seconds` (no defaults — agents must budget all three upfront). The `max_seconds` budget is enforced during both BFS exploration and the liveness phase. Returns one of: `ok`, `invariant_violation` (with trace + invariant name + actions), `deadlock`, `liveness_violation` (with prefix + cycle), `limit_reached` (budget exhausted — not an error; `limit` is one of `max_states`/`max_depth`/`max_seconds`), or `error` (with structured phase + message + optional source span). |
299
+ | `replay_scenario` | Walk a spec step-by-step through a guided scenario (text of `step: <TLA+ expression>` lines). Returns the same `StateSnapshot` shape as `check_spec`, plus per-step `changes` descriptions. On a step that no transition satisfies, returns `status: "failed"` with `available_actions` to help diagnose the mismatch. |
300
+
301
+ The boolean toggles `allow_deadlock` and `check_liveness` are `Option<bool>` — omit them to defer to the cfg file (e.g., `CHECK_DEADLOCK FALSE` or `PROPERTY` directives), pass `true` / `false` to override the cfg. The `symmetry` field appends to any constants declared via cfg `SYMMETRY` rather than replacing them.
302
+
303
+ `validate_spec` and `list_invariants` include a `warnings` array surfacing parser-tolerance warnings — when the parser fails to parse an operator body it silently skips that operator and emits a warning. The same array also surfaces unsupported temporal constructs (`<<A>>_v` diamond actions, `<>[]P` stable-eventually) that the fairness extractor drops. Without the warnings array, a typo in an invariant's body would let `check_spec` "pass" without ever checking that invariant.
304
+
305
+ `check_spec` honors the cfg's `CONSTRAINT` directive (state-space pruning predicate) and accepts an inline `state_constraint: "<TLA+ expression>"` parameter. Constraints are evaluated on every state — states where the expression is false are dropped from the reachable set and not explored further. Use this to bound otherwise-explosive state spaces (e.g., `state_constraint: "Len(queue) <= 3"`) without modifying the spec.
306
+
307
+ ### Counterexample format
308
+
309
+ Each state in a trace is `{ vars: { var_name: { display, json } } }`. The `display` field is the TLA+-formatted value (`"{1, 2, 3}"`, `"<<a, b>>"`); the `json` field is a typed JSON form preserving set/tuple/record/function structure via a `kind` tag.
310
+
311
+ ### Mid-session reload
312
+
313
+ MCP clients spawn server processes at session startup. Rebuilding or reinstalling `tla-mcp` while a Claude Code session is already running will not hot-reload the new binary — restart the client (or open a new session) to pick up changes. Verifying outside an MCP client: `tla-mcp` invoked directly will exit with `ConnectionClosed` after stdin EOF, which is the correct behavior for a stdio server with no peer.
314
+
256
315
  ## Limitations
257
316
 
258
317
  `Nat` and `Int` are bounded (-100 to 100 by default). Temporal operators `[]`, `<>`, `~>` are parsed but cannot be evaluated directly — use `--check-liveness` for fairness/liveness properties via SCC analysis. Unbounded quantifiers (`\E x : P` without `\in S`) and `Seq(S)` enumeration are not supported. Recursive operators must be declared with `RECURSIVE`.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tla-checker",
3
- "version": "0.3.11",
3
+ "version": "0.4.1",
4
4
  "type": "module",
5
5
  "description": "A TLA+ model checker compiled to WebAssembly",
6
6
  "license": "MIT OR Apache-2.0",
Binary file