Skip to content

Replace github.com/invopop/jsonschema with github.com/google/jsonschema-go - #760

Merged
ezynda3 merged 1 commit into
mark3labs:mainfrom
securityguy:feature/replace-invopop-jsonschema
Mar 24, 2026
Merged

Replace github.com/invopop/jsonschema with github.com/google/jsonschema-go#760
ezynda3 merged 1 commit into
mark3labs:mainfrom
securityguy:feature/replace-invopop-jsonschema

Conversation

@securityguy

@securityguy securityguy commented Mar 19, 2026

Copy link
Copy Markdown
Contributor

Summary

This PR replaces github.com/invopop/jsonschema with github.com/google/jsonschema-go for JSON Schema generation, which reduces the dependency footprint and addresses concerns raised in #758 and #702.

Dependencies removed

By switching to github.com/google/jsonschema-go, the following transitive dependencies are no longer required:

  • github.com/invopop/jsonschema — the library being replaced
  • github.com/buger/jsonparser — unmaintained (last commit 4+ years ago) and has known security vulnerability
  • github.com/bahlo/generic-list-go
  • github.com/mailru/easyjson — potential compliance issues for some users
  • github.com/wk8/go-ordered-map/v2

Changes

  • mcp/tools.go: Updated schema generation to use google/jsonschema-go API
  • mcp/tools_test.go: Expanded test coverage for the updated schema generation
  • go.mod / go.sum: Dependency updates
  • examples/structured_input_and_output/main.go: Updated to use new API
  • www/docs/pages/servers/tools.mdx: Updated documentation examples

The behaviour and output of schema generation is equivalent — this is purely a dependency substitution with no breaking changes to the public API.

Closes #758. Related to #702.

Summary by CodeRabbit

  • Refactor
    • Streamlined JSON schema generation for tools with a unified tag format, reducing configuration complexity.
  • Documentation
    • Updated tool documentation and examples to reflect the simplified schema configuration approach.

Replaces github.com/invopop/jsonschema (which has an indirect dependency
on github.com/mailru/easyjson, a library from a sanctioned country) with
github.com/google/jsonschema-go, which has zero external dependencies.

Breaking changes:
- Struct tag for descriptions changed from jsonschema_description:"text"
  to jsonschema:"text"
- jsonschema:"required" tag is no longer supported; fields without
  omitempty are automatically required
- jsonschema:"enum=...", jsonschema:"minimum=...", etc. are no longer
  supported in struct tags; use WithRawInputSchema for these constraints
- additionalProperties: false is now included in generated schemas

Fixes: mark3labs#702

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Mar 19, 2026

Copy link
Copy Markdown
Contributor

Walkthrough

Migrates JSON schema generation from unmaintained github.com/invopop/jsonschema to github.com/google/jsonschema-go, eliminating vulnerable transitive dependencies. Simplifies struct tags to use only jsonschema for descriptions and removes constraint metadata (required, enum, minimum, maximum, default). Updates implementation, examples, tests, and documentation accordingly.

Changes

Cohort / File(s) Summary
Dependency migration
go.mod
Replaced direct dependency on invopop/jsonschema with google/jsonschema-go, removing transitive vulnerabilities from unused dependencies.
Schema generation implementation
mcp/tools.go
Updated WithInputSchema and WithOutputSchema to use jsonschema.For[T]() from google library instead of invopop's reflector-based approach; simplified error handling and removed manual schema cleanup logic.
Example struct tags
examples/structured_input_and_output/main.go
Consolidated struct tags from separate jsonschema_description and jsonschema tags into single jsonschema tag; removed constraint metadata from multiple struct fields across WeatherRequest, WeatherResponse, UserProfile, UserRequest, Asset, and AssetListRequest.
Test updates
mcp/tools_test.go
Updated test struct tags to match new pattern; expanded assertions to verify schema object type, additionalProperties: false, required fields, and description matching.
Documentation
www/docs/pages/servers/tools.mdx
Updated code snippets and examples to reflect simplified struct tag pattern with removal of constraint metadata annotations.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related issues

  • #758: This PR directly resolves the vulnerability concern by removing the unmaintained dependency chain through invopop/jsonschema.
  • #702: This PR implements the proposed library replacement from invopop to google/jsonschema-go with updated schema generation code.

Possibly related PRs

Suggested labels

type: enhancement, area: sdk

Suggested reviewers

  • dugenkui03
  • pottekkat
  • rwjblue-glean
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately and concisely describes the main change: replacing one JSON schema library with another.
Linked Issues check ✅ Passed The PR successfully addresses issue #758 by removing the vulnerable github.com/buger/jsonparser transitive dependency through the library replacement.
Out of Scope Changes check ✅ Passed All changes are directly related to replacing the JSON schema library and updating code to use the new API; no out-of-scope changes detected.
Docstring Coverage ✅ Passed Docstring coverage is 80.00% which is sufficient. The required threshold is 80.00%.
Description check ✅ Passed The PR description is comprehensive and includes all key sections: a clear summary, detailed rationale for the dependency replacement, specific dependencies being removed, a list of changed files, and issue references.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
📝 Coding Plan
  • Generate coding plan for human review comments

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Tip

CodeRabbit can enforce grammar and style rules using `languagetool`.

Configure the reviews.tools.languagetool setting to enable/disable rules and categories. Refer to the LanguageTool Community to learn more.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (2)
mcp/tools.go (2)

844-858: Silent error handling may hide schema generation failures.

When jsonschema.For[T]() or json.Marshal(schema) fails, the function returns early without any indication of failure. This means the tool will be created without a proper input schema, which could cause confusing runtime behavior.

Consider at minimum logging the error, or documenting that schema generation errors are silently ignored:

💡 Optional: Add debug logging for schema generation failures
 func WithInputSchema[T any]() ToolOption {
 	return func(t *Tool) {
 		schema, err := jsonschema.For[T](&jsonschema.ForOptions{IgnoreInvalidTypes: true})
 		if err != nil {
+			// Schema generation failed - tool will use default empty schema
 			return
 		}

 		mcpSchema, err := json.Marshal(schema)
 		if err != nil {
+			// Schema marshaling failed - tool will use default empty schema
 			return
 		}

 		t.InputSchema.Type = ""
 		t.RawInputSchema = json.RawMessage(mcpSchema)
 	}
 }

Based on learnings, the maintainer prefers keeping builder pattern APIs simple without excessive validation, so this is noted as an optional improvement.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@mcp/tools.go` around lines 844 - 858, WithInputSchema currently swallows
errors from jsonschema.For[T] and json.Marshal which leaves tools created
without schemas; update the function so it does not return silently on failures
but logs the error and leaves t.RawInputSchema unset: in WithInputSchema, after
calling jsonschema.For[T] and after json.Marshal(schema), capture any err and
write a debug/error log (use t.Logger if Tool exposes one, otherwise use the
package logger) including the err and context (e.g., "failed to generate input
schema for type T"), then return without mutating t.InputSchema/RawInputSchema;
do not change the function signature or the builder behavior.

894-913: Same silent error handling pattern in WithOutputSchema.

The same concern applies here - schema generation or marshaling failures result in silent early returns. The tool will have no output schema set without any indication of why.

Additionally, after unmarshaling into t.OutputSchema, if that fails (Line 906-908), the function returns but t.OutputSchema may be in a partially populated state from previous operations.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@mcp/tools.go` around lines 894 - 913, WithOutputSchema currently swallows
errors and can leave t.OutputSchema partially populated; change it to unmarshal
into a temporary variable (e.g., tmp map[string]any or a local struct) and only
assign tmp to t.OutputSchema after all operations succeed, set Type="object"
afterward, and replace the silent returns on errors from jsonschema.For,
json.Marshal and json.Unmarshal with visible logging (for example
log.Printf("WithOutputSchema: %v", err) or your project logger) so failures are
reported instead of dropped.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@mcp/tools.go`:
- Around line 844-858: WithInputSchema currently swallows errors from
jsonschema.For[T] and json.Marshal which leaves tools created without schemas;
update the function so it does not return silently on failures but logs the
error and leaves t.RawInputSchema unset: in WithInputSchema, after calling
jsonschema.For[T] and after json.Marshal(schema), capture any err and write a
debug/error log (use t.Logger if Tool exposes one, otherwise use the package
logger) including the err and context (e.g., "failed to generate input schema
for type T"), then return without mutating t.InputSchema/RawInputSchema; do not
change the function signature or the builder behavior.
- Around line 894-913: WithOutputSchema currently swallows errors and can leave
t.OutputSchema partially populated; change it to unmarshal into a temporary
variable (e.g., tmp map[string]any or a local struct) and only assign tmp to
t.OutputSchema after all operations succeed, set Type="object" afterward, and
replace the silent returns on errors from jsonschema.For, json.Marshal and
json.Unmarshal with visible logging (for example log.Printf("WithOutputSchema:
%v", err) or your project logger) so failures are reported instead of dropped.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: df70fdc3-f892-4f03-8ec8-ccdec78600f8

📥 Commits

Reviewing files that changed from the base of the PR and between 4dd76c6 and 3f37ef4.

⛔ Files ignored due to path filters (1)
  • go.sum is excluded by !**/*.sum
📒 Files selected for processing (5)
  • examples/structured_input_and_output/main.go
  • go.mod
  • mcp/tools.go
  • mcp/tools_test.go
  • www/docs/pages/servers/tools.mdx

@securityguy

securityguy commented Mar 19, 2026

Copy link
Copy Markdown
Contributor Author

Regarding the review comments, there does not appear to be a logger available in the package, and I'm not comfortable introducing one.

Regarding the potential for t.OutputSchema to be partially-populated, I'm not sure how problematic that would be. Perhaps someone more familiar with that component could take a look.

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.

Vuln in unmaintained downstream library

3 participants