Skip to main content
Glama
inity13

ScenarioSim MCP

ScenarioSim MCP

A transparent, 100% deterministic Model Context Protocol (MCP) server that gives LLM agents a reliable what-if / scenario simulation engine.

Agents are good at describing a plan but unreliable at projecting it: they drift on multi-period arithmetic, mishandle compounding, and can't show their work. ScenarioSim offloads the simulation to an exact, explainable engine. You provide assumptions (growth rates, churn, pricing, costs, starting metrics, a time horizon); it returns projected outcomes over time, key metrics, the exact assumptions used, plus sensitivity analysis and break-even solving โ€” each with 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, no clocks or randomness in the result.

This is the third product in a suite built to the same engineering standard as PrecisionCalc MCP (deterministic high-precision finance/business math) and DecisionMatrix MCP (transparent multi-criteria decision analysis): identical project structure, output philosophy, and Cloudflare Pages deployment.

๐ŸŒ 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://scenariosim-mcp.pages.dev/mcp
{ "mcpServers": { "scenariosim": {
    "type": "http", "url": "https://scenariosim-mcp.pages.dev/mcp" } } }

It runs in open mode on the free tier (no key, 20 calls/day per IP). Paid plans (Starter $12/mo ยท 5,000/day, Pro $39/mo ยท 50,000/day) are available 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://scenariosim-mcp.pages.dev.


Related MCP server: finance-calc-mcp

What it does

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

Tool

Purpose

run_scenario

Main tool. Project a pre-built template or a free-form model over time โ†’ per-period projections, headline key_results, the assumptions_used, methodology, notes, and a plain-language explanation.

sensitivity_analysis

Vary one or more inputs (one-at-a-time) and report the impact on a target metric โ€” with an elasticity estimate, the output range, and a ranking of the most influential inputs.

break_even

Solve for the input value required to make a target metric hit a target value (deterministic bisection).

compare_scenarios

Run 2โ€“3 scenarios side-by-side with deltas vs a baseline and an optional winner.

list_templates

Discovery: every template with its inputs (defaults + units) and available outputs.

health_check

Version, status, and capabilities.

Scenario templates

id

models

primary output

saas_growth

subscribers + MRR/ARR from acquisition (with its own growth) and churn

ending_mrr

pricing_change

revenue/profit impact of a price change via price elasticity

cumulative_profit_after

churn_impact

retention erosion + revenue lost vs a no-churn baseline

cumulative_revenue_lost

cost_reduction

profit + margin impact of cutting costs

cumulative_savings

hiring_plan

headcount, fully-loaded payroll, revenue capacity

cumulative_payroll

cash_runway

cash balance forward + months-to-zero runway

runway_periods

unit_economics

LTV, LTV:CAC, CAC payback, per-customer margin curve

ltv_cac_ratio

marketing_funnel

visitors โ†’ leads โ†’ customers โ†’ revenue

total_revenue

compound_growth

generic single-metric compound/linear projection

ending_value

custom

free-form: any number of independently-growing metrics

(first metric)

Every template accepts horizon (number of periods, 1โ€“1200) and period_label (day/week/month/quarter/year, which also sets annualization). Inputs you don't provide fall back to documented defaults; unknown inputs are ignored and reported in notes. Call list_templates for the full input/output catalog.

Consistent response envelope

Every successful response contains: status, scenario, period_label, horizon, key_results (+ key_results_detail with units and full-precision value_exact), projections, assumptions_used, methodology, notes, and a natural-language explanation.

{
  "status": "success",
  "scenario": "saas_growth",
  "period_label": "month",
  "horizon": 12,
  "key_results": {
    "ending_customers": 449.7, "ending_mrr": 26982.1, "ending_arr": 323785.2,
    "total_churned_customers": 82.4, "cumulative_revenue": 232104.6
  },
  "projections": [
    { "period": 0, "customers": 200, "mrr": 12000, "new_customers": 0, "churned_customers": 0 },
    { "period": 1, "customers": 234, "mrr": 14040, "new_customers": 40, "churned_customers": 6 }
  ],
  "assumptions_used": {
    "template": "saas_growth", "starting_customers": "200", "new_customers_per_period": "40",
    "acquisition_growth_rate": "0", "churn_rate": "0.03", "arpu": "60",
    "horizon": 12, "period_label": "month"
  },
  "methodology": {
    "model": "SaaS Growth",
    "primary_output": "ending_mrr",
    "precision": "decimal.js (40 significant digits)",
    "deterministic": true,
    "period_convention": "Period 0 is the starting state; periods 1..12 are projected. 12 month(s) per year."
  },
  "notes": ["Churn is applied to the prior period's base before new customers are added."],
  "explanation": "Starting from 200 customers and adding 40 per month (churn 3%), after 12 months you reach ..."
}

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

{
  "status": "error",
  "error": {
    "type": "unknown_template",
    "message": "Unknown scenario template 'saaas'.",
    "hint": "Available templates: saas_growth, pricing_change, churn_impact, cost_reduction, hiring_plan, cash_runway, unit_economics, marketing_funnel, compound_growth. Call list_templates for details ..."
  }
}

Design note โ€” exact numbers: headline numbers in key_results are deterministically rounded (6 dp) for easy consumption; key_results_detail[].value_exact and assumptions_used carry full-precision strings so no precision is lost in JSON. All internal math is exact 40-digit decimal.


Project structure

scenariosim-mcp/
โ”œโ”€โ”€ worker-src/
โ”‚   โ”œโ”€โ”€ index.mjs        # Cloudflare Pages Function (_worker.js): MCP over Streamable HTTP + billing routes
โ”‚   โ”œโ”€โ”€ engine.mjs       # The deterministic simulation engine: 9 templates + 6 tools + solver + validation
โ”‚   โ””โ”€โ”€ billing.mjs      # Stripe Checkout + KV-backed API keys, quota metering, webhook
โ”œโ”€โ”€ server.mjs           # Local stdio MCP server (same engine, no network/state)
โ”œโ”€โ”€ site/
โ”‚   โ”œโ”€โ”€ index.html       # Static landing / pricing / docs page
โ”‚   โ”œโ”€โ”€ mcp.json         # Machine-readable connection manifest
โ”‚   โ”œโ”€โ”€ llms.txt         # LLM-friendly summary
โ”‚   โ””โ”€โ”€ _worker.js       # Built bundle (esbuild output; git-ignored)
โ”œโ”€โ”€ tests/
โ”‚   โ””โ”€โ”€ engine.test.mjs  # 29 core simulation-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; server.mjs re-uses the same engine over stdio.


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

git clone <your-fork> scenariosim-mcp && cd scenariosim-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:8788

# Or run the dependency-light stdio server directly
node server.mjs

Quick 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_templates","arguments":{}}}'

Install via npm (stdio, no hosting)

Run the server locally over stdio with a single command โ€” nothing to deploy:

npx -y scenariosim-mcp

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

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

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

Client configuration

Cursor โ€” ~/.cursor/mcp.json

{ "mcpServers": { "scenariosim": {
    "url": "https://scenariosim-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": { "scenariosim": {
    "command": "npx", "args": ["-y", "mcp-remote", "https://scenariosim-mcp.pages.dev/mcp"] } } }

VS Code โ€” .vscode/mcp.json

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

Windsurf โ€” ~/.codeium/windsurf/mcp_config.json

{ "mcpServers": { "scenariosim": {
    "serverUrl": "https://scenariosim-mcp.pages.dev/mcp" } } }

Any Streamable-HTTP MCP client

Point it at https://scenariosim-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

run_scenario(template?, inputs?, metrics?, horizon?, period_label?)

  • template โ€” one of the template ids above (aliases like saas, pricing, runway, ltv, funnel also resolve). Omit it (or pass "custom") to run a free-form model.

  • inputs โ€” the assumptions object for the template, e.g. { "churn_rate": 0.03, "arpu": 60 }. Also accepted as assumptions, or spread at the top level. Missing keys use documented defaults.

  • metrics โ€” (custom mode) array of { name, start, growth_rate?, mode? } where mode is "compound" (default, xยท(1+r)โฟ) or "linear" (xยท(1+rยทn)).

  • horizon โ€” number of periods to project (1โ€“1200). Default per template (usually 12).

  • period_label โ€” day/week/month/quarter/year (default month).

sensitivity_analysis(template, variable|variables, target_metric?, variation?, steps?, values?, min?, max?, inputs?, horizon?)

Sweeps each listed input across a range (default ยฑvariation=0.2 around the baseline, steps=5) while all others stay at baseline, recomputing target_metric (defaults to the template's primary output) at each point. Returns per-variable sweep rows, an elasticity_estimate, the output_range, and a most_influential ranking. You can also give explicit values: [...] or a min/max grid instead of variation.

break_even(template, solve_for, target_metric?, target_value, bounds?, inputs?, horizon?)

Solves for the value of solve_for (an input name) that makes target_metric equal target_value, via deterministic bisection with automatic bracket expansion. Returns required_input, change_from_baseline, achieved_metric, and residual. Assumes the metric is monotonic in the solved input over the search range; if the target can't be bracketed it returns a clean no_solution error with the achievable range. Pass explicit bounds: [lo, hi] to constrain (or fix) the search.

compare_scenarios(scenarios, compare_metric?, goal?, horizon?, include_projections?)

Runs 2โ€“3 scenarios ({ name?, template, inputs }, or { name?, metrics } for custom) and aligns their key_results, differencing each against the first (baseline). Pass compare_metric + goal (max default | min) to rank and pick a winner. Set a shared horizon at the top level, or per-scenario.

list_templates() / health_check()

Discovery + status. No parameters.


Example tool-call payloads

Project 12 months of SaaS growth:

{ "name": "run_scenario", "arguments": {
  "template": "saas_growth",
  "inputs": { "starting_customers": 200, "new_customers_per_period": 40,
              "acquisition_growth_rate": 0.05, "churn_rate": 0.03, "arpu": 60 },
  "horizon": 12, "period_label": "month"
} }

Which lever moves ending MRR the most?

{ "name": "sensitivity_analysis", "arguments": {
  "template": "saas_growth",
  "inputs": { "starting_customers": 200, "new_customers_per_period": 40, "churn_rate": 0.03, "arpu": 60 },
  "variables": [ { "name": "churn_rate", "variation": 0.5 },
                 { "name": "arpu", "variation": 0.3 },
                 { "name": "new_customers_per_period", "variation": 0.5 } ],
  "target_metric": "ending_mrr", "horizon": 12
} }

What churn keeps 90% of customers after a year?

{ "name": "break_even", "arguments": {
  "template": "churn_impact",
  "inputs": { "starting_customers": 1000, "arpu": 60, "new_customers_per_period": 0 },
  "solve_for": "churn_rate", "target_metric": "retention_pct",
  "target_value": 0.9, "horizon": 12
} }

โ†’ required_input โ‰ˆ 0.008742 (about 0.87%/month).

Compare growth strategies:

{ "name": "compare_scenarios", "arguments": {
  "scenarios": [
    { "name": "Base",           "template": "saas_growth", "inputs": { "churn_rate": 0.04, "new_customers_per_period": 30 } },
    { "name": "Aggressive",     "template": "saas_growth", "inputs": { "churn_rate": 0.04, "new_customers_per_period": 60 } },
    { "name": "RetentionFocus", "template": "saas_growth", "inputs": { "churn_rate": 0.015, "new_customers_per_period": 30 } }
  ],
  "compare_metric": "ending_mrr", "goal": "max", "horizon": 12
} }

Free-form (custom) model:

{ "name": "run_scenario", "arguments": {
  "metrics": [
    { "name": "revenue", "start": 10000, "growth_rate": 0.08, "mode": "compound" },
    { "name": "headcount", "start": 12, "growth_rate": 0.05, "mode": "linear" }
  ],
  "horizon": 12
} }

Deploy on Cloudflare Pages

Same pattern as PrecisionCalc / DecisionMatrix โ€” 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 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 simulation engine is stateless and the server fails open (free tier, quota disabled).

Enabling billing (optional)

Replicate these for a paid deployment:

  1. KV namespace for API keys + daily usage counters, bound as SCENARIOSIM_KV in wrangler.toml (wrangler kv namespace create SCENARIOSIM_KV).

  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):

    wrangler pages secret put STRIPE_SECRET_KEY     --project-name scenariosim-mcp
    wrangler pages secret put STRIPE_WEBHOOK_SECRET  --project-name scenariosim-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. (To add JWT/mTLS/per-org keys, change extractKey + identify only โ€” the engine and transport are untouched.)

  • Quota โ€” consumeQuota() is a KV daily counter (resets 00:00 UTC); the single gating point in handleRpc where method === "tools/call". (Swap for a sliding-window / token-bucket in a Durable Object or Redis for per-minute limits โ€” see the NOTE (rate limiting) comment.)

  • 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.

ScenarioSim 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 simulation logic.


Design decisions & assumptions

  • Deterministic by construction. 40-digit decimal math, ROUND_HALF_UP everywhere, period-by-period iteration (not float**n), and no clocks/randomness in results.

  • Period 0 is the starting state; periods 1..horizon are projected. period_label sets the annualization factor (month โ†’ 12/yr, etc.), which is used for ARR/payroll.

  • Assumptions are echoed back in full (assumptions_used) with defaults filled in, so a caller always knows exactly what was simulated.

  • Counts stay fractional for precision (e.g. 233.6 customers); round to integers in your presentation layer if needed. This is stated in notes.

  • Elasticity/growth models are intentionally simple and transparent (constant elasticity, constant per-period rates). They're honest first-order estimates, not econometric forecasts โ€” the methodology block says so.

  • break_even uses bisection with automatic bracket expansion and a fixed iteration budget โ†’ deterministic. It assumes monotonicity of the metric in the solved input over the range; non-monotonic/ratio metrics (with poles) return a clean no_solution rather than a wrong root. sensitivity_analysis/break_even operate on named templates (not the free-form custom model) and say so if misused.

  • Errors are data, not exceptions โ€” every tool returns status:"error" with a machine type and an actionable hint. Validation covers unknown templates/inputs/metrics, non-numeric values, bad horizons/period labels, unreachable targets, and more.

  • 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  (29 tests, no network)

The suite pins hand-verifiable arithmetic (compound growth, LTV/CAC, elasticity, runway), checks determinism, the multiple assumption-input shapes, period-label annualization, custom free-form models, the sensitivity sweep + influence ranking, the break-even solver (including the unreachable-target path), scenario comparison with goal=min, and every error path.


Roadmap (post-MVP)

  1. More templates: LBO/DCF, inventory & cash-conversion cycle, ad-spend ROAS, cohort retention.

  2. Monte-Carlo mode: distributions on inputs โ†’ confidence bands on outcomes (seeded, still deterministic).

  3. Multi-variable (grid) sensitivity and tornado charts alongside one-at-a-time.

  4. Break-even on the free-form custom model and on multiple simultaneous inputs.

  5. Per-key usage dashboard + Durable-Object quotas for stronger consistency.

License

MIT โ€” see LICENSE.

Available Tools

6 tools
break_evenAInspect

Solve for the input value required to make an output metric reach a target value (bisection). Returns the required input, change from baseline, achieved metric, and residual.

ParametersJSON Schema
NameRequiredDescriptionDefault
boundsNo
inputsNoScenario assumptions {name:value}; valid keys depend on the template (see list_templates). Unknown keys are ignored. May also be passed at top level.
horizonNoPeriods to project (1..1200).
templateYesTemplate id: saas_growth, pricing_change, churn_impact, cost_reduction, hiring_plan, cash_runway, unit_economics, marketing_funnel, compound_growth. Omit or 'custom' for a free-form 'metrics' model.
solve_forYes
period_labelNomonth
target_valueYes
target_metricNo

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. It discloses the bisection method and the return values (required input, change from baseline, achieved metric, residual), which are useful behavioral traits. It does not mention potential failure modes (e.g., no solution exists) or state effects, but for a read-only solver this is adequate.

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?

A single, front-loaded sentence states the purpose, method, and return values without waste. It is well-structured and every clause adds meaningful information.

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

Completeness3/5

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

With no output schema, the description does list the key return values, which is helpful. However, with 8 parameters and no explicit parameter explanations or success/failure conditions, the description is not fully complete for an agent to invoke the tool without additional inference.

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

Parameters2/5

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

Schema description coverage is only 38% (descriptions exist for inputs, horizon, template, but not for bounds, solve_for, target_value, period_label, target_metric). The description does not compensate: it only indirectly hints at solve_for and target_value via the purpose sentence, leaving bounds, inputs, and period_label unexplained.

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?

The description uses a specific verb ('Solve for') with a clear resource ('input value') and goal ('make an output metric reach a target value'), which distinguishes it from sibling tools like sensitivity_analysis and run_scenario. The mention of 'bisection' further clarifies the numeric method. This is a clear, distinct purpose.

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?

The usage context is implied by the purpose: use this tool when you need to find the input value that achieves a target output metric. However, there is no explicit guidance on when not to use it or how it compares to alternatives like run_scenario or sensitivity_analysis.

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

compare_scenariosAInspect

Run 2-3 scenarios and compare their key_results side by side with deltas vs the first (baseline). Optionally rank on 'compare_metric' with 'goal' (max|min).

ParametersJSON Schema
NameRequiredDescriptionDefault
goalNo
horizonNo
scenariosYes
compare_metricNo
include_projectionsNo

TDQS

A3.5/5.0
Behavior3/5

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

No annotations are provided, so the description carries full burden. It discloses key behaviors: first scenario as baseline, side-by-side comparison with deltas, and optional ranking via compare_metric/goal. However, it does not mention whether the tool has side effects (e.g., executing runs) or what happens with different numbers of scenarios, leaving some behavioral ambiguity.

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?

The description is a single, front-loaded sentence that efficiently communicates the core action and options without redundant words. Every clause adds value: 'Run 2-3 scenarios', 'compare key_results side by side with deltas', 'baseline', and optional ranking.

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

Completeness2/5

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

There is no output schema and no annotations, so the description must explain both inputs and outputs. It partially explains outputs (key_results, deltas) but omits details on horizon, include_projections, and the required structure of scenarios. For a tool with 5 parameters and no additional schema context, the description is incomplete.

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

Parameters2/5

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

Schema description coverage is 0%, so the description must compensate. It adds semantic context for compare_metric and goal (ranking), and implies scenarios holds the scenario list. However, horizon and include_projections are completely unexplained, and the structure of scenario objects is not addressed. With 5 parameters and only 2 partially clarified, the description does not sufficiently compensate.

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?

Description uses specific verbs (run, compare) and clearly states the resource (scenarios) and output (key_results side by side with deltas). It distinguishes from siblings like run_scenario by explicitly addressing 2-3 scenarios and comparison, and from sensitivity_analysis by focusing on comparison rather than sensitivity.

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?

The description implies usage when comparing multiple scenarios (2-3) and mentions baseline/deltas, but it does not explicitly state when to use this tool over siblings or include exclusions. There is no alternative named, leaving the guidance at an implied level rather than explicit.

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

health_checkBInspect

Server health, version, and capabilities.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

B3.1/5.0
Behavior2/5

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

No annotations are provided, so the description carries the full burden of behavioral disclosure. It reveals the categories of information returned (health, version, capabilities) but does not state side effects (if any), response format, or whether the check is read-only. This is a sparse disclosure for a tool with no annotations.

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

Conciseness4/5

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

The description is extremely concise and front-loaded, with no filler words. It uses a compact noun phrase to convey the essential scope. However, it is somewhat under-specified, which slightly reduces the appropriateness of its sizeโ€”it could be a full sentence without losing conciseness.

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

Completeness3/5

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

Given the absence of annotations, output schema, and parameters, the description needs to sufficiently explain return values. It lists the major categories (health, version, capabilities) but does not describe the structure or detail of the response. This is adequate for a simple health-check tool but leaves gaps about what 'capabilities' includes and how results are presented.

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

Parameters4/5

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

The tool has zero parameters, so the input schema is empty. Per rubric, 0 params earns a baseline of 4. The description adds no parameter information, but none is needed since there are no parameters to define.

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 'Server health, version, and capabilities' clearly identifies the tool's scope as a resource (server) and the kinds of information it provides (health, version, capabilities). It is distinct from sibling tools like sensitivity_analysis and run_scenario, which focus on scenario modeling. However, it lacks an explicit verb like 'check' or 'retrieve', making it slightly less direct than ideal.

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

Usage Guidelines2/5

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

The description provides no guidance on when to use this tool versus alternatives. It neither states typical use cases nor mentions any exclusions or conditions. With siblings focused on different tasks, some usage context would help, but none is given.

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

list_templatesAInspect

List all pre-built scenario templates (inputs, defaults, outputs) plus the custom-scenario format and period labels.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A4/5.0
Behavior3/5

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

With no annotations, the description must disclose behavior. It states the tool 'List all pre-built scenario templates', which implies a read-only operation, and mentions the content categories. However, it does not explicitly confirm there are no side effects, nor describe what happens with an empty template list or how the output is structured. It adds some value but lacks full transparency.

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?

The description is a single, concise sentence that front-loads the main action and resource. Every phrase adds value: 'all' indicating scope, 'pre-built scenario templates' the resource, and the parenthetical specifics. No wasted words.

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-parameter, no-output-schema listing tool, the description covers the essential aspects: what is listed and what additional information is included. It does not mention output format or ordering, but given the simplicity, the description is complete enough for an agent to know what to expect.

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

Parameters4/5

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

The tool has zero parameters and the schema is empty, so schema coverage is effectively 100%. The description goes beyond the schema by explaining what the output includes ('inputs, defaults, outputs', 'custom-scenario format', 'period labels'), which is useful context. Baseline for 0 params is 4, and the description meets that.

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?

The description clearly states the action ('List') and the resource ('all pre-built scenario templates'), and differentiates from siblings by specifying that it includes 'inputs, defaults, outputs' plus the 'custom-scenario format and period labels.' This is a specific verb+resource pairing that stands apart from run_scenario or sensitivity_analysis.

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?

The description implies the tool is for discovering available templates and the custom-scenario format, but it does not explicitly state when to use this tool versus alternatives (e.g., before running a scenario) or provide exclusions. Some context is given, but no clear usage directives.

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

run_scenarioAInspect

Main simulation tool. Deterministic what-if projection from a template or a free-form 'metrics' model. Returns projections, key_results, assumptions_used, methodology, notes, and a plain-language explanation. 100% deterministic.

ParametersJSON Schema
NameRequiredDescriptionDefault
inputsNoScenario assumptions {name:value}; valid keys depend on the template (see list_templates). Unknown keys are ignored. May also be passed at top level.
horizonNoPeriods to project (1..1200).
metricsNoCustom model: [{name, start, growth_rate?, mode:'compound'|'linear'}].
templateNoTemplate id: saas_growth, pricing_change, churn_impact, cost_reduction, hiring_plan, cash_runway, unit_economics, marketing_funnel, compound_growth. Omit or 'custom' for a free-form 'metrics' model.
period_labelNomonth

TDQS

A3.9/5.0
Behavior4/5

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

With no annotations provided, the description carries the transparency burden. It discloses that the tool is '100% deterministic,' a key behavioral trait, and lists the returned components (projections, key_results, assumptions_used, methodology, notes, plain-language explanation). It doesn't explicitly state side effects, but for a simulation tool, determinism and output transparency are meaningful.

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?

The three-sentence description is front-loaded with the core purpose, includes essential behavioral and output details, and has no fluff. Every sentence earns its place, making it highly efficient.

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

Completeness3/5

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

Given the tool's complexity (5 parameters, nested objects, no output schema), the description provides a solid overview and lists return fields, which is helpful. However, it omits explicit guidance on choosing this tool versus siblings, and nuances like inputs being passable at top level or unknown-key handling are only in the schema, not the description. Adequate but with gaps.

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 high (80%), so the baseline is 3. The description adds little beyond what the schema already provides; it mentions the two modes ('template or a free-form metrics model') but doesn't clarify parameter syntax or relationships beyond the schema. Therefore, it doesn't significantly compensate for the 20% gap.

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?

Description clearly identifies run_scenario as the 'Main simulation tool' and specifies its functionality: 'Deterministic what-if projection from a template or a free-form metrics model.' This gives a specific verb (run/project), resource, and distinguishes it from siblings by positioning it as the primary simulation entry point.

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?

The description provides minimal usage guidance beyond calling it the 'Main simulation tool.' It doesn't explicitly state when to prefer this over sensitivity_analysis, break_even, compare_scenarios, or other siblings, nor does it mention exclusions. The 'main' label implies primary use, but concrete direction is missing.

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

sensitivity_analysisAInspect

Vary one or more inputs and show the impact on a target output metric (one-at-a-time). Returns per-variable sweeps, elasticity estimates, output ranges, and the most influential inputs.

ParametersJSON Schema
NameRequiredDescriptionDefault
maxNo
minNo
stepsNo
inputsNoScenario assumptions {name:value}; valid keys depend on the template (see list_templates). Unknown keys are ignored. May also be passed at top level.
valuesNo
horizonNoPeriods to project (1..1200).
templateYesTemplate id: saas_growth, pricing_change, churn_impact, cost_reduction, hiring_plan, cash_runway, unit_economics, marketing_funnel, compound_growth. Omit or 'custom' for a free-form 'metrics' model.
variableNo
variablesNo
variationNo
period_labelNomonth
target_metricNo

TDQS

A3.7/5.0
Behavior4/5

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

Since no annotations are provided, the description carries the behavioral transparency burden. It discloses the methodology ('one-at-a-time'), the nature of outputs (sweeps, elasticity, ranges, influential inputs), and indicates a read-only analysis operation through its focus on returns. However, it does not explicitly state side effects or prerequisites, which prevents a perfect score.

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?

The description is only two sentences, with the action front-loaded and the output details following concisely. Every word contributes meaning without redundancy.

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

Completeness2/5

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

The tool has 12 parameters, no annotations, no output schema, and low schema coverage. The description provides only a high-level overview and omits critical invocation details like how to specify inputs or the target metric, how variables relate to inputs, and what the response structure looks like. It is not sufficiently complete for an agent to invoke the tool reliably.

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

Parameters2/5

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

Schema description coverage is only 25%, and the description does not map its language ('inputs', 'target output metric') to specific schema properties such as inputs, variables, target_metric, or variation. The mention of 'per-variable sweeps' is the only link to parameters, leaving many parameters semantically unexplained.

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?

The description clearly states the action ('Vary one or more inputs') and the output ('impact on a target output metric'), specifying the one-at-a-time method. It distinguishes itself from siblings by detailing unique outputs like per-variable sweeps, elasticity estimates, and most influential inputs.

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?

The description implies when to use this tool (for sensitivity analysis) but does not explicitly contrast it with sibling tools like run_scenario or compare_scenarios. There is no stated alternative or exclusion, so the guidance is implicit 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. 6 tool updatesv1.0.2
    • First observedbreak_even
    • First observedcompare_scenarios
    • First observedhealth_check
    • First observedlist_templates
    • First observedrun_scenario
    • First observedsensitivity_analysis

TDQS

A3.8/5.0

Scored across 6 tools

Disambiguation5/5

Each tool has a clearly distinct purpose: run_scenario for single projections, sensitivity_analysis for one-at-a-time input variation, break_even for solving target values, compare_scenarios for side-by-side comparisons, list_templates for discovering available models, and health_check for server status. No two tools overlap in functionality, so an agent can unambiguously select the right one.

Naming Consistency4/5

All tool names use lowercase snake_case, which is consistent and predictable. Most follow a verb_noun pattern (run_scenario, compare_scenarios, list_templates), though sensitivity_analysis and health_check are noun-based. This slight deviation from a pure verb-first convention is minor and doesn't hinder readability.

Tool Count5/5

With 6 tools, the server is well-scoped for a scenario simulation domain. Each tool covers a distinct aspect (running, comparing, sensitivity, break-even, template discovery, health), and none feel redundant or missing. This is an appropriate size for the intended functionality.

Completeness4/5

The tool set covers the core simulation lifecycle: discover templates, run a scenario, compare variants, perform sensitivity analysis, and solve for break-even points. A minor gap is the lack of explicit tools for creating or modifying templates, but since run_scenario supports free-form models and list_templates documents the format, users can work around this limitation.

Maintenance

ActivitySlowing
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • F
    license
    Not graded
    quality
    D
    maintenance
    Advanced server for simulating financial models and stochastic processes, offering tools for generating simulations, calculating financial metrics, and visualizing results with interactive components.
    -
  • A
    license
    A
    quality
    D
    maintenance
    An MCP server and CLI providing business, financial, and tax calculations including math expressions, income tax estimates, loan amortization, depreciation, and more.
    10
    2
    MIT
  • A
    license
    Not graded
    quality
    B
    maintenance
    A simulation engine for retirement planning, accessible via an MCP server that allows AI agents to create financial plans, manage income, expenses, loans, taxes, and portfolios, and run Monte Carlo simulations.
    MIT
  • A
    license
    A
    quality
    A
    maintenance
    An MCP server that provides deterministic, high-precision business, finance, and operational calculations such as SaaS metrics, currency conversion, business days, and financial formulas, returning structured JSON results.
    11
    30 npm
    MIT