jsonschema 从 Go 类型生成可直接用于 github.com/google/jsonschema-go 的 JSON Schema,并提供基于同一 schema 的运行时校验。
它内部使用 github.com/invopop/jsonschema 负责反射 Go 类型,再转换为 google/jsonschema-go/jsonschema.Schema。适合需要把 Go 结构体同时用于 schema 输出和参数校验的场景,例如 MCP tool 的 InputSchema / OutputSchema。
这个包同时使用 invopop/jsonschema 和 google/jsonschema-go,是为了把两边各自擅长的部分组合起来:
google/jsonschema-go是官方 MCP Go SDK 使用的 schema 类型。MCP tool 的InputSchema/OutputSchema可以直接接收它,因此最终输出 Google Schema 能减少适配层。invopop/jsonschema的 Go 类型反射和 tag 支持更完整,适合从结构体生成较丰富的 JSON Schema,包括字段描述、枚举、长度、数值范围、数组约束和扩展字段等。- 本包先用
invopop/jsonschema生成完整 schema,再通过 JSON 字节重新反序列化为google/jsonschema-go的 Schema。这样既保留了生成能力,也得到 MCP 生态原生支持的类型。
go get github.com/dpchan/jsonschemapackage main
import (
"fmt"
"log"
"github.com/dpchan/jsonschema"
)
type LookupParams struct {
City string `json:"city" jsonschema:"description=城市名称"`
Days int `json:"days,omitempty" jsonschema:"description=预报天数"`
}
func main() {
s := jsonschema.Schema[LookupParams](
jsonschema.WithTitle("天气查询参数"),
jsonschema.WithDescription("查询指定城市天气所需的参数"),
)
if err := jsonschema.Validate(s, map[string]any{
"city": "Shanghai",
"days": 2,
}); err != nil {
log.Fatal(err)
}
fmt.Println(s.Title)
}func Schema[T any](opts ...Option) *google.SchemaSchema[T] 从 Go 类型 T 生成 github.com/google/jsonschema-go/jsonschema.Schema。结构体字段的名称、必填规则和描述等信息主要来自 json、jsonschema 等 tag。
当 T 是接口类型(例如 any)时返回 nil,表示没有可用 schema。
当前内置的 Option 用于设置 schema 元数据:
WithID(id string):设置$idWithTitle(title string):设置titleWithDescription(desc string):设置description
func Validate(s *google.Schema, instance any) errorValidate 校验 instance 是否符合给定 schema。内部会缓存已解析的 schema,重复校验同一个 schema 时不需要反复解析。
字段定义遵循 invopop/jsonschema 的 tag 规则。jsonschema 和 jsonschema_extras 标签都需要写成 invopop 支持的格式;本包不会定义或解析额外的标签语法。
常用写法:
type Params struct {
Name string `json:"name" jsonschema:"description=用户名称"`
Age int `json:"age,omitempty" jsonschema:"description=年龄"`
}json:"name" 控制 schema 中的属性名。没有 omitempty 的字段通常会进入 required。
jsonschema:"description=..." 用于设置字段描述。更多 tag 能力请以 invopop/jsonschema 的文档和行为为准。
examples/jsonschema_tags:展示常见jsonschematag 生成效果和校验用法。examples/validate:展示Validate对合法输入、缺字段、类型错误、枚举错误和嵌套约束的校验结果。examples/mcp_google_schema:展示如何把生成的 Google Schema 用在官方 MCP Go SDK 的 tool 定义中。
github.com/invopop/jsonschema:用于从 Go 类型生成完整 JSON Schema。jsonschema和jsonschema_extras标签语法以它为准。许可证信息以其仓库为准。github.com/google/jsonschema-go:作为最终 Schema 类型,并用于解析和校验。许可证信息以其仓库为准。github.com/modelcontextprotocol/go-sdk:只在examples/mcp_google_schema独立示例模块中使用,不是根包运行时依赖。许可证信息以其仓库为准。
- 生成失败时会 panic。这通常表示 Go 类型本身不适合生成 JSON Schema,建议在程序启动阶段生成并暴露问题。
- 生成结果会设置
additionalProperties为nil,避免额外属性策略覆盖调用方或下游库的默认行为。 Schema返回的是google/jsonschema-go/jsonschema.Schema,可直接传给依赖 Google Schema 类型的库。
Schema[any]()会返回nil,表示没有可用 schema。调用方不应直接把nil传给Validate,否则当前实现会在解析 schema 时 panic。Validate会按*google.Schema指针缓存解析结果。schema 第一次用于校验后,应视为只读对象,不要继续修改Properties、Required等字段,否则缓存结果可能和修改后的 schema 不一致。- 默认校验器会缓存每个出现过的 schema 指针。如果在请求路径中反复调用
Schema[T]()并立即校验,会产生大量不同的 schema 指针,缓存可能持续增长。建议在程序启动阶段生成 schema,并在后续请求中复用。 - 包级文档目前放在
schema.go顶部。随着文档继续变长,可以考虑迁移到单独的doc.go,让入口代码和包文档分离。
本项目源码使用 MIT License。详见 LICENSE。
第三方依赖不包含在本项目许可证授权范围内,其使用、分发和再授权须遵守各自许可证。