Skip to content

Ayubjon/schema-morph

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

11 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

schema-morph

Convert LLM tool/function schemas between OpenAI, Anthropic, and Gemini formats — CLI and Node.js library, zero dependencies.

demo

Every major LLM provider stores tool/function schemas differently:

Provider Field name Type casing
OpenAI parameters "object" (lowercase)
Anthropic input_schema "object" (lowercase)
Gemini parameters "OBJECT" (UPPERCASE)

schema-morph handles all 6 conversion directions automatically, including deeply nested objects, arrays, enum, required, and all scalar types.

Install

npm install -g schema-morph
# or use directly
npx schema-morph --help

CLI usage

# Convert a single tool from OpenAI → Anthropic format
schema-morph --from openai --to anthropic tool.json

# Pipe JSON directly
echo '{"type":"function","function":{"name":"ping","parameters":{"type":"object","properties":{}}}}' \
  | schema-morph --from openai --to anthropic

# Anthropic → Gemini (note: Gemini types become UPPERCASE)
schema-morph --from anthropic --to gemini tool.json

# Gemini → OpenAI
schema-morph --from gemini --to openai tool.json

# Batch mode: one schema per line (JSONL), output is also JSONL
schema-morph --from openai --to anthropic --batch tools.jsonl

# Validate a schema against a format (exit 0 = valid, exit 1 = invalid)
schema-morph --validate --format gemini tool.json

Supported formats

Token Description
openai OpenAI function/tool schema — both legacy {name, parameters} and new {type:"function", function:{...}} forms
anthropic Anthropic tool schema with input_schema
gemini Gemini function declaration with UPPERCASE type names

Node.js API

import { convert, convertBatch, validateFormat } from 'schema-morph';

// Convert a single schema
const anthropicTool = convert(openaiTool, { from: 'openai', to: 'anthropic' });

// Convert an array of schemas
const geminiTools = convertBatch(openaiTools, { from: 'openai', to: 'gemini' });

// Validate a schema
const { valid, errors } = validateFormat(tool, 'gemini');
if (!valid) console.error(errors);

convert(schema, { from, to })

Parameter Type Description
schema object Source schema object
from string Source format: 'openai', 'anthropic', or 'gemini'
to string Target format

Returns the converted schema object.

convertBatch(schemas, { from, to })

Same as convert but takes and returns an array.

validateFormat(schema, format)

Returns { valid: boolean, errors: string[] }.

Examples

OpenAI → Anthropic

// Input (OpenAI)
{
  "type": "function",
  "function": {
    "name": "get_weather",
    "description": "Get current weather",
    "parameters": {
      "type": "object",
      "properties": {
        "location": { "type": "string" }
      },
      "required": ["location"]
    }
  }
}

// Output (Anthropic)
{
  "name": "get_weather",
  "description": "Get current weather",
  "input_schema": {
    "type": "object",
    "properties": {
      "location": { "type": "string" }
    },
    "required": ["location"]
  }
}

Anthropic → Gemini

// Input (Anthropic)
{
  "name": "search",
  "input_schema": {
    "type": "object",
    "properties": {
      "query": { "type": "string" },
      "limit": { "type": "integer" }
    }
  }
}

// Output (Gemini — note UPPERCASE types)
{
  "name": "search",
  "parameters": {
    "type": "OBJECT",
    "properties": {
      "query": { "type": "STRING" },
      "limit": { "type": "INTEGER" }
    }
  }
}

Type mapping (Gemini ↔ others)

JSON Schema Gemini
"string" "STRING"
"number" "NUMBER"
"integer" "INTEGER"
"boolean" "BOOLEAN"
"array" "ARRAY"
"object" "OBJECT"
"null" "NULL"

Nested schemas (objects within objects, arrays of objects) are converted recursively.

Why

When building apps that target multiple LLM providers, you typically define tools once and need them in each provider's format. Doing this manually is tedious and error-prone — especially the Gemini uppercase types, which silently produce wrong schemas if forgotten.

Requirements

  • Node.js ≥ 18
  • Zero runtime dependencies

License

MIT © 2026 Ayubjon

Support

If this tool saved you time, an optional crypto tip is always welcome:

USDT (Ethereum ERC-20): 0xad39bdf2df0b8dd6991150fcea0a156150ed19b8

Verify on Etherscan — send only on the Ethereum (ERC-20) network.

About

Convert LLM tool/function schemas between OpenAI, Anthropic, and Gemini formats — CLI + zero-dep Node.js library

Topics

Resources

License

Stars

1 star

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors