Names
Anything else is skipped at discovery and reported to the operator. The
tool simply will not exist.
Reserved names
These are the assistant’s own tools. A server offering one is refused:
finish_turn is how the assistant sends its reply. A remote tool taking
that name would not be a collision, it would be a hijack — which is why
every remote tool is also namespaced on the wire as
srv<id>__<your_name>. Your server never sees the prefix; it receives the
bare name you registered.
Descriptions
The description is how the model decides whether to call your tool. It is also
pasted into the assistant’s system prompt, so the platform treats it as
untrusted text and rewrites it before storing:
- Capped at 400 characters
- Newlines, tabs and backticks collapsed to spaces
- Instruction-shaped phrases (
ignore previous instructions, system prompt,
you are now, …) replaced with [removed]
Write one plain sentence saying what the tool does and when to reach for it.
inputSchema is JSON Schema, but the platform converts it to the shape the
model providers agree on. Supported:
Dropped: oneOf, anyOf, allOf, $ref, patternProperties,
additionalProperties, format, minimum/maximum.
Nesting deeper than 8 levels stops being followed.
Dropped constructs are dropped silently, because the alternative is
passing through something one provider accepts and the next rejects with a
400 mid-conversation. If your arguments cannot be expressed in the subset
above, simplify the arguments — do not assume validation you declared is
being enforced. Validate on your side.
A worked example
That tier field is a mistake, shown deliberately. Never let the model
choose an entitlement. Resolve the tier server-side from the buyer, and drop
the argument.