Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
7dca602
Initial plan
Copilot Dec 5, 2025
4287694
Update protocol types to use ReadOnlyMemory<byte> for binary data
Copilot Dec 5, 2025
8e6fcf0
Fix test files to work with new binary data representation
Copilot Dec 5, 2025
e405dfc
Add cache invalidation when Blob/Data properties are set
Copilot Dec 5, 2025
ebe3eef
Apply performance optimizations using MemoryMarshal.TryGetArray
Copilot Dec 8, 2025
1d76c11
Use GetBytes overload with offset and count parameters
Copilot Dec 8, 2025
39213fb
Use Base64.DecodeFromUtf8 to avoid string intermediate during decoding
Copilot Dec 9, 2025
a4ba4a9
Merge branch 'main' into copilot/fix-binary-data-encoding
ericstj Jan 27, 2026
b4e4eaf
Fix merge conflict with DebuggerDisplay
ericstj Jan 27, 2026
61f0dfa
Cleanup refactoring
ericstj Jan 27, 2026
5de847c
Remove string from DataContent conversion
ericstj Jan 29, 2026
dc01608
Add factory methods to data backed types to efficiently initialize fr…
ericstj Jan 29, 2026
2fc35d9
Update some tests to use factory methods
ericstj Jan 29, 2026
14fedca
Fix test assertions in McpServerToolTests
ericstj Jan 30, 2026
b3eacff
Merge branch 'main' of https://github.com/modelcontextprotocol/csharp…
ericstj Jan 30, 2026
0a3015f
Address code review feedback: rename Data to DecodedData, use span-ba…
Copilot Feb 6, 2026
e4f2816
Address code review: remove zero-copy claims, rename FromImage/FromAu…
Copilot Feb 7, 2026
d72030e
Apply feedback
ericstj Feb 10, 2026
d90737f
Remove ifdef and optimize an encoding method
ericstj Feb 10, 2026
5860b78
Address feedback
ericstj Feb 19, 2026
05e906c
Fix up doc comments
ericstj Feb 19, 2026
a9ad676
Merge branch 'main' of https://github.com/modelcontextprotocol/csharp…
ericstj Feb 19, 2026
51acfd5
Fix a couple new tests
ericstj Feb 19, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using System.Runtime.InteropServices;
using System.Text.Json.Serialization;

namespace ModelContextProtocol.Protocol;
Expand Down Expand Up @@ -56,10 +57,11 @@ public ReadOnlyMemory<byte> Data
{
if (_decodedData is null)
{
#if NET6_0_OR_GREATER
#if NET
_decodedData = Convert.FromBase64String(System.Text.Encoding.UTF8.GetString(Blob.Span));
#else
_decodedData = Convert.FromBase64String(System.Text.Encoding.UTF8.GetString(Blob.ToArray()));
byte[] array = MemoryMarshal.TryGetArray(Blob, out ArraySegment<byte> segment) && segment.Offset == 0 && segment.Count == segment.Array!.Length ? segment.Array : Blob.ToArray();
_decodedData = Convert.FromBase64String(System.Text.Encoding.UTF8.GetString(array));
#endif
}
return _decodedData;
Expand Down
11 changes: 7 additions & 4 deletions src/ModelContextProtocol.Core/Protocol/ContentBlock.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using System.ComponentModel;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Runtime.InteropServices;
using System.Text.Json;
using System.Text.Json.Nodes;
using System.Text.Json.Serialization;
Expand Down Expand Up @@ -419,10 +420,11 @@ public ReadOnlyMemory<byte> DecodedData
{
if (_decodedData is null)
{
#if NET6_0_OR_GREATER
#if NET
_decodedData = Convert.FromBase64String(System.Text.Encoding.UTF8.GetString(Data.Span));
#else
_decodedData = Convert.FromBase64String(System.Text.Encoding.UTF8.GetString(Data.ToArray()));
byte[] array = MemoryMarshal.TryGetArray(Data, out ArraySegment<byte> segment) && segment.Offset == 0 && segment.Count == segment.Array!.Length ? segment.Array : Data.ToArray();
_decodedData = Convert.FromBase64String(System.Text.Encoding.UTF8.GetString(array));
#endif
Comment thread
stephentoub marked this conversation as resolved.
Outdated
}
return _decodedData;
Expand Down Expand Up @@ -479,10 +481,11 @@ public ReadOnlyMemory<byte> DecodedData
{
if (_decodedData is null)
{
#if NET6_0_OR_GREATER
#if NET
_decodedData = Convert.FromBase64String(System.Text.Encoding.UTF8.GetString(Data.Span));
#else
_decodedData = Convert.FromBase64String(System.Text.Encoding.UTF8.GetString(Data.ToArray()));
byte[] array = MemoryMarshal.TryGetArray(Data, out ArraySegment<byte> segment) && segment.Offset == 0 && segment.Count == segment.Array!.Length ? segment.Array : Data.ToArray();
_decodedData = Convert.FromBase64String(System.Text.Encoding.UTF8.GetString(array));
#endif
Comment thread
stephentoub marked this conversation as resolved.
Outdated
}
return _decodedData;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
using System.Globalization;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Text;
using System.Text.Json;
using System.Text.Json.Nodes;
Expand Down Expand Up @@ -391,7 +392,14 @@ public override async ValueTask<ReadResourceResult> ReadAsync(

DataContent dc => new()
{
Contents = [new BlobResourceContents { Uri = request.Params!.Uri, MimeType = dc.MediaType, Blob = System.Text.Encoding.UTF8.GetBytes(dc.Base64Data.ToString()) }],
Contents = [new BlobResourceContents
{
Uri = request.Params!.Uri,
MimeType = dc.MediaType,
Blob = MemoryMarshal.TryGetArray(dc.Base64Data, out ArraySegment<char> segment) && segment.Offset == 0 && segment.Count == segment.Array!.Length
Comment thread
ericstj marked this conversation as resolved.
Outdated
? System.Text.Encoding.UTF8.GetBytes(segment.Array)
: System.Text.Encoding.UTF8.GetBytes(dc.Base64Data.ToString())
}],
},

string text => new()
Expand Down Expand Up @@ -420,7 +428,9 @@ public override async ValueTask<ReadResourceResult> ReadAsync(
{
Uri = request.Params!.Uri,
MimeType = dc.MediaType,
Blob = System.Text.Encoding.UTF8.GetBytes(dc.Base64Data.ToString())
Blob = MemoryMarshal.TryGetArray(dc.Base64Data, out ArraySegment<char> segment) && segment.Offset == 0 && segment.Count == segment.Array!.Length
? System.Text.Encoding.UTF8.GetBytes(segment.Array)
: System.Text.Encoding.UTF8.GetBytes(dc.Base64Data.ToString())
},

_ => throw new InvalidOperationException($"Unsupported AIContent type '{ac.GetType()}' returned from resource function."),
Expand Down