DecisionMatrix MCP
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@DecisionMatrix MCPRank these job candidates by salary, experience, and interview score, with weights 1, 2, 1."
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
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{ "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.
Related MCP server: Boundary MCP
What it does
Six tools, all returning a uniform, agent-parseable envelope:
Tool | Purpose |
| Main tool. Rank options against weighted criteria β winner, full ranking, per-criterion breakdowns, methodology, weights, and a plain-language explanation. |
| Return the full normalized scored matrix when scores are supplied separately. |
| Sweep each criterion's weight Β±X% and report how robust the winner is (and where it flips). |
| Head-to-head comparison of exactly two options with per-criterion win counts. |
| Discovery: available scoring methods and when to use each. |
| Version, status, and capabilities. |
Scoring methods
method | model | normalization | notes |
| Simple Additive Weighting (SAW) | min-max per criterion | Most transparent; additive contributions. Handles negatives. |
| Weighted Product Model (WPM) | ratio (x/max, min/x) | Punishes any single weak criterion; requires scores > 0. |
| Closeness to ideal solution | vector (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.
{
"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:
{
"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:
scoreis a deterministically-rounded number (6 dp) for easy consumption;score_exact/raw_scoreare 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.mdSeparation 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) andesbuild(bundler).A Cloudflare account (free tier is fine) to deploy the hosted version.
Run it locally
git clone <your-fork> decisionmatrix-mcp && cd decisionmatrix-mcp
npm 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.mjs
node examples/agent_example.mjs http://127.0.0.1:8788Quick manual call:
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":{}}}'Client configuration
Cursor β ~/.cursor/mcp.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:
{ "mcpServers": { "decisionmatrix": {
"command": "npx", "args": ["-y", "mcp-remote", "https://decisionmatrix-mcp.pages.dev/mcp"] } } }VS Code β .vscode/mcp.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 likesaw,wpm,idealalso 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):
{ "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:
{ "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:
{ "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.
npm install
npx wrangler login # once
# Build + deploy in one shot
npm run deploy # esbuild -> site/_worker.js, then wrangler pages deployOr 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:
KV namespace for API keys + daily usage counters, bound as
DECISIONMATRIX_KVinwrangler.toml.Stripe products/prices (subscription) β put the price IDs in
[vars](PRICE_STARTER,PRICE_PRO) and the daily limits (FREE_DAILY,STARTER_DAILY,PRO_DAILY).Stripe secrets (never in the repo):
wrangler pages secret put STRIPE_SECRET_KEY --project-name decisionmatrix-mcp wrangler pages secret put STRIPE_WEBHOOK_SECRET --project-name decisionmatrix-mcpWebhook β create a Stripe webhook endpoint at
https://<your-domain>/webhookforcustomer.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()readsX-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 inhandleRpcwheremethod === "tools/call".Paywall response β over-quota / invalid / revoked keys get a structured
upsellenvelope 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_UPeverywhere, and stable input-order tie-breaking. No floats, no randomness, no clocks in the result.Normalization is per-criterion and direction-aware.
weighted_sumuses 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_productuses ratio normalization and requires strictly positive scores (clear error otherwise).topsisuses 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 machinetypeand an actionablehint. 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
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)
More methods: AHP (pairwise weight elicitation), ELECTRE, PROMETHEE, Borda count.
Group decisions: aggregate multiple stakeholders' weight/score sets.
Monte-Carlo sensitivity (perturb all weights jointly) alongside one-at-a-time.
Per-key usage dashboard + Redis/Durable-Object quotas for stronger consistency.
Published npm package + a hosted multi-tenant tier.
License
MIT β see LICENSE.
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Servers
- AlicenseAqualityBmaintenanceEnables structured, iterative reasoning for complex problem-solving with features like confidence tracking, revision mechanisms, and branching support. Provides flexible validation and multiple output formats for systematic analysis and decision-making tasks.12272MIT
- AlicenseAqualityDmaintenanceA decision structure analysis engine that transforms emotional dilemmas into structured frameworks by identifying variables, constraints, and strategy paths. It helps users evaluate risk distributions and cognitive biases without offering subjective advice or definitive answers.281MIT

Cruxible Coreofficial
Alicense-qualityAmaintenanceDeterministic decision engine with DAG-based receipts. Build entity graphs, query with MCP, get auditable proof.16Apache 2.0
decisio-mcp-serverofficial
FlicenseAqualityDmaintenanceEnables AI assistants to perform structured decision-making using the Analytic Hierarchy Process (AHP), allowing users to define criteria, compare options pairwise, and calculate ranked results with consistency validation.6
Related MCP Connectors
Rebuilds the scores real systems run on you β credit, actuarial, lending β in the open, cited.
Precision math engine for AI agents. 203 exact methods. Zero hallucination.
Negotiation math engine. Pareto frontier, counteroffer generation, zero LLM tokens.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/inity13/decisionmatrix-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server