Tool Schema Builder — SQL source
Build function-calling and MCP tool schemas that pass strict mode on the first try, and lint pasted ones against the strict-mode contract — additionalProperties, required-sync, defaults, enums — with one-click autofix for every mechanical violation. Runs entirely in your browser.
This is the SQL implementation — the same logic the interactive tool runs, in a shareable, citable form.
-- Tool Schema Builder — the nine strict-mode rules as DDL, plus a
-- CHECK-constraint flavored validation demo.
--
-- Language: SQL (SQLite dialect — Cloudflare D1)
-- Source: CosmoDev polyglot showcase port, from src/lib/tool-schema.ts
-- (the canonical TypeScript lib). The rule ids mirror the tool
-- README one-to-one — the lint output IS the answer surface.
CREATE TABLE IF NOT EXISTS tool_schema_rule (
id INTEGER PRIMARY KEY, -- lint order
rule TEXT NOT NULL UNIQUE, -- the Issue.rule ids, verbatim
applies_to TEXT NOT NULL, -- 'input' | 'tool' | 'object' | 'property'
summary TEXT NOT NULL
);
INSERT INTO tool_schema_rule (id, rule, applies_to, summary) VALUES
(1, 'json-parseable', 'input', 'input parses and input_schema is an object with type: "object"'),
(2, 'non-empty-name', 'tool', 'name is 1-64 chars of [a-z0-9_-] (the get_weather convention)'),
(3, 'description-present', 'tool', 'the tool and every property carry a description'),
(4, 'no-additional-properties','object', 'every object sets additionalProperties: false'),
(5, 'all-required', 'object', 'required lists every property — optionality is semantics, not schema'),
(6, 'no-defaults', 'property', 'strict mode rejects defaults — remove the key'),
(7, 'typed-properties', 'property', 'type is one of string|number|integer|boolean|object|array'),
(8, 'enum-values', 'property', 'enum is non-empty and all values share one primitive type'),
(9, 'array-items', 'property', 'arrays declare items with a type');
-- The rules as the engine itself enforces them. A definition row is only
-- insertable when it satisfies the tool-level rules (2, 3):
CREATE TABLE IF NOT EXISTS tool_definition (
name TEXT PRIMARY KEY,
description TEXT NOT NULL,
CHECK (length(name) BETWEEN 1 AND 64 AND name GLOB '[a-z0-9_-]*'), -- non-empty-name
CHECK (description <> '') -- description-present
);
-- ...and a property row only when it satisfies rules 3, 6, 7, 8, 9:
CREATE TABLE IF NOT EXISTS tool_property (
tool_name TEXT NOT NULL,
path TEXT NOT NULL, -- e.g. 'input_schema.properties.city'
type TEXT NOT NULL,
description TEXT NOT NULL,
has_default INTEGER NOT NULL DEFAULT 0,
enum_kinds TEXT, -- DISTINCT typeof() of enum values; NULL = no enum
items_type TEXT, -- arrays only
PRIMARY KEY (tool_name, path),
CHECK (type IN ('string','number','integer','boolean','object','array')), -- typed-properties
CHECK (description <> ''), -- description-present
CHECK (has_default = 0), -- no-defaults
CHECK (enum_kinds IS NULL OR (enum_kinds <> '' AND enum_kinds NOT LIKE '%,%')), -- enum-values
CHECK (type <> 'array' OR items_type IS NOT NULL) -- array-items
);
-- Demo: inserting the broken definition's rows fires the CHECKs.
-- city has a default -> no-defaults rejects it:
INSERT INTO tool_property VALUES
('get_weather', 'input_schema.properties.city', 'string', 'City name', 1, NULL, NULL);
-- unit's enum mixes text and integer -> enum-values rejects it:
INSERT INTO tool_property VALUES
('get_weather', 'input_schema.properties.unit', 'string', 'celsius or fahrenheit', 0, 'text,integer', NULL);
-- tags is an array without items -> array-items rejects it:
INSERT INTO tool_property VALUES
('get_weather', 'input_schema.properties.tags', 'array', 'Tags to filter by', 0, NULL, NULL);
-- The compliant row inserts cleanly:
INSERT INTO tool_property VALUES
('get_weather', 'input_schema.properties.city', 'string', 'City name', 0, NULL, NULL);
-- Rule 4 and 5 (additionalProperties, required) are structural — they
-- constrain the shape of the definition, not a column — so they stay in
-- the rule table above, enforced by the application-side walk.
Also available in 13 other languages
Every CosmoDev tool ships its pure logic in TypeScript (web) and Go (CLI), with authored implementations in a dozen-plus languages — the same contract, ported. Compare all languages side by side →