Wapgee Logowapgee

LLM Tool & Function Schema Builder

Build Claude and OpenAI function-calling schemas with a form UI, both formats, runs in your browser. Copy JSON, Python, or TypeScript — nothing is uploaded.

Form2/50 params

Describe what the tool does, when to use it, and what it returns — the model chooses tools based on this text.

Parameters
  • Allowed values
Copy as code
{
  "name": "get_weather",
  "description": "Get the current weather in a given location",
  "input_schema": {
    "type": "object",
    "properties": {
      "location": {
        "type": "string",
        "description": "The city and state, e.g. San Francisco, CA"
      },
      "unit": {
        "type": "string",
        "enum": [
          "celsius",
          "fahrenheit"
        ],
        "description": "The unit of temperature, either 'celsius' or 'fahrenheit'"
      }
    },
    "required": [
      "location"
    ]
  }
}

What tool calling actually is

When you give a language model a list of tools, you are not giving it code to run. You are giving it a menu: for each tool, a name, a sentence or two about what it does, and a JSON Schema describing the arguments it takes. The model reads the menu, decides that a request needs one of the tools, and replies with a structured object such as { "name": "get_weather", "input": { "city": "Oslo" } }. Your application runs the real function, sends the result back, and the model continues from there.

Everything about whether that goes well, from picking the right tool to filling in the right arguments, depends on the definition you wrote. This builder turns the definition into a form so you can concentrate on the names and descriptions instead of balancing braces, and shows the Claude and OpenAI JSON updating as you type. Nothing is sent anywhere; the tools you save live in your browser.

Anatomy of a tool definition

Form
name: get_weather
description: Current weather for a city. Use
  when the user asks about conditions now,
  not forecasts.

params:
  city   string  required  City name, e.g. "Oslo"
  units  enum              celsius | fahrenheit
Anthropic JSON
{
  "name": "get_weather",
  "description": "Current weather for a city. Use when the user asks about conditions now, not forecasts.",
  "input_schema": {
    "type": "object",
    "properties": {
      "city": {
        "type": "string",
        "description": "City name, e.g. \"Oslo\""
      },
      "units": {
        "type": "string",
        "enum": ["celsius", "fahrenheit"]
      }
    },
    "required": ["city"]
  }
}

Three parts matter. The name is an identifier of up to 64 letters, digits, underscores, or hyphens; the model uses it verbatim, so search_orders beats tool1. The description is the text the model reads to decide whether to call the tool at all. The schema is a JSON Schema object whose properties become the arguments, with required listing the ones the model must always supply. When nothing is required the key is omitted rather than emitted as an empty array, matching the providers' own examples.

Anthropic versus OpenAI format

Both providers accept the same JSON Schema for the arguments. What differs is the envelope around it, which is why the output has tabs. Claude's Messages API wants { name, description, input_schema }. OpenAI's Chat Completions API wraps the same information as { type: "function", function: { name, description, parameters } }. OpenAI's newer Responses API flattens name, description, and parameters onto the tool object and commonly adds strict: true.

OpenAI (Chat Completions)
{
  "type": "function",
  "function": {
    "name": "get_weather",
    "description": "...",
    "parameters": { "type": "object", ... }
  }
}
Raw JSON Schema tab
{
  "type": "object",
  "properties": { ... },
  "required": ["city"]
}

The third tab gives you the bare schema for anything else that consumes JSON Schema: a validator, an OpenAPI document, or a framework such as LangChain or the Vercel AI SDK that builds its own envelope. The Python and TypeScript views wrap whichever tab is active in a literal you can paste straight into a script.

Writing descriptions the model can act on

The description is the single most important field and the one most people leave short. A label like "weather tool" tells the model nothing about when to use it. Anthropic's own guidance is to write several sentences that cover four things:

  • What the tool does and what it returns.
  • When it should be called, and just as usefully, when it should not. "Use for current conditions; do not use for forecasts" prevents a whole class of wrong calls.
  • What each parameter means, with an example value where the format is not obvious, such as a date format or an id prefix.
  • Limits and failure modes: rate limits, what happens for an unknown city, whether results are paginated.

The builder warns when a description is under 20 characters and when a parameter has none, and flags names like data, input, or value that give the model nothing to ground on. Those are warnings, not errors, because sometimes a short description is genuinely enough; the point is to make the choice deliberate.

Designing the parameters

  • Mark required fields honestly. Only the arguments your handler cannot do without. Everything else is optional, and the description should say what the default is.
  • Use enums for closed sets. A units parameter with celsius | fahrenheit stops the model inventing "C" or "metric".
  • Prefer flat structures. Nested objects and arrays of objects are supported to three levels, which covers a repo.owner or a list of line items. Beyond that, split the tool or accept a JSON string and document its shape.
  • Keep the count down. The form caps a tool at 50 parameters. Long before that, a tool with a dozen arguments is usually two tools.
  • Use integer when you mean it. number permits 2.5; a page number or a count should be integer.

Importing, editing, and keeping a toolkit

Paste an existing definition into Import and the form fills in from it. Anthropic JSON, either OpenAI shape, a raw JSON Schema object, or an array of any of those are all recognised, and a failed parse leaves your current work untouched. That makes the builder a quick way to review a schema someone else wrote: the warnings show you where descriptions are missing before the model finds out.

Saved tools appear in the sidebar and persist in your browser's local storage, so a small toolkit for a project survives a refresh. Export all copies every saved tool as a JSON array in the active tab's format, ready to drop into the tools argument of an API call.

Where it fits

  • Drafting the first version of an agent's tools before any handler code exists, so the team can agree on names and arguments.
  • Porting a tool set from one provider to the other without re-typing the schema.
  • Auditing a large tool list for vague descriptions and generic parameter names.
  • Producing a clean example for documentation or a blog post.

Tool definitions are sent with every request and count as input tokens; paste the exported array into the token counter to see what a large toolkit costs per call. If you have a JSON Schema already and need TypeScript types for the arguments, the JSON Schema to TypeScript and Zod converter generates them.

Tool calling is only as good as the schema

Function calling (Anthropic calls it tool use) is how an LLM asks your application to do something: fetch weather, open a ticket, query a database. The model never runs your code. It returns a structured argument object that must match the JSON Schema you declared. A vague description, a missing required array, or a property with no explanation is how agents call the wrong tool or invent fields. This builder turns that declaration into a form so you can see Claude and OpenAI JSON update live, without balancing braces by hand.

Anthropic vs OpenAI format

Both providers take a JSON Schema object of { "type": "object", "properties": … }. The envelope around that schema is what differs, and it is a common search question on its own:

Anthropic (Claude)OpenAI (Chat Completions)
Envelopename, description, input_schematype: "function", nested function object
Schema fieldinput_schemafunction.parameters
Name pattern^[a-zA-Z0-9_-]{1,64}$Same identifier rules in practice
Empty requiredOmit the key when nothing is requiredSame — do not emit an empty array

OpenAI’s newer Responses API flattens name / description / parameters onto the tool object and often sets strict: true. This page emits the Chat Completions envelope (still what most SDKs paste) and will import either shape.

Editing, not just authoring

Paste an existing tool JSON into Import to populate the form. Failed parses leave your work alone. Saved tools live in localStorage so a small toolkit survives a refresh; Export all copies a JSON array in the active tab’s format. Nested object parameters (and arrays of objects) go two or three levels deep — enough for a repo.owner style argument without turning the form into a schema IDE.

Need types from a payload instead of a tool definition? Use the JSON ⇌ YAML ⇌ TypeScript converter. A companion write-up on designing tool definitions agents actually follow is planned; until then, prefer specific names, required fields that the handler truly needs, and descriptions that mention failure modes.

Free tools. No signup, nothing leaves your browser.

FAQ

Does this work for both Claude and GPT?

Yes. The Anthropic tab emits { name, description, input_schema } for Claude’s Messages API. The OpenAI tab emits the Chat Completions envelope { type: "function", function: { name, description, parameters } }. Import also accepts the flattened Responses API shape.

Is anything sent to a server?

No. The builder, import parser, and copy buttons run entirely in your browser. Schemas stay in localStorage on this device.

Can I import an existing schema?

Yes. Paste Anthropic JSON, OpenAI Chat Completions JSON, OpenAI Responses JSON, or a raw JSON Schema object. If parsing fails, the form is left untouched. A JSON array loads as a toolkit in the sidebar.

What is a good tool description?

Say what the tool does, when the model should call it (and when it should not), what each parameter means, and what it returns. Anthropic’s own guidance is several sentences, not a label. Vague names like data, input, or value also hurt tool selection.