# `@vons/decision-sdk` The TypeScript package mirrors the Vons Python request/response contract and keeps KASI policy and execution in the host. It contains no tool executor and does not treat a model-produced risk or confidence value as permission. The contract-only entry point remains small, while the optional `./onnx` subpath uses pinned `onnxruntime-web@1.30.0` and `@huggingface/tokenizers@0.2.0` for local browser inference. Applications provide a model backend through `DecisionBackend`; the runtime helper verifies bundle bytes, uses the declared WASM or WebGPU provider, and does not silently fall back from an unavailable accelerator. `callFingerprint` returns a canonical JSON consent key. Hosts that persist consent for the Python adapter should SHA-256 this key before storage so the cross-language fingerprint format remains identical. Node 22+ can load the source directly with its TypeScript type stripping during early development. A release build should type-check and bundle the package with the consuming application's toolchain. The local smoke harness covers both pilot bundles and both providers. Build it and serve the repository root so the browser can fetch the ignored ORT runtime files and the existing pilot artifacts: ```sh npm ci npm run build:browser cd ../.. python3 -m http.server 8765 --bind 127.0.0.1 ``` Open `http://127.0.0.1:8765/sdk/typescript/demo/`. The smoke page reports session-load and one-request timings, optional Chromium JS-heap observations, provider evidence, and the contract response. These are diagnostic smoke values, not the repeated benchmark protocol. ## Source preview For a UI that does not require serving the development workspace, build the [Chrome side-panel extension](extension/README.md) with `npm run build:extension`. It packages the runtime locally and accepts a user-selected, hash-verified model folder. The guide explains installation and the separate model requirement. ## MCP stdio server (local-only, ONNX runtime backend) This SDK ships a small, local-only Model Context Protocol (MCP) stdio server in `src/mcp.ts` and `src/mcp-cli.ts`. It is strictly for hosts that already have a user-supplied, hash-verified ONNX decision bundle on the local filesystem. The server uses these exact, pinned npm dependencies: - `@modelcontextprotocol/server` `2.1.0` - `zod` `4.6.5` ### What it exposes Exactly one MCP tool and one read-only MCP resource: - **Tool:** `vons_decide` — takes a strict DecisionRequest JSON object mirroring the shared contract (`state`, `questions[]`, optional `backend`, optional non-negative integer `seed`), validates it through the shared `validateRequest` → `DecisionBackend.decide` → `validateResponse` pipeline, and returns a JSON-serialized DecisionResponse as a single MCP `text` content item. Malformed inputs raise an explicit MCP application error; no fake `choice`, no silent fallback, and no coerced success. Explicit abstentions (`status=abstain`, `choice=null`, `abstain_reason`) round-trip exactly as returned by the backend. - **Resource:** `vons://bundle/manifest/metadata` — non-sensitive metadata only. Returns `schema_version`, `backend`, `model_id` (if declared), `option_count`, and `sequence_length`. No local filesystem path is emitted. Never includes file bytes, file hashes, tokenizer contents, graph data, or runtime asset digests. ### What it explicitly does NOT do Per the Vons pilot scope and AGENTS.md host boundary: - No HTTP listener, no network, no remote MCP service. - Writes MCP JSON-RPC messages **only** to stdout. - Diagnostic messages, errors, warning banners, and runtime logs go **only** to stderr. The `--help` usage text is intentionally written to stdout (exit code 0) so it may be piped or redirected by shell callers; when usage is printed for invalid/missing flags it is still written to stderr with a non-zero exit status. - Never executes downstream tools, never authorizes actions, never runs host-side tooling. - Never performs silent fallback decisions or substitutes a fake `choice` when the input is invalid or the backend fails. - No auto-discovery of bundles, no search for manifests, no default paths. The user must pass an explicit `--bundle