Decisionmatrix Mcp

io.github.inity13由 GitHub 账号 inity13 发布v1.0.2更新于 Oct 24, 2026

Deterministic multi-criteria decision analysis for AI agents — score, rank & explain options.

已验证Streamable HTTP可网页运行效率与工作流数据与分析

概览

AI 生成的概览

确定性的多准则决策引擎,让助手按加权准则为选项打分、排序并给出解释。

可以做什么
  • 按加权准则为选项排序,返回胜出者、完整排名、各准则得分明细、方法与通俗解释
  • 单独提供得分矩阵时,返回完整的归一化选项×准则评分矩阵
  • 进行敏感性分析,逐个调整准则权重,报告稳健性、易变准则与翻转点
  • 对恰好两个选项做正面对比,给出分差与各准则胜负计数
  • 列出可用的评分方法(加权和、加权积、TOPSIS)并检查服务器状态
适用场景
适合助手已收集到多个备选方案、需要以一致且可复现的方式权衡取舍时,例如供应商或产品选型、优先级排序、权衡分析。也适合需要展示结果对权重设定有多敏感的场景。
运行要求
可使用托管的远程端点(Streamable HTTP),或用 Node.js 18 及以上在本地以 stdio 运行 npm 包。免费托管层无需账号或密钥;付费方案的密钥通过 X-API-Key 发送。自行部署到 Cloudflare Pages 需要 Cloudflare 账号。
安装前请注意
托管服务器免费层为每 IP 每天 15 次调用,更高配额需通过 Stripe 订阅付费,API 密钥以 X-API-Key 发送。服务器无状态,仅根据提供的输入计算,结果只相对于给定选项集与权重。自行部署计费功能需要 STRIPE_SECRET_KEY、STRIPE_WEBHOOK_SECRET 等 Stripe 密钥。

安装

在 SourceWeft 中

  1. 打开 控制台中的 Decisionmatrix Mcp,将其添加到工作区。
  2. 为需要使用其工具的对话启用该服务。

Web executable,通过 Streamable HTTP。 远程服务在工作区中配置后即可从网页运行时运行。

交给智能体安装

把这段提示词粘贴到 Claude Code、Codex、Cursor 等智能体,或 SourceWeft 对话中。智能体会读取该服务器的安装指南,先向你展示发布者、端点和登录方式,经你同意后再把它添加到你的客户端。密钥不会写进任何命令。

阅读 https://sourceweft.com/mcp/io.github.inity13%2Fdecisionmatrix-mcp/install.md,并按其中说明把这个 MCP 服务器接入我的客户端。修改任何配置之前,先告诉我它的发布者、端点和登录方式,等我确认。不要把 API 密钥写进命令或我会提交的文件;问我密钥应从哪里获取。

查看智能体所依据的安装指南

其他 MCP 客户端

把它添加到你客户端的 mcpServers 配置中。

{
  "mcpServers": {
    "decisionmatrix": {
      "type": "http",
      "url": "https://decisionmatrix-mcp.pages.dev/mcp"
    }
  }
}

README

DecisionMatrix MCP

A transparent, 100% deterministic Model Context Protocol (MCP) server that gives LLM agents a reliable multi-criteria decision analysis (MCDA) engine.

Agents are great at gathering options but unreliable at weighing them: they lose precision, apply inconsistent weights, and can't show their work. DecisionMatrix offloads the scoring to an exact, explainable engine. You provide options and weighted criteria (plus a score matrix); it returns a fully scored, ranked, and explained result — with per-criterion breakdowns, the methodology used, the weights applied, and a plain-language explanation.

Every number flows through decimal.js at 40-digit precision (never floats), so identical inputs always produce byte-identical output. The server is stateless — no database, no sessions.

🌐 Live hosted server (free, no install)

A public remote MCP server runs on Cloudflare's edge — point any Streamable-HTTP MCP client at it:

https://decisionmatrix-mcp.pages.dev/mcp
json
{ "mcpServers": { "decisionmatrix": {    "type": "http", "url": "https://decisionmatrix-mcp.pages.dev/mcp" } } }

It runs in open mode on the free tier (no key, 15 calls/day per IP). Paid plans (Starter $12/mo · 5,000/day, Pro $39/mo · 50,000/day) are live via Stripe Checkout — buy a plan, get an API key instantly, and send it as X-API-Key. Self-host for unlimited calls with no keys. Landing page + pricing: https://decisionmatrix-mcp.pages.dev.


What it does

Six tools, all returning a uniform, agent-parseable envelope:

ToolPurpose
create_decisionMain tool. Rank options against weighted criteria → winner, full ranking, per-criterion breakdowns, methodology, weights, and a plain-language explanation.
score_optionsReturn the full normalized scored matrix when scores are supplied separately.
sensitivity_analysisSweep each criterion's weight ±X% and report how robust the winner is (and where it flips).
compare_twoHead-to-head comparison of exactly two options with per-criterion win counts.
list_methodsDiscovery: available scoring methods and when to use each.
health_checkVersion, status, and capabilities.

Scoring methods

methodmodelnormalizationnotes
weighted_sum (default)Simple Additive Weighting (SAW)min-max per criterionMost transparent; additive contributions. Handles negatives.
weighted_productWeighted Product Model (WPM)ratio (x/max, min/x)Punishes any single weak criterion; requires scores > 0.
topsisCloseness to ideal solutionvector (Euclidean)0–1 closeness coefficient; robust with many criteria.

Each criterion has a direction: benefit (higher is better — quality, speed) or cost (lower is better — price, latency, risk). Weights are relative; they are normalized to sum to 1 internally.

Consistent response envelope

Every successful response contains: status, method, winner, ranking (with per-criterion breakdown), methodology, weights_used, inputs_used, notes, and a natural-language explanation.

json
{  "status": "success",  "method": "weighted_sum",  "winner": { "option": "Gamma", "score": 0.666667, "score_exact": "0.666667", "rank": 1, "tie": false, "tied_with": [] },  "ranking": [    { "rank": 1, "option": "Gamma", "score": 0.666667, "score_exact": "0.666667",      "breakdown": [        { "criterion": "Price", "direction": "cost", "weight": 0.5, "weight_raw": "3",          "raw_score": "900", "normalized_score": 1, "weighted_contribution": 0.5 }      ] }  ],  "methodology": {    "method": "weighted_sum",    "name": "Weighted Sum Model (Simple Additive Weighting)",    "normalization": "min-max per criterion (best value -> 1, worst -> 0)",    "score_range": "0 to 1 (higher is better)",    "weighting": "Criteria weights are normalized to sum to 1; only their relative sizes matter.",    "deterministic": true  },  "weights_used": [ { "criterion": "Price", "direction": "cost", "weight_input": "3", "weight_normalized": 0.5 } ],  "inputs_used": { "options": ["Alpha","Beta","Gamma"], "method": "weighted_sum", "option_count": 3, "criterion_count": 3 },  "notes": [ "Scores are normalized within this option set; they express relative standing, not an absolute grade." ],  "explanation": "Using the Weighted Sum Model, 'Gamma' ranks #1 with a score of 0.666667, ahead of 'Alpha' (0.527778) by 26.32% ..."}

Errors never cross the tool boundary as exceptions — they come back as a structured, actionable envelope:

json
{  "status": "error",  "error": {    "type": "incomplete_scores",    "message": "Missing 1 score(s) in the options x criteria matrix.",    "hint": "Provide a score for every option and criterion. Missing: Beta / Weight."  }}

Design note — exact numbers: score is a deterministically-rounded number (6 dp) for easy consumption; score_exact / raw_score are full-precision strings so no precision is lost in JSON. Rankings are computed on the exact values, with input order as a stable tie-break.


Project structure

decisionmatrix-mcp/├── worker-src/│   ├── index.mjs        # Cloudflare Pages Function (_worker.js): MCP over Streamable HTTP + billing routes│   ├── engine.mjs       # The deterministic MCDA engine: 3 methods + 6 tools + validation│   └── billing.mjs      # Stripe Checkout + KV-backed API keys, quota metering, webhook├── site/│   ├── index.html       # Static landing / pricing / docs page│   └── _worker.js        # Built bundle (esbuild output; git-ignored)├── tests/│   └── engine.test.mjs  # 21 core scoring-logic tests (node --test)├── examples/│   └── agent_example.mjs # End-to-end MCP client demo over HTTP├── package.json         # build / deploy / dev / test scripts├── wrangler.toml        # Cloudflare Pages config├── .env.example         # Optional auth/rate-limit env reference├── LICENSE              # MIT└── README.md

Separation of concerns: engine.mjs is pure and transport-agnostic (import it directly in tests or any Node/Deno/edge runtime); index.mjs only handles the MCP JSON-RPC wiring, HTTP, CORS, and the auth/metering seam.


Requirements

  • Node 18+ (for the build, tests, and local dev). Only two dev/runtime deps: decimal.js (math) and esbuild (bundler).
  • A Cloudflare account (free tier is fine) to deploy the hosted version.

Run it locally

bash
git clone <your-fork> decisionmatrix-mcp && cd decisionmatrix-mcpnpm install
# Run the test suite (no server needed)npm test
# Serve the MCP endpoint locally via Wrangler (builds + runs Pages dev)npm run dev          # -> http://127.0.0.1:8788/mcp
# Try the end-to-end client demo (hosted by default, or pass a local URL)node examples/agent_example.mjsnode examples/agent_example.mjs http://127.0.0.1:8788

Quick manual call:

bash
curl -s http://127.0.0.1:8788/mcp \  -H 'content-type: application/json' \  -H 'accept: application/json, text/event-stream' \  -d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{        "name":"list_methods","arguments":{}}}'

Install via npm (stdio, no hosting)

Run the server locally over stdio with a single command — nothing to deploy:

bash
npx -y decisionmatrix-mcp

Claude Desktop / any stdio MCP client (claude_desktop_config.json):

json
{ "mcpServers": { "decisionmatrix": { "command": "npx", "args": ["-y", "decisionmatrix-mcp"] } } }

This is the same deterministic engine as the hosted server, running on your machine.

Client configuration

Cursor — ~/.cursor/mcp.json

json
{ "mcpServers": { "decisionmatrix": {    "url": "https://decisionmatrix-mcp.pages.dev/mcp" } } }

Claude Desktop — claude_desktop_config.json

Claude Desktop launches stdio servers, so bridge to the HTTP endpoint with mcp-remote:

json
{ "mcpServers": { "decisionmatrix": {    "command": "npx", "args": ["-y", "mcp-remote", "https://decisionmatrix-mcp.pages.dev/mcp"] } } }

VS Code — .vscode/mcp.json

json
{ "servers": { "decisionmatrix": {    "type": "http", "url": "https://decisionmatrix-mcp.pages.dev/mcp" } } }

Any Streamable-HTTP MCP client

Point it at https://decisionmatrix-mcp.pages.dev/mcp (or your self-hosted URL). If you enable auth, add X-API-Key (or Authorization: Bearer <key>) in the client's headers.


Tools & parameters

create_decision(options, criteria, scores, method="weighted_sum")

  • options — array of names (["Vendor A","Vendor B"]) or objects ([{"name":"Vendor A","scores":{...}}]). Minimum 2, names unique.
  • criteria — array of { "name", "weight" (>=0), "direction": "benefit"|"cost" }. At least one weight must be > 0.
  • scores — the option×criterion matrix. Accepted shapes:
    • object map: { "Vendor A": { "Price": 100, "Quality": 8 }, ... }
    • array: [ { "option": "Vendor A", "scores": { ... } }, ... ]
    • inline on each option object.
  • method — weighted_sum (default) · weighted_product · topsis (aliases like saw, wpm, ideal also resolve).

score_options(options, criteria, scores, method)

Same inputs as create_decision; returns the full scored matrix (per-option, per-criterion normalized scores + totals) without the winner narrative.

sensitivity_analysis(options, criteria, scores, method, variation=0.2, steps=10)

Sweeps each criterion's weight from -variation to +variation (fractional, e.g. 0.2 = ±20%) in steps increments (2–100), renormalizing the others, and recomputes the winner each time. Returns a robustness_score (share of scenarios the baseline winner stays #1), the fragile_criteria, and per-criterion flip points.

compare_two(option_a, option_b, criteria, scores, method)

Head-to-head between exactly two options (pass option_a/option_b names, or a 2-element options array). Returns the winner, score margin, criteria_wins, and a per_criterion breakdown showing which option each criterion favours.

list_methods() / health_check()

Discovery + status. No parameters.


Example tool-call payloads

Choose a laptop (price & weight are cost criteria):

json
{ "name": "create_decision", "arguments": {  "options": ["Alpha", "Beta", "Gamma"],  "criteria": [    { "name": "Price",   "weight": 3, "direction": "cost" },    { "name": "Battery", "weight": 2, "direction": "benefit" },    { "name": "Weight",  "weight": 1, "direction": "cost" }  ],  "scores": {    "Alpha": { "Price": 1000, "Battery": 8,  "Weight": 1.5 },    "Beta":  { "Price": 1200, "Battery": 12, "Weight": 1.8 },    "Gamma": { "Price": 900,  "Battery": 6,  "Weight": 1.2 }  }} }

Test how robust the winner is:

json
{ "name": "sensitivity_analysis", "arguments": {  "options": ["Alpha", "Beta", "Gamma"],  "criteria": [    { "name": "Price", "weight": 3, "direction": "cost" },    { "name": "Battery", "weight": 2 }  ],  "scores": { "Alpha": {"Price":1000,"Battery":8}, "Beta": {"Price":1200,"Battery":12}, "Gamma": {"Price":900,"Battery":6} },  "variation": 0.3, "steps": 8} }

Head-to-head:

json
{ "name": "compare_two", "arguments": {  "option_a": "Alpha", "option_b": "Beta",  "criteria": [ { "name": "Price", "weight": 3, "direction": "cost" }, { "name": "Battery", "weight": 2 } ],  "scores": { "Alpha": {"Price":1000,"Battery":8}, "Beta": {"Price":1200,"Battery":12} }} }

Deploy on Cloudflare Pages

Same pattern as PrecisionCalc — one build step bundles worker-src/ into site/_worker.js (Pages "advanced mode" Function), then Wrangler deploys the site/ directory.

bash
npm installnpx wrangler login          # once
# Build + deploy in one shotnpm run deploy              # esbuild -> site/_worker.js, then wrangler pages deploy

Or wire it to Git: create a Pages project, set the build command to npm run build and the output directory to site. Every push deploys automatically. The compatibility_date and project name live in wrangler.toml.

To run fully free / private, you need no bindings, secrets, or env vars — the scoring engine is stateless and the server fails open (free tier, quota disabled).

Enabling billing (already live on the hosted server)

The hosted server uses these — replicate them for your own paid deployment:

  1. KV namespace for API keys + daily usage counters, bound as DECISIONMATRIX_KV in wrangler.toml.
  2. Stripe products/prices (subscription) — put the price IDs in [vars] (PRICE_STARTER, PRICE_PRO) and the daily limits (FREE_DAILY, STARTER_DAILY, PRO_DAILY).
  3. Stripe secrets (never in the repo):
    bash
    wrangler pages secret put STRIPE_SECRET_KEY     --project-name decisionmatrix-mcpwrangler pages secret put STRIPE_WEBHOOK_SECRET  --project-name decisionmatrix-mcp
  4. Webhook → create a Stripe webhook endpoint at https://<your-domain>/webhook for customer.subscription.updated + customer.subscription.deleted.

Routes wired up: /checkout?plan=starter|pro → Stripe Checkout, /success provisions and shows the API key (idempotent), /portal opens the Stripe billing portal, /webhook handles subscription lifecycle (revoke/restore), /metrics reports usage.


Auth & rate limiting

The hosted server enforces tiered quotas in worker-src/billing.mjs:

  • Identity — identify() reads X-API-Key / Authorization: Bearer, looks the key up in KV, and falls back to per-IP free tier.
  • Quota — consumeQuota() is a KV daily counter (resets 00:00 UTC); the single gating point in handleRpc where method === "tools/call".
  • Paywall response — over-quota / invalid / revoked keys get a structured upsell envelope with pricing + checkout URLs (agents can read and act on it).
  • Usage metering — in-memory counters at /metrics.

DecisionMatrix has no paid-only tools — every tool works on every tier; paid plans only raise the daily quota. To make a tool paid-only, add its name to PAID_ONLY_TOOLS in index.mjs. Because the engine is pure and stateless, none of this touches the scoring logic.


Design decisions & assumptions

  • Deterministic by construction. 40-digit decimal math, ROUND_HALF_UP everywhere, and stable input-order tie-breaking. No floats, no randomness, no clocks in the result.
  • Normalization is per-criterion and direction-aware. weighted_sum uses min-max (best→1, worst→0); if a criterion is identical across all options it's treated as neutral (normalized to 1) and noted. weighted_product uses ratio normalization and requires strictly positive scores (clear error otherwise). topsis uses vector normalization and ranks by closeness to the ideal/anti-ideal.
  • Weights are relative — normalized to sum to 1, so [3,2,1] and [30,20,10] give identical results.
  • Scores are relative to the option set — they measure standing within the provided alternatives, not an absolute grade. This is stated in notes.
  • Errors are data, not exceptions — every tool returns status:"error" with a machine type and an actionable hint. Validation covers duplicate names, missing cells (listing exactly which), non-numeric scores, bad weights/directions, and unknown methods.
  • Stateless & side-effect-free — trivially cacheable, horizontally scalable, and safe to run anywhere (Cloudflare, Node, Deno, Bun).

Testing

bash
npm test          # node --test tests/*.test.mjs  (21 tests, no network)

The suite pins the hand-verifiable weighted_sum arithmetic, checks determinism, weight-relativity, direction handling, ties, all three methods, compare_two, sensitivity_analysis, the multiple score-input shapes, and every error path.


Roadmap (post-MVP)

  1. More methods: AHP (pairwise weight elicitation), ELECTRE, PROMETHEE, Borda count.
  2. Group decisions: aggregate multiple stakeholders' weight/score sets.
  3. Monte-Carlo sensitivity (perturb all weights jointly) alongside one-at-a-time.
  4. Per-key usage dashboard + Redis/Durable-Object quotas for stronger consistency.
  5. Published npm package + a hosted multi-tenant tier.

License

MIT — see LICENSE.

来源:README.md,提交 4fde2b2

工具

6

create_decision

Rank named options against weighted criteria and return the winner, full ranking, per-criterion score breakdowns, methodology, the weights used, and a plain-language explanation. This is the main tool. Provide options, criteria [{name, weight, direction}], and a scores matrix. method defaults to weighted_sum (also: weighted_product, topsis). 100% deterministic.

输入参数methodscores必填options必填criteria必填

score_options

Score options against criteria when the score matrix is supplied separately. Returns the full normalized scored matrix (per-option, per-criterion) plus a ranking, without the narrative winner explanation. Use create_decision if you want a winner + explanation.

输入参数methodscores必填options必填criteria必填

sensitivity_analysis

Test how robust the winner is to changes in criteria weights. Sweeps each criterion's weight +/- 'variation' (default 0.2 = 20%) over 'steps' (default 10) increments, recomputes the ranking, and reports a robustness score, which criteria are most likely to flip the result, and the flip points.

输入参数stepsmethodscores必填options必填criteria必填variation

compare_two

Direct head-to-head comparison of exactly two options. Returns the winner, the score margin, how many criteria each option wins, and a per-criterion breakdown of who each criterion favours. Pass option_a and option_b (names) or a 2-element options array, plus criteria and scores.

输入参数methodscores必填optionscriteria必填option_aoption_b

list_methods

List the available scoring methods (weighted_sum, weighted_product, topsis) with descriptions, normalization details, score ranges, and when to use each. No parameters.

无需输入参数。

health_check

Server health, version, and capabilities. No parameters.

无需输入参数。

版本历史

1
  1. v1.0.2最新Sep 16, 2026

评分

已满足适用检查项的 100%

该评分衡量此收录条目的完整程度,依据注册中心条目、端点与公开来源计算得出。它不是对服务器本身的评价,也不表示服务器安全或当前可用:可连通性是带日期的检查结果,评分也不包含安装量或用户评价。

  • 近 30 天内可连通必需25 分
  • 已声明认证方式必需10 分
  • 已列出工具必需15 分
  • 描述必需15 分
  • 图标10 分
  • 文档15 分
  • 许可证10 分