"Your MCP server's tool list can be refused before the model sees it: the rules three AI APIs applied to 21,812 lists" A developer tested 21,812 MCP server tool lists against the Batch APIs of Claude Haiku 5.5, GPT-5-nano and Gemini 2.5 Flash, finding that each vendor validates tool lists before the model sees them and applies its own rules, so the same list can be accepted by one API and refused by another. Common refusals included top-level oneOf/allOf/anyOf in input_schema (267 lists), non-conforming tool names (173), and, for OpenAI's API, more than 128 tools (171 lists, ranging up to 1,711). No MCP server was contacted and no tool was run; only published names, descriptions and schemas were sent. We read the tool lists of MCP servers in the official MCP registry. Then we sent each list, once, to three small AI models through their vendors' Batch APIs: Claude Haiku 5.5, GPT-5-nano and Gemini 2.5 Flash. Each model was set to its lowest reasoning level and got one fixed request. That was 21,812 tool lists, one per server, with answers dated 2026-10-25 to 2026-10-26 UTC . No MCP server was contacted and no tool was run. We sent only the tool names, descriptions and input schemas, exactly as each server publishes them. The finding most useful to server authors: each API checks the tool list before its model sees it, and each API has its own rules. The same list can be accepted by one API and refused by another. A refusal is the API's answer about the list as written. It is not a fault in the server's code, but it does mean that client never offers your tools to the model. Counts are tool lists, one per server, from our run. An API can have other rules, and can change them. | Rule | API message | Lists | |---|---|---| | oneOf / allOf / anyOf at the top level of input schema | input schema does not support oneOf, allOf, or anyOf at the top level | 267 | | Tool name outside ^ a-zA-Z0-9 - {1,128}$ | String should match pattern '^ a-zA-Z0-9 - {1,128}$' | 173 | | Two tools with the same name | Tool names must be unique. | 29 | | Schema not valid JSON Schema draft 2020-12 | JSON schema is invalid. It must match JSON Schema draft 2020-12 … | 6 | | Top-level property key outside ^ a-zA-Z0-9 .- {1,64}$ | Property keys should match pattern … | 4 | | Rule | API message | Lists | |---|---|---| | Top level not type: object , or has oneOf / anyOf / allOf / enum / const / not | schema must have type 'object' and not have 'oneOf'/'anyOf'/'allOf'/'enum'/'const'/'not' at the top level. | 262 | | More than 128 tools | Invalid 'tools': array too long. Expected an array with maximum length 128 … | 171 | | Tool name outside ^ a-zA-Z0-9 - +$ | string does not match pattern … | 167 | | A pattern it does not read as a regex every case used \p{…} Unicode classes | '^ \\p{L}\\p{N} - +$' is not a 'regex' | 19 | | A number in the schema too large | a numeric value in the function parameters is too large | 4 | | List longer than the input limit | Input tokens exceed the configured limit of 272000 tokens. | 3 | The 128-tool limit is not stated on the chat completions API reference page we read on 2026-10-25. The refused lists ranged from 129 to 1,711 tools. | Rule | API message | Lists | |---|---|---| | Tool name starts with a digit, or has a space, braces or square brackets | Invalid function name. Must start with a letter or an underscore. … | 7 | For 4 of those 7 lists, the names started with a digit. That meets the docs text we read, which gives no rule for the first character, but the API still refused them. Google's API also answered Request contains an invalid argument. for 135 more lists without naming a rule. Of those 135, 34 had tuple-style items an array of schemas and 30 had two tools with the same name. No list that Google's API answered had either. That is an association we measured, not a reason Google gave. From the rules above, a tool list is accepted by all three APIs in our run more often when: a-z A-Z 0-9 - , start with a letter, and stay at 64 characters or fewer. inputSchema is type: "object" at the top level, with no oneOf / anyOf / allOf / enum / const / not there. pattern values avoid \p{…} Unicode classes. items , not a tuple. They describe three small models on the dates shown, each at its lowest reasoning setting. They do not describe the vendors' other models or a real client with its own system prompt. They are not a judgment of any server or publisher. We do not rank the models. Each model's own figures are on the full page https://protocolprobe.com/updates/three-models , and each server's own API message is on its server page.