ProvenPin Install

Hono + Zod validator API: working versions (tested 2026-10-15)

Hono routes with @hono/zod-validator for JSON and query validation, tested with app.request().

passed3 passed · 0 failed2026-10-15 13:08 UTC
Status
passed
Last passed
2026-10-15 13:08 UTC
Tests
3 / 3
Language
TypeScript
Runtime
node v22.23.3
pinned versions5
hono@4.13.13zod@4.6.7@hono/zod-validator@0.9.1tsx@4.23.15@types/node@24.19.2
run it
npm install --no-audit --no-fund --ignore-scripts=false
npm test
test environment
node v22.23.3
linux 6.17.0-1022-azure
x64
runner: github-actions 38738874208

The code

Exactly the files that passed. Your agent can pull them with get_recipe("hono-zod-validator") (install), or see them on GitHub.

package.json
{
  "name": "hono-zod-validator",
  "private": true,
  "type": "module",
  "scripts": {
    "test": "node --import tsx --test test/*.test.ts"
  },
  "dependencies": {
    "hono": "4.13.13",
    "zod": "4.6.7",
    "@hono/zod-validator": "0.9.1"
  },
  "devDependencies": {
    "tsx": "4.23.15",
    "@types/node": "24.19.2"
  }
}
src/app.ts
import { Hono } from "hono";
import { zValidator } from "@hono/zod-validator";
import { z } from "zod";

const Post = z.object({ title: z.string().min(3), body: z.string() });
const Page = z.object({ page: z.coerce.number().int().min(1).default(1) });

export const app = new Hono()
  .post("/posts", zValidator("json", Post), (c) => c.json({ ok: true, post: c.req.valid("json") }, 201))
  .get("/posts", zValidator("query", Page), (c) => c.json({ page: c.req.valid("query").page }));
test/app.test.ts
import { test } from "node:test";
import assert from "node:assert/strict";
import { app } from "../src/app.ts";

test("valid json passes", async () => {
  const res = await app.request("/posts", { method: "POST", headers: { "content-type": "application/json" }, body: JSON.stringify({ title: "Hello", body: "x" }) });
  assert.equal(res.status, 201);
});
test("invalid json is 400", async () => {
  const res = await app.request("/posts", { method: "POST", headers: { "content-type": "application/json" }, body: JSON.stringify({ title: "Hi" }) });
  assert.equal(res.status, 400);
});
test("query is coerced", async () => {
  const res = await app.request("/posts?page=3");
  assert.deepEqual(await res.json(), { page: 3 });
});

Connect to ProvenPin

Add the free MCP server so your agent can pull this recipe and others like it. Same setup as the docs.

terminal
claude mcp add --transport http provenpin https://mcp.provenpin.com/mcp

Any other MCP client: Streamable HTTP at https://mcp.provenpin.com/mcp. No API key, no signup.