Convert OpenAI functions to Anthropic tools (and back) without hand-editing JSON
OpenAI functions, OpenAI Responses tools, Anthropic tools and plain JSON Schema all describe the same thing in slightly different JSON. My free tool schema converter detects which one you pasted, converts it to any of the others, can apply OpenAI strict mode for you and flags the mistakes that make a provider reject the tool. It runs in your browser.
Function calling (or tool use, depending on whose docs you're reading) is the same idea everywhere: you describe a tool with a name, a description and a JSON Schema for its arguments. Then every provider wraps that in its own envelope, and you spend twenty minutes moving parameters to input_schema and wondering why OpenAI's strict mode is angry at you.
I did that dance enough times switching a project between providers that I built a tool schema converter.
What's actually different between the formats?
Not much, which is exactly why it's so easy to get wrong.
| Format | Shape | Where the schema lives |
|---|---|---|
| JSON Schema | The schema itself | The root |
| Anthropic tool | { name, description, input_schema } | input_schema |
| OpenAI Chat Completions | { type: "function", function: { name, description, parameters } } | function.parameters |
| OpenAI Responses | { type: "function", name, description, parameters } | parameters (flat, no function wrapper) |
The same tool in OpenAI Chat Completions and Anthropic form:
{
"type": "function",
"function": {
"name": "get_weather",
"description": "Get the current weather for a city.",
"parameters": {
"type": "object",
"properties": { "city": { "type": "string" } },
"required": ["city"]
}
}
}
{
"name": "get_weather",
"description": "Get the current weather for a city.",
"input_schema": {
"type": "object",
"properties": { "city": { "type": "string" } },
"required": ["city"]
}
}
How do I convert between them?
flowchart LR
A[Paste any format] --> B{Detect}
B --> C[JSON Schema]
B --> D[Anthropic tool]
B --> E[OpenAI Chat function]
B --> F[OpenAI Responses function]
C & D & E & F --> G[Pick target tab]
G --> H[Checks + copy]- Paste a JSON Schema, an Anthropic tool or an OpenAI function into the converter. It works out which format you pasted.
- Pick the target tab: JSON Schema, Anthropic, OpenAI Chat or OpenAI Responses.
- Copy the result, after fixing anything the checks flag.
If you pasted a bare JSON Schema, there's no name to carry over, so you can type the tool's name and description in and they go into the output.
What are the alternatives?
| Approach | Good for | Watch out for | Honest assessment |
|---|---|---|---|
| Hand-editing JSON | One tool, once | Typos, forgotten wrappers, strict mode | Fine until the fifth tool. |
| SDK helpers (Zod or Pydantic to schema) | Generating schemas from types in code | Each SDK outputs its own provider's shape | The right answer inside a codebase. |
| Multi-provider libraries (LiteLLM, Vercel AI SDK) | Converting at runtime | Another dependency; you don't see the final JSON | Great if you're already using them. |
| Sidd's tool schema converter | Seeing and copying the exact JSON for each provider, with checks | Converts one tool at a time | The one for "I just need this JSON in the other shape". |
What does OpenAI strict mode change?
Turn on Strict for the OpenAI targets and the converter rewrites the schema the way strict function calling needs it: every object lists all its properties in required, and gets "additionalProperties": false, at every level of nesting. It also adds "strict": true to the definition.
What does it check?
The checks catch the errors that make a provider reject your tool, before you find out from a 400 response:
- A tool name is present and only uses letters, numbers, underscores and hyphens, up to 64 characters.
- There's a description (the model uses it to decide when to call the tool).
- The root of the schema is
"type": "object". - Every name in
requiredactually exists inproperties, including in nested objects and array items. - With strict on: every property is required and
additionalPropertiesisfalse, at every level.
Each issue names the path where it happens, like address.city, so you're not hunting through nested JSON.
Is my schema uploaded?
No. Parsing, conversion and checks run in your browser.
FAQ
How do I convert an OpenAI function to a Claude tool?
Paste the OpenAI function into the tool schema converter and open the Anthropic tab. The parameters schema becomes input_schema, and the name and description carry over.
What's the difference between OpenAI Chat Completions and Responses function definitions?
Chat Completions nests the definition inside a function object. The Responses API puts name, description and parameters at the top level next to "type": "function".
Can I convert a JSON Schema into a tool definition?
Yes. Paste the schema, type a name and description and pick the Anthropic or OpenAI tab.
Why does OpenAI strict mode reject my schema?
Strict mode needs every property listed in required and "additionalProperties": false on every object. Turn on Strict in the converter and it applies both for you.
What characters are allowed in a tool name?
Letters, numbers, underscores and hyphens, up to 64 characters. The converter flags anything else.
Want to try it?
Open the tool schema converter, paste the gnarliest tool definition you have and flip through the tabs. If you're also building the prompts that go with it, try the prompt template playground, and check what it'll cost with the token calculator. Everything's in free tools.
Want Gemini's format added? Email siddhant06137@gmail.com or say hi on X as @creatorsidd. Building agents and want help? Book a 15-minute call.