agentsclimarketplace

Zod first tools

Skill connordibble/dibble/plugins/zod-first-tools/skills/zod-first-tools

Build LLM tool definitions and MCP servers from one schema instead of two. Use when defining tools for the Anthropic, OpenAI, or Gemini APIs, building an MCP server with tools, wiring structured outputs, or validating model tool-call arguments. Also use when reviewing tool-use code for schema drift, or when a zod-first-tools lint finding points at a hand-written tool schema next to a Zod schema.From its SKILL.md

Install
npx -y skills add connordibble/dibble --skill zod-first-tools

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

SKILL.md

3.6 KB, 754 tokens by cl100k_base, as published. Nobody here has run it

One schema for the tool boundary

Every tool call has two contracts that want to drift apart. The provider needs a JSON Schema so the model knows what shape to return. Your code needs a validator so model output is checked before it touches anything real. Write those separately and the mismatch shows up late: a range limit lives in one, an enum value lands in the other, an "optional" field means different things to the provider and the validator.

The fix is to keep one source of truth and derive the rest. Write the schema once in Zod, derive the provider's JSON Schema from it, and validate tool input with the same object. The schema is the contract; everything else is generated.

The rule

For any tool or structured output:

  1. Define the input shape once as a Zod object.
  2. Derive the provider tool definition from it, never hand-write the input_schema / parameters / inputSchema object.
  3. Validate the model's tool arguments with the same Zod object before acting.

If you find yourself typing { type: "object", properties: { ... } } next to a Zod schema for the same tool, stop: that is the drift smell, and the linter in this skill (scripts/lint-tools.mjs) flags exactly it.

node <this-skill-directory>/scripts/lint-tools.mjs src/    # find duplicated schemas

How to derive, per provider

Zod 4 ships z.toJSONSchema(); on Zod 3, zod-to-json-schema fills the gap. The provider SDKs also offer helpers. See references/patterns.md in this skill's directory for copy-paste-ready snippets covering:

  • Anthropic Messages API tools (input_schema from Zod)
  • OpenAI tools and structured outputs (zodFunction, zodResponseFormat, and the strict-mode rules for optional fields)
  • MCP server tools (deriving inputSchema, validating the handler's arguments)
  • Validating tool-call arguments before executing

Read that file when writing the actual wiring; the patterns encode the sharp edges (strict mode representing optional as nullable, additionalProperties, Zod 3 vs 4 differences) that are easy to get subtly wrong.

Keep the boundary small

Deriving the schema is the whole job; resist the urge to build a framework around it. The tool layer should not parse streams, run the tool loop, or decide which function to call. It takes a Zod object, gives the provider a tool definition, and gives your code a validator. When you want that packaged rather than hand-rolled, zod-ai-tool on npm does exactly this across Anthropic, OpenAI, and Gemini shapes, supports Zod 3 and 4 without version sniffing, and carries no runtime SDK dependency. Using it (or the raw derivation above) is what makes the linter pass: both are "derive," not "duplicate."

Why validate with the same object

The provider schema tells the model what to send; it does not guarantee the model sends it. Models omit required fields, coerce types, and occasionally invent enum values. Validating tool arguments against the same Zod schema before you act closes the loop, and because it is the same schema that shaped the tool, there is no gap between "what the model was told" and "what you accept." Two derivations from one source cannot disagree; two hand-written schemas eventually will.

What ships with it: 2 files

8.5 KB alongside SKILL.md, 1 of them executable

references/

scripts/

Gives 0 of the 12 instructions most mcp tooling skills give in 754 tokens

Counted across 638 of the 750 authors here whose files we hold, read 2026-08-07

  • Create ten complex or independent read-only evaluation questionsin 69 of 638, across 15 files
  • Test servers using MCP Inspectorin 61 of 638, across 19 files
  • Provide actionable error messages with specific next stepsin 54 of 638, across 12 files
  • Prioritize comprehensive API coverage over specific workflows or workflow toolsin 54 of 638, across 12 files
  • Use TypeScript and Streamable HTTP for remote servers or clientsin 54 of 638, across 8 files
  • Define structured output schemas where possiblein 50 of 638, across 8 files
  • Use Zod or Pydantic for input schemasin 47 of 638, across 5 files
  • Fetch MCP specification pages with markdown suffixin 46 of 638, across 4 files
  • Load framework documentation using WebFetchin 45 of 638, across 3 files
  • Verify each evaluation answer independentlyin 45 of 638, across 3 files
  • Implement API client with authentication and paginationin 45 of 638, across 3 files
  • Define input schemas with validationin 27 of 638, across 9 files

Said here and by no other author read

  • Define the input shape as a Zod object
  • Derive the provider tool definition from Zod
  • Run the lint script to find duplicated schemas
  • Read the patterns reference before wiring code

Grouped from the skills themselves: near-identical wordings counted once, and counted by distinct author, so one author publishing three of these counts once. Length counted with cl100k_base; the agent that loads this file may tokenize it differently.

Keep looking

Skills are one crate of 326,764. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.