Skip to content

Gracefully handle numeric parameters passed as strings#2130

Merged
almaleksia merged 3 commits intomainfrom
almaleksia/gracefully-handle-string-params
Mar 4, 2026
Merged

Gracefully handle numeric parameters passed as strings#2130
almaleksia merged 3 commits intomainfrom
almaleksia/gracefully-handle-string-params

Conversation

@almaleksia
Copy link
Contributor

@almaleksia almaleksia commented Mar 3, 2026

Summary

This PR changes prevent tools that accept numeric values from failing when number is passed as string.

Why

Fixes #2044

What changed

  1. Changed Decode to WeakDecode to do type coercion when numeric value is passed as string.
  2. Changed RequiredInt validation to first perform string conversion to int

Tested locally.

MCP impact

  • No tool or API changes
  • Tool schema or behavior changed
  • New tool added

Prompts tested (tool changes only)

Security / limits

  • No security or limits impact
  • Auth / permissions considered
  • Data exposure, filtering, or token/size limits considered

Tool renaming

  • I am renaming tools as part of this PR (e.g. a part of a consolidation effort)
    • I have added the new tool aliases in deprecated_tool_aliases.go
  • I am not renaming tools as part of this PR

Note: if you're renaming tools, you must add the tool aliases. For more information on how to do so, please refer to the official docs.

Lint & tests

  • Linted locally with ./script/lint
  • Tested locally with ./script/test

Docs

  • Not needed
  • Updated (README / docs / examples)
  • [ ]

@almaleksia almaleksia requested a review from a team as a code owner March 3, 2026 15:28
Copilot AI review requested due to automatic review settings March 3, 2026 15:28
v, err := RequiredParam[float64](args, p)
if err != nil {
return 0, err
v, ok := args[p]
Copy link
Contributor Author

@almaleksia almaleksia Mar 3, 2026

Choose a reason for hiding this comment

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

the most important change is here and in OptionalIntParam

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR aims to make tool argument handling more tolerant of MCP clients that send numeric inputs as JSON strings by adding weak type coercion during parameter decoding and by extending numeric parameter helpers to parse numeric strings.

Changes:

  • Switched several tool handlers from mapstructure.Decode to mapstructure.WeakDecode to allow string→number coercion during decode.
  • Added toFloat64 plus updated numeric param helpers (RequiredInt, RequiredBigInt, OptionalIntParam) to accept numeric strings.
  • Added unit tests covering numeric-string inputs for PR reviews, discussions, Copilot assignment, and param helpers.

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
pkg/github/pullrequests.go Uses mapstructure.WeakDecode for PR review-related handler param decoding.
pkg/github/discussions.go Uses mapstructure.WeakDecode for discussion handler param decoding.
pkg/github/copilot.go Uses mapstructure.WeakDecode for Copilot assignment handler param decoding.
pkg/github/params.go Adds numeric string parsing helper and updates int parsing helpers.
pkg/github/pullrequests_test.go Adds tests covering string-encoded numeric inputs for PR review tools.
pkg/github/discussions_test.go Adds tests covering string-encoded numeric inputs for discussion tools.
pkg/github/copilot_test.go Adds tests covering string-encoded numeric inputs for Copilot assignment.
pkg/github/params_test.go Adds tests for numeric-string inputs in param helpers and pagination.
Comments suppressed due to low confidence (2)

pkg/github/discussions.go:421

  • Same concern here: changing to WeakDecode won't help if argument validation occurs before handler execution. Since the tool's InputSchema still uses type: number for discussionNumber (and pagination params via WithCursorPagination), clients sending strings will still fail validation unless the schema or pre-validation layer is updated.
			if err := mapstructure.WeakDecode(args, &params); err != nil {
				return utils.NewToolResultError(err.Error()), nil, nil

pkg/github/pullrequests.go:1909

  • Same as above: WeakDecode helps only after the handler starts. If schema validation happens before handler execution, string values for pullNumber/line/startLine will still fail because the tool input schema continues to declare these as type: number. Consider updating the schema (e.g., allow string-or-number) or adding coercion before validation.
			if err := mapstructure.WeakDecode(args, &params); err != nil {
				return utils.NewToolResultError(err.Error()), nil, nil

Copy link
Contributor

@mattdholloway mattdholloway left a comment

Choose a reason for hiding this comment

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

lgtm!

@SamMorrowDrums
Copy link
Collaborator

SamMorrowDrums commented Mar 3, 2026

In a lot of ways I find this ridiculous, the agents get the schema and clients could also coerce values before sending across the wire, but practically I think it's fine to just be less strict.

Thanks for addressing this, I hope it increases success with a bunch of models.

@almaleksia almaleksia merged commit b50a343 into main Mar 4, 2026
18 checks passed
@almaleksia almaleksia deleted the almaleksia/gracefully-handle-string-params branch March 4, 2026 08:01
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.

Bug: MCP clients sending numeric parameters as strings causes "Expected number, received string" validation errors

4 participants