Skip to main content
Glama
README.md
# open-jev-mcp

Every prompt you send to **Claude Code** or **Hermes** goes through this pipeline:

```
prompt ──► local LLM planner (Ollama, JSON-schema output) ──► 2-5 typed questions (noul/choice/score)
       ──► local Open-Jev server (/v1/systemone) ──► calibrated probabilities
       ──► injected as context ──► the main agent decides what to do with it
```

The pipeline fails open: if Ollama or Jev is down or slow, the prompt goes through unchanged.
Failures are logged to `~/.cache/openjev-mcp/errors.log`. Each successful run is logged to
`~/.cache/openjev-mcp/runs.jsonl` with the questions, answers and latencies.

Prompts are sent only to the two localhost services above; nothing leaves your machine. The logs stay local
in `~/.cache/openjev-mcp` and are git-ignored.

## Install
Requires Python 3.10+, [uv](https://docs.astral.sh/uv/), [Ollama](https://ollama.com) and an NVIDIA GPU
(about 10 GB of VRAM is enough for Open-Jev-2B plus `qwen3.5:4b`). Below, `<repo>` is where you clone this project.

1. This project and the planner model:
   ```bash
   git clone https://github.com/yogeshvar/open-jev-mcp <repo> && cd <repo> && uv sync
   ollama pull qwen3.5:4b
   ```
2. [Open-Jev](https://github.com/Zefan-Cai/Open-Jev) with the published 2B checkpoint (the default location is `~/Projects/Open-Jev`):
   ```bash
   git clone https://github.com/Zefan-Cai/Open-Jev ~/Projects/Open-Jev && cd ~/Projects/Open-Jev
   uv venv --python 3.12 .venv && uv pip install --python .venv/bin/python -e '.[train]' huggingface_hub
   .venv/bin/hf download ZefanCai/Open-Jev-2B --revision 0c7aa498b1627be8da4acf34c863ff0ee0a92785 --local-dir models/Open-Jev-2B
   ```
3. The server command:
   ```bash
   ln -s <repo>/bin/jev-server ~/.local/bin/jev-server && jev-server start
   ```
4. **Claude Code**: register the MCP server and add the prompt hook to `~/.claude/settings.json`:
   ```bash
   claude mcp add --scope user open-jev -- uv run --quiet --project <repo> openjev-mcp
   ```
   ```json
   { "hooks": { "UserPromptSubmit": [ { "hooks": [
     { "type": "command", "command": "python3 <repo>/hooks/claude_prompt_hook.py", "timeout": 20 } ] } ] } }
   ```
5. **Hermes**: link the plugin, then enable the plugin and the MCP server in `~/.hermes/config.yaml`:
   ```bash
   ln -s <repo>/hermes_plugin/open-jev ~/.hermes/plugins/open-jev
   ```
   ```yaml
   plugins:
     enabled:
       - open-jev
   mcp_servers:
     open-jev:
       command: uv
       args: [run, --quiet, --project, <repo>, openjev-mcp]
       enabled: true
   ```

## Pieces
| Path | What it does |
| --- | --- |
| `openjev_mcp/planner.py` | Ollama writes question designs for the prompt. Test it with `python3 -m openjev_mcp.planner "your prompt"` |
| `openjev_mcp/validate.py` | Applies Open-Jev's `compile_request` rules and the candidate budget |
| `openjev_mcp/pipeline.py` | `run(prompt)` returns the context string or `None` |
| `openjev_mcp/fallback_questions.json` | General questions used when the planner fails but Jev is up |
| `openjev_mcp/server.py` | MCP tools: `jev_ask`, `jev_plan`, `jev_analyze`, `jev_health` |
| `hooks/claude_prompt_hook.py` | Claude Code `UserPromptSubmit` hook (in `~/.claude/settings.json`) |
| `hermes_plugin/open-jev/` | Hermes `pre_llm_call` plugin (symlinked to `~/.hermes/plugins/open-jev`) |

## Run the services
```bash
ollama pull qwen3.5:4b
jev-server start      # background Open-Jev server; waits until /health is ready
jev-server status     # Jev + Ollama readiness (exit 0 only when Jev is ready)
jev-server stop       # also stops a server started by hand on the same port
jev-server restart
jev-server logs [n]   # follow ~/.cache/openjev-mcp/jev-server.log
```
`bin/jev-server` is symlinked into `~/.local/bin`. Override with `JEV_HOME` (default `~/Projects/Open-Jev`),
`JEV_CHECKPOINT`, `JEV_DEVICE`, `JEV_PORT` and `JEV_START_TIMEOUT`.

## Config (env vars)
`OPENJEV_URL` (default `http://127.0.0.1:8791/v1/systemone`), `OPENJEV_LLM_URL` (`http://127.0.0.1:11434`),
`OPENJEV_LLM_MODEL` (`qwen3.5:4b`), `OPENJEV_PLAN_TIMEOUT` (10 s), `OPENJEV_JEV_TIMEOUT` (5 s),
`OPENJEV_MAX_CHARS` (6000), `OPENJEV_MAX_QUESTIONS` (5), `OPENJEV_MAX_CANDIDATES` (24),
`OPENJEV_FALLBACK` (`static` or `none`), `OPENJEV_DISABLE=1` (turns the pipeline off).

## Tests
```bash
OPENJEV_SOURCE=/path/to/Open-Jev python3 -m unittest discover -s tests -v
```

TDQS

A3.7/5.0

Scored across 4 tools

Disambiguation4/5

Most tools are clearly distinct: health checks availability, plan generates a probe, and analyze runs the full pipeline. The slight overlap is between ask and analyze, since both involve asking the Open-Jev server questions, but ask is a direct query about a state while analyze runs the complete planner-to-Jev flow.

Naming Consistency5/5

All tool names follow the same jev_<verb> pattern with clear verbs: ask, plan, analyze, and health. This makes the toolset highly predictable and easy for an agent to navigate.

Tool Count5/5

Four tools is well-scoped for this focused server. Each tool covers a meaningful operation without redundancy or unnecessary surface area.

Completeness4/5

The core workflows are covered: checking health, inspecting a generated plan, asking direct questions, and running the full analysis pipeline. A minor gap is that there is no explicit tool to run a previously generated probe exactly, though analyze effectively covers the end-to-end use case.

Maintenance

ActivityMaintained
ResponsivenessNo issues