Hacktoberfest 2026 : les issues que les mainteneurs ont marquées pour octobre, ouvertes et accessibles aux débutants. Parcourir les issues Hacktoberfest

2.2.0: binary content blocks (ImageContentBlock, BlobResourceContents) serialize invalid base64 - client-side CallToolResult deserialization throws (regression of #1340)

Ouverte
#1,835 1 commentaire 0 réactions 0 personnes assignées Voir sur GitHub

Les mainteneurs répondent en général sous 2 jours

Personne n'a encore pris cette issue.

Évaluation

Difficulté
3/5
Temps estimé
1-2 jours
Accessibilité débutants
55/100
Type d'issue
Bug
Clarté
Plutôt claire
Activité
Active
Stack technique
csharp
Domaine
api, backend

Piste de recherche

Commencez par la reproduction fournie dans la console avec McpJsonUtilities.DefaultOptions, puis suivez le chemin de sérialisation polymorphe de ContentBlock et ResourceContents et comparez-le à la sérialisation directe de BlobResourceContents. La correction est complète lorsque les données de ImageContentBlock et les blobs de BlobResourceContents sont émis sous forme de base64 valide et que CallToolResult effectue un aller-retour sans JsonException.

Rédigé par le modèle d'indexation à partir du texte de l'issue.

Description

Description

Binary content blocks (ImageContentBlock, EmbeddedResourceBlock with BlobResourceContents) round-trip incorrectly through McpJsonUtilities.DefaultOptions in 2.2.0: the writer does not emit valid base64 for the binary payload, so deserializing the produced JSON throws

System.Text.Json.JsonException: The JSON value could not be converted to ModelContextProtocol.Protocol.ResourceContents.
 ---> System.FormatException: Cannot decode JSON text that is not encoded as valid Base64 to bytes.
   at System.Text.Json.Utf8JsonReader.GetBytesFromBase64()
   at ModelContextProtocol.Protocol.ResourceContents.Converter.Read(...)

In practice this means a tool that returns a PDF via EmbeddedResourceBlock/BlobResourceContents (or an image via ImageContentBlock) over the Streamable HTTP transport breaks the client-side deserialization of the whole CallToolResult — the client (McpClient.CallToolAsync) throws and the result is lost.

This looks like a regression of #1340 / #1064: ImageContentBlock.Data is serialized as the raw bytes reinterpreted as a UTF-16 string (mostly U+FFFD replacement characters and escaped control characters in the JSON), not as base64.

Repro (console app, ModelContextProtocol.Core 2.2.0, net10.0)
using System.Text.Json;
using ModelContextProtocol;
using ModelContextProtocol.Protocol;

var bytes = new byte[900_000];
Random.Shared.NextBytes(bytes);

var result = new CallToolResult
{
    Content =
    [
        new EmbeddedResourceBlock
        {
            Resource = new BlobResourceContents
            {
                Uri = "demo://files/1/test.pdf",
                MimeType = "application/pdf",
                Blob = bytes,
            },
        },
    ],
};

var json = JsonSerializer.Serialize(result, McpJsonUtilities.DefaultOptions);
// throws FormatException("Cannot decode JSON text that is not encoded as valid Base64 to bytes."):
var back = JsonSerializer.Deserialize<CallToolResult>(json, McpJsonUtilities.DefaultOptions);

Same shape for images: serializing new ImageContentBlock { Data = bytes, MimeType = "image/png" } as ContentBlock produces a "data" property that is not base64 (raw bytes as string), and deserializing it back throws the same FormatException.

Interestingly, serializing the BlobResourceContents directly (not through the polymorphic CallToolResult/ContentBlock path) produces correct base64 — the asymmetry sits in the polymorphic converter path.

Expected behavior

blob/data are written as base64 strings (per spec) and round-trip through McpJsonUtilities.DefaultOptions.

Environment
  • ModelContextProtocol / ModelContextProtocol.Core / ModelContextProtocol.AspNetCore 2.2.0
  • .NET 10.0 (net10.0), macOS arm64
  • Observed both in the minimal repro above and end-to-end over the Streamable HTTP transport (ASP.NET Core server to McpClient)
Langage dominant
C#
Étoiles
4.6k
Forks
821
Merge moyen
9 j 3 h
PR mergées (30 j)
3

Préparer son environnement

Ouvrir dans Codespaces

Lance le conteneur de développement du projet dans votre navigateur, avec votre propre compte GitHub.

Par où commencer

  1. Lisez l'issue en entier, puis le guide de contribution du projet.
  2. Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
  3. Forkez le dépôt et travaillez sur une branche.
  4. Ouvrez une pull request qui référence le numéro de l'issue.

Autres issues de modelcontextprotocol/csharp-sdk

Toutes les issues de modelcontextprotocol/csharp-sdk

Issues similaires

Plus d'issues C#

Recevez les nouvelles issues par e-mail

Un résumé court des issues GitHub adaptées aux débutants.