arabicfmt-mcp
The arabicfmt-mcp server exposes 17 tools for Arabic-first formatting, parsing, and validation via the Model Context Protocol (MCP):
format_currency– Format a number as an Arabic currency amount with the correct symbol, grouping, and decimal precision for all 22 Arab League currencies (e.g.1234.5 SAR→"1,234.50 ر.س").spell_currency– Spell out a currency amount in full Arabic words with correct grammatical agreement / تفقيط (e.g.1234.5 SAR→"ألف ومئتان وأربعة وثلاثون ريالاً وخمسون هللة").format_hijri– Format a Gregorian date as a Hijri (Islamic) calendar date string with Arabic month names (e.g.2025-09-23→"٢٣ رمضان ١٤٤٧ هـ").to_hijri– Convert a Gregorian date to its Hijri year/month/day components as a JSON object.arabic_to_words– Convert an integer to its full Arabic cardinal word representation with optional feminine gender agreement.arabic_ordinal– Convert an integer to Arabic ordinal words with gender awareness (e.g.25→"الخامس والعشرون").format_number– Format a number with locale-aware grouping, decimal separators, and optional Eastern Arabic numerals.format_compact– Format a number in compact notation using Arabic scale words (e.g.1,200,000→"1.2 مليون").parse_number– Parse a string containing Latin or Eastern Arabic digits into a JavaScript number (e.g."١٬٢٣٤٫٥٦"→1234.56).format_duration– Format a duration in milliseconds as natural spoken Arabic words with correct grammatical agreement (e.g.7500000→"ساعتان وخمس دقائق").format_relative_time– Format a date relative to a reference date in Arabic (e.g."منذ ٣ أيام").arabic_plural– Select the correct Arabic plural form for a count from the six CLDR categories (zero, one, two, few, many, other).isolate_foreign– Wrap LTR runs (phone numbers, Latin text, URLs) inside Arabic text with Unicode bidi isolates to fix RTL rendering issues.transliterate– Transliterate Arabic text to Latin script (e.g."مُحَمَّد"→"muhammad").slugify– Convert Arabic or mixed text into a URL-safe slug (e.g."مدينة جدة"→"mdynh-jdh").validate_iban– Validate an IBAN using ISO 7064 mod-97 checksum and country-specific length rules.validate_saudi_id– Validate a Saudi national ID or Iqama number using its Luhn-style checksum.
arabicfmt
Arabic-first formatting for JavaScript & TypeScript
Currency symbols · Hijri/Islamic calendar · number-to-words · تفقيط · 6 plural forms · RTL/bidi — correct for all 22 Arab League countries, with zero dependencies and full TypeScript types.
arabicfmt is the only JavaScript library that handles the entire Arabic formatting stack in one zero-dependency package — currency symbols, number precision, Hijri/Islamic calendar dates, RTL bidirectional text, Arabic number-to-words and تفقيط — with full TypeScript types. Works in Node, the browser, Deno, Bun and React Native.
npm install arabicfmtWhat other libraries get wrong
Problem | Other libraries | arabicfmt |
Saudi riyal U+20C1 | Emits ﷼ (U+FDFC) — the Iranian rial | Correct U+20C1 with a safe text fallback |
Iraqi dinar (IQD) decimals | 0 (CLDR practical) | 3 decimals — ISO 4217 legal standard |
Hijri date output | Varies between Node, Chrome, Safari, Hermes | Frozen Umm al-Qura tables — identical on every engine |
Arabic plurals | 1–2 forms; Arabic legally needs 6 | Full CLDR 6-form system (zero/one/two/few/many/other) |
Number to Arabic words | No zero-dep solution |
|
Spell money for cheques (تفقيط) | Build it yourself, get the grammar wrong |
|
Ordinals (ترتيبية) | Missing or gender-blind |
|
Spoken durations |
|
|
RTL broken sentences | Phone numbers flip mid-sentence | Unicode isolates wrap LTR runs automatically |
Eastern Arabic digit parsing |
|
|
Arabic URL slugs | Strip to empty or mojibake |
|
IBAN / Saudi ID checks | Regex that accepts bad numbers | Real ISO 7064 mod-97 + Luhn checksums |
Related MCP server: arabic-dict-mcp
Install
npm install arabicfmt
# or
yarn add arabicfmt
# or
pnpm add arabicfmtRequirements: Node.js ≥ 18 · TypeScript ≥ 4.7 (optional) · zero runtime dependencies.
Browser / CDN — no build step
Every release is mirrored on the jsDelivr and unpkg CDNs automatically. Import the browser-ready ESM bundle straight from a URL — no install, no bundler:
<script type="module">
import { formatCurrency, formatHijri } from "https://cdn.jsdelivr.net/npm/arabicfmt/+esm";
console.log(formatCurrency(1234.5, { currency: "SAR", numerals: "arab" })); // ١٬٢٣٤٫٥٠ ر.س
console.log(formatHijri(new Date(), { numerals: "arab" })); // ٢٧ ذو الحجة ١٤٤٧ هـ
</script>Subpaths work too — e.g. https://cdn.jsdelivr.net/npm/arabicfmt/dist/currency/index.js for just the currency module. Pin a version for production, e.g. arabicfmt@0.1.
Quick start
import {
formatCurrency, // correct symbol + precision for every Arab currency
formatCompact, // 1,200,000 → "1.2M" / "١٫٢ مليون"
arabicToWords, // 1234 → "ألف ومئتان وأربعة وثلاثون"
spellCurrency, // تفقيط: 1234.5 SAR → "...ريالاً وخمسون هللةً"
arabicOrdinal, // 25 → "الخامس والعشرون"
formatDuration, // 7_500_000ms → "ساعتان وخمس دقائق"
formatFileSize, // 1536 → "1.5 كيلوبايت"
formatRelativeTime, // "منذ ٣ أيام"
formatList, // ["أحمد","علي"] → "أحمد وعلي"
parseCurrency, // "١٬٢٣٤٫٥٠ ر.س" → 1234.5
arabicPlural, // full 6-form Arabic plural selection
sortArabic, // Arabic-locale collation
slugify, // "مدينة جدة" → "mdynh-jdh" (URL slugs)
isValidIBAN, // ISO 7064 mod-97 IBAN checksum
isValidSaudiId, // Saudi national ID / Iqama check digit
isolateForeign, // fix broken RTL sentences
normalizeForSearch, // search-key normalization
detectLocale, // auto-detect from browser / Node environment
} from "arabicfmt";
import { formatHijri, toHijri } from "arabicfmt/umalqura"; // deterministic Hijri calendar
// Currency
formatCurrency(1.2, { currency: "KWD" }); // "1.200 د.ك"
formatCurrency(1234, { locale: "ar-SA", numerals: "arab" }); // "١٬٢٣٤٫٠٠ ر.س"
formatCurrency(-500, { currency: "SAR", accounting: true }); // "(500.00 ر.س)"
formatCompact(1_500_000, { locale: "ar", numerals: "arab" }); // "١٫٥ مليون"
// Number to Arabic words
arabicToWords(1234); // "ألف ومئتان وأربعة وثلاثون"
arabicToWords(1_000_000); // "مليون"
arabicToWords(5, { gender: "female" }); // "خمس"
// Spell money for invoices & cheques (التفقيط)
spellCurrency(1234.5, { currency: "SAR" });
// "ألف ومئتان وأربعة وثلاثون ريالاً وخمسون هللةً"
spellCurrency(100, { currency: "SAR", suffix: true }); // "مئة ريال فقط لا غير"
// Ordinals — gender-aware
arabicOrdinal(1); // "الأول"
arabicOrdinal(25); // "الخامس والعشرون"
arabicOrdinal(1, { gender: "female" }); // "الأولى"
// Duration & file size
formatDuration(7_500_000); // "ساعتان وخمس دقائق"
formatFileSize(1536); // "1.5 كيلوبايت"
// Lists
formatList(["أحمد", "محمد", "علي"]); // "أحمد ومحمد وعلي"
formatList(["تفاح", "موز"], { type: "disjunction" }); // "تفاح أو موز"
// Hijri dates (deterministic — same output on Node, Chrome, Safari, Hermes)
formatHijri(new Date("2025-09-23")); // "1 ربيع الآخر 1447 هـ"
formatHijri(new Date("2025-09-23"), { numerals: "arab" }); // "١ ربيع الآخر ١٤٤٧ هـ"
toHijri(new Date("2025-09-23")); // { year: 1447, month: 4, day: 1 }
// Relative time
formatRelativeTime(new Date(Date.now() - 3 * 86400_000)); // "منذ 3 أيام"
// Parse formatted strings back to numbers
parseCurrency("١٬٢٣٤٫٥٠ ر.س"); // 1234.5
parseCurrency("(500.00 SAR)"); // -500
// RTL
isolateForeign("اتصل على +1 (555) 234-5678 الآن"); // phone stays intact in RTL
// Locale auto-detection
detectLocale(); // "ar-SA" in a Saudi browser, "ar-EG" in Node with LANG=ar_EGCurrency formatting
Symbol strategy: symbolMode
The Saudi riyal received its own Unicode symbol (U+20C1) in September 2025. Most libraries either emit the wrong ligature (U+FDFC, the Iranian rial) or fall back to SAR. arabicfmt gives you full control:
import { formatCurrency, resolveCurrencySymbol, getCurrencyInfo } from "arabicfmt/currency";
formatCurrency(1234.5, { currency: "SAR" });
// → "1,234.50 ر.س" (auto: safe text symbol, renders everywhere today)
formatCurrency(1234.5, { currency: "SAR", symbolMode: "new" });
// → "1,234.50 " (U+20C1 — use with a webfont; see webfont guide below)
formatCurrency(1234.5, { currency: "SAR", symbolMode: "code" });
// → "1,234.50 SAR" (ISO code — for accounting tables)
| SAR | AED | OMR | Use when |
|
|
|
| Default. AED/OMR use the dedicated sign; SAR stays on safe text |
|
|
|
| Force the dedicated sign (needs font support) |
|
|
|
| Always the safe text symbol — renders everywhere |
|
|
|
| ISO code |
Unicode 18.0 (September 2026): the AED (U+20C3) and OMR (U+20C4) signs are now
live, andautoprefers them. Need maximum compatibility today? UsesymbolMode: "text". The Saudi riyal keeps its safe text default by design.
Correct decimal precision — all 22 Arab League countries
Generated from CLDR 48.2.0 at build time and verified on every build:
formatCurrency(1.2, { currency: "KWD" }); // "1.200 د.ك" ← 3 decimals
formatCurrency(1.2, { currency: "BHD" }); // "1.200 د.ب" ← 3 decimals
formatCurrency(1.2, { currency: "IQD" }); // "1.200 ع.د" ← 3 decimals (ISO 4217, not CLDR's 0)
formatCurrency(500, { currency: "KMF" }); // "500 ف.ج.ق" ← 0 decimals
formatCurrency(500, { currency: "SAR" }); // "500.00 ر.س" ← 2 decimalsDecimals | Currencies |
3 | KWD, BHD, OMR, JOD, IQD, LYD, TND |
0 | DJF, KMF |
2 | SAR, AED, QAR, and the rest |
All currency options
// Resolve from locale region — no need to know the currency code
formatCurrency(99.9, { locale: "ar-BH" }); // "99.900 د.ب"
formatCurrency(1234, { locale: "ar-AE", numerals: "arab", symbolMode: "text" }); // "١٬٢٣٤٫٠٠ د.إ" (auto → U+20C3 sign)
// Accounting notation (negatives in parentheses)
formatCurrency(-1234.5, { currency: "SAR", accounting: true }); // "(1,234.50 ر.س)"
// Hide/override
formatCurrency(100, { currency: "SAR", showSymbol: false, fractionDigits: 0 }); // "100"
// Currency metadata
getCurrencyInfo("SAR");
// {
// code: "SAR", digits: 2,
// symbols: { auto: "ر.س", text: "ر.س", code: "SAR", new: "" },
// unicode: { codepoint: "U+20C1", unicodeVersion: "17.0", live: true, autoDefault: false },
// displayName: "ريال سعودي"
// }Webfont guide for U+20C1
/* Scope the Saudi Riyal font to just that codepoint — zero impact on body text */
@font-face {
font-family: "Riyal";
src: url("/fonts/saudi-riyal.woff2") format("woff2");
unicode-range: U+20C1;
}
:root { font-family: "Riyal", "Noto Naskh Arabic", sans-serif; }Number formatting
import {
formatNumber, formatCompact, formatPercent,
toArabicDigits, toLatinDigits,
parseNumber, parseCurrency,
arabicToWords,
formatRelativeTime,
} from "arabicfmt/number";
// Standard
formatNumber(1_234_567.89, { locale: "en" }); // "1,234,567.89"
formatNumber(1234.5, { numerals: "arab" }); // "١٬٢٣٤٫٥"
// Compact / short notation — dashboards and data cards
formatCompact(1_500_000); // "1.5M"
formatCompact(1_500_000, { locale: "ar" }); // "1.5 مليون"
formatCompact(1_500_000, { locale: "ar", numerals: "arab" }); // "١٫٥ مليون"
// Percent
formatPercent(0.853, { locale: "en" }); // "85.3%"
// Transliteration
toArabicDigits("Order #2026"); // "Order #٢٠٢٦"
toLatinDigits("٢٠٢٦"); // "2026" (handles Persian ۰–۹ too)
// Parsing — round-trip support
parseNumber("١٬٢٣٤٫٥٦"); // 1234.56 (Eastern Arabic digits + separators)
parseNumber("1,234.56"); // 1234.56 (Western)
parseCurrency("١٬٢٣٤٫٥٠ ر.س"); // 1234.5
parseCurrency("(500.00 SAR)"); // -500 (accounting notation)
// Relative time
formatRelativeTime(new Date(Date.now() - 3 * 86400_000)); // "منذ 3 أيام"
formatRelativeTime(new Date(Date.now() + 3600_000), new Date(), { locale: "en" }); // "in 1 hour"Number to Arabic words (arabicToWords)
Convert integers to their Arabic word representation — handles gender agreement and all six scale levels.
import { arabicToWords } from "arabicfmt";
// Basic
arabicToWords(0) // "صفر"
arabicToWords(1) // "واحد"
arabicToWords(2) // "اثنان"
arabicToWords(11) // "أحد عشر"
arabicToWords(25) // "خمسة وعشرون"
arabicToWords(100) // "مئة"
arabicToWords(350) // "ثلاثمئة وخمسون"
// Thousands
arabicToWords(1000) // "ألف"
arabicToWords(2000) // "ألفان"
arabicToWords(5000) // "خمسة آلاف"
arabicToWords(11000) // "أحد عشر ألفاً"
arabicToWords(100000) // "مئة ألف"
// Millions / billions
arabicToWords(1_000_000) // "مليون"
arabicToWords(2_000_000) // "مليونان"
arabicToWords(5_000_000) // "خمسة ملايين"
arabicToWords(1_000_000_000)// "مليار"
// Large composite
arabicToWords(1_234_567)
// "مليون ومئتان وأربعة وثلاثون ألفاً وخمسمئة وسبعة وستون"
// Gender agreement — feminine noun (ليرة، روبية…)
arabicToWords(3, { gender: "female" }) // "ثلاث"
arabicToWords(5, { gender: "female" }) // "خمس"
// Negative
arabicToWords(-42) // "سالب اثنان وأربعون"
// Decimals — opt in (default truncates, stays backward compatible)
arabicToWords(3.14, { fraction: "digits" }) // "ثلاثة فاصلة واحد أربعة"
arabicToWords(3.14, { fraction: "number" }) // "ثلاثة فاصلة أربعة عشر"
// Common fractions (denominators 2–10)
import { arabicFraction } from "arabicfmt";
arabicFraction(1, 2) // "نصف"
arabicFraction(3, 4) // "ثلاثة أرباع"
arabicFraction(2, 3) // "ثلثان"Spell money in words — التفقيط
spellCurrency is the tafqit every Arabic invoice, cheque and contract needs: it turns a numeric amount into its full legal Arabic wording, splitting major and minor units and inflecting every noun for correct grammatical agreement (singular / dual / plural / accusative).
import { spellCurrency } from "arabicfmt";
spellCurrency(1234.5, { currency: "SAR" })
// "ألف ومئتان وأربعة وثلاثون ريالاً وخمسون هللةً"
// Unit agreement is automatic (العدد والمعدود)
spellCurrency(1, { currency: "SAR" }) // "ريال واحد" (singular)
spellCurrency(2, { currency: "SAR" }) // "ريالان" (dual)
spellCurrency(3, { currency: "SAR" }) // "ثلاثة ريالات" (plural, 3–10)
spellCurrency(11, { currency: "SAR" }) // "أحد عشر ريالاً" (accusative, 11–99)
spellCurrency(100, { currency: "SAR" }) // "مئة ريال" (genitive singular)
// Minor-unit precision comes from CLDR — KWD = 1000 fils, SAR = 100 halalas
spellCurrency(1.5, { currency: "KWD" }) // "دينار واحد وخمسمئة فلس"
spellCurrency(0.75, { currency: "SAR" }) // "خمس وسبعون هللةً"
// Cheque-ready ending and locale-derived currency
spellCurrency(100, { currency: "SAR", suffix: true }) // "مئة ريال فقط لا غير"
spellCurrency(-5, { locale: "ar-AE" }) // "سالب خمسة دراهم"Full Arabic noun paradigms are bundled for all 22 Arab League currencies (SAR, AED, KWD, BHD, QAR, OMR, JOD, EGP, IQD, LYD, TND, DZD, MAD, SDG, LBP, SYP, YER, SOS, DJF, KMF, MRU). Inspect or extend them via the exported CURRENCY_WORDS table.
Ordinal numbers — الأعداد الترتيبية
import { arabicOrdinal } from "arabicfmt";
arabicOrdinal(1) // "الأول"
arabicOrdinal(2) // "الثاني"
arabicOrdinal(10) // "العاشر"
arabicOrdinal(11) // "الحادي عشر"
arabicOrdinal(25) // "الخامس والعشرون"
// Gender agreement
arabicOrdinal(1, { gender: "female" }) // "الأولى"
arabicOrdinal(25, { gender: "female" }) // "الخامسة والعشرون"
// Indefinite (drop the article ال)
arabicOrdinal(3, { definite: false }) // "ثالث"
arabicOrdinal(25, { definite: false }) // "خامس وعشرون"Duration — spelled Arabic
formatDuration turns a time span into its spoken Arabic form, with correct
dual/plural/accusative agreement on every unit — something Intl.DurationFormat
(still barely supported) does not give you.
import { formatDuration } from "arabicfmt";
formatDuration(7_500_000) // "ساعتان وخمس دقائق" (2h 5m)
formatDuration(90, { input: "s" }) // "دقيقة واحدة وثلاثون ثانيةً"
formatDuration(3_600_000, { largest: 1 }) // "ساعة واحدة"
formatDuration(2 * 86_400_000) // "يومان"
formatDuration(500) // "أقل من ثانية"
// Restrict the units considered
formatDuration(125 * 60_000, { units: ["minute"], largest: 1 })
// "مئة وخمس وعشرون دقيقةً"largest (default 2) caps how many units appear, biggest first. Want to drive
the noun agreement yourself? countedNoun(n, forms) is exported for any custom
counted noun.
File size — Arabic data units
import { formatFileSize } from "arabicfmt";
formatFileSize(0) // "0 بايت"
formatFileSize(1536) // "1.5 كيلوبايت"
formatFileSize(5 * 1024 * 1024) // "5 ميجابايت"
formatFileSize(1_500_000, { base: 1000 }) // "1.5 ميجابايت" (decimal/SI)
formatFileSize(2048, { numerals: "arab" }) // "٢ كيلوبايت"
formatFileSize(2048, { unitStyle: "latin" })// "2 KB"Units scale through بايت · كيلوبايت · ميجابايت · جيجابايت · تيرابايت · بيتابايت,
with base: 1024 (binary, default) or base: 1000 (decimal).
Arabic plural rules (6 forms)
Arabic has six plural forms — more than any other major language. Standard i18n libraries handle 1–2 forms and break for Arabic.
import { arabicPluralForm, arabicPlural } from "arabicfmt";
// Get the CLDR form name
arabicPluralForm(0) // "zero"
arabicPluralForm(1) // "one"
arabicPluralForm(2) // "two"
arabicPluralForm(5) // "few" (3–10)
arabicPluralForm(15) // "many" (11–99)
arabicPluralForm(100) // "other"
// Select the right string
const forms = {
zero: "لا كتب",
one: "كتاب واحد",
two: "كتابان",
few: "كتب", // 3–10
many: "كتاباً", // 11–99
other: "كتاب",
};
arabicPlural(0, forms) // "لا كتب"
arabicPlural(1, forms) // "كتاب واحد"
arabicPlural(2, forms) // "كتابان"
arabicPlural(5, forms) // "كتب"
arabicPlural(25, forms) // "كتاباً"
arabicPlural(100, forms) // "كتاب"Hijri / Islamic calendar dates
Two engines with an identical API:
|
| |
Algorithm | Tabular arithmetic | Official Umm al-Qura tables |
Accuracy | ±1–2 days | Exact |
Bundle | Tiny (no tables) | Larger (frozen ICU tables) |
Range | Any year | AH 1300–1599 |
Deterministic | Yes | Yes — same on Node/Chrome/Safari/Hermes |
import { toHijri, fromHijri, formatHijri, umalquraToGregorian } from "arabicfmt/umalqura";
// Convert
toHijri(new Date("2025-09-23")) // { year: 1447, month: 4, day: 1 }
umalquraToGregorian(1447, 9, 1) // JavaScript Date — first day of Ramadan 1447
// Format — Arabic
formatHijri(new Date("2025-09-23"))
// "1 ربيع الآخر 1447 هـ"
formatHijri(new Date("2025-09-23"), { numerals: "arab" })
// "١ ربيع الآخر ١٤٤٧ هـ"
// Format — English
formatHijri(new Date("2025-09-23"), { locale: "en" })
// "1 Rabi al-Thani 1447 AH"
// Format — ISO-style numeric
formatHijri(new Date("2025-09-23"), {
locale: "en", month: "2-digit", day: "2-digit", order: "ymd", era: false,
})
// "1447/04/01"Month and weekday name tables
import {
HIJRI_MONTHS_AR, // Arabic Hijri month names
HIJRI_MONTHS_EN, // English Hijri month names
GREGORIAN_MONTHS_AR, // Arabic Gregorian month names (يناير، فبراير…)
GREGORIAN_MONTHS_EN,
ARABIC_WEEKDAYS_AR, // Arabic weekday names (الأحد، الاثنين…)
ARABIC_WEEKDAYS_EN,
} from "arabicfmt/date";
HIJRI_MONTHS_AR[8] // "رمضان" (index 0 = Muharram)
GREGORIAN_MONTHS_AR[0] // "يناير" (index 0 = January)
ARABIC_WEEKDAYS_AR[5] // "الجمعة" (index 0 = Sunday)Bidirectional (RTL) text helpers
Stop phone numbers and English words from scrambling Arabic sentences:
import { detectDirection, isolate, isolateForeign, stripBidi } from "arabicfmt/bidi";
// Before fix: "+1 (555) 234-5678" flips the area code in RTL context
// After fix: the phone number is wrapped in Unicode isolates — sentence intact
isolateForeign("اتصل على +1 (555) 234-5678 الآن");
detectDirection("مرحبا"); // "rtl"
detectDirection("Hello"); // "ltr"
isolate("9:41 AM"); // FSI … PDI isolate around a mixed run
stripBidi(dirtyStr); // remove every Unicode bidi control characterText normalization for Arabic search
Match Arabic text despite diacritics, alef variants, hamza and taa marbuta differences:
import {
stripTashkeel,
normalizeArabic,
normalizeForSearch,
sortArabic,
compareArabic,
} from "arabicfmt/text";
stripTashkeel("مُحَمَّد") // "محمد"
normalizeArabic("الأحمد") // "الاحمد" (alef variants unified)
// Robust search — these two strings produce the same key:
normalizeForSearch("مُؤسَّسة") === normalizeForSearch("موسسه") // true
// Arabic-locale collation
sortArabic(["ياسر", "أحمد", "بسام"]) // ["أحمد", "بسام", "ياسر"]
["ج", "أ", "ب"].sort(compareArabic) // ["أ", "ب", "ج"]List formatting
Join values into a grammatical Arabic list. Wraps Intl.ListFormat and degrades gracefully on runtimes without it.
import { formatList } from "arabicfmt";
formatList(["أحمد", "محمد", "علي"]) // "أحمد ومحمد وعلي"
formatList(["تفاح", "موز", "برتقال"], { type: "disjunction" }) // "تفاح أو موز أو برتقال"
formatList([1, 2, 3], { numerals: "arab" }) // "١ و٢ و٣"Transliteration & URL slugs
Romanize Arabic script to readable Latin, or turn it into URL-safe slugs for routes, filenames and CMS permalinks. Deterministic — short vowels appear only when the text is vowelled (carries tashkeel).
import { transliterate, slugify } from "arabicfmt";
transliterate("مُحَمَّد") // "muhammad" (vowelled)
transliterate("محمد") // "mhmd" (bare → consonant-only)
transliterate("الرياض") // "alryad"
transliterate("غرفة ٢٠١") // "ghrfh 201" (digits converted)
slugify("مدينة جدة") // "mdynh-jdh"
slugify("الرياض 2026") // "alryad-2026"
slugify("Hello العالم", { separator: "_" }) // "hello_alalm"
slugify("Hello World", { lowercase: false }) // "Hello-World"Note: this is a pragmatic, reversible-ish romanization, not a strict academic transliteration (DIN 31635 / ISO 233). It is built for slugs, search keys and readable IDs.
Validation — IBAN & Saudi ID
Real checksums, not regex guesses. isValidIBAN runs the ISO 7064 mod-97
algorithm with SWIFT-registry length checks; isValidSaudiId runs the Luhn
check digit and classifies citizen vs. resident.
import { isValidIBAN, formatIBAN, isValidSaudiId, saudiIdType } from "arabicfmt";
isValidIBAN("SA03 8000 0000 6080 1016 7519") // true
isValidIBAN("SA03 8000 0000 6080 1016 7510") // false (bad checksum)
formatIBAN("SA0380000000608010167519") // "SA03 8000 0000 6080 1016 7519"
isValidSaudiId("1012345672") // true
saudiIdType("1012345672") // "citizen"
saudiIdType("2100000005") // "resident" (Iqama)Registry lengths are enforced for SA, AE, KW, BH, QA, JO, LB, EG, IQ, PS, TN, MR, LY (plus common partners). Unknown-country IBANs are validated by checksum and the general 15–34 length bound, never accepted on structure alone.
Framework usage
React / Next.js
import { formatCurrency, detectLocale } from "arabicfmt";
import { formatHijri } from "arabicfmt/umalqura";
export function PriceTag({ amount, currency }: { amount: number; currency: string }) {
const locale = detectLocale();
return (
<span dir="rtl">
{formatCurrency(amount, { currency, locale })}
</span>
);
}
export function HijriDate({ date }: { date: Date }) {
return <time>{formatHijri(date, { numerals: "arab" })}</time>;
}Vue 3
import { formatCurrency } from "arabicfmt";
// composable
export function useArabicCurrency(currency: string) {
return (amount: number) =>
formatCurrency(amount, { currency, numerals: "arab" });
}Node.js / Express
import { formatCurrency, detectLocale } from "arabicfmt";
import { formatHijri } from "arabicfmt/umalqura";
app.get("/invoice/:id", (req, res) => {
const locale = req.headers["accept-language"]?.split(",")[0] ?? "ar-SA";
const total = formatCurrency(order.total, { locale });
const date = formatHijri(order.date, { locale: "ar" });
res.json({ total, date });
});Locale auto-detection
import { detectLocale } from "arabicfmt";
// Browser: reads navigator.language
// Node.js: reads LANG / LANGUAGE / LC_ALL / LC_MESSAGES env vars
// Fallback: "ar"
const locale = detectLocale(); // "ar-SA", "ar-EG", "en-US", …
formatCurrency(1234, { locale });Subpath imports — tree-shakeable
Pick only what you need for the smallest possible bundle:
import { formatCurrency, spellCurrency } from "arabicfmt/currency";
import { formatNumber, arabicToWords, formatDuration, formatFileSize } from "arabicfmt/number";
import { formatHijri, toHijri } from "arabicfmt/date"; // tabular core (tiny)
import { formatHijri, toHijri } from "arabicfmt/umalqura"; // accurate, opt-in
import { isolateForeign } from "arabicfmt/bidi";
import { normalizeForSearch, arabicPlural, slugify } from "arabicfmt/text";
import { isValidIBAN, isValidSaudiId } from "arabicfmt/validate";Measured cost of each entry point (esbuild --bundle --minify, gzipped — v0.1.0):
Import | What you get | min + gzip |
| everything below | 11.4 kB |
| 22 currencies, تفقيط, Unicode transition data | 5.7 kB |
| words, ordinals, fractions, parse, duration, … | 3.5 kB |
| 300 years of official Umm al-Qura tables | 2.2 kB |
| normalize, plurals, collation, lists, slugs | 1.6 kB |
| tabular Hijri core | 1.5 kB |
| direction detection + isolates | 0.7 kB |
| IBAN + Saudi ID checksums | 0.6 kB |
The complete Arabic formatting stack costs less than a single small image.
Full API reference
Every public function, by module. Full signatures and options are in the sections above and in the bundled TypeScript types.
Module | Functions |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| re-exports everything above + |
MCP server — use arabicfmt from AI agents
AI agents (Claude Desktop, Claude Code, Cursor) can call arabicfmt directly through the
arabicfmt-mcp Model Context Protocol server —
17 tools (format_currency, spell_currency, format_hijri, arabic_to_words,
isolate_foreign, validate_iban, …). Add it to your client's mcpServers config:
{
"mcpServers": {
"arabicfmt": { "command": "npx", "args": ["-y", "arabicfmt-mcp"] }
}
}Source and full tool list: mcp/.
Examples
Runnable scripts for every feature live in examples/:
cd examples && npm install
node currency.mjs # or numbers / words / dates / text / bidi / validateEngineering
Dependencies | Zero runtime dependencies |
Size | ~11.4 kB min+gzip for the whole library; subpath imports from 0.6 kB |
Formats | Dual ESM + CJS, full |
Tree-shaking |
|
Data source | CLDR 48.2.0 + ICU — verified at build time, not hand-typed |
Test coverage | 194 tests — currency transition, precision, Hijri, plurals, words, tafqit, durations, IBAN/ID |
Platforms | Node ≥ 18, all evergreen browsers, React Native / Hermes, Deno, Bun |
Published with | npm provenance (GitHub Actions attestation) |
Unicode currency-sign transition
Live since Unicode 18.0 (September 2026)
The UAE dirham (U+20C3) and Omani rial (U+20C4) signs are now live, and
symbolMode: "auto" prefers them — completing the transition that began with
the Saudi riyal sign (U+20C1) in Unicode 17.0. Because system-font coverage for
brand-new signs still varies, symbolMode: "text" always returns the safe
Arabic abbreviation (د.إ, ر.ع.), and the Saudi riyal keeps the text symbol
as its auto default by design.
Currency | Sign | Unicode |
|
Saudi riyal (SAR) |
| 17.0 (2025) | text |
UAE dirham (AED) |
| 18.0 (2026) | sign |
Omani rial (OMR) |
| 18.0 (2026) | sign |
Live demo
arabicfmt.vercel.app — the whole library, interactive and computed live in your browser. Change any input and watch the Arabic update in real time: currency studio, تفقيط, Hijri converter, plurals, RTL fixes and more.

Run it locally:
cd demo && npm install && npm run devContributing
Issues and pull requests are welcome on GitHub.
License
MIT — free for commercial and personal use.
Author & more projects
Built and maintained by cc1a2b.
If arabicfmt saves you time, please star it on GitHub — it helps other Arabic developers find it. Explore my other open-source projects, or open an issue with ideas, bugs and feature requests.
Available Tools
17 toolsarabic_ordinalA
Convert an integer to its Arabic ordinal words (e.g. 25 -> "الخامس والعشرون").
| Name | Required | Description | Default |
|---|---|---|---|
| n | Yes | The integer to convert to an Arabic ordinal. | |
| feminine | No | Use feminine grammatical gender. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations provided, so description bears full burden. It does not disclose behaviors such as handling of negative numbers, zero, the effect of the 'feminine' parameter, or any error conditions. The example only shows a positive ordinal.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Single sentence with an example. Extremely concise and immediately conveys the purpose without extra words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Simple tool, but missing key context: no mention of the feminine option, return format (string implied), or limitations. Adequate for basic use but leaves gaps for advanced agents.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% with descriptions for both parameters. The description adds a usage example but does not explain the 'feminine' parameter or provide additional semantics beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool converts an integer to Arabic ordinal words, with a specific example (25 -> "الخامس والعشرون"). This verb+resource pair is distinct from sibling tools like arabic_to_words (cardinal) or arabic_plural (plural forms).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No explicit guidance on when to use this tool vs alternatives like arabic_to_words or arabic_plural. The description implies ordinal conversion context via the example, but lacks when-not-to-use or prerequisite information.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
arabic_pluralA
Select the correct Arabic plural form for a count from the six CLDR categories (e.g. 5 books -> "كتب"). Returns the chosen word.
| Name | Required | Description | Default |
|---|---|---|---|
| n | Yes | The count that selects the plural form. | |
| forms | Yes | Arabic plural forms keyed by CLDR category. 'other' is required; 'zero','one','two','few','many' are optional. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, and the description lacks behavioral details such as input validation, error handling, or edge cases (e.g., missing forms). It only states the basic return, adding minimal value beyond the purpose.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single sentence with a concrete example, front-loaded with the core function. No extraneous words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description covers the basic purpose and example but does not explain the return format (e.g., a string, the exact word from forms) or behavior when not all CLDR forms are provided. Given no output schema, more detail is warranted.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, with both parameters described. The description adds value with an example and mentions CLDR categories, slightly enhancing the schema's information.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's purpose: selecting the correct Arabic plural form based on a count and CLDR categories, with an example. It distinguishes from sibling tools (e.g., arabic_ordinal) by focusing on plural forms.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage for Arabic plural selection but provides no explicit guidance on when to use or avoid this tool, nor does it compare with alternatives like arabic_to_words.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
arabic_to_wordsA
Convert an integer to its full Arabic cardinal words (e.g. 1234567 -> "مليون ومئتان وأربعة وثلاثون ألفاً وخمسمئة وسبعة وستون").
| Name | Required | Description | Default |
|---|---|---|---|
| n | Yes | The integer to convert to Arabic words. | |
| feminine | No | Use feminine grammatical gender for the counted noun. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations provided; description does not disclose edge cases, error handling, or performance traits. For a simple conversion tool, minimal disclosure is acceptable but not thorough.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Single sentence with embedded example, zero wasted words. Front-loaded with core purpose.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given a simple integer-to-words conversion with no output schema, the description plus schema sufficiently explain behavior. Missing minor detail about feminine parameter effect on output, but schema mitigates.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema covers both parameters with descriptions. Description adds value via example showing correct output and implying the result format, but does not elaborate on feminine parameter usage beyond schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Description clearly states verb (convert), resource (integer to Arabic cardinal words), and provides an illustrative example. Distinguishes from siblings like arabic_ordinal or arabic_plural by specifying cardinal words.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Implies usage for converting integers to cardinal Arabic words, contrasting with ordinal/plural siblings, but lacks explicit when-to-use/when-not-to-use guidance or alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
format_compactA
Format a number in compact notation with Arabic scale words (e.g. 1200000 with locale "ar" -> "1.2 مليون").
| Name | Required | Description | Default |
|---|---|---|---|
| value | Yes | The number to format compactly. | |
| locale | No | BCP-47 locale, e.g. 'ar', 'ar-SA', 'en'. Defaults to 'ar'. | |
| numerals | No | Numeral system: 'latn' (1234), 'arab' (Eastern Arabic ١٢٣٤), or 'arabext' (Persian/Urdu ۱۲۳۴). | |
| compactDisplay | No | Compact form: 'short' or 'long'. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries full burden. It states the core formatting behavior but does not disclose edge cases (e.g., handling of very large numbers, negative numbers), error conditions, or additional behavioral traits beyond the example. The description is minimal.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single concise sentence with a relevant example, front-loading the core functionality. No unnecessary words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 4-parameter tool with no output schema, the description provides a basic understanding of the tool's purpose but lacks details on parameter combinations, return format, or locale-specific behavior beyond the example. It is minimally adequate but not comprehensive.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the schema already documents all parameters. The description adds context by mentioning 'Arabic scale words' and providing an example that illustrates the effect of locale and value, but does not elaborate on each parameter individually. Baseline of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool formats numbers in compact notation with Arabic scale words, and provides a concrete example. It effectively distinguishes itself from sibling tools like format_number, which likely handles more general formatting.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage for compact formatting with Arabic locale via the example, but it does not explicitly state when to use this tool over alternatives (e.g., format_number for other locales) or when not to use it. The guidance is implicit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
format_currencyA
Format a number as an Arabic currency amount with the correct symbol, grouping, and decimal precision (e.g. 1234.5 SAR -> "1,234.50 ر.س"). Handles the 2025-2026 Unicode currency-symbol transition (Saudi Riyal U+20C1, etc.).
| Name | Required | Description | Default |
|---|---|---|---|
| amount | Yes | The monetary amount to format. | |
| locale | No | BCP-47 locale, e.g. 'ar', 'ar-SA', 'en'. Defaults to 'ar'. | |
| currency | No | ISO 4217 currency code, e.g. 'SAR', 'AED', 'KWD'. Defaults to SAR-area default. | |
| numerals | No | Numeral system: 'latn' (1234), 'arab' (Eastern Arabic ١٢٣٤), or 'arabext' (Persian/Urdu ۱۲۳۴). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries full burden. It discloses handling of the Unicode symbol transition and indicates input/output format but does not cover error behavior (e.g., invalid locale/currency), edge cases (negative amounts), or whether the operation is read-only. Some transparency is provided but gaps remain.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences, tightly written with no redundancy. The key purpose and example are front-loaded, making it efficient for an agent to parse quickly.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given 4 parameters and no output schema, the description covers basic input/output and a notable behavioral detail (Unicode transition). However, it lacks explicit return type (string) and error scenarios, leaving some uncertainty. A more complete description would mention the string output and handle edge cases.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so baseline is 3. The description adds an example and mentions Unicode transition but does not elaborate on parameter semantics beyond what the schema provides. It confirms the output format but adds no new meaning per parameter.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states that the tool formats a number as an Arabic currency amount with correct symbol, grouping, and decimal precision. It provides a concrete example (1234.5 SAR -> '1,234.50 ر.س') and differentiates from siblings like format_number and spell_currency by specifying Arabic currency context.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage for Arabic currency formatting but does not explicitly state when to use this tool versus siblings like format_number (general formatting) or spell_currency (spelling out). No when-not or alternatives are mentioned, leaving the agent to infer context from the purpose.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
format_durationA
Format a duration in milliseconds as natural Arabic words (e.g. 7500000 -> "ساعتان وخمس دقائق").
| Name | Required | Description | Default |
|---|---|---|---|
| value | Yes | Duration in milliseconds. | |
| locale | No | BCP-47 locale, e.g. 'ar', 'ar-SA', 'en'. Defaults to 'ar'. | |
| numerals | No | Numeral system: 'latn' (1234), 'arab' (Eastern Arabic ١٢٣٤), or 'arabext' (Persian/Urdu ۱۲۳۴). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries full burden. It discloses the input unit and output format, but does not specify behavior for edge cases (negative, zero, large values) or locale/numerals effects beyond schema defaults.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single sentence with an example, which is efficient and front-loaded. Minimal but no wasted words; the example aids understanding.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple formatting tool with no output schema, the description adequately explains input (milliseconds) and output (Arabic words). It covers the main purpose, though could mention return type or handle more edge cases.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so baseline is 3. The description provides an example but adds no extra meaning to parameters beyond what the schema already describes for 'value', 'locale', and 'numerals'.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool formats a duration in milliseconds to natural Arabic words, with a concrete example. It distinguishes from siblings like 'arabic_ordinal' and 'format_relative_time' which handle different formats.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No explicit guidance on when to use this tool versus alternatives like 'format_relative_time'. The description implies its use for Arabic duration formatting but lacks 'when not to use' context.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
format_hijriB
Format a Gregorian date as a Hijri (Islamic) date string with Arabic month names and era (e.g. 2025-09-23 -> "٢٣ رمضان ١٤٤٧ هـ").
| Name | Required | Description | Default |
|---|---|---|---|
| date | Yes | Gregorian date as ISO 8601 string, e.g. '2025-09-23' or '2025-09-23T00:00:00Z'. | |
| locale | No | BCP-47 locale, e.g. 'ar', 'ar-SA', 'en'. Defaults to 'ar'. | |
| numerals | No | Numeral system: 'latn' (1234), 'arab' (Eastern Arabic ١٢٣٤), or 'arabext' (Persian/Urdu ۱۲۳۴). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description must fully cover behavioral traits. It only states the output format with an example but does not disclose error handling, timezone sensitivity, input validation, or any side effects. This is insufficient for a tool with no annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single sentence with an example, containing zero waste. It is front-loaded with the core purpose and efficient.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple tool with three parameters and no output schema, the description provides the essential purpose and an example. However, it lacks details about parameter interactions, error scenarios, or the behavior for invalid dates, which feels incomplete for production use.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema already describes all three parameters (date, locale, numerals) with 100% coverage. The description adds value by showing an example output format, but does not elaborate on how locale or numerals affect the result. Baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool converts a Gregorian date to a Hijri date string with Arabic month names and era, and provides an illustrative example. However, it does not explicitly distinguish this from the sibling tool 'to_hijri', so the purpose is clear but differentiation is missing.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description does not provide any guidance on when to use this tool versus alternatives like 'to_hijri' or other formatting tools. It implies usage for Hijri conversion with Arabic month names but lacks explicit context or exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
format_numberA
Format a number with locale-aware grouping, decimal separators, and optional Eastern Arabic numerals (e.g. 1234567.89 with numerals "arab" -> "١٬٢٣٤٬٥٦٧٫٨٩").
| Name | Required | Description | Default |
|---|---|---|---|
| value | Yes | The number to format. | |
| locale | No | BCP-47 locale, e.g. 'ar', 'ar-SA', 'en'. Defaults to 'ar'. | |
| numerals | No | Numeral system: 'latn' (1234), 'arab' (Eastern Arabic ١٢٣٤), or 'arabext' (Persian/Urdu ۱۲۳۴). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Since no annotations are provided, the description carries the full burden. It discloses core formatting behavior (grouping, decimals, numerals) but omits details on edge cases like negative numbers, precision, or error handling, leaving some ambiguity.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single sentence with an example, containing no redundant information. Every word serves a purpose.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with 3 parameters and no output schema, the description provides sufficient context through an illustrative example. However, it does not fully explain the locale parameter's impact or defaults, leaving minor gaps.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so baseline is 3. The description adds an example tying value and numerals together but does not elaborate on locale effects or default values beyond what the schema provides.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's function: formatting a number with locale-aware grouping, decimal separators, and optional numeral systems. It provides a concrete example and is distinct from sibling tools like format_currency or format_compact.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implicitly suggests usage for locale-aware number formatting but does not explicitly state when to use this tool over siblings like format_compact or format_currency. No alternatives or exclusions are mentioned.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
format_relative_timeA
Format a date relative to a base date in Arabic (e.g. three days ago -> "منذ ٣ أيام"). Defaults the base to now.
| Name | Required | Description | Default |
|---|---|---|---|
| base | No | Base/reference date as ISO 8601 string. Defaults to the current time. | |
| date | Yes | Target date as ISO 8601 string, e.g. '2025-09-20'. | |
| locale | No | BCP-47 locale, e.g. 'ar', 'ar-SA', 'en'. Defaults to 'ar'. | |
| numerals | No | Numeral system: 'latn' (1234), 'arab' (Eastern Arabic ١٢٣٤), or 'arabext' (Persian/Urdu ۱۲۳۴). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden. It mentions defaulting base to now and provides an example, but doesn't disclose edge cases (e.g., future dates, timezone handling, or output when date equals base). There is no contradiction with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single sentence with a parenthetical example. Every word earns its place; no redundancy or unnecessary details.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description adequately explains the core purpose and provides an example. However, it omits details about the output format for future dates, error handling, and does not cover all parameters' behaviors adequately.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3. The description adds an example and explains the relative concept, but does not provide additional meaning beyond what the schema already offers for each parameter.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the verb 'Format', the resource 'date relative to a base date', and specifies the language 'Arabic'. The example 'three days ago -> "منذ ٣ أيام"' makes the purpose immediately obvious and distinguishes it from sibling tools like format_duration or arabic_plural.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage for relative time formatting in Arabic, but lacks explicit guidance on when to use this tool versus alternatives (e.g., format_duration for lengths, arabic_plural for plurals). No 'when not to use' or exclusions are provided.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
isolate_foreignA
Wrap foreign/LTR runs (phone numbers, Latin text, URLs) inside Arabic text with Unicode bidi isolates so they render correctly in RTL contexts (e.g. "اتصل على +1 (555) 234-5678 الآن").
| Name | Required | Description | Default |
|---|---|---|---|
| text | Yes | The mixed-direction text to process. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries full burden. It discloses that the tool modifies text by adding Unicode bidi isolates, and the example shows the effect. However, it could mention that the original text content is preserved aside from the wrapping, but overall it's sufficient for a text transformation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single sentence with an example, containing no unnecessary words. Every part is informative and earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's simplicity (one required parameter, no output schema), the description explains the purpose, usage, and behavior completely. No additional context is needed.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema has 100% coverage with a description for the `text` parameter. The tool description adds value by providing an example and listing the types of foreign runs (phone numbers, Latin text, URLs) that should be isolated, going beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool wraps foreign/LTR runs inside Arabic text with Unicode bidi isolates, using specific examples like phone numbers and URLs. It distinguishes itself from sibling tools which deal with formatting numbers, plurals, etc., rather than bidi handling.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides a clear use case (rendering foreign text correctly in RTL contexts) with an example. While it doesn't explicitly state when not to use or mention alternatives, the sibling list makes this tool unique for bidi isolation, so the guidance is adequate.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
parse_numberA
Parse a string containing Latin or Eastern Arabic digits (with Arabic grouping/decimal separators) into a JavaScript number (e.g. "١٬٢٣٤٫٥٦" -> 1234.56). Returns the number as a string.
| Name | Required | Description | Default |
|---|---|---|---|
| input | Yes | The numeric string to parse, e.g. '١٬٢٣٤٫٥٦' or '1,234.56'. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations provided; description discloses return type (number as string) but does not mention error handling, character validation, or behavior for invalid input.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences with an example; no wasted words, front-loaded with purpose.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
No output schema; description states return format. Missing edge-case handling but adequate for a simple parsing tool given other context.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema covers the single parameter with description; description adds value with explicit input format examples, enhancing understanding beyond schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's action: parse a string containing Latin or Eastern Arabic digits with Arabic separators into a JavaScript number, and gives an example. It distinguishes from sibling tools like format_number.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage for parsing numeric strings with Arabic digits but does not explicitly state when to use this tool vs alternatives like format_number or other parsing options.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
slugifyA
Convert Arabic (or mixed) text into a URL-safe slug (e.g. "مدينة جدة" -> "mdynh-jdh").
| Name | Required | Description | Default |
|---|---|---|---|
| text | Yes | The text to slugify. | |
| separator | No | Word separator character. Defaults to '-'. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries full burden. It states the conversion to a URL-safe slug and gives an example, but does not disclose details like the transliteration algorithm, handling of non-Arabic characters, or edge cases (e.g., empty string, special symbols).
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single sentence with an example, front-loading the action and result. Every part is useful and there is no redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple slugification tool, the description provides purpose and example. However, it lacks details about the underlying algorithm (appears to be phonetic transliteration) and separator behavior, which would help an agent understand edge cases. It is mostly adequate but not exhaustive.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% for both parameters ('text' and 'separator'). The description adds context about Arabic-specific conversion but does not explain the separator parameter or its default behavior. Thus, it adds minimal value beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the verb 'Convert' and the resource 'Arabic (or mixed) text', with a concrete example showing the output format ('mdynh-jdh'). It distinguishes slugify from sibling tools which handle other Arabic text operations like pluralization and number formatting.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies the tool is used for generating URL-safe slugs from Arabic text, which is a unique capability among siblings. However, it does not explicitly specify when to use or not use it, such as cases where exact transliteration is needed versus other formatting.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
spell_currencyA
Spell out a currency amount in full Arabic words, including the major and minor units with correct grammatical agreement (e.g. 1234.5 SAR -> "ألف ومئتان وأربعة وثلاثون ريالاً وخمسون هللة").
| Name | Required | Description | Default |
|---|---|---|---|
| amount | Yes | The monetary amount to spell out. | |
| locale | No | BCP-47 locale, e.g. 'ar', 'ar-SA', 'en'. Defaults to 'ar'. | |
| currency | No | ISO 4217 currency code, e.g. 'SAR', 'AED', 'KWD'. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden. It discloses key behavior: it handles major and minor units with grammatical agreement and uses locales and currency codes. However, it does not explain behavior for edge cases like zero amounts, large numbers, or unsupported currencies. The description is adequate but not exhaustive.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, well-structured sentence with an example. It front-loads the core purpose and is free of any extraneous text. Every part earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given no output schema, the description explains the return format well. It covers the main use case but lacks details on parameter defaults, supported currencies, and error handling. For a tool with 3 parameters and 1 required, it is reasonably complete but could be more thorough.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so each parameter already has a description. The tool description adds value by explaining the overall output format and the inclusion of grammatical agreement, but it does not provide additional constraints or examples for each parameter beyond what the schema offers. Baseline of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool spells out a currency amount in full Arabic words, including major and minor units with grammatical agreement. It provides a concrete example, making the purpose unmistakable. This distinguishes it from sibling tools like arabic_to_words and format_currency.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies when to use the tool (when you need Arabic spelling of a currency amount), but it does not explicitly compare with alternatives or mention when not to use it. It lacks guidance on prerequisites or edge cases.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
to_hijriA
Convert a Gregorian date to its Hijri components. Returns a JSON object string like {"year":1447,"month":9,"day":23}.
| Name | Required | Description | Default |
|---|---|---|---|
| date | Yes | Gregorian date as ISO 8601 string, e.g. '2025-09-23'. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description discloses the output format (JSON object string) and components. However, it does not mention potential errors (e.g., invalid date input), edge cases, or any limitations. No annotations are provided, so the description carries the full burden.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
One concise sentence that includes the essential information: operation, input, and output format. No unnecessary words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool is simple with one parameter and no output schema. The description adequately explains the output format and content. Could mention that the output is a string representation of a JSON object, but that is clear. Minor improvement would be to clarify that the date must be in the format YYYY-MM-DD.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, and the description adds the example '2025-09-23' which is already implied by the ISO 8601 specification in the schema. No additional semantic value beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the action (convert), the inputs (Gregorian date), the outputs (Hijri components), and the output format (JSON object string). It is distinct from sibling tools like format_hijri which likely formats an existing Hijri date.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance on when to use this tool versus alternatives. For example, if a user wants a formatted Hijri string, format_hijri might be better. The description does not mention any prerequisites or exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
transliterateA
Transliterate Arabic text to Latin script (e.g. "مُحَمَّد" -> "muhammad").
| Name | Required | Description | Default |
|---|---|---|---|
| text | Yes | The Arabic text to transliterate. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations exist, so the description carries full burden. It only states the script transformation, omitting details like transliteration standard, handling of diacritics, or whether it's reversible.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Single sentence with an embedded example—maximally concise and front-loaded with purpose.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a single-parameter tool, the description covers input (Arabic text) and output (transliterated Latin script) via example. No output schema exists, but the example implies string return; slightly lacking in stating output type explicitly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% with property description matching the tool. The description adds an example but no extra parameter-level insight beyond the existing schema documentation.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states it transliterates Arabic text to Latin script with a concrete example ('مُحَمَّد' -> 'muhammad'), which distinguishes it from siblings like arabic_to_words or arabic_ordinal that perform different operations.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage when Arabic-to-Latin transliteration is needed but provides no explicit guidance on when not to use it or alternatives among sibling tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
validate_ibanA
Validate an IBAN (International Bank Account Number) using its checksum and country length (e.g. "SA03 8000 0000 6080 1016 7519" -> "true"). Returns "true" or "false".
| Name | Required | Description | Default |
|---|---|---|---|
| iban | Yes | The IBAN to validate; spaces are allowed. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations provided. Description mentions the validation method (checksum, country length) and return type. Lacks details on edge cases, but behavior is simple and mostly transparent.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two concise sentences with an example. No unnecessary words, but could be slightly more structured.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple validation tool with one parameter and no output schema, the description is complete. It covers what the tool does, how it works, and returns.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Only one parameter 'iban' with schema description covering 100%. Description adds no extra meaning beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool validates an IBAN using checksum and country length, returns 'true' or 'false', and provides an example. It distinguishes from sibling tools like validate_saudi_id.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No explicit when-to-use or when-not-to-use guidance, but the purpose is clear. Sibling tools include other validations, but no differentiation is provided.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
validate_saudi_idA
Validate a Saudi national/iqama ID number using its Luhn-style checksum (e.g. "1012345672" -> "true"). Returns "true" or "false".
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | The 10-digit Saudi ID number to validate. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries full burden. It discloses the checksum algorithm and return values but does not mention error handling, side effects, or performance. Sufficient but not thorough.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, front-loaded with the main action and an example. No unnecessary words, highly efficient.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple validation tool with one parameter and no output schema, the description is fairly complete. It explains return values. Minor gap: does not clarify behavior for invalid input format (e.g., non-numeric or wrong length), though likely returns false.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema already covers the parameter with 100% description coverage. The description adds value by specifying 'Saudi national/iqama ID number' and providing an example, enhancing meaning beyond the schema's generic description.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool validates a Saudi national/iqama ID using a Luhn-style checksum, with an example input and output. It distinguishes itself from sibling tools which handle formatting, translation, or other validation (validate_iban).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage for validating Saudi IDs but does not explicitly state when to use it or provide alternatives. No exclusions are mentioned.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections. Dates show when Glama detected each change.
17 tool updates
v0.1.0- First observed
arabic_ordinal - First observed
arabic_plural - First observed
arabic_to_words - First observed
format_compact - First observed
format_currency - First observed
format_duration - First observed
format_hijri - First observed
format_number - First observed
format_relative_time - First observed
isolate_foreign - First observed
parse_number - First observed
slugify - First observed
spell_currency - First observed
to_hijri - First observed
transliterate - First observed
validate_iban - First observed
validate_saudi_id
TDQS
Most tools have clearly distinct purposes, though some overlap exists (e.g., format_number vs format_compact, format_currency vs spell_currency). Descriptions effectively differentiate them, so confusion is minimal.
All names use snake_case, but patterns vary: some are verb_noun (format_currency), some descriptive noun (arabic_ordinal), and some single verbs (slugify). This mild inconsistency prevents a higher score.
17 tools cover a wide range of Arabic formatting and validation tasks without feeling excessive. The count is appropriate for the server's scope, though it could potentially be trimmed by merging some overlapping functions.
The set covers number conversion, date formatting (Hijri), currency, duration, relative time, transliteration, and validation (IBAN, Saudi ID). Missing a general Gregorian date formatter, but the core domain is well-served.
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Connectors
The only MCP server for Arabic academic research — search, read & cite Arabic + English papers.
Lingo.dev MCP Server - World-class i18n implementation with ICU MessageFormat.
MCP server for Quaderno — tax-rate calculation, invoices, contacts, products, receipts & expenses.
Related MCP Servers
- AlicenseAqualityCmaintenanceMCP server exposing Arabic text utilities: normalisation, tashkeel stripping, transliteration, heuristic dialect detection, and token counting.5MIT
- AlicenseAqualityBmaintenanceMCP server that provides grounded Arabic dictionary lookup, enabling AI agents to search word roots, inflections, and meanings from real dictionary data.31MIT
- AlicenseAqualityAmaintenanceMCP server that gives coding agents right-to-left awareness with tools to lint RTL code, normalize Arabic text, and detect text direction.439MIT
- AlicenseBqualityAmaintenanceAn MCP server for elite Arabic and bilingual RTL/LTR UI/UX design, providing tools for design pipelines, anti-AI-slop auditing, RTL layout conversion, Arabic typography optimization, and accessibility checks.14MIT
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/cc1a2b/arabicfmt'
If you have feedback or need assistance with the MCP directory API, please join our Discord server