npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@manushya/tool-schema-kit

v0.4.0

Published

Utilities for editing and serializing supported API tool input schemas.

Readme

@manushya/tool-schema-kit

Utilities for building, importing, validating, and serializing a focused input-schema model for API tools and LLM tool calling.

This package is framework-independent TypeScript with no runtime dependencies. It is intended for products that need a user-editable schema tree, then need to serialize that tree into a supported JSON Schema subset for tool definitions.

Install

npm install @manushya/tool-schema-kit

The package ships ESM, CommonJS, and TypeScript declarations.

import {
  inferTreeFromJson,
  parseSupportedSchema,
  treeToSchema,
  validateTree,
  UnsupportedSchemaError,
} from '@manushya/tool-schema-kit';

What It Does

tool-schema-kit works with two representations:

  • SchemaTree: an editing-friendly tree of field nodes.
  • SupportedJsonSchema: the canonical schema output used by tool runtimes.

Use SchemaTree in UI or builder flows. Persist or pass around the serialized JSON Schema from treeToSchema().

Supported Schema Subset

This is not a full JSON Schema implementation. It supports the subset useful for describing tool input shapes:

  • object with properties
  • nested objects
  • string, number, integer, boolean
  • array with exactly one items schema
  • required and optional object properties
  • string-only enum choices
  • description
  • nullable primitive and enum fields as type: [T, "null"]

For nullable enum fields, treeToSchema() also includes null in the emitted enum array so the JSON Schema is valid for a null value:

{
  "type": ["string", "null"],
  "enum": ["auto", "manual", null]
}

Every object emitted by treeToSchema() includes:

{
  "additionalProperties": false
}

When importing an existing schema with parseSupportedSchema(), omitted additionalProperties and additionalProperties: true are accepted for convenience. The canonical output from treeToSchema() still normalizes every object to additionalProperties: false. Schema-valued additionalProperties is not supported.

Unsupported keywords include $ref, $defs, allOf, oneOf, anyOf, if, then, else, dependentRequired, dependentSchemas, patternProperties, tuple-style arrays, prefixItems, minimum, maximum, multipleOf, minLength, maxLength, and regex pattern.

API

inferTreeFromJson(json)

Creates a best-effort editable tree from an example JSON payload. This function always succeeds once the input is valid parsed JSON.

import { inferTreeFromJson } from '@manushya/tool-schema-kit';

const tree = inferTreeFromJson({
  agentId: 'agent_123',
  settings: {
    brandingEnabled: true,
  },
  prompts: [
    {
      text: 'Hello',
      icon: 'wave',
    },
  ],
});

Inference is intentionally editable:

  • all inferred fields default to optional
  • integers are guessed with Number.isInteger()
  • null values become nullable strings
  • enum values are not inferred automatically

parseSupportedSchema(schema)

Strictly parses an existing supported JSON Schema into a SchemaTree.

import {
  parseSupportedSchema,
  UnsupportedSchemaError,
} from '@manushya/tool-schema-kit';

try {
  const tree = parseSupportedSchema({
    type: 'object',
    properties: {
      agentId: {
        type: 'string',
        description: 'Agent identifier',
      },
      startMode: {
        type: ['string', 'null'],
        enum: ['auto', 'manual', null],
      },
    },
    required: ['agentId'],
    additionalProperties: false,
  });
} catch (error) {
  if (error instanceof UnsupportedSchemaError) {
    console.error(error.keyword, error.path);
  }
}

UnsupportedSchemaError identifies the first unsupported keyword and where it was found, so callers can show precise import errors. If a nullable enum includes null, parseSupportedSchema() records the field as nullable: true and keeps only string choices in FieldNode.enumValues.

For object schemas, omitted additionalProperties and additionalProperties: true are imported successfully. They are normalized to additionalProperties: false the next time the tree is serialized with treeToSchema().

validateTree(tree)

Checks structural correctness before serialization or save.

import { validateTree } from '@manushya/tool-schema-kit';

const result = validateTree(tree);

if (!result.valid) {
  console.log(result.errors);
}

Validation checks include:

  • root node exists and is an object
  • referenced child and item nodes exist
  • object sibling names are unique
  • object child fields have names
  • array nodes have one item schema
  • enum nodes have at least one value
  • nullable is used only on supported field types

treeToSchema(tree)

Serializes a valid SchemaTree into the supported JSON Schema subset.

import { treeToSchema, validateTree } from '@manushya/tool-schema-kit';

const validation = validateTree(tree);

if (!validation.valid) {
  throw new Error(validation.errors.join('\n'));
}

const inputSchema = treeToSchema(tree);

Example output:

{
  "type": "object",
  "properties": {
    "agentId": {
      "type": "string",
      "description": "Agent identifier"
    },
    "startMode": {
      "type": ["string", "null"],
      "enum": ["auto", "manual", null]
    }
  },
  "required": ["agentId"],
  "additionalProperties": false
}

Types

export type FieldType =
  | 'string'
  | 'number'
  | 'integer'
  | 'boolean'
  | 'object'
  | 'array'
  | 'enum';

export interface FieldNode {
  id: string;
  name: string;
  type: FieldType;
  description?: string;
  required?: boolean;
  nullable?: boolean;
  enumValues?: string[];
  childIds?: string[];
  itemId?: string;
}

export interface SchemaTree {
  rootId: string;
  nodes: Record<string, FieldNode>;
}

export interface SupportedJsonSchema {
  type: string | string[];
  description?: string;
  properties?: Record<string, SupportedJsonSchema>;
  required?: string[];
  additionalProperties?: boolean;
  items?: SupportedJsonSchema;
  enum?: Array<string | null>;
}

Development

npm install
npm test
npm run build

Build output is written to dist/.