Allow skipping validation for schema#362
Conversation
|
Thanks for the PR and the feedback. I agree that the issue here is the performance hit from validating the schema on every instantiation. Adding an option like So rather than skipping I've opened #363 with the caching approach. What do you think? |
Makes sense. Will leave comments on your opened PR if I see something |
## Motivation and Context `MCP::Tool::Schema#initialize` validated every instance against the draft-04 metaschema via `JSON::Validator.fully_validate`, costing ~32ms for deep schemas (up to ~100ms). When schemas are built dynamically and repeatedly, this work is wasted because the result depends only on the schema content. This caches successful validations by a content digest, so an identical schema is validated once and subsequent constructions skip the traversal (~100ms to ~0.1ms on a cache hit). The cache is bounded and thread-safe. It supersedes the `validate: false` escape hatch proposed in #362, which would have added permanent public interface and allowed invalid schemas to reach clients. Python and TypeScript SDKs do not metaschema-validate schema definitions, so this cost is specific to the Ruby SDK; caching reduces it without weakening the default or changing validation semantics. ## How Has This Been Tested? Added regression tests in `test/mcp/tool/schema_test.rb`: identical schemas validate only once, distinct schemas validate separately, a cache hit still yields a usable and correctly validated schema, invalid schemas raise on every construction and are not cached, a schema at the normalization depth limit is cached without a nesting error, and `ValidationCache` evicts the oldest entry beyond its max size. The full suite (`rake test`) and `rake rubocop` pass. ## Breaking Changes None. Validation safety is preserved: every distinct schema is still validated, and invalid schemas continue to raise. The initializer signature and validation semantics are unchanged.
Motivation and Context
If you're building dynamic tool schemas - every time you build one it has to be validated as the
Schemaclass callsvalidate_schema!in the initializer. This can get slow (taking up to ~100ms) for deeper schemas.This PR allows the user of the
Schemaclass to build the schema themselves and not pay the performance penalty ofJSON.parse(JSON.dump(schema))andvalidate_schema!.How Has This Been Tested?
Added unit tests.
Breaking Changes
None.
Types of changes
Checklist
Additional context
An alternative