Skip to main content
Glama
README.md
# Ultimath MCP

**Stop hallucinating numbers.** An MCP server that runs every math expression
through eight independent engines in parallel — exact symbolic, ball, interval,
three different arbitrary-precision floats, deferred symbolic and IEEE 754, each
with its own failure modes — and returns all eight readings side by side, so when
they disagree you know the answer is numerically unreliable.

| Engine            | What it does                                      |
| ----------------- | ------------------------------------------------- |
| Exact symbolic    | Exact arithmetic: decides a value instead of approximating it |
| Multiprecision    | Ball arithmetic, rigorous radius carried through  |
| Interval          | Rigorous lower/upper bounds (guaranteed enclosure)|
| Binary float      | Arbitrary-precision binary floats, no GMP below   |
| PARI/GP           | Built without GMP: its own integer and transcendental kernels |
| NTL RR            | Exact integer mantissa × 2^e; only operations round |
| Deferred symbolic | Rewrites before evaluating: a cancellation never rounds |
| IEEE-754 double   | Standard hardware floating point                  |

## What each engine stands behind

Reading eight numbers is only half the answer. Each engine also says how far it
underwrites its own — and the three answers are **not degrees of one another**:

| Field | What the engine is saying |
| --- | --- |
| `"exact": true` | It holds the value. The reading is a truncation of it: every further digit you ask for is a digit **of the number**, not a closer approximation. |
| `"digits": N` | Its **own** error bound covers the first `N` significant digits. `0` is a real answer — that is what catastrophic cancellation does to a value. |
| *neither* | It carries **no error bound**. It printed as many digits as you asked for and can say nothing about any of them. |

That last row is not `0`, and it is the reason the other engines exist. Five of
the eight are there by construction.

On `exp(pi*sqrt(163)) - 262537412640768744`, one engine prints 63 digits of
which 34 are right — and says nothing about it. Two others prove 33 and stop.
One holds the value exactly. Reading the eight numbers alone would not tell you
which was which.

No engine is ever asked about another: each statement is about itself.

## The exact engine

calcium settles an equality rather than comparing digits, reaches poles the
others can only approach (`tan(pi/2)` is `uinf`), and when the printed digits
are just a truncation it also returns the closed form — `sqrt(2)+1` comes back
with `Add(Sqrt(2), 1)`, in plain form and in LaTeX, and `acosh(0.5)` with
`Div(Mul(NumberI, Pi), 3)` — the named value, not the field element it is
stored in.

The closed form is opt-in on the HTTP API (`"closed_form": true`) because
proving one costs more than reading the digits. **This client always asks for
it**: quoting an exact value is what its output schema promises.

## Tools

- **`evaluate`** — evaluate an expression on all eight engines and compare.
  Supports arithmetic, trig (`sin`, `cos`, `tan`), exp/log (`exp`, `ln`, `log`),
  roots and powers (`sqrt`, `x^y`), factorial, complex numbers (`3+2i`),
  alternate bases (`0xFF`, `0b1010`), and constants (`pi`, `e`, golden ratio `PHI`).
- **`list_functions`** — list every function the engines expose
  (name, arity, category, description). Optionally filter by category.

> Comparisons do not mean the same thing on every engine. On the enclosure
> engines, `!=`, `<` and `>` are true only once **proven**; `==`, `<=` and `>=`
> are true as soon as they are **not disproven**. A true `==` there is not a
> proof of equality — calcium decides that one exactly — but a true `!=` is a
> proof of difference.

> Multiplication must be **explicit**: write `2*pi`, `2*sin(x)`, `(a+b)*(c+d)`.
> Adjacency is not a product (`2pi` is an error). Expressions are purely
> mathematical — no type casts or constructors; write a complex number as
> `1+2i`.

## Setup

1. Get a free API key at **https://ultimath.ai**.
2. Add the server to your MCP client config (example for Claude Desktop):

```json
{
  "mcpServers": {
    "ultimath": {
      "command": "npx",
      "args": ["-y", "ultimath-mcp"],
      "env": {
        "ULTIMATH_API_KEY": "your_api_key_here"
      }
    }
  }
}
```

That's it — `npx` fetches and runs the server on demand.

## Requirements

- Node.js ≥ 18
- An Ultimath API key (`ULTIMATH_API_KEY`)

## Links

- Website: https://ultimath.ai
- Source: https://github.com/Flupke68/ultimath-mcp

## Under the hood

Ultimath's engines build on FLINT/Arb, Calcium, GMP/MPFR and MPFI — full
credits at https://ultimath.ai/credits.

## Privacy

Ultimath stores only a hash of your API key and basic usage metrics to run and
secure the service; expressions are evaluated, not retained for training. Full
policy: https://ultimath.ai/privacy/

## License

MIT

TDQS

A4.6/5.0

Scored across 2 tools

Disambiguation5/5

evaluate performs mathematical computation and returns multi-engine results, while list_functions only returns metadata about supported functions. There is no overlap or ambiguity between the two operations.

Naming Consistency4/5

Both names are imperative and clear, but evaluate is a bare verb while list_functions follows a verb_noun pattern. This is a minor stylistic inconsistency that does not create confusion.

Tool Count4/5

Two tools is below the typical 3–15 range, but the server's scope is narrow: one computational entry point plus one discovery helper. Each tool is necessary, so the count is slightly under but reasonable.

Completeness4/5

The core workflow is complete: discover functions with list_functions, then evaluate expressions with evaluate. Since this is a stateless computation service, lifecycle operations do not apply; the main minor gap is that supported constants are documented only in evaluate's description rather than being discoverable through list_functions.

Maintenance

ActivityMaintained
ResponsivenessNo issues