Test regex patterns, find all matches with offsets, and replace text via @mukundakatta/regex-test-mcp (npx)
@mukundakatta/regex-test-mcp v latest
3-tool MCP server for trustworthy JavaScript regex testing — returns real match offsets, group dicts, and full vs partial match info.
Setup
npx @mukundakatta/regex-test-mcp # stdio transport, zero configTools
| Tool | Params | Returns |
|---|---|---|
test_regex | pattern, text, flags? | First match: {matched, match, start, end, groups, named_groups} |
find_all | pattern, text, flags? | All non-overlapping matches (auto-adds g flag): {matches: [...], count} |
replace | pattern, text, replacement, flags? | {result, replaced} — supports $1, $<name>, $& backrefs |
Note: pattern is the JS regex body (no surrounding / slashes). flags is a string like "i", "gm", "isu".
Verified Traces
1. test_regex — email pattern (case-insensitive):
→ {"pattern": "[\\w.+-]+@[\\w-]+\\.[a-z]{2,}", "text": "Contact us at [email protected] or [email protected]", "flags": "i"}
← {"matched": true, "match": "[email protected]", "start": 14, "end": 30, "groups": [], "named_groups": {}}2. test_regex — no match returns `{matched: false}`:
→ {"pattern": "\\d{3}-\\d{4}", "text": "No phone numbers here"}
← {"matched": false}3. test_regex — named capture groups:
→ {"pattern": "(?<year>\\d{4})-(?<month>\\d{2})-(?<day>\\d{2})", "text": "Date: 2026-06-14 is today"}
← {"matched": true, "match": "2026-06-14", "start": 6, "end": 16, "groups": ["2026", "06", "14"], "named_groups": {"year": "2026", "month": "06", "day": "14"}}4. find_all — extract all capitalized words:
→ {"pattern": "\\b[A-Z][a-z]+\\b", "text": "The Quick Brown Fox Jumps Over The Lazy Dog"}
← {"matches": [{"match": "The", "start": 0, "end": 3}, {"match": "Quick", "start": 4, "end": 9}, ...], "count": 8}5. find_all — extract URLs:
→ {"pattern": "https?://[\\w.-]+(?:/[\\w./?%&=-]*)?", "text": "Visit https://tani.ai and http://example.com/path?q=1"}
← {"matches": [{"match": "https://tani.ai", "start": 6, "end": 21}, {"match": "http://example.com/path?q=1", "start": 26, "end": 53}], "count": 2}6. find_all — hex colors:
→ {"pattern": "#[0-9a-fA-F]{3,8}\\b", "text": "Colors: #ff0000, #0f0, #336699cc, text #abc"}
← {"count": 4} // #ff0000, #0f0, #336699cc, #abc7. replace — mask emails:
→ {"pattern": "([\\w.+-]+)@([\\w-]+\\.[a-z]{2,})", "text": "Email: [email protected] and [email protected]", "replacement": "***@$2", "flags": "gi"}
← {"result": "Email: ***@example.com and ***@test.org", "replaced": true}8. replace — named group backrefs (ISO → US date format):
→ {"pattern": "(?<y>\\d{4})-(?<m>\\d{2})-(?<d>\\d{2})", "text": "Dates: 2026-06-14 and 2025-12-25", "replacement": "$<m>/$<d>/$<y>", "flags": "g"}
← {"result": "Dates: 06/14/2026 and 12/25/2025", "replaced": true}9. test_regex — Unicode property escapes (`\\p{Script=Latin}`):
→ {"pattern": "[\\p{Script=Latin}]+", "text": "Hello мир 世界 مرحبا", "flags": "u"}
← {"matched": true, "match": "Hello", "start": 0, "end": 5}10. find_all — multiline `^` anchor:
→ {"pattern": "^\\w+", "text": "first\nsecond\nthird", "flags": "m"}
← {"matches": [{"match": "first"}, {"match": "second"}, {"match": "third"}], "count": 3}11. replace — camelCase to kebab-case:
→ {"pattern": "([a-z])([A-Z])", "text": "backgroundColor fontSize borderRadius", "replacement": "$1-$2", "flags": "g"}
← {"result": "background-Color font-Size border-Radius", "replaced": true}Note: produces background-Color not background-color — you need a second pass or toLowerCase() to finish kebab conversion.
12. test_regex — lookahead:
→ {"pattern": "\\d+(?= dollars)", "text": "I have 42 dollars and 15 euros"}
← {"matched": true, "match": "42", "start": 7, "end": 9}Key observations
- 12/12 calls succeeded, p50=0.6ms, first call ~2.9ms
- **Nam