Skip to main content
OPEN SOURCE · MIT

schemafit

Lint your LLM structured-output & JSON schemas against OpenAI, Anthropic, Gemini, Mistral, and Cohere — and fail CI before they 400 in production.

Open source (MIT) · Static & offline · Zero runtime dependencies · CI-enforceable.

Watch schemafit in action

Download the demo video

Recorded output from schemafit v0.5.0, edited as a replay of a synthetic schema. Static versioned rules; no live provider calls or acceptance claim. Locally synthesized Dan narration.

Read the transcript

This is schemafit, a local schema linter. This synthetic order schema fails the bundled OpenAI rule pack. The output points to two missing constraints before any model call. Repair writes a new file and flags a lossy change. Making a property required can change what your application accepts, so review the diff instead of applying it blindly. The repaired schema passes the same static pack. This is a check against versioned rules, not live provider verification. The source and quickstart are linked below.

The problem

A JSON Schema / tool definition / response_format that works on OpenAI can 400 on Anthropic or Gemini (and vice-versa): nested oneOf, a missing additionalProperties: false, a default in a property, Anthropic-rejected keywords (minLength, format, pattern), Gemini’s lack of anyOf. The API tells you it failed — not which constraint — so teams hand-port schemas and debug by trial-and-error at runtime.

schemafit encodes each provider’s documented constraint surface as a versioned, declarative rule pack and lints your schema statically — pointing at the exact JSON-Pointer path, the keyword, and why — with a non-zero exit code so CI fails the PR instead of prod. A repair pass emits a best-effort provider-valid variant. It makes no model calls, needs no API key, and has zero runtime dependencies.

Demo

lint statically checks your schema against each provider’s rule pack, names the exact violation, and exits non-zero so CI blocks the PR. repair emits a provider-valid variant. (Illustrative schema; the output format is the tool’s real one.)

terminal
# 1. Lint a schema against all three providers
schemafit lint order.schema.json --provider openai,anthropic,gemini
openai PASS
anthropic FAIL /properties/email keyword: format
→ Anthropic rejects `format` in tool input schemas
gemini FAIL /properties/items keyword: anyOf
→ Gemini does not support anyOf / union types
SCHEMAFIT_STATUS=FAIL (exit 1 — build blocked)
 
# 2. Auto-repair to a provider-valid variant
schemafit repair order.schema.json --provider anthropic --out fixed.json
wrote fixed.json (1 keyword rewritten, intent preserved)

Quickstart

On PyPI — pip install and lint your schema. No API key, no model calls; the core has zero runtime dependencies.

InstallStatic, offline CLI
pip install schemafit
Lint a schema against the providers you ship to
schemafit lint my-schema.json \
  --provider openai,anthropic,gemini,mistral,cohere
Prove the spine (hermetic, no config required)
schemafit demo

Command surface

lint
Lint one or more schemas against one or more providers; reports each violation’s JSON-Pointer, keyword, and reason, and exits non-zero so CI fails the build.
repair
Emit a best-effort provider-valid variant of a schema — stripping or rewriting the offending keywords while preserving intent.
providers
List the supported providers and the versioned rule pack backing each (OpenAI, Anthropic, Gemini, Mistral, Cohere).
demo
Run a hermetic, end-to-end proof from a fresh clone — no API key, no network, deterministic output.

Why it is different

Static, pre-ship CI lint

Instructor, BAML, LiteLLM and the Vercel AI SDK are excellent runtime clients — they normalize or repair at call-time. schemafit fills the gap they leave: a static lint that fails the build before the schema ever reaches a provider, over the raw schemas you already ship, with no DSL or codegen buy-in.

Zero runtime deps, no API key

It makes no model calls and needs no key — easy to vendor, audit, and trust in a build pipeline. Runs from a fresh clone or a single pip install, fully offline.

Grounded, versioned rule packs — with drift detection

Every rule is grounded in a real, cited provider issue. Provider constraints are encoded as declarative, versioned rule packs — so the lint stays honest and reviewable as provider APIs change. New in v0.5: automatic rule-pack drift detection — an opt-in --live-verify run that rejects a schema the static pack passed flags the pack as lagging the provider’s docs, so the packs stay honest as the APIs move.

CI-enforceable, with SARIF

A non-zero exit fails the PR; lint --format sarif feeds GitHub code-scanning / the Security tab. An opt-in --live-verify can confirm against a real provider, but it is mock-default and never required in CI.