PrecisionCalc MCP
A deterministic Model Context Protocol (MCP) server that gives LLM agents
reliable, high-precision business, finance, and operational calculations.
LLMs routinely lose precision or hallucinate on multi-step financial formulas,
currency conversions, business-day logic, and growth math. PrecisionCalc offloads
that work to exact, transparent tools. Every monetary/financial value is computed
with Python's decimal module (never floats), and every result is returned in
a consistent, agent-parseable JSON envelope that includes the exact value, a
human-readable value, the formula applied, the inputs used, the unit, and
any assumptions/warnings.
v2 highlights: live + historical FX (ECB), 14 SaaS metrics, NPV/IRR,
loan amortization, depreciation, a batch_calculate tool, per-country holidays,
API-key auth + rate limiting + usage metering on the HTTP transport, structured
JSON logging, optional OpenTelemetry tracing, and property-based tests.
🌐 Live hosted server (free, no install)
A public remote MCP server runs on Cloudflare's edge — point any Streamable-HTTP
MCP client at it:
Install via npm (stdio, no hosting)
Run the server locally over stdio with a single command — nothing to deploy:
Claude Desktop / any stdio MCP client (claude_desktop_config.json):
This is the same deterministic engine as the hosted server, running on your machine.
The edge build (worker-src/) is a Cloudflare Pages Function that mirrors the
Python engine using decimal.js — verified 17/17 exact output parity. Landing
page + docs: https://precisioncalc-mcp.pages.dev.
Plans (hosted endpoint)
Checkout is Stripe (subscription). On success you get an API key instantly; send it as
X-API-Key: <key> (or Authorization: Bearer <key>). Manage/cancel at /portal.
When a limit is hit, tools return a structured status:"error" envelope with type,
usage, and an upgrade block containing checkout URLs — so an agent can surface the
paywall to the user and act on it. Self-host (below) for unlimited calls with your own keys.
Billing internals live in worker-src/billing.mjs (Stripe REST + Cloudflare KV for keys
and daily counters). Server env: STRIPE_SECRET_KEY, STRIPE_WEBHOOK_SECRET,
PRICE_STARTER, PRICE_PRO, FREE_DAILY, STARTER_DAILY, PRO_DAILY, and a
PRECISIONCALC_KV namespace binding (see wrangler.toml).
Rebuild/redeploy the edge server:
What it does
11 tools, all returning a uniform structured response:
Consistent response envelope
Success:
Error (never raised across the tool boundary):
Project structure
Requirements
- Python 3.11+ (developed/tested on 3.12)
- Core:
mcp, python-dateutil
- Recommended:
uvicorn + starlette (HTTP transport), holidays (per-country calendars)
- Optional:
opentelemetry-sdk (tracing), pytest + hypothesis (tests)
The server auto-detects the SDK layout and works with mcp >= 2.0
(MCPServer), mcp 1.x (FastMCP), or the standalone fastmcp package.
Run it locally
Demo + tests:
Register with an MCP client (stdio)
Deploy
Docker
Fly.io
Render.com
Push to GitHub, then New + → Blueprint and point at the repo (render.yaml).
Set PRECISIONCALC_API_KEYS as a secret in the dashboard.
Configuration (env vars)
Tools & parameters
calculate_metric(metric, params, currency="USD")
Rates/margins are decimals (0.05 = 5%).
currency_convert(amount, from_currency, to_currency, date=None, live=None)
USD, EUR, GBP, JPY, CAD, AUD, CHF, CNY, INR. date (YYYY-MM-DD) or live=true
uses live/historical ECB rates (frankfurter.app), with automatic static fallback
on any network failure. Returns rate, provider, is_live, and timestamps.
business_days(operation, start_date, days=None, end_date=None, region="US", custom_holidays=None)
operation: add_business_days | count_business_days (inclusive) | next_business_day |
previous_business_day. region: US | UK | EU | NONE, or any ISO country code
when the holidays package is installed (DE, FR, CA, AU, JP, IN, ...).
compound_growth(operation, rate, years, present_value, future_value, begin_value, end_value, compounding="annually", currency="USD")
operation: future_value | present_value | cagr.
compounding: daily | weekly | monthly | quarterly | semiannually | annually | continuous.
net_present_value(rate, cashflows, currency="USD")
NPV = Σ CFₜ/(1+rate)ᵗ. cashflows[0] = period 0 (usually the negative outlay).
internal_rate_of_return(cashflows, guess=0.1)
Per-period rate where NPV = 0. Requires a sign change in the cashflows.
loan_amortization(principal, annual_rate, term_months, extra_payment=0, currency="USD", include_schedule=false)
Returns monthly payment, months-to-payoff, total interest, total paid, and (optionally)
the full month-by-month schedule.
depreciation(method, cost, salvage_value, useful_life_years, currency="USD")
method: straight_line | declining_balance | sum_of_years_digits. Returns the
full yearly schedule; book value converges to salvage_value.
batch_calculate(calls)
calls: list of {"tool": <name>, "arguments": {...}} (max 100). One item failing never
aborts the batch.
list_metrics() / health_check()
Discovery + status. No parameters.
Example MCP tool-call payloads
Design decisions & assumptions
- Decimal everywhere money/rates matter;
value is serialized as a string to
prevent float loss in JSON, with a separate pretty formatted_value. Precision = 50 sig figs.
- Rates/margins are decimals (
0.05 = 5%), documented in every tool.
- FX:
static USD-based table (as_of 2024-06-01) is the offline default; frankfurter
provider adds live + historical ECB rates with in-memory TTL cache and graceful static fallback.
- Business days: holidays computed per-year (floating US, Easter-based UK/EU);
count is
inclusive; add accepts negatives; custom holidays unioned; any ISO country via holidays lib.
- IRR uses Newton's method with a bracketed bisection fallback; requires a sign change.
- Errors never cross the tool boundary as exceptions — always
status:"error" with a machine
type + actionable hint.
- HTTP hardening is opt-in via env: API keys, token-bucket rate limiting,
/metrics usage.
- SDK compatibility shim runs on
mcp>=2.0, mcp 1.x, or standalone fastmcp unchanged.
Monetization hooks
- Auth —
PRECISIONCALC_API_KEYS; requests need X-API-Key or Authorization: Bearer.
- Rate limiting — per-key token bucket (per-IP in open mode); swap for Redis to scale.
- Usage metering — in-memory counters exposed at
/metrics; the seam for per-key billing.
- FX provider —
calculations/currency.py::RateProvider is the drop-in point for a licensed feed.
Roadmap (post-v2)
- Redis-backed rate limiting + billing-grade usage metering.
- Persisted historical FX + more providers; multi-currency carry through metrics.
- Bond pricing/yield, WACC, options (Black-Scholes), tax/VAT, unit conversions.
- Prometheus exporter + Grafana dashboard alongside OTel traces.
- Published PyPI package + Docker image on GHCR; hosted multi-tenant SaaS.