schema

package
v2.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 29, 2026 License: MIT Imports: 4 Imported by: 0

Documentation

Overview

Package schema provides LLM-tool–oriented JSON Schema builders for Go structs. It generates the JSON Schema subset required by OpenAI, Anthropic, Gemini, and other LLM APIs that accept tool definitions.

Quick start — use the package-level shortcuts backed by the Default builder:

tool := schema.StrictTool("search_web", "Search the web.", SearchArgs{})

Advanced — create a custom Builder to override type schemas or tag names:

b := schema.NewBuilder(
    schema.WithTypeSchema(reflect.TypeFor[uuid.UUID](), map[string]any{
        "type": "string", "format": "uuid",
    }),
)
tool := b.StrictTool("create_user", "Create a user.", UserArgs{})

Index

Examples

Constants

This section is empty.

Variables

View Source
var Default = NewBuilder()

Default is the Builder used by the package-level convenience functions. Replace it to apply custom type overrides or tag names globally:

schema.Default = schema.NewBuilder(schema.WithTypeSchema(...))

Functions

func ApplyStrict

func ApplyStrict(s map[string]any)

ApplyStrict recursively sets additionalProperties: false on every object schema in the tree, including objects nested inside array item schemas. Call this when building a schema manually and you need full OpenAI structured-output compliance across all nested objects.

func InputSchema

func InputSchema(v any) map[string]any

InputSchema is a package-level shortcut that calls Default.InputSchema.

Example
package main

import (
	"fmt"

	"github.com/v8tix/mcp-toolkit/v2/schema"
)

type queryArgs struct {
	Query string `json:"query" description:"Search query."`
	Topic string `json:"topic,omitempty" description:"Category." enum:"general,news,finance"`
	Limit *int   `json:"limit,omitempty" description:"Max results."`
}

func main() {
	s := schema.InputSchema(queryArgs{})

	fmt.Println(s["type"])
	props := s["properties"].(map[string]any)
	fmt.Println(props["query"].(map[string]any)["description"])
	fmt.Println(props["topic"].(map[string]any)["enum"])
	fmt.Println(s["required"])
}
Output:
object
Search query.
[general news finance]
[query]

func StrictTool

func StrictTool(name, description string, args any) *sdkmcp.Tool

StrictTool is a package-level shortcut that calls Default.StrictTool.

Example
package main

import (
	"fmt"

	"github.com/v8tix/mcp-toolkit/v2/schema"
)

type queryArgs struct {
	Query string `json:"query" description:"Search query."`
	Topic string `json:"topic,omitempty" description:"Category." enum:"general,news,finance"`
	Limit *int   `json:"limit,omitempty" description:"Max results."`
}

func main() {
	def := schema.StrictTool("search_web", "Search the web.", queryArgs{})

	fmt.Println(def.Name)
	fmt.Println(def.Description)
	s := def.InputSchema.(map[string]any)
	fmt.Println(s["additionalProperties"])
}
Output:
search_web
Search the web.
false

func Tool

func Tool(name, description string, args any) *sdkmcp.Tool

Tool is a package-level shortcut that calls Default.Tool.

Example
package main

import (
	"fmt"

	"github.com/v8tix/mcp-toolkit/v2/schema"
)

type queryArgs struct {
	Query string `json:"query" description:"Search query."`
	Topic string `json:"topic,omitempty" description:"Category." enum:"general,news,finance"`
	Limit *int   `json:"limit,omitempty" description:"Max results."`
}

func main() {
	// Use Tool for APIs that do not require additionalProperties constraints.
	def := schema.Tool("search_web", "Search the web.", queryArgs{})

	fmt.Println(def.Name)
	s := def.InputSchema.(map[string]any)
	_, hasAdditional := s["additionalProperties"]
	fmt.Println(hasAdditional)
}
Output:
search_web
false

Types

type Builder

type Builder struct {
	// contains filtered or unexported fields
}

Builder generates LLM-compatible JSON Schema from annotated Go structs. Construct one with NewBuilder and chain With* methods to configure it. Use the package-level shortcuts (StrictTool, Tool, InputSchema) for the common case where no customisation is needed.

b := schema.NewBuilder().
    WithTypeSchema(reflect.TypeFor[uuid.UUID](), map[string]any{"type":"string","format":"uuid"}).
    WithDescriptionTag("desc")
tool := b.StrictTool("create_user", "Create a user.", UserArgs{})

func NewBuilder

func NewBuilder() *Builder

NewBuilder returns a Builder with default settings: description tag "description", enum tag "enum", no type overrides.

func (*Builder) InputSchema

func (b *Builder) InputSchema(v any) map[string]any

InputSchema derives a JSON Schema from a struct suitable for use as an LLM tool input schema. Pointer fields are optional (not in "required") and never nullable. Embedded structs are flattened, matching encoding/json behaviour. Nested struct fields generate recursive object schemas.

Panics with a descriptive message if v is nil or not a struct / *struct.

func (*Builder) StrictTool

func (b *Builder) StrictTool(name, description string, args any) *sdkmcp.Tool

StrictTool builds a *sdkmcp.Tool and applies additionalProperties: false recursively to every nested object schema. Recommended for OpenAI and any LLM API that supports structured-output mode.

func (*Builder) Tool

func (b *Builder) Tool(name, description string, args any) *sdkmcp.Tool

Tool builds a *sdkmcp.Tool without strict constraints. Use for APIs that do not require additionalProperties to be set (e.g. Anthropic, Gemini).

func (*Builder) WithDescriptionTag

func (b *Builder) WithDescriptionTag(tag string) *Builder

WithDescriptionTag returns a new Builder that reads field descriptions from the given struct tag instead of the default "description".

b := schema.NewBuilder().WithDescriptionTag("desc")

func (*Builder) WithEnumTag

func (b *Builder) WithEnumTag(tag string) *Builder

WithEnumTag returns a new Builder that reads enum values from the given struct tag instead of the default "enum".

b := schema.NewBuilder().WithEnumTag("oneof")

func (*Builder) WithTypeSchema

func (b *Builder) WithTypeSchema(t reflect.Type, s map[string]any) *Builder

WithTypeSchema returns a new Builder that overrides the JSON Schema emitted for a specific Go type. The provided map is cloned so the caller may safely reuse or mutate it after the call.

b := schema.NewBuilder().
    WithTypeSchema(reflect.TypeFor[uuid.UUID](), map[string]any{"type":"string","format":"uuid"}).
    WithTypeSchema(reflect.TypeFor[time.Time](), map[string]any{"type":"string","format":"date-time"})

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL