Skip to main content
Glama

laya-mcp

MCP server that exposes Laya's typed decisions to coding agents. Optional by design. Your existing setup runs unchanged if Laya or this server are missing.

laya-mcp is a Model Context Protocol server that gives your coding agent ten typed-decision tools backed by a local Laya instance. Every tool returns calibrated probabilities so the agent can branch, sort, and gate on real confidence instead of vibe-checking its own output.

┌──────────────────┐  stdio JSON-RPC  ┌────────────────────┐  HTTP  ┌────────────────────┐
│ OpenCode CLI     │ ───────────────▶ │ laya-mcp (Node/TS) │ ─────▶ │ laya-server (Py)   │
│ Claude Code      │                  │  - 10 tools        │        │  - FastAPI         │
│ Codex            │                  │  - health watcher  │        │  - Laya SDK        │
│ Pi              │ ◀─────────────── │  - graceful fail   │ ◀───── │  - HuggingFace model│
└──────────────────┘                  └────────────────────┘        └────────────────────┘

The ten tools (one per file under src/tools/):

Tool

What it does

Laya primitive

laya_screen

Prompt-injection / substance / relevance guard before content enters context

noul × 3

laya_verify

Verify one or more claims against supplied evidence

noul per claim

laya_find

Pick the best candidate id for a query (or none)

choice

laya_rerank

Score and sort all candidates by relevance

noul per candidate

laya_classify

Batch-classify items against a shared catalog

choice per item

laya_decide

Pick one of 2-6 bounded options + optional per-requirement checks

choice + noul

laya_compare

Compare two passages overall and per aspect

choice per aspect

laya_extract

Pull structured field values from a document (regex + judgment)

choice over regex matches

laya_review

Score a proposed diff against the original request before merging

score + noul

laya_gate

Completion gate: laya_review plus per-claim verification

combined

The shape and purpose of each tool is modeled after jkudish/jev-mcp (155 ★, the reference Jev MCP server) and itsmostafa/typesafe-mcp (133 ★). Replace Jev with self-hosted Laya and keep the same ergonomics.


Why this exists

Jev is a hosted decision model from TypeSafe AI ($0.042/M input tokens, ~264 ms p50, English-only, closed weights). Laya is the open-source answer (NandhaKishorM/laya, Apache 2.0, $0 self-hosted, ~38 ms p50, 100+ languages, open weights). laya-mcp is the glue: it lets any MCP-compatible coding agent use Laya the same way it would use Jev, with the same ten tools and the same typed outputs, but locally, cheaply, and multilingual.

The MCP server is completely independent:

  • If laya-mcp is not installed, your agent runs exactly as it does today.

  • If laya-server (the Python process) is down, the MCP server advertises zero tools and every call returns a structured error. The agent keeps working.

  • If Laya itself is missing, the Python wrapper exits with a clear error at startup time -- nothing silently breaks.


Related MCP server: governed-mcp

Install

The installer is idempotent and does not touch any of your existing agent configuration. It only creates $HOME/laya-mcp/.

Requirements

  • Python 3.10+ with pip

  • Node.js 20+ with npm

  • ~1 GB disk for the Laya model weights (downloaded on first run)

  • Optional: NVIDIA GPU with CUDA for ~30 ms inference. CPU works too (~200 ms per call).

One-command install

git clone https://github.com/andragon3110/laya-mcp.git
cd laya-mcp
./install.sh

The script:

  1. Creates a Python venv at $HOME/laya-mcp/.venv/

  2. Pins laya>=0.3.0,<0.4.0 (the version line that ships the typed-decisions subfolder) and installs laya, fastapi, uvicorn, huggingface_hub

  3. Runs npm install and tsc

  4. Pre-downloads all 3 Laya checkpoints (~1.7 GB total) so the Router starts ready: english (~440 MB), multilingual (~320 MB), typed-decisions (~440 MB). All three are bundled under the convaiinnovations/laya repo at different subfolders; only the requested weights are downloaded.

  5. Generates start_laya.sh, start_mcp.sh, uninstall.sh, examples/opencode.snippet.json

You can override paths with LAYA_MCP_HOME, LAYA_HOST, LAYA_PORT, LAYA_MCP_NO_ALL=1 (skip the auxiliary checkpoints, Router will fetch them on first request), PYTHON. See install.sh.

Start the laya-server

In one terminal:

$HOME/laya-mcp/start_laya.sh
# -> [laya-server] loading Laya Router (device=auto, preload=True, auto_task_detection=True, max_loaded=3)
# -> [laya-server] Laya Router ready: loaded=['english', 'multilingual', 'typed-decisions'], laya_sdk=0.3.4
# -> [laya-server] laya-server starting on http://127.0.0.1:8765

Because the installer pre-downloaded all three checkpoints, the first start is seconds, not minutes. The Router keeps all three resident so script detection + workflow auto-detection never pay a model-load cost.

The Router picks a checkpoint per request:

Input language

Detected script

Checkpoint used

Spanish ("Me cobraron dos veces...")

Latin, lang=es

multilingual

English ("I was charged twice...")

Latin, lang=en

english

Question ids match a typed-decisions workflow

any

typed-decisions (auto)

Caller passes model="typed-decisions"

any

typed-decisions (force)

Every /predict response includes a routing block with the model chosen and the reason. The MCP tools surface it in their text output so the agent can audit routing decisions.

Verify

curl http://127.0.0.1:8765/health
# -> {"status":"ok","ready":true,"loaded":["english","multilingual","typed-decisions"],"auto_task_detection":true,"max_loaded":3,"device":"auto","laya_sdk_version":"0.3.4","uptime_seconds":2.3}

If ready: true and loaded lists all three checkpoints, the MCP server will advertise all ten tools.

How the Router picks a checkpoint (default behaviour)

install.sh configures the server with three env vars:

Var

Default

Effect

LAYA_PRELOAD

1

Load all 3 checkpoints up front so routing never pays a load cost

LAYA_AUTO_TASK_DETECTION

1

Use typed-decisions when question ids match its 4 workflows

LAYA_MAX_LOADED

3

Keep up to 3 resident (LRU eviction if you raise / lower this)

With those defaults, every /predict call returns a routing block that the MCP tools surface to the agent:

{
  "model": "multilingual",
  "repo": "convaiinnovations/laya/multilingual",
  "reason": "Latin script but language looks like 'es', not English",
  "detection": { "script": "latin", "language": "es", "is_english": false },
  "workflow": null
}

Forcing a specific checkpoint

Pass model, task, or lang on the /predict body to override the Router. The MCP tools do not currently expose these directly, but the HTTP endpoint accepts them and you can build wrappers around them:

curl -X POST http://127.0.0.1:8765/predict \
  -H 'Content-Type: application/json' \
  -d '{"state":{"text":"Hola"},"questions":{"q":{"type":"choice","instructions":"...","criteria":{}}},"model":"multilingual"}'

Choosing a different setup

If you only need one language (e.g. Spanish only), set LAYA_MAX_LOADED=1 LAYA_PRELOAD=0 and preload just the checkpoint you want:

LAYA_MAX_LOADED=1 LAYA_PRELOAD=0 LAYA_AUTO_TASK_DETECTION=0 \
  $HOME/laya-mcp/start_laya.sh

The Router will lazily download the first checkpoint you hit and evict others. ~ 400 MB RAM instead of 1.7 GB, at the cost of paying a model load on first use of each language.


Wire into your agent

laya-mcp is an optional MCP server. Your agent only sees its tools if you register it. None of the snippets below modify anything you already have -- they only add an mcp.laya entry.

OpenCode

Edit ~/.config/opencode/opencode.json and merge the snippet:

SNIPPET="$HOME/laya-mcp/examples/opencode.snippet.json"
python3 - <<PY
import json, pathlib
cfg = json.loads(pathlib.Path("$HOME/.config/opencode/opencode.json").read_text())
cfg.setdefault("mcp", {}).setdefault("laya", json.loads("""$SNIPPET""")["mcp"]["laya"])
pathlib.Path("$HOME/.config/opencode/opencode.json").write_text(json.dumps(cfg, indent=2))
PY

Restart OpenCode. The ten laya_* tools now appear in the agent's tool palette (only when the Python server is reachable).

Claude Code

Add to ~/.claude.json (or the project's .mcp.json):

{
  "mcpServers": {
    "laya": {
      "command": "node",
      "args": ["$HOME/laya-mcp/dist/index.js"],
      "env": { "LAYA_URL": "http://127.0.0.1:8765" }
    }
  }
}

Restart Claude Code.

Codex

Add to ~/.codex/config.toml:

[mcp_servers.laya]
command = "node"
args = ["$HOME/laya-mcp/dist/index.js"]
env = { LAYA_URL = "http://127.0.0.1:8765" }

Restart Codex.

Pi

Pi has no MCP client. The reference companion is gentle-pi which ships its own native extensions. To wire laya-mcp into Pi today, run the server as a child process via Pi's extension API (see Pi docs), or expose laya-server's HTTP endpoint to whatever script wraps Pi.


Optional: integrate with Gentle-AI sub-agents

Gentle-AI orchestrates SDD/Odd/RDD workflows across many sub-agents on top of OpenCode/Pi/Claude Code. Two opt-in patterns make sense:

  1. sdd-apply -> laya_review: Before declaring an SDD task done, the orchestrator (or the sdd-apply agent) calls laya_review on the diff against the original task. A contradicted safe_to_apply (probability < 0.5) escalates instead of auto-archiving.

  2. GitHub issues -> laya_classify: A webhook action calls laya_classify against your label set with each new issue body. Auto-label only when confidence >= 0.85.

Both patterns are documented in examples/gentle-ai-integration.md. None of these are enabled by default -- you wire them by editing your agent's skill files (e.g. .opencode/agents/sdd-apply.md).


Diagnose with doctor

doctor checks the whole stack and tells you exactly what is broken, if anything: Laya SDK import + version, downloaded checkpoints, torch/CUDA, free disk, free RAM, install-dir layout, MCP bundle boot, the live /health and /predict probes, and the optional opencode.json entry.

# Human-readable report (--no-live skips the server probes)
$HOME/laya-mcp/doctor.sh
$HOME/laya-mcp/doctor.sh --no-live

# JSON for scripts/CI (exit 1 when any check fails)
$HOME/laya-mcp/doctor.sh --json
$HOME/laya-mcp/doctor.sh --json --fail-on warn   # stricter: 1 also on warnings

# Same report over HTTP while the server is running (?live=false skips probes)
curl http://127.0.0.1:8765/doctor | python3 -m json.tool
curl 'http://127.0.0.1:8765/doctor?live=false' | python3 -m json.tool

Expected output (everything healthy):

[ laya-mcp doctor ]  [OK]  11 pass  2 warn  0 fail  1 skip
  install_dir: /home/you/laya-mcp
  hf_cache:    /home/you/.cache/huggingface
  python:      3.12.1  platform: linux

  ✓ [PASS] laya-sdk                laya 0.3.4 installed with Router
  ✓ [PASS] laya-version            laya 0.3.4 supports subfolder kwarg
  ✓ [PASS] torch                   torch 2.5.1 installed
  ! [WARN] gpu                      no CUDA GPU detected -- Laya will run on CPU (~200 ms/call)
  ✓ [PASS] disk                    42.1 GB free at /home/you
  ✓ [PASS] memory                  12.4 GB available of 15.6 GB total
  ✓ [PASS] install-dir             /home/you/laya-mcp looks complete
  ✓ [PASS] checkpoint:english      convaiinnovations/laya (root) cached
  ✓ [PASS] checkpoint:multilingual convaiinnovations/laya-multilingual (root) cached
  ✓ [PASS] checkpoint:typed-decisions convaiinnovations/laya-typed-decisions (typed-decisions) cached
  ✓ [PASS] laya-server             GET http://127.0.0.1:8765/health reachable in 12 ms
  ✓ [PASS] live-predict            POST http://127.0.0.1:8765/predict ok in 210 ms
  ✓ [PASS] mcp-server-boot         index.js booted and was reachable for stdio
  - [SKIP] opencode-config         ~/.config/opencode/opencode.json exists but no mcp.laya entry

Run this first whenever something looks wrong -- paste the output when asking for help and the failure is usually obvious from the check name.

Test the install

After installing and starting start_laya.sh:

# Full diagnostic (preferred -- runs every check at once)
$HOME/laya-mcp/doctor.sh

# Sanity-check the Python wrapper
$HOME/laya-mcp/tests/test_health.sh

# End-to-end smoke (loads Laya and runs one /predict call)
$HOME/laya-mcp/.venv/bin/python $HOME/laya-mcp/tests/smoke.py

# MCP-level smoke (uses the official inspector)
cd $HOME/laya-mcp && npm run inspect

Expected: doctor.sh shows 0 fail; the inspector shows 10 tools in the left panel. With the Python server down, doctor.sh shows a laya-server warning and the inspector shows 0 tools.


Uninstall

$HOME/laya-mcp/uninstall.sh

Removes $HOME/laya-mcp and the mcp.laya entry from ~/.config/opencode/opencode.json (with timestamped backup). The rest of your setup is untouched.


Configuration

All env vars (with defaults):

Var

Default

Purpose

LAYA_URL

http://127.0.0.1:8765

Where the Python server listens

LAYA_HOST / LAYA_PORT

127.0.0.1 / 8765

Bind address for the Python server

LAYA_DEVICE

auto

auto / cpu / cuda

LAYA_PRELOAD

1

Load all 3 checkpoints at startup

LAYA_AUTO_TASK_DETECTION

1

Auto-route to typed-decisions on workflow match

LAYA_MAX_LOADED

3

Max resident checkpoints (LRU eviction)

LAYA_STANDALONE_REPOS

0

Use per-checkpoint repos instead of the hub repo

LAYA_TIMEOUT_MS

5000

Per-call HTTP timeout from MCP to Python

LAYA_TOOL_TIMEOUT_MS

8000

Per-tool MCP timeout

LAYA_HEALTH_INTERVAL_MS

10000

Background watcher poll interval

LAYA_LOG_LEVEL

WARNING

uvicorn log level

LAYA_MODEL and LAYA_SUBFOLDER are no longer used by laya_server.py itself -- the Router selects checkpoints automatically. They are still honoured by download_models.py if you want to pre-fetch a single checkpoint.


Architecture & guarantees

  • Three independent layers: laya-mcp (Node stdio) → laya-server (FastAPI HTTP) → Laya (Python SDK). Any layer can be restarted without restarting the others.

  • No silent degradation: if Laya is unreachable, the MCP server advertises zero tools so the agent sees nothing rather than tools that always fail.

  • Hard timeouts: every HTTP call has a bounded timeout. The agent never hangs because of laya-mcp.

  • Structured errors: when a tool does fail, the response is {isError: true, content: [{type: "text", text: ...}]} with a hint describing how to recover.

  • Stateless: the MCP server holds no conversation state. Each tool call is independent.


License

MIT. See LICENSE.

The Laya model itself is Apache 2.0 (NandhaKishorM/laya) and the TypeSafe AI patterns this server is patterned on are theirs.

[mc

Related MCP Connectors

Related MCP Servers

  • F
    license
    Not graded
    quality
    C
    maintenance
    MCP server that enforces governance on agentic decisions with auditable evidence records, providing tools for understanding, calibrating confidence, and navigating handoffs based on policy.
    1
    -
  • F
    license
    Not graded
    quality
    B
    maintenance
    A self-hosted MCP server that provides tools for structured reasoning, confidence calibration, and detecting recurring gaps in AI outputs, aiming to reduce workload by improving verification and attention allocation.
    -
  • A
    license
    A
    quality
    A
    maintenance
    An MCP server that exposes governance, trust-scoring, compliance, guardrail, cost, drift, and supply-chain scanning tools and resources to any MCP client over stdio, Streamable HTTP, or legacy HTTP+SSE. It lets agents route every tool call through a deterministic five-way decision (allow, redact, require approval, deny, or quarantine) with hash-chained evidence, human approval workflows, and in-agent trust gates for LangChain, LangGraph, and Google ADK.
    30
    44 PyPI
    1
    MIT