modelcontextprotocol / modelcontextprotocol/python-sdk

Tool input schemas carry a pydantic-derived title on every property

Đang mở
#3,391 5 bình luận 0 reaction 0 người được giao Xem trên GitHub

Chưa có ai nhận issue này.

v1 v2
Ngôn ngữ chính
Python
Star
24.3k
Fork
4k
Merge trung bình
1 ngày 1 giờ
Pull request đã merge (30 ngày)
31

Mô tả

Description

Every tool's inputSchema carries a title on every property, derived by pydantic from the field name. A parameter named exercise_id gets "title": "Exercise Id" — a restatement of the key it already sits under. Tool schemas are re-sent to the model on every request, so this is paid for in context on every turn.

I ran into this running a local 27B model against the wger MCP server, where context is genuinely scarce. Measuring its live tools/list:

bytes share
whole payload, 49 tools 43,710 100%
tool descriptions (prose) 10,904 25%
auto-derived title keys (297 of them) 8,333 19%
anyOf null-wrapping on optionals 1,869 4%

My agent is granted 43 of those tools, which is ~11,100 tokens of schema against a 32k window — 42% of the context gone before the first message, once the system prompt is counted. Roughly 2,000 of those tokens are titles.

Reproduction — any tool at all:

from mcp.server.mcpserver import MCPServer

mcp = MCPServer("demo")

@mcp.tool()
def log_set(exercise_id: str, reps: int) -> str:
    """Log a set."""
    return "ok"

inputSchema.properties is:

{
  "exercise_id": {"title": "Exercise Id", "type": "string"},
  "reps": {"title": "Reps", "type": "integer"}
}

I'd expect the titles not to be there, since they add nothing a model can act on that the property name doesn't already say.

GenerateJsonSchema has a hook for exactly this — field_title_should_be_set — and Tool.from_function already passes a custom generator elsewhere in the file, so it's a small change. Suppressing the automatic titles leaves an explicit Field(title=...) intact, which seems like the right line to draw: an explicit title is the author's choice, an auto-derived one is a default nobody asked for.

Two things I'd want a maintainer's call on before this is worth doing:

  1. Default or opt-in. Changing the default updates 12 test expectations in this repo (mostly snapshot(...) in tests/docs_src/), so it's visible. An opt-in flag on MCPServer(...) avoids that but adds public API.
  2. Scope. Output schemas, prompts and resource templates generate titles the same way. Output schemas alone are another 61 titles in the payload I measured. Worth doing together, or separately?

Happy to open a PR if it's useful — I have the change and the test updates working locally against main, full suite green. Equally happy to leave it if you'd rather write it yourselves.

Disclosure: I used an AI agent to take the measurements and draft the change. The problem is one I actually hit, and I've read and can explain the result.

References

Hướng dẫn đóng góp

Mở hướng dẫn đóng góp

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.

Hướng nghiên cứu

Bắt đầu từ Tool.from_function và custom generator hiện có của nó, sau đó kiểm tra hook GenerateJsonSchema.field_title_should_be_set của Pydantic. Xem lại các kỳ vọng của snapshot trong tests/docs_src/ và trao đổi với maintainer để quyết định liệu thay đổi này chỉ áp dụng cho input schema hay cả các schema được tạo khác. Hoàn tất khi các property title tự động được loại bỏ, các Field title tường minh vẫn được giữ lại, và các test bị ảnh hưởng đã được cập nhật và chạy thành công.

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

Đánh giá

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

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.