Repository navigation
Commit aa95cdf
committed
fix(mcpserver): base64-encode bytes tool output instead of crashing on non-UTF-8
A tool annotated `-> bytes` advertises output schema {"type":"string","format":"binary"}, but returning non-UTF-8 binary data (e.g. PNG magic bytes) crashed with PydanticSerializationError.
Root cause: _convert_to_content fed bytes to pydantic_core.to_json, which UTF-8-decodes them (fallback=str only applies to types pydantic cannot serialize), and the generated structured-output model serialized bytes with the default ser_json_bytes='utf8'. Both raise on non-UTF-8 bytes; UTF-8-decodable bytes also came back as a raw JSON string rather than base64.
Fix:
- _convert_to_content now base64-encodes bytes before the to_json branch, matching Image/Audio and the lowlevel server, so all bytes become a consistent base64 string.
- Generated output models (_create_wrapped_model, _create_model_from_class) set ser_json_bytes='base64' so the structured-content path serializes bytes as base64 instead of crashing.
- StrictJsonSchema.bytes_schema pins the advertised schema to format: binary, so ser_json_bytes='base64' does not leak base64url into outputSchema.
Only generated output models are covered; a user-defined BaseModel/TypedDict with a bytes field is unchanged (pydantic forbids a TypeAdapter config override there).
Signed-off-by: Udaya Tejas <udayatejas2004@gmail.com>1 parent 91941ed commit aa95cdf
2 files changed
Lines changed: 99 additions & 4 deletions
File tree
- src/mcp/server/mcpserver/utilities
- tests/server/mcpserver
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
1 | 2 | | |
2 | 3 | | |
3 | 4 | | |
| |||
22 | 23 | | |
23 | 24 | | |
24 | 25 | | |
25 | | - | |
| 26 | + | |
| 27 | + | |
26 | 28 | | |
27 | 29 | | |
28 | 30 | | |
| |||
73 | 75 | | |
74 | 76 | | |
75 | 77 | | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
76 | 83 | | |
77 | 84 | | |
78 | 85 | | |
| |||
577 | 584 | | |
578 | 585 | | |
579 | 586 | | |
580 | | - | |
| 587 | + | |
| 588 | + | |
| 589 | + | |
| 590 | + | |
| 591 | + | |
581 | 592 | | |
582 | 593 | | |
583 | 594 | | |
| |||
618 | 629 | | |
619 | 630 | | |
620 | 631 | | |
621 | | - | |
| 632 | + | |
| 633 | + | |
| 634 | + | |
| 635 | + | |
| 636 | + | |
| 637 | + | |
| 638 | + | |
| 639 | + | |
622 | 640 | | |
623 | 641 | | |
624 | 642 | | |
| |||
649 | 667 | | |
650 | 668 | | |
651 | 669 | | |
| 670 | + | |
| 671 | + | |
| 672 | + | |
| 673 | + | |
| 674 | + | |
652 | 675 | | |
653 | 676 | | |
654 | 677 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
3 | 3 | | |
4 | 4 | | |
5 | 5 | | |
| 6 | + | |
6 | 7 | | |
7 | 8 | | |
8 | 9 | | |
| |||
17 | 18 | | |
18 | 19 | | |
19 | 20 | | |
20 | | - | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
21 | 27 | | |
22 | 28 | | |
23 | 29 | | |
| |||
724 | 730 | | |
725 | 731 | | |
726 | 732 | | |
| 733 | + | |
| 734 | + | |
| 735 | + | |
| 736 | + | |
| 737 | + | |
| 738 | + | |
| 739 | + | |
| 740 | + | |
| 741 | + | |
| 742 | + | |
| 743 | + | |
| 744 | + | |
| 745 | + | |
| 746 | + | |
| 747 | + | |
| 748 | + | |
| 749 | + | |
| 750 | + | |
| 751 | + | |
| 752 | + | |
| 753 | + | |
| 754 | + | |
| 755 | + | |
| 756 | + | |
| 757 | + | |
| 758 | + | |
| 759 | + | |
| 760 | + | |
| 761 | + | |
| 762 | + | |
| 763 | + | |
| 764 | + | |
| 765 | + | |
| 766 | + | |
| 767 | + | |
| 768 | + | |
| 769 | + | |
| 770 | + | |
| 771 | + | |
| 772 | + | |
| 773 | + | |
| 774 | + | |
| 775 | + | |
| 776 | + | |
| 777 | + | |
| 778 | + | |
| 779 | + | |
| 780 | + | |
| 781 | + | |
| 782 | + | |
| 783 | + | |
| 784 | + | |
| 785 | + | |
| 786 | + | |
| 787 | + | |
| 788 | + | |
| 789 | + | |
| 790 | + | |
| 791 | + | |
| 792 | + | |
| 793 | + | |
| 794 | + | |
| 795 | + | |
| 796 | + | |
| 797 | + | |
| 798 | + | |
727 | 799 | | |
728 | 800 | | |
729 | 801 | | |
| |||
0 commit comments