Skip to main content
Glama

Run a Monte Carlo simulation of a model

run_monte_carlo_simulation

Runs a Monte Carlo simulation of a model and returns the full range of possible outcomes, not one guessed number. A model is a set of uncertain inputs, the formulas that combine them, and the links between them. The simulation draws random values for every input many times; each draw is a trial, and one call is one run. Use this when you need to know how likely different outcomes are for a plan built on uncertain inputs: a project's total cost or budget (for example from low / most likely / high estimates per line item), a schedule or delivery date, capacity, revenue, or an investment's NPV, IRR or payback. It returns a summary: for each output node (the nodes nothing else depends on, or the ones you list in run_params.output_request.nodes) the mean, the 10th, 50th and 90th percentiles (the value that share of trials fall below), the minimum and maximum in the last time period, and the same per period; plus any metrics you asked for, such as NPV, IRR, payback or the chance of beating a target or budget; and a run_id. Pass that run_id to get_simulation_results for other nodes, periods or percentiles. A run that takes longer than about 40 seconds keeps running in the background: you get status running and a run_id, and get_simulation_results gives you progress and then the result. Cost: without an account, 1 of your 3 free runs per UTC day (models up to 1,000 trials and 20 nodes); with an account, 1 credit for a small run or 5 for a large one, currently $0.50 per credit. A model that is invalid or over the no-account limits is rejected before running and costs nothing. If it fails mid-run: anonymous, the free run is used; account, not charged.

Tool call template

Replace each placeholder with a value matching the input schema. Only required parameters are included; add optional parameters as needed.

{
  "id": 1,
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "arguments": {
      "graph": "<graph>"
    },
    "name": "run_monte_carlo_simulation"
  }
}

Input Schema

NameRequiredDescriptionDefault
seedNoOptional whole number that fixes the random draws, so repeating the call gives the same result. Exact repeats are guaranteed only for small runs, where trials × nodes × time periods is at most 100,000.
graphYesThe model. A model has four parts. root_nodes are the uncertain inputs; each one draws a value from a probability distribution in every trial. calc_nodes are formulas that combine values. edges are links that carry a value from one node to another; a formula refers to its incoming edges by id, like {e1} * {e2}. run_params sets how many trials (random samples) and time periods to simulate. A time period is whatever unit the model's author chooses, such as a month, quarter or year. run_params.time_periods is a count, while time_period arguments and output_request.time_periods are indices counted from 0: with 12 monthly periods, index 11 is month 12. Formula syntax is described on calc_nodes[].formula. Common distributions and their parameters: normal{mean,std}, log_normal{mu,sigma}, uniform{low,high}, triangle{min_val,max_val,mode_val}, beta{alpha,beta}, poisson{lambda_val}, bernoulli{p}.
detailNoHow much to return. summary (the default): the output nodes' mean, 10th/50th/90th percentiles, minimum and maximum, a compact per-period series, and your metrics. full: every node and edge in every period with histograms, cut down with a truncation note if it would be too large for the client. Prefer summary, then ask get_simulation_results for the specific numbers you need.summary

Output Schema

NameRequiredDescriptionDefault
tierYessmall or large; sets the credit price for an account.
resultNoEvery node and edge per period (only with detail full).
run_idYesId of this run. Pass it to get_simulation_results for progress, the result, or specific numbers.
statusYescompleted, or running / queued: the run continues in the background, so call get_simulation_results with run_id. A run that fails within this call returns an error instead.
billingNoWho you are and what this call cost.
summaryNoThe headline numbers (the default).
progressNoPercent done while the run is running or queued.
next_stepNoWhat to do while the run is still going.
truncationNoPresent only when the summary left data out to stay small: what was left out and how to get it.
total_trialsYesNumber of trials run.
credits_debitedNoCredits charged (0 without an account).
estimated_secondsNoRough total run time, in seconds.

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed29 schema fields changed
    • removedInput schema / properties / api_key
      Removed value: -{
      -  "anyOf": [
      -    {
      -      "type": "string"
      -    },
      -    {
      -      "type": "null"
      -    }
      -  ],
      -  "default": null,
      -  "description": "Your Neumann API key. Get one by creating an account (POST https://neumann.kromatic.com/api/v1/accounts, which returns the key once); setup docs: https://kromatic.com/mcp/neumann. Leave it out if your connection is already signed in, or to use the free no-account tier.",
      -  "title": "Api Key"
      -}
    • addedInput schema / properties / detail
      Added value: +{
      +  "default": "summary",
      +  "description": "How much to return. summary (the default): the output nodes' mean, 10th/50th/90th percentiles, minimum and maximum, a compact per-period series, and your metrics. full: every node and edge in every period with histograms, cut down with a truncation note if it would be too large for the client. Prefer summary, then ask get_simulation_results for the specific numbers you need.",
      +  "enum": [
      +    "summary",
      +    "full"
      +  ],
      +  "title": "Detail",
      +  "type": "string"
      +}
    • changedOutput schema / $defs / BillingInfo / properties / auth_source / description
      Previous value: -"How you were identified: bearer (a signed-in connection token), api_key (the api_key argument) or anonymous."New value: +"How you were identified: bearer (a credential sent in the Authorization: Bearer header) or anonymous."
    • changedOutput schema / $defs / BillingInfo / properties / auth_source / enum
      Previous value: -[
      -  "bearer",
      -  "api_key",
      -  "anonymous"
      -]New value: +[
      +  "bearer",
      +  "anonymous"
      +]
    • changedOutput schema / $defs / BillingInfo / properties / charged_to / enum
      Previous value: -[
      -  "anonymous_allowance",
      -  "credits",
      -  "none"
      -]New value: +[
      +  "anonymous_allowance",
      +  "free_daily_run",
      +  "credits",
      +  "none"
      +]
    • addedOutput schema / $defs / BillingInfo / properties / free_run_limits
      Added value: +{
      +  "anyOf": [
      +    {
      +      "$ref": "#/$defs/SignedInLimits"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ],
      +  "default": null,
      +  "description": "The free signed-in tier's bounds. Null unless the account signed in with Kromatic."
      +}
    • addedOutput schema / $defs / BillingInfo / properties / free_runs_remaining_today
      Added value: +{
      +  "anyOf": [
      +    {
      +      "type": "integer"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ],
      +  "default": null,
      +  "description": "Free signed-in runs left in the current UTC day, counting this call. Null unless the account signed in with Kromatic.",
      +  "title": "Free Runs Remaining Today"
      +}
    • addedOutput schema / $defs / BillingInfo / properties / free_runs_reset_at
      Added value: +{
      +  "anyOf": [
      +    {
      +      "type": "string"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ],
      +  "default": null,
      +  "description": "ISO-8601 instant the free signed-in runs next refill (the next UTC midnight). Null unless the account signed in with Kromatic.",
      +  "title": "Free Runs Reset At"
      +}
    • addedOutput schema / $defs / MetricSummary
      Added value: +{
      +  "description": "One requested metric across trials. For a prob metric, probability is the chance (0 to 1).",
      +  "properties": {
      +    "function": {
      +      "anyOf": [
      +        {
      +          "type": "string"
      +        },
      +        {
      +          "type": "null"
      +        }
      +      ],
      +      "default": null,
      +      "title": "Function"
      +    },
      +    "id": {
      +      "title": "Id",
      +      "type": "string"
      +    },
      +    "mean": {
      +      "title": "Mean",
      +      "type": "number"
      +    },
      +    "p10": {
      +      "title": "P10",
      +      "type": "number"
      +    },
      +    "p50": {
      +      "title": "P50",
      +      "type": "number"
      +    },
      +    "p90": {
      +      "title": "P90",
      +      "type": "number"
      +    },
      +    "probability": {
      +      "anyOf": [
      +        {
      +          "type": "number"
      +        },
      +        {
      +          "type": "null"
      +        }
      +      ],
      +      "default": null,
      +      "description": "For a prob metric: the probability (0 to 1), which is its mean.",
      +      "title": "Probability"
      +    },
      +    "target": {
      +      "anyOf": [
      +        {
      +          "type": "string"
      +        },
      +        {
      +          "type": "null"
      +        }
      +      ],
      +      "default": null,
      +      "description": "The node or metric it was computed on.",
      +      "title": "Target"
      +    }
      +  },
      +  "required": [
      +    "id",
      +    "mean",
      +    "p10",
      +    "p50",
      +    "p90"
      +  ],
      +  "title": "MetricSummary",
      +  "type": "object"
      +}
    • addedOutput schema / $defs / OutputNodeSummary
      Added value: +{
      +  "description": "One output node: mean, 10th/50th/90th percentiles, minimum and maximum in the last period, and a per-period series.",
      +  "properties": {
      +    "max": {
      +      "title": "Max",
      +      "type": "number"
      +    },
      +    "mean": {
      +      "title": "Mean",
      +      "type": "number"
      +    },
      +    "min": {
      +      "title": "Min",
      +      "type": "number"
      +    },
      +    "name": {
      +      "anyOf": [
      +        {
      +          "type": "string"
      +        },
      +        {
      +          "type": "null"
      +        }
      +      ],
      +      "default": null,
      +      "title": "Name"
      +    },
      +    "node_id": {
      +      "title": "Node Id",
      +      "type": "string"
      +    },
      +    "p10": {
      +      "title": "P10",
      +      "type": "number"
      +    },
      +    "p50": {
      +      "title": "P50",
      +      "type": "number"
      +    },
      +    "p90": {
      +      "title": "P90",
      +      "type": "number"
      +    },
      +    "period": {
      +      "description": "The period these numbers describe (the last one).",
      +      "title": "Period",
      +      "type": "integer"
      +    },
      +    "series": {
      +      "anyOf": [
      +        {
      +          "$ref": "#/$defs/OutputSeries"
      +        },
      +        {
      +          "type": "null"
      +        }
      +      ],
      +      "default": null,
      +      "description": "Mean and P10/P50/P90 per period. Absent for a one-period model."
      +    }
      +  },
      +  "required": [
      +    "node_id",
      +    "period",
      +    "mean",
      +    "p10",
      +    "p50",
      +    "p90",
      +    "min",
      +    "max"
      +  ],
      +  "title": "OutputNodeSummary",
      +  "type": "object"
      +}
    • addedOutput schema / $defs / OutputSeries
      Added value: +{
      +  "description": "An output node over time, sampled to at most 24 periods.",
      +  "properties": {
      +    "mean": {
      +      "items": {
      +        "type": "number"
      +      },
      +      "title": "Mean",
      +      "type": "array"
      +    },
      +    "p10": {
      +      "items": {
      +        "type": "number"
      +      },
      +      "title": "P10",
      +      "type": "array"
      +    },
      +    "p50": {
      +      "items": {
      +        "type": "number"
      +      },
      +      "title": "P50",
      +      "type": "array"
      +    },
      +    "p90": {
      +      "items": {
      +        "type": "number"
      +      },
      +      "title": "P90",
      +      "type": "array"
      +    },
      +    "periods": {
      +      "description": "Period indices, counted from 0.",
      +      "items": {
      +        "type": "integer"
      +      },
      +      "title": "Periods",
      +      "type": "array"
      +    }
      +  },
      +  "required": [
      +    "periods",
      +    "mean",
      +    "p10",
      +    "p50",
      +    "p90"
      +  ],
      +  "title": "OutputSeries",
      +  "type": "object"
      +}
    • addedOutput schema / $defs / RunProgress
      Added value: +{
      +  "description": "How far a queued or running run has got.",
      +  "properties": {
      +    "done": {
      +      "title": "Done",
      +      "type": "integer"
      +    },
      +    "percent": {
      +      "description": "0 to 100.",
      +      "title": "Percent",
      +      "type": "number"
      +    },
      +    "total": {
      +      "title": "Total",
      +      "type": "integer"
      +    },
      +    "unit": {
      +      "description": "trials for a simulation; runs (internal simulations) for a sensitivity sweep.",
      +      "enum": [
      +        "trials",
      +        "runs"
      +      ],
      +      "title": "Unit",
      +      "type": "string"
      +    }
      +  },
      +  "required": [
      +    "percent",
      +    "done",
      +    "total",
      +    "unit"
      +  ],
      +  "title": "RunProgress",
      +  "type": "object"
      +}
    • addedOutput schema / $defs / RunSummary
      Added value: +{
      +  "description": "Headline numbers: output nodes, requested metrics, and the ids of the other nodes you can ask get_simulation_results about.",
      +  "properties": {
      +    "metrics": {
      +      "items": {
      +        "$ref": "#/$defs/MetricSummary"
      +      },
      +      "title": "Metrics",
      +      "type": "array"
      +    },
      +    "note": {
      +      "default": "This is a summary. For other nodes, periods, percentiles, the chance of reaching a threshold, or a histogram, call get_simulation_results with this run_id and the nodes, periods, percentiles, threshold or histogram arguments.",
      +      "title": "Note",
      +      "type": "string"
      +    },
      +    "other_nodes": {
      +      "description": "Ids of the other nodes, which you can query by name.",
      +      "items": {
      +        "type": "string"
      +      },
      +      "title": "Other Nodes",
      +      "type": "array"
      +    },
      +    "other_nodes_count": {
      +      "default": 0,
      +      "description": "How many other nodes there are.",
      +      "title": "Other Nodes Count",
      +      "type": "integer"
      +    },
      +    "outputs": {
      +      "items": {
      +        "$ref": "#/$defs/OutputNodeSummary"
      +      },
      +      "title": "Outputs",
      +      "type": "array"
      +    },
      +    "time_periods": {
      +      "title": "Time Periods",
      +      "type": "integer"
      +    },
      +    "trials": {
      +      "title": "Trials",
      +      "type": "integer"
      +    }
      +  },
      +  "required": [
      +    "trials",
      +    "time_periods"
      +  ],
      +  "title": "RunSummary",
      +  "type": "object"
      +}
    • addedOutput schema / $defs / SignedInLimits
      Added value: +{
      +  "description": "The free signed-in tier's bounds (neumann#334), rendered from ``Settings``.",
      +  "properties": {
      +    "max_nodes": {
      +      "description": "Maximum nodes in a free run's graph.",
      +      "title": "Max Nodes",
      +      "type": "integer"
      +    },
      +    "max_trials": {
      +      "description": "Maximum trials in a free run.",
      +      "title": "Max Trials",
      +      "type": "integer"
      +    },
      +    "runs_per_day": {
      +      "description": "Free runs per UTC calendar day.",
      +      "title": "Runs Per Day",
      +      "type": "integer"
      +    }
      +  },
      +  "required": [
      +    "runs_per_day",
      +    "max_trials",
      +    "max_nodes"
      +  ],
      +  "title": "SignedInLimits",
      +  "type": "object"
      +}
    • addedOutput schema / $defs / TruncationInfo
      Added value: +{
      +  "description": "What the default summary left out of the result.",
      +  "properties": {
      +    "applied": {
      +      "description": "The reductions applied, in order.",
      +      "items": {
      +        "type": "string"
      +      },
      +      "title": "Applied",
      +      "type": "array"
      +    },
      +    "hint": {
      +      "description": "How to get the omitted data.",
      +      "title": "Hint",
      +      "type": "string"
      +    }
      +  },
      +  "required": [
      +    "applied",
      +    "hint"
      +  ],
      +  "title": "TruncationInfo",
      +  "type": "object"
      +}
    • changedOutput schema / description
      Previous value: -"Result of one run. The run finishes before this returns."New value: +"Result of one run: a summary when it finished within the call, or status running and a run_id when it is still going."
    • addedOutput schema / properties / estimated_seconds
      Added value: +{
      +  "anyOf": [
      +    {
      +      "type": "number"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ],
      +  "default": null,
      +  "description": "Rough total run time, in seconds.",
      +  "title": "Estimated Seconds"
      +}
    • addedOutput schema / properties / next_step
      Added value: +{
      +  "anyOf": [
      +    {
      +      "type": "string"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ],
      +  "default": null,
      +  "description": "What to do while the run is still going.",
      +  "title": "Next Step"
      +}
    • addedOutput schema / properties / progress
      Added value: +{
      +  "anyOf": [
      +    {
      +      "$ref": "#/$defs/RunProgress"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ],
      +  "default": null,
      +  "description": "Percent done while the run is running or queued."
      +}
    • removedOutput schema / properties / result / $ref
      Removed value: -"#/$defs/SimulationResult"
    • addedOutput schema / properties / result / anyOf
      Added value: +[
      +  {
      +    "$ref": "#/$defs/SimulationResult"
      +  },
      +  {
      +    "type": "null"
      +  }
      +]
    • addedOutput schema / properties / result / default
      Added value: +null
    • changedOutput schema / properties / result / description
      Previous value: -"The summarized outcomes."New value: +"Every node and edge per period (only with detail full)."
    • changedOutput schema / properties / run_id / description
      Previous value: -"Id of this run; pass it to get_simulation_results to fetch the result again later."New value: +"Id of this run. Pass it to get_simulation_results for progress, the result, or specific numbers."
    • changedOutput schema / properties / status / description
      Previous value: -"Always completed. A failed run returns an error instead of a result."New value: +"completed, or running / queued: the run continues in the background, so call get_simulation_results with run_id. A run that fails within this call returns an error instead."
    • addedOutput schema / properties / status / enum
      Added value: +[
      +  "completed",
      +  "running",
      +  "queued"
      +]
    • addedOutput schema / properties / summary
      Added value: +{
      +  "anyOf": [
      +    {
      +      "$ref": "#/$defs/RunSummary"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ],
      +  "default": null,
      +  "description": "The headline numbers (the default)."
      +}
    • addedOutput schema / properties / truncation
      Added value: +{
      +  "anyOf": [
      +    {
      +      "$ref": "#/$defs/TruncationInfo"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ],
      +  "default": null,
      +  "description": "Present only when the summary left data out to stay small: what was left out and how to get it."
      +}
    • changedOutput schema / required
      Previous value: -[
      -  "run_id",
      -  "status",
      -  "tier",
      -  "total_trials",
      -  "result"
      -]New value: +[
      +  "run_id",
      +  "status",
      +  "tier",
      +  "total_trials"
      +]
  2. Added

TDQS

A4.6/5.0
Behavior5/5

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

Goes well beyond annotations: discloses the ~40-second background-run behavior with 'status running' and run_id, the full cost model (3 free runs/day, 1 or 5 credits, $0.50/credit), that invalid/over-limit models cost nothing, and that failures charge or consume a free run depending on account type. This is exactly the mutation/charging context the annotations do not carry.

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?

Front-loads purpose then usage then return shape, which is well-ordered. The long cost paragraph earns its place, though minor redundancy ('each draw is a trial, and one call is one run') and its length keep it from a perfect score.

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

Completeness5/5

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

For a complex nested-schema tool, the description covers what is run, what is returned (percentiles, min/max, metrics, run_id), background execution, and cost/charging. With an output schema present and annotations covering safety, this is complete enough for an agent to call correctly.

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 coverage is 100%, so parameters are already well documented. The description adds value by explaining output_request.nodes selection and what the summary contains, but it does not explain seed reproducibility or the detail enum, leaving those to the schema. Baseline 3 is appropriate.

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

Purpose5/5

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

States a specific verb and resource ('Runs a Monte Carlo simulation of a model and returns the full range of possible outcomes, not one guessed number') and defines what a model is. It also distinguishes itself from get_simulation_results by name, so an agent can route correctly without opening schemas.

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

Usage Guidelines5/5

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

Provides an explicit when-to-use trigger ('know how likely different outcomes are for a plan built on uncertain inputs') with concrete examples (total cost, schedule, capacity, revenue, NPV/IRR). It also names the follow-up tool (get_simulation_results) for narrower queries, giving a clear selection rule.

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

Try in Browser

Glama MCP Gateway

Add one secure layer between your agents and this server.

Resources