Skip to main content
Glama

decisions-mcp

Let your AI agent scan huge codebases for a fraction of a cent — without reading them.

An MCP server that gives any coding agent — Claude Code, Claude Desktop, Cursor, VS Code, Codex, Windsurf — access to tiny decision models on OpenRouter: Jev by default, Cloudflare Clef, Mercury Decide, Liquid D1 and every other model behind the Decisions API. The agent describes what it's looking for; the model sifts through every line and points to the exact spot.

CI Node MCP License

English · Русский


Why

Your agent needs to find a bug somewhere in 80 files. Reading them costs ~270k tokens of its context. With this server it asks "where does this happen?" and gets back ~1k tokens: the file, the line range, and the code. Then it reads and fixes just that — it's already an LLM, it doesn't need another one.

Decision models don't write text. They score and pick: yes/no with a probability, one of N options, a level on a scale. That's exactly what's needed to narrow down a search — and it costs $0.02–0.05 per 1M input tokens, output free.

Related MCP server: Code Context Engine

How it works

flowchart LR
    A["Agent: 'valid tokens get<br/>401 Token has expired'"] --> B[locate_in_files]
    B --> C["Pass 1 · Jev scores<br/>every chunk of every file"]
    C --> D["Pass 2 · Jev re-scores<br/>~40-line windows in the top chunks"]
    D --> E["bearerAuth.js:31-70 · 0.97<br/>+ the code"]
    E --> A

Nothing is truncated: large files are split into overlapping chunks and all of them are scored, so a bug in the middle of a 20k-line file is still found.

Benchmarks

Measured on the compiled MCP TypeScript SDK 1.32.1 — 87 files, ~230k tokens — with ground truth that can be checked mechanically. Reproduce with npm run bench; raw results are in bench/results.

  • Bug — 6 one-line bugs planted one at a time (inverted comparisons, an off-by-one, a wrong constant), in 6 different files. The model gets only the symptom, half of them in Russian. file #1 — the buggy file ranks first; line window #1 — the top ~40-line window contains the bug.

  • Facts — 6 yes/no questions for every file (calls fetch, defines a class, throws, uses timers, uses zod, async), checked with regexes.

  • Classify — client / server / shared / examples for 71 files, with paths anonymized so the model has to read the code.

Model

Bug: file #1

Bug: file top-3

Bug: line window #1

Bug: line top-3

Facts acc

Facts F1

Classify acc

Cost

Time

inception/mercury-decide

6/6

6/6

6/6

6/6

99%

0.96

85%

$0.0313

88s

cloudflare/clef

6/6

6/6

6/6

6/6

99%

0.97

83%

$0.0889

139s

openai/gpt-6-luna-decisions

6/6

6/6

6/6

6/6

97%

0.89

79%

$0.1760

47s

perplexity/pplx-decider-v1.1-27b

6/6

6/6

5/6

6/6

99%

0.97

85%

$0.0443

65s

nace-ai/drex-v2.0

6/6

6/6

5/6

6/6

99%

0.94

72%

$0.0907

63s

liquid/d1

6/6

6/6

5/6

6/6

98%

0.93

72%

$0.0436

54s

typesafe/jev-1.13

6/6

6/6

4/6

5/6

98%

0.91

87%

$0.0775

53s

microsoft/microsoft-decision-1

6/6

6/6

4/6

5/6

99%

0.96

80%

$0.0658

57s

nace-ai/drex-v1.5

6/6

6/6

4/6

5/6

98%

0.91

76%

$0.0597

59s

cloudflare/clef-omni

6/6

6/6

3/6

5/6

99%

0.97

75%

$0.2532

49s

cloudflare/clef-flash

5/6

6/6

3/6

5/6

97%

0.92

69%

$0.0425

75s

togethercomputer/tev1-4b-experimental

4/6

4/6

3/6

4/6

99%

0.96

73%

$0.0945

61s

jaredpalmer/kev-4b

4/6

4/6

2/6

3/6

98%

0.95

73%

$0.0639

134s

scaledown/classify-1

4/6

5/6

1/6

3/6

98%

0.96

66%

$0.0916

115s

respan/span-01-lite

2/6

4/6

2/6

3/6

89%

0.75

n/a

$0.0000

57s

upstage/solar-decide

1/6

3/6

1/6

2/6

94%

0.88

69%

$0.1341

631s

upstage/solar-decide-flash

1/6

2/6

1/6

1/6

90%

0.83

66%

$0.1336

116s

Takeaways

  • Every top-10 model found the right file for all 6 bugs on the first try, out of 87 files.

  • inception/mercury-decide is the best all-rounder and the cheapest model that handles every task: perfect bug localization, 0.96 facts F1, about $0.03 for the whole benchmark. cloudflare/clef matches it on localization and ties for the best facts score. Jev 1.13 has the best classification accuracy.

  • Small 4B models and the Upstage / Respan models are noticeably weaker at localization. Respan is an LLM-judge model and only supports yes/no questions.

  • Runs vary a little: with 6 bugs, one window more or less moves line #1 by a whole step. Treat differences of ±1 as noise.

Tools

Tool

What it does

Example

locate_in_files

Finds where something is: a bug from its symptoms, the code behind a feature, where a setting lives. Returns ranked file:lines with probabilities, a per-file ranking and the code of the top hits

"valid tokens get 401 'Token has expired', expired ones pass"

classify_files

Sorts every file into your labels with a confidence score

test, config, dead-code: unused or unreachable, business-logic

decide_files

Several typed questions per file: yes_no, choice, score. only_matching returns only files where a flag is yes

uses_db (yes/no), layer (api/domain/ui), complexity (low → high)

list_models

Decision models available on OpenRouter with context size and price; pass any id as model

cloudflare/clef, inception/mercury-decide

Common parameters: paths (files and/or directories), include / exclude (globs), respect_gitignore, model, dry_run (show what would be scanned — no API calls).

Most likely locations (probability · file:lines):
1. 0.97  server/auth/middleware/bearerAuth.js:31-70
2. 0.72  examples/server/demoInMemoryOAuthProvider.js:91-130
3. 0.62  examples/server/elicitationUrlExample.js:151-190

Files ranking:
1. 0.97  server/auth/middleware/bearerAuth.js
2. 0.68  examples/server/simpleStreamableHttp.js
3. 0.66  examples/server/elicitationUrlExample.js

--- server/auth/middleware/bearerAuth.js:31-70 (0.97)
...
45|             // Check if the token is set to expire or if it is expired
46|             if (typeof authInfo.expiresAt !== 'number' || isNaN(authInfo.expiresAt)) {
47|                 throw new InvalidTokenError('Token has no expiration time');
48|             }
49|             else if (authInfo.expiresAt > Date.now() / 1000) {
50|                 throw new InvalidTokenError('Token has expired');
51|             }
...

---
files: 88 | ~source tokens: 268700 | chunks: 108 | windows: 48 | model calls: 156 | cost: $0.01175

Any decision model

Every tool takes a model argument, and DECISIONS_MODEL sets the default. The server adapts to each model automatically:

  • Context size is read from OpenRouter's catalog, and chunks are sized to fit — from 8k-token models like jaredpalmer/kev-4b to 1M-token ones.

  • Request quirks are learned from the first rejection and remembered: models that want state as a string (ScaleDown, Respan) or accept only yes/no questions with plain-string criteria (Respan) just work.

  • Fallbacks: list backups in DECISIONS_FALLBACK_MODELS, and they take over if the primary model fails.

Install

You need Node.js 18+ and a regular OpenRouter API key — openrouter.ai/keys (a management/provisioning key won't work).

git clone https://github.com/GorOhanyan/decisions-mcp.git
cd decisions-mcp && npm install

Every config below runs node /ABS/PATH/decisions-mcp/src/index.js. Desktop apps often don't see your shell PATH, so use the absolute path to node (which node) if node alone doesn't start.

Or skip the clone and let npx fetch it from GitHub: use "command": "npx", "args": ["-y", "github:GorOhanyan/decisions-mcp"].

claude mcp add decisions --scope user -e OPENROUTER_API_KEY=sk-or-... -- node /ABS/PATH/decisions-mcp/src/index.js

macOS: ~/Library/Application Support/Claude/claude_desktop_config.json · Windows: %APPDATA%\Claude\claude_desktop_config.json

{
  "mcpServers": {
    "decisions": {
      "command": "node",
      "args": ["/ABS/PATH/decisions-mcp/src/index.js"],
      "env": { "OPENROUTER_API_KEY": "sk-or-..." }
    }
  }
}
{
  "mcpServers": {
    "decisions": {
      "command": "node",
      "args": ["/ABS/PATH/decisions-mcp/src/index.js"],
      "env": { "OPENROUTER_API_KEY": "sk-or-..." }
    }
  }
}

Same format for Windsurf (~/.codeium/windsurf/mcp_config.json).

{
  "inputs": [
    { "type": "promptString", "id": "openrouter-key", "description": "OpenRouter API key", "password": true }
  ],
  "servers": {
    "decisions": {
      "type": "stdio",
      "command": "node",
      "args": ["/ABS/PATH/decisions-mcp/src/index.js"],
      "env": { "OPENROUTER_API_KEY": "${input:openrouter-key}" }
    }
  }
}
[mcp_servers.decisions]
command = "node"
args = ["/ABS/PATH/decisions-mcp/src/index.js"]
tool_timeout_sec = 300

[mcp_servers.decisions.env]
OPENROUTER_API_KEY = "sk-or-..."

Make the agent actually use it

The server ships MCP instructions telling the agent when to call it, but a line in CLAUDE.md / AGENTS.md / .cursor/rules makes it reliable:

When you need to find something in a lot of code or text (a bug from its symptoms, where a feature
is implemented, where a setting lives) or triage many files — use the decisions MCP first
(locate_in_files / classify_files / decide_files), then read only the lines it points to.

Configuration

The old JEV_* names (from when the project was called jev-offload-mcp) are still accepted.

Variable

Default

Description

OPENROUTER_API_KEY

—

Required

DECISIONS_MODEL

typesafe/jev-1.13

Default decision model (any id from list_models)

DECISIONS_FALLBACK_MODELS

—

Comma-separated backups tried in order if the primary fails

DECISIONS_CONCURRENCY

8

Parallel requests to Jev

DECISIONS_BASE_DIR

workspace root from MCP roots, else cwd

What relative paths resolve against

DECISIONS_ALLOWED_ROOTS

—

Restrict reading to these directories (:-separated)

DECISIONS_MAX_FILE_BYTES / DECISIONS_MAX_FILES

1000000 / 2000

Limits for file collection

DECISIONS_ALLOW_SECRETS

—

1 stops excluding .env, keys etc. (not recommended)

DECISIONS_DECISIONS_URL

https://openrouter.ai/api/alpha/decisions

Decisions API endpoint

DECISIONS_MODELS_URL

OpenRouter decision-model catalog

Where context sizes and prices are read from

DECISIONS_TIMEOUT_MS

120000

Per-request timeout

What never leaves your machine

node_modules, .git, dist / build, lock files, minified bundles, binaries, everything in .gitignore, and secrets — .env*, *.pem, *.key, id_rsa*, credentials*, .npmrc, .aws/, .ssh/ and similar. Use dry_run: true to see exactly what would be sent.

Development

npm install
npm test

The test is end-to-end: a real MCP client talks to the server over stdio while the Decisions API is mocked. It covers every tool, dry runs, filters, secret / .gitignore / binary exclusion, a full scan of a large file with pinpointing to a line window, context-aware chunk sizing, per-model request adaptation, fallback models and workspace-root detection via MCP roots.

npm run bench runs the quality benchmark against the real API (needs OPENROUTER_API_KEY; about $1–2 for all models).

License

MIT © Gor Ohanyan

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    C
    maintenance
    Provides semantic code search and retrieval capabilities for AI agents, enabling them to query codebases using natural language with automatic learning, hybrid search, and intelligent chunking of functions and classes.
    7 npm
    30
    ISC
  • A
    license
    Not graded
    quality
    B
    maintenance
    Indexes codebases and lets AI agents retrieve precise code snippets (functions, classes, routes) instead of reading entire files, reducing token usage and improving accuracy.
    96 npm
    7
    MIT
  • A
    license
    Not graded
    quality
    C
    maintenance
    Adds semantic code search to AI coding agents, enabling natural language queries across entire codebases to retrieve relevant code chunks, saving tokens and providing deep context.
    7 npm
    1
    MIT