mcp: typed tool arguments lose precision for large int64 values

Đã đóng
#1,201 1 bình luận 0 reaction 0 người được giao Xem trên GitHub

Maintainer thường phản hồi trong vòng 1 ngày

@jstar0 đang làm issue này rồi.

Từ ngày 6/9/2026.

  • #1244 của @jstar0 — đang mở

Đánh giá

Độ khó
3/5
Thời gian dự kiến
1-2 ngày
Mức phù hợp với người mới
74/100
Loại issue
Lỗi
Độ rõ ràng
Khá rõ ràng
Mức độ hoạt động
Sôi nổi
Công nghệ
go
Lĩnh vực
api

Hướng nghiên cứu

Bắt đầu trong mcp/tool.go và theo dõi việc áp dụng schema đối số của AddTool cùng đường dẫn mặc định, sử dụng bản tái hiện trong bộ nhớ được cung cấp làm bước kiểm tra đầu tiên. Thêm một bài kiểm thử hồi quy bao quát giá trị int64 9007199254740993 và xác minh rằng typed handler nhận được giá trị này không thay đổi, đồng thời hành vi xác thực hiện có và dữ liệu ở cuối vẫn được giữ nguyên.

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Mô tả

Describe the bug

When using the typed mcp.AddTool API, an integer larger than the IEEE-754
safe integer range can be silently rounded before it reaches the tool handler.
The value is accepted as a JSON integer, but the handler receives a different
value.

To Reproduce

Environment:

  • Go MCP SDK: v1.7.0
  • Go: go1.25.7 linux/amd64

Save the following as main.go in a module that requires
github.com/modelcontextprotocol/go-sdk v1.7.0:

package main

import (
  "context"
  "fmt"
  "log"

  "github.com/modelcontextprotocol/go-sdk/mcp"
)

type input struct {
  ID int64 `json:"id"`
}

func main() {
  const want int64 = 9007199254740993 // 2^53 + 1

  server := mcp.NewServer(
    &mcp.Implementation{Name: "server", Version: "repro"}, nil)
  mcp.AddTool(server, &mcp.Tool{Name: "echo_id"},
    func(_ context.Context, _ *mcp.CallToolRequest, in input) (
      *mcp.CallToolResult, input, error) {
      fmt.Printf("handler_received=%d\n", in.ID)
      return nil, in, nil
    })

  clientTransport, serverTransport := mcp.NewInMemoryTransports()
  ctx := context.Background()

  serverSession, err := server.Connect(ctx, serverTransport, nil)
  if err != nil {
    log.Fatal(err)
  }
  defer serverSession.Close()

  client := mcp.NewClient(
    &mcp.Implementation{Name: "client", Version: "repro"}, nil)
  clientSession, err := client.Connect(ctx, clientTransport, nil)
  if err != nil {
    log.Fatal(err)
  }
  defer clientSession.Close()

  _, err = clientSession.CallTool(ctx, &mcp.CallToolParams{
    Name: "echo_id",
    Arguments: map[string]any{"id": want},
  })
  if err != nil {
    log.Fatal(err)
  }
  fmt.Printf("want=%d\n", want)
}

Run:

go mod init example.com/mcp-int64-repro
go get github.com/modelcontextprotocol/[email protected]
go run .

Observed output:

handler_received=9007199254740992
want=9007199254740993

The issue is reproducible with the in-memory transport and does not depend on
an external server.

Expected behavior

The typed tool handler should receive exactly the integer sent by the client:

handler_received=9007199254740993
want=9007199254740993

Values representable by Go int64 should not be silently changed during
schema validation or default application.

Logs

No error is returned. The value is silently rounded.

Additional context

The behavior appears to come from the schema application path in
mcp/tool.go: tool arguments are decoded into map[string]any, and the
generic JSON number is then represented as float64. Applying defaults causes
the value to be marshaled again, making the rounding observable before the
typed handler decodes it.

A possible implementation direction is to preserve JSON numbers (for example,
using Decoder.UseNumber()) while applying the schema and defaults, while
retaining strict validation of trailing JSON data. The low-level
Server.AddTool handler path does not have this particular schema round-trip,
but it also does not provide the typed validation/default behavior.

This affects any tool that accepts IDs or counters outside the IEEE-754 safe
integer range, even though those values are valid JSON integers and valid Go
int64 values.

Ngôn ngữ chính
Go
Star
5.3k
Fork
607
Merge trung bình
1 ngày 11 giờ
Pull request đã merge (30 ngày)
82

Chuẩn bị môi trường

Mở trong Codespaces

Khởi chạy dev container của dự án ngay trên trình duyệt, bằng tài khoản GitHub của bạn.

Bắt đầu từ đâu

  1. Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
  2. Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
  3. Fork repository và làm thay đổi trên một nhánh.
  4. Mở pull request có tham chiếu số hiệu của issue.

Issue khác của modelcontextprotocol/go-sdk

Tất cả issue của modelcontextprotocol/go-sdk

Issue tương tự

Thêm issue về Go

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.