Build on Sortia

@sortia/engine 0.1.0sortia-mcp 0.1.0spec v1

Sortia gives spreadsheet decisions their odds inside Google Sheets: estimates in, odds out, plus optimization, decision trees, forecasting, statistics and machine learning. The engine behind the odds, the optimizer and the statistics also runs headless in plain Node, driven by a small JSON document, so your scripts and your AI agents can use it too.

Where to get it: the packages on this page are not on npm yet. Today the source lives in the Sortia repository. Want early access? Email hello@sortia.io.

The engine: @sortia/engine

@sortia/engine (version 0.1.0) is a plain Node library with zero runtime dependencies. It needs Node 18 or newer. It is not a rewrite of the add-on: the package loads the exact engine source files the Sheets add-on ships and wraps them with a thin spec layer. The numbers you get in Node are the numbers the add-on produces, by construction, and the whole thing is covered by the same automated test suite.

The public API is small:

The model spec

One versioned JSON document describes a model. specVersion is always 1 today, and kind selects the tool family: simulation, optimization, riskOptimization, decisionTree, goalSeek, dataTable, statTest, fit, regression, or forecast.

Everything is referenced by declared names, never by spreadsheet cell addresses. Formulas are ordinary spreadsheet expressions over those names, the same functions you would type into a cell. Unknown fields, unknown parameters, and undeclared names are rejected with precise errors instead of being silently ignored, which makes the format friendly to code generation: a wrong spec fails loudly with a pointer to the exact field.

A worked example: startup runway

How many months of runway does a startup have when burn, growth, and starting revenue are all estimates? This is a complete, runnable spec:

{
  "specVersion": 1,
  "kind": "simulation",
  "name": "Startup runway",
  "trials": 20000,
  "seed": 42,
  "sampling": "lhs",
  "inputs": [
    { "name": "monthly_burn",   "dist": "triangular",
      "params": { "min": 70000, "mode": 90000, "max": 120000 } },
    { "name": "revenue_growth", "dist": "triangular",
      "params": { "min": 0.03, "mode": 0.12, "max": 0.20 } },
    { "name": "starting_mrr",   "dist": "pert",
      "params": { "min": 15000, "mode": 22000, "max": 30000 } }
  ],
  "correlations": [
    { "a": "monthly_burn", "b": "starting_mrr", "rho": 0.35 }
  ],
  "model": [
    { "name": "starting_cash",    "formula": "1800000" },
    { "name": "revenue_12mo",     "formula":
      "starting_mrr * ((1 + revenue_growth)^12 - 1) / revenue_growth" },
    { "name": "cash_at_month_12", "formula":
      "starting_cash - 12 * monthly_burn + revenue_12mo" },
    { "name": "runway_months",    "formula":
      "IF(monthly_burn <= starting_mrr, 60, starting_cash / (monthly_burn - starting_mrr))" }
  ],
  "outputs": ["runway_months", "cash_at_month_12"]
}

Run it:

const { run } = require('@sortia/engine');
const result = run(spec);

const runway = result.outputs[0];
runway.stats.mean;      // 25.7516 months
runway.stats.median;    // 25.4867
runway.percentiles;     // p5 20.4849, p95 32.1179, full ladder p1 to p99
runway.stats.minimum;   // 17.9854
runway.stats.maximum;   // 40.0267
runway.sensitivity;     // tornado, by |Spearman|: monthly_burn -0.961,
                        //   starting_mrr -0.097, revenue_growth -0.001

result.outputs[1].stats.mean;  // cash_at_month_12: 1216196.59

Those numbers are not illustrative. They are what version 0.1.0 returns for this spec, every time, on every machine. Each output also carries the raw per-trial values, and the result echoes a reproducibility receipt: spec version, kind, engine version, and seed.

The determinism contract

run(spec) is a pure function of the spec document. That means:

SIPmath libraries

Where a distribution leaves or enters Sortia it travels as a SIPmath 3.0 library, the open standard from probabilitymanagement.org for passing uncertain quantities between tools as one small JSON file. In the add-on, Risk Analysis, the Monte Carlo panel, Project schedule risk and Distribution Fitting save their results as a .SIPmath library, validated against the Standard's published schema; a Risk run saves every output, or the model's full input set with its correlation matrix. Risk Analysis reads a library back as inputs: Metalog 1.0 entries on an HDR generator are used, and GeneralizedMetalog and Metalog 2.0 entries, stored arrays and lookup tables are listed but skipped with a reason. A coherent run option draws each SIPmath input from the file's own seeds, so its trials are the ones any other SIPmath tool reads from the same file; an input the file correlates through a copula, or one you truncate or correlate in Sortia, shares the shape rather than the trial order. Because the file is a published standard, your own scripts can read it with nothing from Sortia installed.

MCP quickstart

sortia-mcp (version 0.1.0) wraps the engine as a local Model Context Protocol server over stdio. Everything runs in-process on your machine; the server makes no network calls. Until it reaches npm, run it from the repository:

cd sortia/packages/mcp
npm install

Then point your MCP client at it. For clients configured with JSON:

{
  "mcpServers": {
    "sortia": {
      "command": "node",
      "args": ["/absolute/path/to/sortia/packages/mcp/bin/sortia-mcp.js"]
    }
  }
}

For Claude Code:

claude mcp add sortia -- node /absolute/path/to/sortia/packages/mcp/bin/sortia-mcp.js

The server exposes one tool per engine, 21 in all as of 2026-09-26. The ones most agents reach for first:

Validation errors pass through to the agent verbatim, with stable codes, JSON Pointer paths, and hints, so a model that emits a bad spec can read the error and fix its own output.

Pointing an assistant at Sortia without the server? llms.txt is the plain-text summary of the product and this page, written for a model to read.

Questions

Building something on Sortia, or want the packages before they land on npm? Email hello@sortia.io.

Estimates in, odds out.

Home· Start here· Templates· Pricing· Teams· Tell someone· Privacy· Terms· Developers· Support· Changelog· Validation· Performance· © 2026 Sortia · Made for Google Sheets™. Google Sheets™ and Google Workspace™ are trademarks of Google LLC.