feat(core): add specTypeSchema() for runtime validation of any spec type#1887
feat(core): add specTypeSchema() for runtime validation of any spec type#1887felixweinberger wants to merge 4 commits intomainfrom
Conversation
🦋 Changeset detectedLatest commit: a08445c The changes in this PR will be included in the next version bump. This PR includes changesets to release 6 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
@modelcontextprotocol/client
@modelcontextprotocol/server
@modelcontextprotocol/express
@modelcontextprotocol/fastify
@modelcontextprotocol/hono
@modelcontextprotocol/node
commit: |
|
@claude review |
There was a problem hiding this comment.
LGTM — clean, additive, follows established patterns.
Extended reasoning...
Overview
This PR adds five new type-guard functions (, , , , ) to packages/core/src/types/guards.ts, exports them via the public API barrel, and adds 29 unit tests. It also corrects a pre-existing issue where guards.test.ts lived under src/types/ and was never executed by vitest (which only scans test/**).
Security risks
None. These are pure read-only type predicates that delegate to Zod's safeParse — no side effects, no I/O, no auth-sensitive paths.
Level of scrutiny
Low. Each new guard is a single-line lambda following the exact same pattern as the existing isCallToolResult and other guards already present in the file. The public-index export list is alphabetized correctly. The test coverage is thorough (valid inputs, missing required fields, non-object primitives).
Other factors
The only reported issue is a nit: CLAUDE.md's co-location guideline contradicts the vitest include pattern. This is a pre-existing doc inconsistency and is already flagged as an inline comment on the PR — it does not affect the correctness of the code changes. No outstanding human-reviewer comments exist. The changeset correctly marks downstream packages as patch releases.
5408732 to
1219736
Compare
Adds specTypeSchema(name) returning a StandardSchemaV1 validator for any named MCP spec type, and isSpecType(name, value) as a boolean predicate. The SpecTypeName union and SpecTypes map are derived from the internal Zod schemas, so they cover every spec type with no curation. Replaces the earlier curated-5-predicates approach with a single keyed entrypoint that does not require a new export each time an extension embeds a different spec type. Also: moves guards.test.ts to test/ (vitest include is test/**/*.test.ts; the file was previously dead) and corrects CLAUDE.md test-location guidance.
1219736 to
06882c8
Compare
specTypeSchema()/isSpecType() now also cover the OAuth/OpenID types from shared/auth.ts (OAuthTokens, OAuthMetadata, OAuthClientMetadata, etc.), addressing the standalone-validation use noted in #1680 for auth implementers.
Adds
specTypeSchema(name)andisSpecType(name, value)for runtime validation of any MCP spec type by name.SpecTypeNameandSpecTypesare derived from the internal schema map, so every spec type is covered with no per-type curation.Motivation and Context
Extension authors who embed spec types inside custom-method payloads need a runtime validator. A single keyed function avoids exporting one symbol per type.
How Has This Been Tested?
Unit tests (
specTypeSchema.test.ts, valid/invalid/null cases for 5 representative types + JSON-RPC envelope, type-level checks). Reachable from both@modelcontextprotocol/clientand@modelcontextprotocol/serverdist.Breaking Changes
None — additive.
Types of changes
Checklist
Additional context
Also moves
guards.test.tstotest/(it was previously not picked up by vitest) and corrects the CLAUDE.md test-location guidance.