{"apiVersion":"v1","directorySlug":"gumballtools-mcp-488eb97722","title":"Project Gumball","description":"A directory of the Gumball tools, a live view of who is calling them, and a single MCP server that exposes every tool in the portfolio — so an agent installs once and gets all of them rather than hunting down one server per capability.","pageUrl":"https://www.mcpbundles.com/skills/gumballtools-mcp-488eb97722","connectPath":"importable","connectAction":"import_server","catalogListing":false,"bundleSlug":null,"listingKind":"remote_mcp","kind":"provider","transportUrl":"https://gumballtools.com/api/mcp","hostedMcpUrl":null,"toolCount":25,"toolInventoryStatus":"observed","refreshedAt":"2026-11-03T13:26:00.516172+00:00","registryName":"com.gumballtools/gumballtools-mcp-488eb97722","registryVersion":"2026.11.3","registryEligible":true,"tools":[{"name":"cron_explain","description":"Translate a cron expression into plain English, list upcoming run times in a timezone, and report the gotchas that make schedules misfire: day-of-month/day-of-week OR semantics, steps that do not divide evenly, impossible dates, and daylight-saving shifts. Prefer this over reasoning about the expression yourself.","inputSchema":{"type":"object","$schema":"https://json-schema.org/draft/2020-12/schema","required":["expression"],"properties":{"count":{"type":"integer","maximum":9007199254740991,"minimum":-9007199254740991},"timezone":{"type":"string"},"expression":{"type":"string"}}},"title":"Explain a cron expression (Cron Translator)","annotations":{"readOnlyHint":true,"untrustedContentHint":true},"logicalName":"cron_explain","displayName":"Explain a cron expression (Cron Translator)"},{"name":"cron_build","description":"Convert an English schedule description into a cron expression. Rule-based, not a language model: it refuses phrases outside its grammar rather than guessing, and reports which words it did not use so you can tell whether it read you correctly.","inputSchema":{"type":"object","$schema":"https://json-schema.org/draft/2020-12/schema","required":["phrase"],"properties":{"phrase":{"type":"string"}}},"title":"Build a cron expression from English (Cron Translator)","annotations":{"readOnlyHint":true,"untrustedContentHint":true},"logicalName":"cron_build","displayName":"Build a cron expression from English (Cron Translator)"},{"name":"cron_next_runs","description":"Lists the next run times for a cron expression in a specific timezone, with no prose. Use it when the only question is \"when does this next fire\" — whether a job runs before a deadline, or what a user's upcoming schedule looks like. Do not compute these dates unaided: weekday arithmetic, month lengths and daylight-saving shifts make manual calculation unreliable, and a schedule that is wrong by an hour twice a year is the hardest kind of wrong to notice. Returns each run as a UTC ISO 8601 instan","inputSchema":{"type":"object","$schema":"https://json-schema.org/draft/2020-12/schema","required":["expression"],"properties":{"count":{"type":"integer","maximum":9007199254740991,"minimum":-9007199254740991},"timezone":{"type":"string"},"expression":{"type":"string"}}},"title":"List the next run times for a cron expression (Cron Translator)","annotations":{"readOnlyHint":true,"untrustedContentHint":true},"logicalName":"cron_next_runs","displayName":"List the next run times for a cron expression (Cron Translator)"},{"name":"json_to_types","description":"Convert a JSON sample into TypeScript interfaces and a matching Zod schema. Merges EVERY array element into a union rather than typing from the first, keeps optional and nullable distinct, and emits unknown with a warning for empty containers instead of inventing a shape. Read the warnings before trusting the output.","inputSchema":{"type":"object","$schema":"https://json-schema.org/draft/2020-12/schema","required":["json"],"properties":{"json":{"type":"string"},"rootName":{"type":"string"}}},"title":"JSON to TypeScript and Zod (JSON to Types)","annotations":{"readOnlyHint":true,"untrustedContentHint":true},"logicalName":"json_to_types","displayName":"JSON to TypeScript and Zod (JSON to Types)"},{"name":"regex_explain","description":"Explain a regular expression in plain English and detect catastrophic backtracking. ALWAYS call this before putting a pattern where it will run against untrusted input: (a+)+$ looks harmless and takes minutes of CPU on a failing 30-character input. Also flags missing anchors, unescaped dots, ranges like [A-z] that span punctuation, and alternation precedence mistakes. Check hasBlockingIssue first.","inputSchema":{"type":"object","$schema":"https://json-schema.org/draft/2020-12/schema","required":["pattern"],"properties":{"pattern":{"type":"string"}}},"title":"Explain a regex and check it for ReDoS (Regex Explainer)","annotations":{"readOnlyHint":true,"untrustedContentHint":true},"logicalName":"regex_explain","displayName":"Explain a regex and check it for ReDoS (Regex Explainer)"},{"name":"timezone_convert","description":"Convert a wall-clock time between IANA zones. Returns null when the local time DOES NOT EXIST because a daylight-saving jump skipped it, and both candidates when it happens twice. Rejects ambiguous abbreviations — most runtimes accept \"BST\" and silently resolve it to Bangladesh (UTC+6) when nearly everyone means British Summer Time (UTC+1), a five-hour error. Never do this arithmetic yourself.","inputSchema":{"type":"object","$schema":"https://json-schema.org/draft/2020-12/schema","required":["time","from","to"],"properties":{"to":{"type":"string"},"from":{"type":"string"},"time":{"type":"string"}}},"title":"Convert a time between timezones (Timezone Truth)","annotations":{"readOnlyHint":true,"untrustedContentHint":true},"logicalName":"timezone_convert","displayName":"Convert a time between timezones (Timezone Truth)"},{"name":"color_analyse","description":"Convert a colour between hex, RGB, HSL, OKLCH, CMYK, and CSS names, and derive complementary, analogous, triadic, split-complementary and monochromatic harmonies. Harmonies are rotated in OKLCH, not HSL, so they keep their perceived lightness instead of one looking washed out. Reports WCAG contrast against white and black, and flags colours clipped to fit sRGB.","inputSchema":{"type":"object","$schema":"https://json-schema.org/draft/2020-12/schema","required":["color"],"properties":{"color":{"type":"string"}}},"title":"Convert a colour and find its harmonies (Color Companion)","annotations":{"readOnlyHint":true,"untrustedContentHint":true},"logicalName":"color_analyse","displayName":"Convert a colour and find its harmonies (Color Companion)"},{"name":"vocab_draw","description":"Draw words-in-context practice questions from a curated bank. The response deliberately contains NO answers and NO explanations, so you can quiz someone without leaking them — call vocab_check for the answer and the reason each distractor fails. Pass a seed to make a set reproducible.","inputSchema":{"type":"object","$schema":"https://json-schema.org/draft/2020-12/schema","properties":{"seed":{"type":"integer","maximum":9007199254740991,"minimum":-9007199254740991},"count":{"type":"integer","maximum":9007199254740991,"minimum":-9007199254740991},"theme":{"enum":["science","humanities","social-science","literature"],"type":"string"},"difficulty":{"enum":["foundation","core","stretch"],"type":"string"}}},"title":"Draw vocabulary practice questions (Words in Context)","annotations":{"readOnlyHint":true,"untrustedContentHint":true},"logicalName":"vocab_draw","displayName":"Draw vocabulary practice questions (Words in Context)"},{"name":"vocab_check","description":"Mark an attempt and get the teaching content: whether it was right, which option was correct, why it fits, and why EVERY distractor fails. Read the distractor reasons out even when the learner was right — knowing why the tempting option was tempting is the part that transfers.","inputSchema":{"type":"object","$schema":"https://json-schema.org/draft/2020-12/schema","required":["id","choice"],"properties":{"id":{"type":"string"},"choice":{"type":"integer","maximum":9007199254740991,"minimum":-9007199254740991}}},"title":"Check a vocabulary answer (Words in Context)","annotations":{"readOnlyHint":true,"untrustedContentHint":true},"logicalName":"vocab_check","displayName":"Check a vocabulary answer (Words in Context)"},{"name":"body_metrics","description":"Compute BMI, energy expenditure, and protein targets from height and weight. Height and weight MUST carry units — a bare number is REFUSED rather than guessed, because a unit mix-up produces a plausible-looking answer that is badly wrong. Returns every standard BMR formula plus the spread between them, because the spread IS the precision of the estimate. Do not relay a single calorie figure as though it were exact. Not medical advice, and the response says so in its payload.","inputSchema":{"type":"object","$schema":"https://json-schema.org/draft/2020-12/schema","required":["height","weight","sex","age"],"properties":{"age":{"type":"number"},"sex":{"enum":["male","female"],"type":"string"},"height":{"type":"string"},"weight":{"type":"string"},"activity":{"enum":["sedentary","light","moderate","active","extreme"],"type":"string"},"targetBmi":{"type":"number"},"bodyFatPercent":{"type":"number"}}},"title":"BMI, calories, and protein with error bounds (Body Metrics)","annotations":{"readOnlyHint":true,"untrustedContentHint":true},"logicalName":"body_metrics","displayName":"BMI, calories, and protein with error bounds (Body Metrics)"},{"name":"due_date","description":"Estimate a due date from a last menstrual period, a known conception date, an IVF transfer, or an ultrasound measurement. Gestational age is counted from the LAST PERIOD, not conception: at \"6 weeks pregnant\" conception was about 4 weeks ago. Applies the cycle-length adjustment most calculators skip, and the ACOG Committee Opinion 700 thresholds for when a scan should replace the period-based date. Dates must be YYYY-MM-DD; free-form dates are refused. A due date is a reference point, not a pred","inputSchema":{"type":"object","$schema":"https://json-schema.org/draft/2020-12/schema","required":["method","date"],"properties":{"lmp":{"type":"string"},"asOf":{"type":"string"},"date":{"type":"string"},"method":{"enum":["lmp","conception","ivf-day3","ivf-day5","ultrasound"],"type":"string"},"scanDays":{"type":"number"},"scanWeeks":{"type":"number"},"cycleLength":{"type":"number"}}},"title":"Due date and gestational age, with ACOG redating applied (Due Date)","annotations":{"readOnlyHint":true,"untrustedContentHint":true},"logicalName":"due_date","displayName":"Due date and gestational age, with ACOG redating applied (Due Date)"},{"name":"round_cash_total","description":"Settle a transaction: exact subtotal, tax computed on that exact subtotal, then round the final total to the nearest nickel — and ONLY for cash. Card, EFT and gift-card payments stay priced to the cent, so the same basket legitimately comes to two amounts. Rounding applies to the TOTAL, never per item. A final digit of 1, 2, 6 or 7 rounds down; 3, 4, 8 or 9 rounds up. A string amount is read as dollars, a number as integer cents. Not legal or tax advice — there was no federal rounding law as of","inputSchema":{"type":"object","$schema":"https://json-schema.org/draft/2020-12/schema","required":["subtotal"],"properties":{"rule":{"enum":["symmetric","always-down","always-up","none"],"type":"string"},"tender":{"enum":["cash","card"],"type":"string"},"subtotal":{"type":"string"},"taxRatePercent":{"type":"number"}}},"title":"Round a cash total the way the post-penny rules work (Penny Rounding)","annotations":{"readOnlyHint":true,"untrustedContentHint":true},"logicalName":"round_cash_total","displayName":"Round a cash total the way the post-penny rules work (Penny Rounding)"},{"name":"rounding_impact","description":"Compute the mean rounding delta per cash transaction across a price list. Answers \"does rounding make retailers money\" with arithmetic rather than a guess: symmetric rounding nets to essentially zero by construction. Pass always-up to quantify the \"just round everything up\" idea, which is worth about 2 cents a sale and which no jurisdiction has adopted for retail.","inputSchema":{"type":"object","$schema":"https://json-schema.org/draft/2020-12/schema","required":["prices"],"properties":{"rule":{"enum":["symmetric","always-down","always-up","none"],"type":"string"},"prices":{"type":"string"},"taxRatePercent":{"type":"number"}}},"title":"What cash rounding is actually worth (Penny Rounding)","annotations":{"readOnlyHint":true,"untrustedContentHint":true},"logicalName":"rounding_impact","displayName":"What cash rounding is actually worth (Penny Rounding)"},{"name":"price_band","description":"For a list price and a tax rate, finds every nearby list price that settles to the SAME cash total, and the highest one. Use it for \"what should I charge\" and \"can I price to gain from rounding\" questions.","inputSchema":{"type":"object","$schema":"https://json-schema.org/draft/2020-12/schema","required":["listPrice"],"properties":{"listPrice":{"type":"string"},"spreadCents":{"type":"integer","maximum":9007199254740991,"minimum":-9007199254740991},"taxRatePercent":{"type":"number"}}},"title":"Find every list price that settles to the same cash total (Penny Rounding)","annotations":{"readOnlyHint":true,"untrustedContentHint":true},"logicalName":"price_band","displayName":"Find every list price that settles to the same cash total (Penny Rounding)"},{"name":"offside","description":"Returns a verdict plus every step taken. THREE verdicts, not two: offside, onside, and no-offside-offence — the last is real and common, because in soccer an offside POSITION is not an offence without involvement in active play. Soccer: hands and arms never count (boundary at the bottom of the armpit), there is no offence direct from a throw-in, goal kick or corner, and a DELIBERATE play by an opponent resets it while a deflection does not. Hockey: skates decide it, not the stick, and since 2021","inputSchema":{"type":"object","$schema":"https://json-schema.org/draft/2020-12/schema","required":["sport"],"properties":{"ball":{"type":"number"},"sport":{"enum":["soccer","hockey"],"type":"string"},"restart":{"enum":["open-play","throw-in","goal-kick","corner-kick","free-kick","kick-off","drop-ball"],"type":"string"},"attacker":{"type":"number"},"rearSkate":{"type":"number"},"situation":{"enum":["zone-entry","tag-up"],"type":"string"},"skateOnIce":{"type":"boolean"},"involvement":{"enum":["none","interfering-with-play","interfering-with-opponent","gaining-advantage"],"type":"string"},"secondLastDefender":{"type":"number"}}},"title":"Work an offside call through IFAB Law 11 or NHL Rule 83 (Sports Rules)","annotations":{"readOnlyHint":true,"untrustedContentHint":true},"logicalName":"offside","displayName":"Work an offside call through IFAB Law 11 or NHL Rule 83 (Sports Rules)"},{"name":"offside_rule_contrast","description":"Returns the structural differences between soccer offside and hockey offside, one dimension at a time. Use it when someone asks how the two compare, and — more usefully — before reasoning about one sport using an intuition from the other, which is the commonest way to get either wrong.","inputSchema":{"type":"object","$schema":"https://json-schema.org/draft/2020-12/schema","properties":{}},"title":"Contrast soccer and hockey offside, dimension by dimension (Sports Rules)","annotations":{"readOnlyHint":true,"untrustedContentHint":true},"logicalName":"offside_rule_contrast","displayName":"Contrast soccer and hockey offside, dimension by dimension (Sports Rules)"},{"name":"check_digit_run","description":"Checks the check digit on an IBAN (ISO 7064 MOD 97-10), ISBN-10, ISBN-13, EAN-13, UPC-A, or a Luhn-checked card number. When the checksum fails it searches for the single substitution or adjacent transposition that would repair it, so the answer is which character to fix rather than merely that something is wrong. Reports the ambiguity when more than one fix would work. Refuses an IBAN whose country code is not in the length registry rather than assuming a length, and requires the format to be n","inputSchema":{"type":"object","$schema":"https://json-schema.org/draft/2020-12/schema","required":["input","format"],"properties":{"input":{"type":"string"},"format":{"enum":["iban","isbn10","isbn13","ean13","upca","luhn"],"type":"string"}}},"title":"Validate a check digit and localise a single-digit error (Check Digit Validator)","annotations":{"readOnlyHint":true,"untrustedContentHint":true},"logicalName":"check_digit_run","displayName":"Validate a check digit and localise a single-digit error (Check Digit Validator)"},{"name":"amortize_schedule","description":"Returns the full row-by-row schedule: per-period interest, scheduled principal, any extra principal, PMI, payment and running balance. Handles monthly or daily accrual (daily needs a start date, so leap years follow from the calendar rather than an assumption), biweekly payments, one-off or recurring extra principal, and PMI termination under the Homeowners Protection Act at 78% or 80% of the ORIGINAL value — plus the midpoint trigger that ends PMI regardless of balance. The final payment differ","inputSchema":{"type":"object","$schema":"https://json-schema.org/draft/2020-12/schema","required":["principal","annualRatePercent","termMonths"],"properties":{"principal":{"type":"number"},"startDate":{"type":"string"},"termMonths":{"type":"number"},"compounding":{"enum":["monthly","daily"],"type":"string"},"dayCountBasis":{"enum":["30/360","actual/365","actual/actual"],"type":"string"},"paymentFrequency":{"enum":["monthly","biweekly"],"type":"string"},"annualRatePercent":{"type":"number"}}},"title":"Build a loan amortization schedule (Amortization Schedule)","annotations":{"readOnlyHint":true,"untrustedContentHint":true},"logicalName":"amortize_schedule","displayName":"Build a loan amortization schedule (Amortization Schedule)"},{"name":"iso_week_run","description":"Converts calendar dates to ISO 8601 week-numbering dates and back, in either direction, and reports how many weeks an ISO year has.","inputSchema":{"type":"object","$schema":"https://json-schema.org/draft/2020-12/schema","required":["input"],"properties":{"input":{"type":"string"}}},"title":"Convert between dates and ISO week numbers (ISO Week Number)","annotations":{"readOnlyHint":true,"untrustedContentHint":true},"logicalName":"iso_week_run","displayName":"Convert between dates and ISO week numbers (ISO Week Number)"},{"name":"validate_json","description":"Validates a JSON document and reports every problem in one pass with a 1-based line and column, a stable rule code and a fix hint. Reports the three things JSON.parse cannot: duplicate keys (accepted by every parser, which then disagree about which value wins), integer precision loss past 2^53-1 proved with exact BigInt arithmetic (any 64-bit ID is in the lossy range), and unpaired surrogates that parse here and fail on re-serialisation. Also trailing commas, comments, single quotes, unquoted ke","inputSchema":{"type":"object","$schema":"https://json-schema.org/draft/2020-12/schema","required":["input"],"properties":{"input":{"type":"string"}}},"title":"Validate JSON (Payload Validator)","annotations":{"readOnlyHint":true,"untrustedContentHint":true},"logicalName":"validate_json","displayName":"Validate JSON (Payload Validator)"},{"name":"validate_yaml","description":"Validates a YAML document, including the values that mean different things to different loaders — found by resolving each unquoted scalar under both spec versions and comparing, not by matching a list of words. In YAML 1.1 (PyYAML) the bare words no/yes/on/off/y/n are booleans, so a country list loses Norway and the \"on:\" key of every GitHub Actions workflow is really the key true; 0755 is 493 under 1.1 and 755 under 1.2, both numbers so nothing looks wrong; 1:30 is the base-60 integer 90. Also","inputSchema":{"type":"object","$schema":"https://json-schema.org/draft/2020-12/schema","required":["input"],"properties":{"input":{"type":"string"}}},"title":"Validate YAML (Payload Validator)","annotations":{"readOnlyHint":true,"untrustedContentHint":true},"logicalName":"validate_yaml","displayName":"Validate YAML (Payload Validator)"},{"name":"validate_xml","description":"Validates XML for well-formedness, namespace correctness and entity-based attacks. Catches four classes of invalid XML that ordinary well-formedness checkers accept: two root elements, undeclared namespace prefixes (well-formed as raw XML and rejected by XPath, XSLT, SOAP and every schema validator), undeclared entities such as the HTML-only &nbsp;, and a bare ampersand — usually inside a URL. Security findings for input you did not write: external entity declarations (XXE, reported with the URI","inputSchema":{"type":"object","$schema":"https://json-schema.org/draft/2020-12/schema","required":["input"],"properties":{"input":{"type":"string"}}},"title":"Validate XML (Payload Validator)","annotations":{"readOnlyHint":true,"untrustedContentHint":true},"logicalName":"validate_xml","displayName":"Validate XML (Payload Validator)"},{"name":"validate_csv","description":"Validates CSV against RFC 4180 and reports ragged rows individually with both field counts, because \"row 4813 has 6 fields, the header has 5\" is the entire answer. A ragged row loads without complaint almost everywhere — pandas pads or throws by engine, Excel shifts the columns, split(\",\") mis-assigns every field after the extra one — so nobody notices until a figure is wrong. Sniffs the delimiter from the header ignoring quoted regions, and always reports it, because a semicolon-separated Europ","inputSchema":{"type":"object","$schema":"https://json-schema.org/draft/2020-12/schema","required":["input"],"properties":{"input":{"type":"string"},"delimiter":{"type":"string","maxLength":1,"minLength":1},"hasHeader":{"type":"boolean"}}},"title":"Validate CSV (Payload Validator)","annotations":{"readOnlyHint":true,"untrustedContentHint":true},"logicalName":"validate_csv","displayName":"Validate CSV (Payload Validator)"},{"name":"validate_auto","description":"Detects whether a payload is JSON, YAML, XML or CSV, then validates it. Use it for a file with no extension, a clipboard paste, or a response body with an unhelpful content type. Detection is structural and the reason is always returned, so the assumption is visible: a leading \"<\" is XML, \"{\" or \"[\" is JSON, a %YAML directive or key: value lines are YAML, a consistent delimiter count across lines is CSV. JSON is checked before YAML deliberately, since JSON is a strict subset of YAML 1.2. If the","inputSchema":{"type":"object","$schema":"https://json-schema.org/draft/2020-12/schema","required":["input"],"properties":{"input":{"type":"string"}}},"title":"Detect the format and validate (Payload Validator)","annotations":{"readOnlyHint":true,"untrustedContentHint":true},"logicalName":"validate_auto","displayName":"Detect the format and validate (Payload Validator)"},{"name":"equation_steps_run","description":"Solves a linear or quadratic equation in one variable and returns every step: expanding parentheses, combining like terms, moving terms across the equals sign, and applying the quadratic formula with the discriminant stated. Reports identities and contradictions as such rather than as \"no answer\", gives roots as exact fractions with a decimal alongside, and labels complex roots explicitly instead of claiming no solution. Refuses rather than guesses on a missing or duplicated \"=\", a second variab","inputSchema":{"type":"object","$schema":"https://json-schema.org/draft/2020-12/schema","required":["input"],"properties":{"input":{"type":"string"}}},"title":"Solve an equation and show every step (Equation Steps)","annotations":{"readOnlyHint":true,"untrustedContentHint":true},"logicalName":"equation_steps_run","displayName":"Solve an equation and show every step (Equation Steps)"}],"toolSource":"directory_preview","agentAction":"both","installLinks":[{"id":"cursor","label":"Cursor","href":"cursor://anysphere.cursor-deeplink/mcp/install?name=Project-Gumball&config=eyJ1cmwiOiAiaHR0cHM6Ly9ndW1iYWxsdG9vbHMuY29tL2FwaS9tY3AifQ%3D%3D"},{"id":"vscode","label":"VS Code","href":"vscode:mcp/install?%7B%22name%22%3A%22Project-Gumball%22%2C%22type%22%3A%22http%22%2C%22url%22%3A%22https%3A%2F%2Fgumballtools.com%2Fapi%2Fmcp%22%7D"},{"id":"vscode-insiders","label":"VS Code Insiders","href":"vscode-insiders:mcp/install?%7B%22name%22%3A%22Project-Gumball%22%2C%22type%22%3A%22http%22%2C%22url%22%3A%22https%3A%2F%2Fgumballtools.com%2Fapi%2Fmcp%22%7D"},{"id":"claude-web","label":"Claude.ai","href":"https://claude.ai/customize/connectors?modal=add-custom-connector&connectorName=Project+Gumball&connectorUrl=https%3A%2F%2Fgumballtools.com%2Fapi%2Fmcp"},{"id":"codex","label":"Codex","copyText":"codex mcp add \"Project-Gumball\" --url \"https://gumballtools.com/api/mcp\""},{"id":"chatgpt","label":"ChatGPT","href":"https://www.mcpbundles.com/docs/integrations/chatgpt"}],"catalogUrl":"https://www.mcpbundles.com/api/directory/v1/servers/gumballtools-mcp-488eb97722","callUrl":"https://www.mcpbundles.com/api/directory/v1/servers/gumballtools-mcp-488eb97722/tools/{tool}","mcpServerUrl":"https://gumballtools.com/api/mcp","liveCatalogUrl":"https://www.mcpbundles.com/api/directory/v1/servers/gumballtools-mcp-488eb97722?live=1"}