Locale-aware number formatting via @mukundakatta/number-mcp — decimal, currency, percent, compact notation with BCP 47 locales
How to format numbers with locale-aware separators, currency symbols, percentages, and compact notation using a credential-free MCP server.
@mukundakatta/number-mcp v0.1.0 — locale-aware number formatting. 1 tool: format ({value, style?, locale?, currency?, minimumfractiondigits?, maximumfractiondigits?}). style enum: decimal (default), currency, percent, compact. locale is BCP 47 (default en-US). 32 calls, 100% success, p50=0.4ms. KEY GOTCHAS: (1) style "compact" produces abbreviated output: 1000000→"1M", 1500→"1.5K", 1234567890→"1.2B"; (2) percent multiplies by 100: 0.156→"16%" (use minimumfractiondigits:1 for "15.6%"); (3) NaN/Infinity serialize as null in JSON → formatted as "0" (no error); (4) floating point handled cleanly: 0.1+0.2→"0.3"; (5) Arabic locale (ar-SA) outputs Eastern Arabic numerals (١٬٢٣٤٫٥٦); (6) French locale uses non-breaking space as thousands separator; (7) JPY auto-rounds to whole number (correct — no subunit); (8) NO parse/unformat tool — format-only, one-way; (9) params minimumfractiondigits/maximumfractiondigits (not decimals/notation — those are silently ignored); (10) first call ~34ms JIT, subsequent 0.1-1ms. Install: npm install @mukundakatta/number-mcp. Entry: dist/server.js. Tested locales: en-US, de-DE, tr-TR, fr-FR, ja-JP, ar-SA, hi-IN. Tested currencies: USD, EUR, GBP, JPY, TRY.
{ "server": "@mukundakatta/number-mcp", "version": "0.1.0", "transport": "stdio", "tools": ["format"], "calls": 32, "success_rate": 1, "p50_ms": 0.4, "traces": [ { "tool": "format", "args": { "value": 1234567.89 }, "result": { "formatted": "1,234,567.89" }, "ms": 34 }, { "tool": "format", "args": { "value": 1234567.89, "locale": "de-DE" }, "result": { "formatted": "1.234.567,89" }, "ms": 0.8 }, { "tool": "format", "args": { "value": 1234567.89, "locale": "tr-TR" }, "result": { "formatted": "1.234.567,89" }, "ms": 0.8 }, { "tool": "format", "args": { "value": 0.156, "style": "percent" }, "result": { "formatted": "16%" }, "ms": 0.6, "note": "no fraction digits by default" }, { "tool": "format", "args": { "value": 0.156, "style": "percent", "minimum_fraction_digits": 1 }, "result": { "formatted": "15.6%" }, "ms": 0.2 }, { "tool": "format", "args": { "value": 42.5, "style": "currency", "currency": "USD" }, "result": { "formatted": "$42.50" }, "ms": 0.8 }, { "tool": "format", "args": { "value": 42.5, "style": "currency", "currency": "EUR", "locale": "de-DE" }, "result": { "formatted": "42,50 €" }, "ms": 0.5 }, { "tool": "format", "args": { "value": 1000000, "style": "compact" }, "result": { "formatted": "1M" }, "ms": 1.9 }, { "tool": "format", "args": { "value": 1500, "style": "compact" }, "result": { "formatted": "1.5K" }, "ms": 0.4 }, { "tool": "format", "args": { "value": 1234567890, "style": "compact" }, "result": { "formatted": "1.2B" }, "ms": 0.5 }, { "tool": "format", "args": { "value": 1250.99, "style": "currency", "currency": "JPY", "locale": "ja-JP" }, "result": { "formatted": "¥1,251" }, "ms": 1, "note": "JPY auto-rounds — no subunit" }, { "tool": "format", "args": { "value": 1250.99, "style": "currency", "currency": "TRY", "locale": "tr-TR" }, "result": { "formatted": "₺1.250,99" }, "ms": 0.3 }, { "tool": "format", "args": { "value": 3.14159, "maximum_fraction_digits": 2 }, "result": { "formatted": "3.14" }, "ms": 12 }, { "tool": "format", "args": { "value": 42, "minimum_fraction_digits": 2 }, "result": { "formatted": "42.00" }, "ms": 0.6 }, { "tool": "format", "args": { "value": 1234.56, "locale": "ar-SA" }, "result": { "formatted": "١٬٢٣٤٫٥٦" }, "ms": 0.4, "note": "Eastern Arabic numerals" }, { "tool": "format", "args": { "value": 1234.56, "locale": "fr-FR" }, "result": { "formatted": "1 234,56" }, "ms": 0.8, "note": "non-breaking space separator" } ] }