The short answer#
An AI agent should not do arithmetic in its head. A large language model predicts the next token; it does not carry digits. It is usually right on small sums and confidently wrong on long multiplications, percentages of percentages and anything that needs exact rounding.
MCP Toolbelt's calculate tool does the arithmetic instead. It takes one argument, a math expression as a string, and returns the number:
- Exact basic arithmetic.
+,-,*,/,%and integer powers run on exact rational numbers, so0.1 + 0.2is0.3and1/3*3is1. - Scientific functions.
sqrt,cbrt,exp,ln,log,log2,log10,sin,cos,tan, their inverses and hyperbolic forms,atan2,hypotandpow, plus the constantspi,eandtau. - Rounding you can rely on.
round,floor,ceilandtruncwork on the exact value, andround(x, 2)rounds half away from zero. - Safe by design. A small parser, not
eval: no variables, no code execution and no network calls. Bad input returns a stable error code.
Agents call it over MCP (Model Context Protocol) or a plain REST endpoint, one expression per call or many in a batch.
Why language models get math wrong#
- Models predict digits, they do not compute them.
123456789 × 987654321is121932631112635269. A model has to produce those 18 digits one token at a time, and a single slip in the middle looks just as plausible as the right answer. - Code is not automatically exact either. An agent that writes
0.1 + 0.2in Python or JavaScript gets0.30000000000000004, because binary floating point cannot store 0.1. Python'sround(2.675, 2)returns2.67for the same reason. - Rounding rules differ. Python rounds
-2.5to-2(half to even); most invoices expect-3. Python says-7 % 3is2; C, Java, JavaScript and PHP say-1. - Operator precedence trips people and models up. Is
-2^2equal to4or-4? Is3^2^2equal to81or6561? - Answers are not reproducible. Ask twice and you can get two totals. A tool returns the same number for the same expression every time.
Spinning up a code interpreter for every sum is slow, needs a sandbox and still inherits floating-point surprises. A calculator tool is one fast, deterministic call. The model decides what to calculate; the tool does the calculation.
What the calculate tool supports#
| Feature | Syntax | Exact? |
|---|---|---|
| Arithmetic | + - * / and parentheses |
Yes |
| Remainder | % (takes the sign of the dividend: -7 % 3 is -1) |
Yes |
| Powers | ^ or **, right-associative, binding tighter than unary minus: -2^2 is -4, 3^2^2 is 81 |
Yes for integer exponents |
| Numbers | 42, 3.14, .5, 1.5e3 |
Yes |
| Rounding | round(x), round(x, digits) with digits from −308 to 308, floor, ceil, trunc |
Yes |
| Other exact | abs, min(a, b, ...), max(a, b, ...), pow(x, y) (the same as x^y) |
Yes |
| Roots and logs | sqrt, cbrt, exp, ln, log(x) (base 10), log(x, base), log2, log10, hypot(x, y) |
Approximate (double precision) |
| Trigonometry | sin, cos, tan, asin, acos, atan, atan2(y, x), sinh, cosh, tanh, in radians |
Approximate (double precision) |
| Constants | pi, e, tau |
Approximate (double precision) |
Function names are case-insensitive and whitespace is ignored. An expression can be up to 1,000 characters long.
The output is {"expression": "...", "result": ...}. result is a JSON number: an integer when the exact result is a whole number that fits in a signed 64-bit integer, otherwise the nearest double. Exact intermediate values may grow to 4,096 digits.
Calculate an expression with one API call#
What is 123456789 × 987654321?
curl -s https://mcptoolbelt.com/v1/tools/calculate \
-H "Authorization: Bearer $MCP_TOOLBELT_API_KEY" \
-H "Content-Type: application/json" \
-d '{"expression": "123456789 * 987654321"}'
The result (the REST API wraps it in data.output):
{
"expression": "123456789 * 987654321",
"result": 121932631112635269
}
Every digit is right, and it is an integer, not 1.2193263111263526e17. Whole numbers up to 9,223,372,036,854,775,807 (the largest signed 64-bit integer) come back as integers. 2^63 and larger do not fit and come back as the double 9.223372036854776e+18.
Exact decimals: why 0.1 + 0.2 is 0.3 here#
{ "expression": "0.1 + 0.2" }
returns 0.3. Basic arithmetic runs on exact fractions, so 0.1 really is one tenth and the sum really is three tenths. Only the final result is converted to a JSON number. Likewise:
| Expression | calculate result |
Floating point (Python, JavaScript) |
|---|---|---|
0.1 + 0.2 |
0.3 |
0.30000000000000004 |
0.07 * 100 |
7 |
7.000000000000001 |
1.1 * 3 |
3.3 |
3.3000000000000003 |
round(2.675, 2) |
2.68 |
2.67 |
round(-2.5) |
-3 |
-2 (Python) |
This matters for money. Rounding the wrong way on one line of an invoice is a one-cent difference; on a thousand lines it is a reconciliation problem.
Everyday calculations for agents#
Prices, VAT and discounts#
Three items at €49.99 with 21% VAT:
{ "expression": "round(49.99 * 3 * 1.21, 2)" }
returns 181.46. Without round the result is 181.4637. Put the rounding in the expression, where your business rule says it belongs (per line or per total), instead of asking the model to round afterwards.
Note that % is the remainder operator, not "percent". Write 12.5% of 80 as 80 * 12.5 / 100 or 80 * 0.125 (both 10); 12.5% * 80 is rejected as invalid_expression.
Compound interest#
€1,000 at 5% a year, compounded monthly, for 10 years:
{ "expression": "round(1000 * (1 + 0.05/12)^(12*10), 2)" }
returns 1647.01. The power has an integer exponent, so it is computed exactly before rounding; the unrounded result is 1647.009497690283.
Unit-free engineering math#
hypot(3, 4) is 5, log(8, 2) is 3, (2 + 3) * sqrt(16) / 4 is 5 and atan2(1, 1) * 4 is 3.141592653589793. To convert between units such as miles and kilometres, use the separate convert_units tool rather than typing conversion factors into an expression.
Where results are approximate#
Square roots, logarithms, trigonometry and fractional powers such as 2^0.5 use IEEE 754 double precision, which is about 15 to 17 significant digits. The tool never pretends otherwise:
sin(pi)returns1.2246467991473532e-16, not0, becausepiitself is a 17-digit approximation. Round the result if you need a tidy number.- Exact arithmetic resumes after the function:
sqrt(16)is4, and everything around a function call keeps its precision. - Results that are too large for a double (
10^400) fail withoverflow, and nonzero results too small to represent (exp(-1000)) fail withunderflow, instead of silently becoming infinity or zero.
Use it from an MCP client#
Any client that supports remote MCP servers (Claude, Claude Code, Cursor, VS Code with GitHub Copilot, ChatGPT developer mode, Gemini CLI, Codex and others) can connect to MCP Toolbelt with one URL:
https://mcptoolbelt.com/mcp
Once connected, calculate shows up next to the other tools with its input and output schema, and the model calls it with the same expression argument as the REST API. Tell the agent when to use it:
Never do arithmetic yourself, not even simple sums. Call the calculate tool
with one expression and use its result. Put any rounding rule in the
expression, e.g. round(subtotal * 1.21, 2). Write percentages as
multiplication: 15% of x is x * 0.15. If it returns an error, fix the
expression instead of estimating.
Agents without an account can register themselves through /auth.md. Prices for every tool are published at /pricing.json and in the tool catalog.
Run many calculations in one batch#
Totalling every line of an order or recomputing a column of a spreadsheet? When batching is enabled for the tool, send many expressions to /v1/tools/calculate/batch:
{
"inputs": [
{ "expression": "round(49.99 * 3 * 1.21, 2)" },
{ "expression": "round(19.99 * 0.85, 2)" },
{ "expression": "round(1000 * (1 + 0.05/12)^(12*10), 2)" }
]
}
Results come back in the same order in data.output.results: 181.46, 16.99 and 1647.01. A calculation either produces a number or fails, so one failing item (a division by zero, say) fails the whole batch, the error names the item, and nothing is charged. Send an Idempotency-Key header so retries are never charged twice.
Error codes your agent can branch on#
| Code | Meaning |
|---|---|
invalid_input |
The arguments do not match the schema, such as a missing or empty expression |
invalid_expression |
A syntax error, with its position: 2 + gives "Unexpected end of expression." |
unknown_identifier |
An unknown function or constant, such as foo(2) or a variable name x |
division_by_zero |
Division or remainder by zero, including 0^-1 |
domain_error |
Undefined for these values, such as sqrt(-1) or ln(0) |
overflow |
The result is too large to represent, such as 10^400 |
underflow |
A nonzero result too small to represent, such as exp(-1000) |
calculation_limit |
Exact arithmetic would exceed 4,096 digits, such as 10^5000 |
Calls that fail with one of these errors are not charged.
Frequently asked questions#
Can ChatGPT or Claude do math on their own?#
Not reliably. Language models generate numbers as text and often get long multiplications, divisions and rounding wrong while sounding certain. Connect a calculator tool such as calculate over MCP and let the model call it for every calculation.
Why does 0.1 + 0.2 equal 0.30000000000000004 in code?#
Most programming languages store decimals as binary floating-point numbers, which cannot represent 0.1 or 0.2 exactly. The calculate tool does basic arithmetic on exact fractions, so 0.1 + 0.2 returns 0.3.
Is it safe to send user input to the calculator?#
Yes. The expression is parsed by a small dedicated grammar, never run with eval or a code interpreter. It accepts only numbers, operators, parentheses and a fixed list of functions and constants, and it limits length, nesting depth and the size of exact numbers.
Does it support variables or equations?#
No. An expression contains only numbers, constants and functions, so the agent substitutes the values itself: round(1000 * (1 + 0.05/12)^120, 2), not P * (1 + r/n)^(n*t). It does not solve equations or do symbolic algebra.
How does round work, and are angles in degrees?#
round(x, digits) rounds half away from zero on the exact value, so round(2.675, 2) is 2.68 and round(-2.5) is -3. Negative digits round to tens, hundreds and so on: round(1234567, -3) is 1235000. Trigonometric functions use radians; convert degrees with round(sin(30 * pi / 180), 12), which is 0.5 (without round it is 0.49999999999999994).
What does % mean in an expression?#
The remainder after division, with the sign of the dividend: 7 % 3 is 1 and -7 % 3 is -1. It is not a percent sign; write 15% of x as x * 0.15.
What does a calculation cost?#
Each expression is one call unit. Calls that fail because of invalid input are not charged. Current prices and any free monthly calls are listed in the tool catalog and at /pricing.json.
Sources#
- IEEE 754: the floating-point standard behind doubles and the 0.1 + 0.2 problem.
- Python documentation, Floating-Point Arithmetic: Issues and Limitations: why
round(2.675, 2)gives2.67. - What Every Computer Scientist Should Know About Floating-Point Arithmetic by David Goldberg.
- Model Context Protocol: the open standard agents use to discover and call tools.