Skip to content

[UPDATE PRIMITIVE] Fix ZodEffects schema rejection in CLI tool registration and resolve_queries parameter name#225

Merged
data-douser merged 2 commits intocopilot/improve-error-message-for-paramsfrom
copilot/fix-github-actions-workflow
Apr 6, 2026
Merged

[UPDATE PRIMITIVE] Fix ZodEffects schema rejection in CLI tool registration and resolve_queries parameter name#225
data-douser merged 2 commits intocopilot/improve-error-message-for-paramsfrom
copilot/fix-github-actions-workflow

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Apr 6, 2026

📝 Update Information

Primitive Details

  • Type: Tool
  • Name: All CLI tools registered via registerCLITool + codeql_resolve_queries integration test
  • Update Category: Bug Fix

⚠️ CRITICAL: PR SCOPE VALIDATION

ALLOWED FILES:

  • Server implementation files (server/src/**/*.ts)
  • Modified registration files (server/src/tools/*.ts)
  • Updated test files (server/test/**/*.ts)
  • Client integration test runner (client/src/lib/integration-test-runner.js)

🚫 FORBIDDEN FILES: None included.


🛑 MANDATORY PR VALIDATION CHECKLIST

  • ONLY server implementation files are included
  • NO temporary or output files are included
  • NO unrelated configuration files are included
  • ALL existing tests continue to pass
  • NEW functionality is properly tested

  • Impact Scope: Extensive — affects all 24 CLI tool registrations and one integration test

Update Metadata

  • Breaking Changes: No
  • API Compatibility: Maintained
  • Performance Impact: Neutral

🎯 Changes Description

Current Behavior

Server crashes at startup on every OS:

Error: Tool codeql_bqrs_decode expected a Zod schema or ToolAnnotations,
       but received an unrecognized object
    at McpServer.tool (...)
    at registerCLITool (...)

The codeql_resolve_queries/resolve_queries integration test sends params.path which doesn't exist in the tool schema, causing validation rejection.

Updated Behavior

Server starts successfully. All 24 CLI tools register without error. The codeql_resolve_queries integration test uses the correct parameter name directory.

Motivation

buildEnhancedToolSchema() returns a ZodEffects object (via .passthrough().transform()). The MCP SDK's tool() argument parser calls isZodRawShapeCompat() which returns false for any Zod schema instance (it checks isZodSchemaInstance() first). The object then falls into the ToolAnnotations branch, which rejects it because Zod internals contain nested objects.

registerTool() bypasses this argument-parsing entirely — it passes inputSchema directly to getZodSchemaObject(), which correctly recognizes ZodEffects as a valid schema instance.

🔄 Before vs. After Comparison

Functionality Changes

// BEFORE: tool() rejects ZodEffects via isZodRawShapeCompat() → throws
server.tool(
  name,
  description,
  enhancedSchema as unknown as Record<string, z.ZodTypeAny>,
  async (params) => { /* ... */ }
);

// AFTER: registerTool() passes schema directly to getZodSchemaObject() → works
server.registerTool(
  name,
  { description, inputSchema: enhancedSchema },
  async (params) => { /* ... */ }
);

API Changes

No external API changes. registerTool() is the non-deprecated replacement for tool() in the MCP SDK.

Output Format Changes

No output format changes.

🧪 Testing & Validation

Test Coverage Updates

  • Existing Tests: All existing tests continue to pass
  • New Test Cases: N/A — existing tests updated to match new call signature
  • Regression Tests: Existing param-normalization tests cover the ZodEffects schema
  • Edge Case Tests: N/A

Validation Scenarios

  1. Backward Compatibility: All 1281 unit tests pass — tool behavior unchanged
  2. New Functionality: N/A — bug fix only
  3. Error Handling: Param normalization still rejects unknown properties (verified via codeql_resolve_queries test fix)
  4. Performance: No performance-sensitive changes

Test Results

  • Unit Tests: All pass (1281/1281 tests, 58/58 files)
  • Integration Tests: codeql_resolve_queries/resolve_queries fixed; codeql_pack_install/install_pack passes in CI (fails in sandbox only due to SSL cert issue reaching GHCR)
  • Manual Testing: Verified server starts and registers all tools
  • Performance Testing: No regressions detected

📋 Implementation Details

Files Modified

  • Core Implementation: server/src/lib/cli-tool-registry.tsserver.tool()server.registerTool()
  • Tests: server/test/src/lib/cli-tool-registry.test.ts — mock registerTool instead of tool, fix handler extraction index [0][3][0][2]
  • Tests: server/test/src/tools/codeql-tools.test.ts — mock both tool and registerTool, split tool count assertion, fix CLI tool description access via config object
  • Integration Test Runner: client/src/lib/integration-test-runner.jsparams.pathparams.directory for codeql_resolve_queries

Code Changes Summary

  • Bug Fixes: Fixed server crash from ZodEffects schema rejection; fixed wrong parameter name in integration test
  • Error Handling: Param normalization continues to work correctly via the ZodEffects .transform() pipeline

Dependencies

  • No New Dependencies: Uses existing @modelcontextprotocol/sdk registerTool() API

🔍 Quality Improvements

Bug Fixes (if applicable)

  • Issue: Server crashes at startup — tool() rejects ZodEffects schema as "unrecognized object"
  • Root Cause: SDK's isZodRawShapeCompat() returns false for Zod schema instances, then the ToolAnnotations branch rejects nested objects in Zod internals
  • Solution: Use registerTool() which routes inputSchema through getZodSchemaObject(), correctly handling any Zod schema type
  • Prevention: registerTool() is the SDK's recommended non-deprecated API; it doesn't rely on fragile argument-position heuristics

Code Quality Enhancements

  • Readability: Removed unsafe as unknown as Record<string, z.ZodTypeAny> cast
  • Maintainability: Uses the SDK's recommended registerTool() API instead of deprecated tool() overloads

🔗 References

External References

  • MCP SDK tool() deprecation: @modelcontextprotocol/sdk/dist/esm/server/mcp.d.ts lines 110-144

🚀 Compatibility & Migration

Backward Compatibility

  • Fully Compatible: No breaking changes

API Evolution

  • Maintained Contracts: Core API contracts preserved — all tools register with identical schemas and handlers

👥 Review Guidelines

For Reviewers

Please verify:

  • ⚠️ SCOPE COMPLIANCE: PR contains only server implementation files
  • ⚠️ NO UNRELATED FILES: No temporary, output, or unrelated files
  • ⚠️ BACKWARD COMPATIBILITY: Existing functionality preserved
  • Functionality: Updates work as described
  • Test Coverage: All existing tests pass, updated tests match new API
  • Code Quality: Maintains or improves code quality

Testing Instructions

npm run build-and-test   # From repo root — builds + runs all 1281 unit tests
npm run lint:fix          # Verify lint compliance

📊 Impact Assessment

Server Impact

  • Startup Time: No significant impact on server startup
  • Runtime Stability: Fixes startup crash — major stability improvement
  • Resource Usage: No change
  • Concurrent Usage: No change

AI Assistant Impact

  • Improved Reliability: Server no longer crashes at startup

Copilot AI and others added 2 commits April 6, 2026 19:15
…s schema rejection by MCP SDK

The MCP SDK's tool() method argument parsing rejects ZodEffects schemas
(from buildEnhancedToolSchema) as 'unrecognized objects' because its
isZodRawShapeCompat() check returns false for Zod schema instances.

registerTool() passes inputSchema directly to getZodSchemaObject(),
which correctly recognises any Zod schema instance, avoiding the error:
'Tool codeql_bqrs_decode expected a Zod schema or ToolAnnotations,
but received an unrecognized object'

Agent-Logs-Url: https://github.com/advanced-security/codeql-development-mcp-server/sessions/ba14c9e0-173d-49fd-820b-b77bfdd973b0

Co-authored-by: data-douser <70299490+data-douser@users.noreply.github.com>
…eql_resolve_queries integration test

The codeql_resolve_queries tool schema defines 'directory' as the parameter
for specifying the directory to search for queries, but the integration test
runner was sending 'path' which was rejected as an unknown property by the
parameter normalization layer.

Agent-Logs-Url: https://github.com/advanced-security/codeql-development-mcp-server/sessions/ba14c9e0-173d-49fd-820b-b77bfdd973b0

Co-authored-by: data-douser <70299490+data-douser@users.noreply.github.com>
@data-douser data-douser marked this pull request as ready for review April 6, 2026 20:22
@data-douser data-douser requested review from a team, data-douser and enyil as code owners April 6, 2026 20:22
@data-douser data-douser merged commit 92af8e0 into copilot/improve-error-message-for-params Apr 6, 2026
@data-douser data-douser deleted the copilot/fix-github-actions-workflow branch April 6, 2026 20:26
data-douser added a commit that referenced this pull request Apr 7, 2026
…onable error messages for CLI tools (#224)

* Initial plan

* feat: improve error messages for unrecognized CLI tool params and accept camelCase aliases

Add parameter normalization layer (buildEnhancedToolSchema) that:
- Silently normalizes camelCase/snake_case keys to kebab-case equivalents
  (e.g. sourceRoot → source-root)
- Rejects truly unknown properties with the property name in the error
  and a "did you mean?" suggestion when a close match exists
- Applies to all 16+ CLI tools that use kebab-case parameter names

Closes #208 (Area 2)

Agent-Logs-Url: https://github.com/advanced-security/codeql-development-mcp-server/sessions/5ed1c1a7-10c5-4e53-8454-128d1d6e46ae

Co-authored-by: data-douser <70299490+data-douser@users.noreply.github.com>

* [UPDATE PRIMITIVE] Fix ZodEffects schema rejection in CLI tool registration and resolve_queries parameter name (#225)

* fix: use registerTool() instead of deprecated tool() to fix ZodEffects schema rejection by MCP SDK

The MCP SDK's tool() method argument parsing rejects ZodEffects schemas
(from buildEnhancedToolSchema) as 'unrecognized objects' because its
isZodRawShapeCompat() check returns false for Zod schema instances.

registerTool() passes inputSchema directly to getZodSchemaObject(),
which correctly recognises any Zod schema instance, avoiding the error:
'Tool codeql_bqrs_decode expected a Zod schema or ToolAnnotations,
but received an unrecognized object'

Agent-Logs-Url: https://github.com/advanced-security/codeql-development-mcp-server/sessions/ba14c9e0-173d-49fd-820b-b77bfdd973b0

Co-authored-by: data-douser <70299490+data-douser@users.noreply.github.com>

* fix: use correct parameter name 'directory' instead of 'path' for codeql_resolve_queries integration test

The codeql_resolve_queries tool schema defines 'directory' as the parameter
for specifying the directory to search for queries, but the integration test
runner was sending 'path' which was rejected as an unknown property by the
parameter normalization layer.

Agent-Logs-Url: https://github.com/advanced-security/codeql-development-mcp-server/sessions/ba14c9e0-173d-49fd-820b-b77bfdd973b0

Co-authored-by: data-douser <70299490+data-douser@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: data-douser <70299490+data-douser@users.noreply.github.com>

* fix: capture suggestion alongside unknownEntries for "did you mean?" hints

The hint is now stored at determination time rather than re-computed
in the error loop (where it was always undefined). When both kebab-case
and camelCase forms are provided (e.g. source-root + sourceRoot), the
duplicate is now rejected with a "did you mean?" suggestion instead of
being silently ignored.

Agent-Logs-Url: https://github.com/advanced-security/codeql-development-mcp-server/sessions/02a09bd4-39e4-4e83-968e-8562405a9f4c

Co-authored-by: data-douser <70299490+data-douser@users.noreply.github.com>

* More fixes for PR review feedback

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: data-douser <70299490+data-douser@users.noreply.github.com>
Co-authored-by: Nathan Randall <data-douser@github.com>
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.

2 participants