Skip to main content
Glama

jev-mcp

CI License: MIT

An MCP server that lets AI assistants make typed decisions with Jev, TypeSafe's decision model on OpenRouter.

Instead of a fixed workflow, you write rules: yes/no or multiple-choice questions in plain language. The AI passes in the context (a GitHub issue, an email, a support ticket, a social media post) and gets back a decision with a probability.

"Should this issue be split into sub-issues?"  ->  yes  (probability 0.85)
"How big is this work?"                        ->  large (confidence 0.86)
"Should we create the pull request now?"       ->  no   (probability 0.60, uncertain -> ask the user)

About this project

I built this for my own use. It does not support every Jev feature (for example the score and box question types and image input), and some design choices fit my personal workflow only.

I am sharing it so others can get ideas from it and build or customize their own MCP server for their needs. Feel free to fork it and change anything.

Related MCP server: jev-mcp

Why

  • Rules instead of a hard-coded workflow. Change behavior by editing a YAML file, not code.

  • Consistent, measurable decisions. Jev returns a probability, not a free-text opinion. You set the threshold for each rule.

  • Knows when it is unsure. Results close to the threshold are marked uncertain, so the AI asks you instead of guessing.

  • Cheap. Jev charges $0.042 per 1M input tokens, and output is free. A typical call with 5 rules costs about $0.00003.

Who is it for

  • Developers: decide whether to split an issue, run a code review, add tests or open a PR. See examples/github-issues.yaml.

  • Support teams: route tickets, detect angry customers, decide when a human must take over.

  • Anyone using an AI assistant: triage email, check a draft before publishing. No coding needed.

See examples/ for ready-to-use rule sets and what to say to the AI.

Requirements

  • Node.js 22 or newer

  • An OpenRouter API key with credits

  • An MCP client, for example Claude Code, Claude Desktop, Cursor or VS Code

Install

git clone https://github.com/achapla/jev-mcp.git
cd jev-mcp
pnpm install
pnpm build

This creates dist/index.js. Use its full path in the client config below.

Claude Code

claude mcp add jev --scope user -e OPENROUTER_API_KEY=sk-or-... -- node /full/path/to/jev-mcp/dist/index.js

If OPENROUTER_API_KEY is already set in your environment, you can leave out -e ....

Claude Desktop (no coding needed)

  1. Install Node.js (LTS version).

  2. Download this repository (green Code button → Download ZIP) and unzip it.

  3. Open a terminal in the unzipped folder and run npx pnpm install and then npx pnpm build.

  4. In Claude Desktop, open Settings → Developer → Edit Config, and add:

{
  "mcpServers": {
    "jev": {
      "command": "node",
      "args": ["C:/path/to/jev-mcp/dist/index.js"],
      "env": {
        "OPENROUTER_API_KEY": "sk-or-...",
        "JEV_RULES_FILE": "C:/path/to/my-rules.yaml"
      }
    }
  }
}
  1. Restart Claude Desktop. Then ask, for example: "Use jev to check if this email needs a reply today: ..."

JEV_RULES_FILE is optional. Without it, you can still ask one-off questions, or tell Claude which rules file to use.

Other MCP clients

Use the same command, args and env as above. The server uses the stdio transport.

Rules

Rules live in a YAML file. By default, the server looks for .jev/rules.yaml in the working directory. You can change this with JEV_RULES_FILE or the rules_file tool argument.

defaults:          # optional
  threshold: 0.5   # yes_no: decision = yes when probability >= threshold
  margin: 0.1      # yes_no: uncertain when probability is within margin of threshold
  min_confidence: 0.6  # choice: uncertain when confidence is below this

rules:
  split_issue:
    type: yes_no
    question: Should this issue be split into sub-issues?
    yes_when: Several independent parts, or too big for one pull request.
    no_when: One focused change that fits in a single pull request.
    threshold: 0.6   # optional, overrides the default

  work_size:
    type: choice
    question: How big is this work?
    options:
      small: Less than one day of work.
      medium: One to three days of work.
      large: More than three days of work.
    min_confidence: 0.7  # optional

Tips for writing good rules are in examples/README.md.

Tools

Tool

Arguments

Use it for

evaluate_rules

context, rule_ids?, custom_rules?, rules_file?

Run several rules in one call. Omit rule_ids to run all file rules. Pass rule_ids: [] to run only custom_rules.

ask_yes_no

context, question, yes_when, no_when, threshold?, margin?

One custom yes/no question

ask_choice

context, question, options, min_confidence?

One custom multiple-choice question

list_rules

rules_file?

Show the rules in the rules file

context can be plain text or a JSON object.

Example result of evaluate_rules:

{
  "decisions": {
    "split_issue": {
      "type": "yes_no",
      "question": "Should this issue be split into sub-issues?",
      "decision": "yes",
      "probability": 0.85,
      "threshold": 0.6,
      "uncertain": false
    },
    "work_size": {
      "type": "choice",
      "question": "How big is this work?",
      "decision": "large",
      "confidence": 0.86,
      "probabilities": { "small": 0, "medium": 0.09, "large": 0.91 },
      "uncertain": false
    }
  },
  "model": "typesafe/jev-1.14-20261014",
  "cost_usd": 0.000025662
}

Configuration

Env var

Required

Default

Description

OPENROUTER_API_KEY

yes

Your OpenRouter API key

JEV_MODEL

no

~typesafe/jev-latest

Jev model ID, for example typesafe/jev-1.14 to pin a version

JEV_RULES_FILE

no

.jev/rules.yaml

Default rules file

Privacy

The context you pass is sent to OpenRouter and TypeSafe to make the decision. Do not send data you are not allowed to share with them. See the OpenRouter privacy policy.

Limitations

  • Only OpenRouter is supported as the provider.

  • Jev and the OpenRouter Decisions API are in beta (/api/alpha/), so the API may change.

  • Only text context is supported. Image input and Jev's score and box question types are not exposed yet.

  • Very long context (over about 32 KB of text) runs in Jev's slower, less accurate long-context mode. Send only what the decision needs.

Contributing

See CONTRIBUTING.md.

License

MIT

This is an independent project. It is not affiliated with TypeSafe or OpenRouter.

Available Tools

4 tools
ask_choicePick one optionA

Decide one multiple-choice question for the given context, e.g. 'How big is this work?' or 'What is the tone of this comment?'. Returns the chosen option, confidence, per-option probabilities, and 'uncertain'. When 'uncertain' is true, ask the user instead of acting.

NameRequiredDescriptionDefault
contextYesEverything needed to decide, as plain text or a JSON object. Examples: a GitHub issue (title, body, labels, comments), an email, a social media post, a support ticket, a document, the current state of a task.
optionsYesOption name -> what it means. At least 2.
questionYesThe question to decide, e.g. 'How big is this work?'
min_confidenceNoMark 'uncertain' when confidence is below this

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden, and it delivers useful behavior: the return payload (chosen option, confidence, per-option probabilities, 'uncertain') and the escalation policy when uncertain. It does not disclose that this is a model-driven, potentially non-deterministic call whose confidence threshold is user-tunable.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three sentences, front-loaded with the action and its scope, then examples, then return shape, then the escalation rule. No sentence is filler and nothing is buried.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no annotations and no output schema, the description compensates well by describing the return payload and the uncertain-handling path, which are the two things an agent most needs. The remaining gap is the absence of any guidance on choosing this tool over its siblings for a given decision.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so all four parameters are already documented in the schema, including min_confidence's threshold semantics; baseline 3 applies. The description only indirectly reinforces 'context' via the example questions and adds what happens downstream of the uncertain flag rather than new per-parameter meaning.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource: 'Decide one multiple-choice question for the given context', backed by two concrete examples ('How big is this work?', 'What is the tone of this comment?'). The 'one multiple-choice question' framing also implicitly separates it from the binary ask_yes_no sibling and from the rule-evaluation siblings.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives clear operating context plus an explicit conditional rule: when the 'uncertain' flag is true, ask the user instead of acting. It does not, however, say when to prefer this tool over ask_yes_no or evaluate_rules, so no true when-not/alternative routing is provided.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

ask_yes_noAsk a yes/no questionA

Decide one yes/no question for the given context, e.g. 'Should this issue be split into sub-issues?' or 'Should I reply to this email today?'. Returns decision, probability of yes, and 'uncertain'. When 'uncertain' is true, ask the user instead of acting.

NameRequiredDescriptionDefault
marginNoMark 'uncertain' when probability is within this distance of the threshold
contextYesEverything needed to decide, as plain text or a JSON object. Examples: a GitHub issue (title, body, labels, comments), an email, a social media post, a support ticket, a document, the current state of a task.
no_whenYesWhat 'no' means
questionYesThe question to decide, e.g. 'Should this issue be split into sub-issues?'
yes_whenYesWhat 'yes' means
thresholdNoProbability at or above this is 'yes'

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden, and it does disclose the return contract (decision, probability of yes, 'uncertain') plus the escalation semantics. It does not describe determinism, latency, or whether the call has side effects, but the key behavioral trait — defer to the user on uncertainty — is explicit.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three tight sentences: purpose with examples, return values, then the escalation rule. Front-loaded and free of filler; each sentence earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

There is no output schema, so the description correctly compensates by naming the three returned fields. With threshold and margin fully documented in the schema, the only remaining gap is guidance on choosing threshold/margin values, which is minor.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so every parameter including threshold and margin is already documented in the schema with its meaning and bounds. The description adds no syntax or interpretation beyond what the schema provides, so the baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Decide one yes/no question') and immediately grounds it with two concrete examples drawn from plausible agent contexts. The yes/no framing implicitly distinguishes it from the ask_choice sibling without needing to name it.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives a clear conditional rule: 'When uncertain is true, ask the user instead of acting.' This is exactly the guidance an agent needs to avoid acting on a low-confidence decision. It stops short of naming when to prefer this tool over ask_choice or evaluate_rules.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

evaluate_rulesEvaluate rulesA

Decide several rules at once (one Jev call) for the given context. Uses rules from the rules file and/or custom rules. Each yes/no result has decision, probability and 'uncertain'; each choice result has decision, confidence and 'uncertain'. When 'uncertain' is true, ask the user instead of acting.

NameRequiredDescriptionDefault
contextYesEverything needed to decide, as plain text or a JSON object. Examples: a GitHub issue (title, body, labels, comments), an email, a social media post, a support ticket, a document, the current state of a task.
rule_idsNoWhich rules from the file to run. Omit to run all. Pass [] to run only custom_rules.
rules_fileNoPath to a rules YAML file. Default: JEV_RULES_FILE env var, then .jev/rules.yaml in the working directory.
custom_rulesNoExtra rules defined now, keyed by id. Same format as rules in the file.

TDQS

A3.8/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden and does meaningfully: it discloses the result shape for both rule types and gives an actionable behavioral rule ('When uncertain is true, ask the user instead of acting'). It does not cover error behavior or how the single Jev call handles large rule sets, but the uncertainty-handling guidance is genuine behavioral value.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three sentences, each load-bearing: scope, output shape (needed because there is no output schema), and the uncertainty-handling rule. The scope is front-loaded and nothing is repeated from the schema.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a tool with no output schema and no annotations, the description usefully explains both result variants and the uncertain flag. The nested custom_rules structure and file-resolution defaults are left entirely to the schema, which is acceptable given 100% coverage, but a note on rule precedence would round it out.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the baseline is 3. The description adds only a loose mapping of 'rules from the rules file and/or custom rules' to the rules_file/custom_rules parameters, with no format, precedence, or override semantics beyond what the schema already documents.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource ('Decide several rules at once ... for the given context') and the phrase 'several rules at once' implicitly contrasts with the single-decision siblings ask_yes_no and ask_choice. It stops short of naming those siblings explicitly, so differentiation is inferable rather than stated.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

'Decide several rules at once' implies the batch use case, and 'Uses rules from the rules file and/or custom rules' hints at the input source, but there is no explicit when-to-use versus ask_yes_no/ask_choice or list_rules, and no exclusions. Usage is left to inference.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_rulesList rulesA

Show the rules defined in the rules file, so you know which rule_ids exist.

NameRequiredDescriptionDefault
rules_fileNoPath to a rules YAML file. Default: JEV_RULES_FILE env var, then .jev/rules.yaml in the working directory.

TDQS

A3.6/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations exist, so the description carries the burden. 'Show' implies a non-destructive read, which is the key behavioral trait for this tool, and it hints at the returned content (rule_ids). But it says nothing about behavior when the file is missing, empty, or when the env-var default fails to resolve.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

One sentence, zero waste, with the action front-loaded and the motivation trailing. Nothing to trim and nothing missing for the size.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a zero-required-parameter read-only listing tool with no output schema, the description supplies the action, the target file, and the reason to call it. Return shape is only loosely hinted ('rule_ids'), which is a minor gap given no output schema exists.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% for the single rules_file parameter, including the env-var and working-directory default chain, so the baseline is 3. The description adds no format or resolution details beyond what the schema already documents.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Show the rules defined in the rules file') and adds the agent-facing purpose of discovering valid rule_ids. It does not explicitly differentiate itself from the sibling evaluate_rules, though the discover-vs-evaluate distinction is implied.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

'so you know which rule_ids exist' implies the usage context: consult this before invoking evaluate_rules. However, no alternative is named and no when-not-to-use condition is given, so the guidance is implied rather than explicit.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 4 tool updatesv0.1.0
    • First observedask_choice
    • First observedask_yes_no
    • First observedevaluate_rules
    • First observedlist_rules

TDQS

A4/5.0

Scored across 4 tools

Disambiguation4/5

evaluate_rules is clearly for batched rule evaluation, while ask_yes_no and ask_choice handle single ad-hoc questions. The overlap is minor—ask_yes_no and ask_choice are essentially specialized single-rule cases—but descriptions provide enough distinction.

Naming Consistency5/5

All tool names use snake_case with a consistent verb-first pattern: evaluate_rules, ask_yes_no, ask_choice, list_rules. The convention is predictable and readable throughout.

Tool Count5/5

Four tools is well-scoped for a rule-based decision server: one for listing rules, one for batch evaluation, and two for single-question decisions. Each tool earns its place without bloat.

Completeness4/5

The surface covers listing rules, evaluating multiple rules, and asking single yes/no or multiple-choice questions. Minor gaps exist (no rule creation/editing or open-ended question type), but core decision workflows are supported.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    A
    quality
    B
    maintenance
    Enables AI coding agents to make fast, zero-output-token decisions by evaluating context, diffs, logs, or options through the OpenRouter Decisions API using TypeSafe Jev, returning calibrated probabilities for binary, categorical, or scoring questions.
    1
    20 npm
    3
    MIT
  • A
    license
    A
    quality
    C
    maintenance
    Enables local, LLM-free probabilistic decisions (choice, classification, scoring, yes/no) with real probabilities in 100+ languages, as a drop-in replacement for jev-local tools.
    4
    MIT
  • A
    license
    Not graded
    quality
    A
    maintenance
    Enables typed decisions (yes/no, choice, score) with transparent preflight checks, honest confidence reporting, and health monitoring.
    65 npm
    Apache 2.0