Skip to content

infer: emit $ref/$defs for recursive types instead of erroring - #79

Open
rafaeljusto wants to merge 1 commit into
google:mainfrom
rafaeljusto:recursive-types
Open

infer: emit $ref/$defs for recursive types instead of erroring#79
rafaeljusto wants to merge 1 commit into
google:mainfrom
rafaeljusto:recursive-types

Conversation

@rafaeljusto

Copy link
Copy Markdown
Contributor

For and ForType previously returned "cycle detected for type ..." when a Go type referred to itself, directly or indirectly. This made it impossible to generate a schema for self-referential types such as jsonschema.Schema itself, which is a common need when accepting a JSON schema as input to an MCP tool.

Now, when a named type closes a cycle, its schema is emitted once under "$defs" and referenced with "$ref" wherever it recurs. The recursion bookkeeping (seen set, assigned def names, collected defs) is threaded through forType via a shared inferState. Output for non-recursive types is unchanged: no "$defs" is added and no "$ref" is emitted.

Verified end to end against the modelcontextprotocol/go-sdk, which depends on this library: ForType, Resolve{ValidateDefaults:true}, Validate, ApplyDefaults, the JSON wire round-trip, and AddTool all handle the generated recursive schemas, and the SDK's own test suite passes.

Resolves #46

@google-cla

google-cla Bot commented Jun 29, 2026

Copy link
Copy Markdown

Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

View this failed invocation of the CLA check for more information.

For the most up to date status, view the checks section at the bottom of the pull request.

@rafaeljusto

rafaeljusto commented Jun 29, 2026

Copy link
Copy Markdown
Contributor Author

a0abba9 Co-Author: <no****y​@anthropic.com>

Oh, looks like I cannot set the co-author thing due to the CLA rules (Claude Opus 4.8 (1M context) <noreply@anthropic.com>).

image

I will force-push again.

For and ForType previously returned "cycle detected for type ..." when a
Go type referred to itself, directly or indirectly. This made it
impossible to generate a schema for self-referential types such as
jsonschema.Schema itself, which is a common need when accepting a JSON
schema as input to an MCP tool.

Now, when a named type closes a cycle, its schema is emitted once under
"$defs" and referenced with "$ref" wherever it recurs. The recursion
bookkeeping (seen set, assigned def names, collected defs) is threaded
through forType via a shared inferState. Output for non-recursive types
is unchanged: no "$defs" is added and no "$ref" is emitted.

Verified end to end against the modelcontextprotocol/go-sdk, which
depends on this library: ForType, Resolve{ValidateDefaults:true},
Validate, ApplyDefaults, the JSON wire round-trip, and AddTool all
handle the generated recursive schemas, and the SDK's own test suite
passes.

Resolves google#46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Support self-referential structures

1 participant