diff --git a/index.bs b/index.bs
index 847677e..3f38945 100644
--- a/index.bs
+++ b/index.bs
@@ -2149,6 +2149,66 @@ page, protecting against malicious scripts or dependencies from using WebMCP API
**How:** This restriction would not fully solve prompt injection attacks but helps shrink the possible universe of attacks, preventing longer prompts that leverage e.g. repetition and sockpuppetting [[SOCKPUPPETTING]] to convince agents of malicious tasks. The specification already implements a nominal size restriction of 128 characters for the tool {{ModelContextTool/name}} (see [[#supporting-concepts]]), but further work is needed to evaluate the right size limits for titles, names, and other inputs. See [Issue #73](https://github.com/webmachinelearning/webmcp/issues/73).
+
Handling invisible characters in tool metadata
+
+**What:** Rejecting tool registrations with invisible characters in metadata, rather than silently
+removing those characters.
+
+**Threats addressed:** [[#metadata-description-attacks]]
+
+**How:** A tool's {{ModelContextTool/title}}, {{ModelContextTool/description}}, and the strings in
+its {{ModelContextTool/inputSchema}} and {{ModelContextTool/outputSchema}} can contain characters
+that take no space on screen: Unicode tag characters (U+E0000 to U+E007F), which can encode ASCII
+text, zero-width characters, and bidirectional formatting controls that change the displayed order of
+text. An instruction hidden this way is no more persuasive to a model than a visible one, but it is
+missed by anything that relies on the displayed text, such as code review, a tool list or
+confirmation prompt shown to the user, or a guardrail that matches keywords or uses a small model.
+This matters most when a script that the site author does not control registers tools on the page.
+Tool names are limited to ASCII (see [[#supporting-concepts]]) and are not affected. Length limits
+([[#mitigation-restrict-input-lengths]]) do not help, because many of these characters fit within any
+practical limit.
+
+Rejecting a registration lets the developer fix the text rather than having the host silently change
+it. Stripping descriptive text changes what the developer wrote; stripping property names or values
+such as `enum`, `const`, and `default` also changes what the tool accepts or receives. Implementers
+considering registration-time validation are encouraged to:
+
+ - Define the rejected character set using the Unicode
+ [Default_Ignorable_Code_Point](https://www.unicode.org/reports/tr44/#Default_Ignorable_Code_Point)
+ property as a baseline, rather than a hand-written list. This includes tag characters, zero-width
+ characters, bidirectional controls, and Hangul fillers. Use the same Unicode version and explicitly
+ defined exceptions across implementations, so the same metadata is not accepted by one browser
+ and rejected by another.
+ - Inspect [=code points=], not individual UTF-16 code units. Tag characters are represented by
+ [=surrogate=] pairs, so a per-code-unit range check misses them. Reject lone surrogates in
+ {{ModelContextTool/description}} and parsed schema strings as well, rather than replacing or
+ removing them. The {{ModelContextTool/title}} is a {{USVString}}, whose conversion already
+ replaces lone surrogates.
+ - Check {{ModelContextTool/title}}, {{ModelContextTool/description}}, and both schemas. After
+ [=serializing a tool schema=], inspect the parsed JSON recursively, including every object member
+ name and string value, not only schema descriptions. This covers property names and strings nested
+ in `enum`, `const`, and `default`, and resolves `\uXXXX` escapes before checking. Checking the
+ serialized representation also covers changes made by a schema's `toJSON()` method, rather than
+ inspecting only the original JavaScript object. Reject the registration if any checked string
+ contains a disallowed character; do not rewrite the schema.
+ - Account for legitimate uses of these characters. A blanket rejection also rejects emoji with
+ U+FE0F VARIATION SELECTOR-16, emoji sequences using U+200D ZERO WIDTH JOINER, the England,
+ Scotland, and Wales flag tag sequences, and spellings that need U+200C ZERO WIDTH NON-JOINER in
+ Persian and Indic languages. If exceptions are chosen, define them in terms of well-formed
+ sequences and their context, not unrestricted permission for those characters: standalone or
+ repeated invisible characters can still carry hidden data.
+ - Provide a diagnostic identifying the offending code point (for example, `U+E0061`) or lone
+ surrogate, and its location, such as the title, description, or a path within a schema. Render the
+ offending character as a visible escape, rather than embedding it invisibly in the message, so
+ the developer can locate and fix it.
+ - Show the user the same accepted text that is given to the model when asking for approval.
+ Do not sanitize only the approval UI while passing unmodified hidden text to the model.
+
+
+This guidance does not add a rejection step to {{ModelContext/registerTool()}}. A normative
+registration check would need an interoperable definition of the Unicode version, any exceptions,
+the schema checks, and the rejection behavior.
+
Supporting interoperable probabilistic defense structures through shared attack eval datasets
**What:** Shared evals for prompt injection attacks against WebMCP