GlyphGuard
Find hidden or deceptive Unicode in text (zero-width characters, bidi controls, hidden tag text, mixed scripts and lookalike letters), clean it, and check a name against up to 50 protected names for lookalikes. Free, with no sign-up and no API key; about 60 checks per minute per IP, up to 2,000 UTF-16 code units per text (about 2,000 characters for most text; emoji count as 2). Results are a screening signal, not a security guarantee. Nothing you submit is stored. GlyphGuard is not affiliated with the Unicode Consortium.
Hosted MCP Server
npx add-mcp 'https://glyphguard.mike-tusa.workers.dev/mcp'Installs into Claude Code, Codex, Cursor and more
Documentation
GlyphGuard
Paste any text to find characters you can't see or that only look like what they seem: zero-width characters, bidi controls (Trojan Source), hidden Unicode tag text, mixed-script words and lookalike letters such as a Cyrillic "а" in "pаypal". Nothing you paste is stored.
What it checks
Risk: high = bidi overrides/isolates, Unicode tag characters, mixed-script words or lookalikes inside them; medium = zero-width and other invisible characters, control characters, lookalike letters in Latin-looking words; low = variation selectors, unusual spaces, private-use characters; lone surrogates (malformed UTF-16) are medium. Joiners in legitimate context are info (type joiner_in_context, risk unchanged): ZWJ inside emoji ZWJ sequences, VS16 emoji presentation, ZWNJ/ZWJ between letters of joining scripts (Arabic, Persian) and after an Indic virama. ZWJ/ZWNJ anywhere else (for example inside an ASCII word) stay medium. clean keeps the in-context joiners by default (keep_joiners=true); strict=true removes them all. Offsets are UTF-16 code units (JavaScript string indexes). Up to 100 findings are listed; counts are always complete. Legitimate text in Cyrillic, Greek or CJK on its own is not flagged; only words that mix scripts are.
Emoji, Persian and Indic text are safe: zero-width joiners inside emoji like 🏳️🌈 and 👨👩👧👦, the Persian half-space in میخواهم and the Devanagari joiner in क्ष are shown as info and kept when cleaning. Add strict=true (or keep_joiners=false) to remove them anyway.
Text: up to 2000 UTF-16 code units, URL-encoded on GET (for example %E2%80%8B for a zero-width space). Names and targets: up to 128 characters each, 1-50 targets separated by | (or repeat target=). Booleans: true/false or 1/0.
JSON API
curl -s 'https://glyphguard.mike-tusa.workers.dev/api/scan?text=p%D0%B0ypal%E2%80%8B'
curl -s 'https://glyphguard.mike-tusa.workers.dev/api/compare?name=p%D0%B0ypal&targets=paypal|apple'
Routes: /api/scan, /api/clean and /api/compare (up to 50 protected names). No key needed: about 60 requests per minute per IP. OpenAPI 3.1 spec
For AI agents
GlyphGuard is also a remote Model Context Protocol (MCP) server with three read-only tools: scan_text, clean_text and compare_names. Agents can scan tool descriptions, retrieved pages or user input for hidden instructions before acting on them. Works with AI agents and assistants that can call an MCP server or a JSON API, for example Muse, Claude, ChatGPT or Cursor (descriptive only). Most MCP clients accept this config; some use a different format (for example, VS Code uses a servers key).
{ "mcpServers": { "glyphguard": { "type": "http", "url": "https://glyphguard.mike-tusa.workers.dev/mcp" } } }
Machine-readable docs: llms.txt · OpenAPI 3.1 spec · MCP server card. See Unicode TR #39. GlyphGuard is not affiliated with, endorsed by or sponsored by the Unicode Consortium, Meta, Anthropic, OpenAI or Anysphere. Results are a screening signal, not a security guarantee.