Background and motivation
MarkItDownMcpReader always sends the document as an inline base64 data: URI, so large files exceed the MCP message-size limit (413/-32600) with no alternative — even though the convert_to_markdown tool accepts file:/http: URIs. Callers whose file is reachable by the server (mounted volume, shared path, URL) should be able to have the server read it directly.
API Proposal
namespace Microsoft.Extensions.DataIngestion;
public sealed class MarkItDownMcpReaderOptions
{
public Func<FileInfo, Uri>? SourceUriResolver { get; set; }
}
public class MarkItDownMcpReader : IngestionDocumentReader
{
public MarkItDownMcpReader(
Uri mcpServerUri,
ModelContextProtocol.Client.McpClientOptions? options = null,
MarkItDownMcpReaderOptions? readerOptions = null);
}
API Usage
// Input dir mounted into the MarkItDown container at /data
var reader = new MarkItDownMcpReader(
new Uri("http://localhost:3001/mcp"),
readerOptions: new MarkItDownMcpReaderOptions
{
SourceUriResolver = fi => new Uri($"file:///data/{fi.Name}")
});
var doc = await reader.ReadAsync(new FileInfo("data/input/very_large.docx"), ct); // no inline bytes, no 413
Alternative Designs
overload ReadAsync(Uri sourceUri, string identifier, …) so callers pass a server-reachable URI directly; or add a bool InlineContent toggle plus a base-path map.
Risks
additive/opt-in — default (inline data:) is unchanged, so no breaking change. Resolver misconfiguration yields a server-side "file not found," which pairs naturally with fixing the IsError handling so it surfaces as a real error.
Background and motivation
MarkItDownMcpReaderalways sends the document as an inline base64data:URI, so large files exceed the MCP message-size limit (413/-32600) with no alternative — even though theconvert_to_markdowntool acceptsfile:/http:URIs. Callers whose file is reachable by the server (mounted volume, shared path, URL) should be able to have the server read it directly.API Proposal
API Usage
Alternative Designs
overload
ReadAsync(Uri sourceUri, string identifier, …)so callers pass a server-reachable URI directly; or add abool InlineContenttoggle plus a base-path map.Risks
additive/opt-in — default (inline
data:) is unchanged, so no breaking change. Resolver misconfiguration yields a server-side "file not found," which pairs naturally with fixing theIsErrorhandling so it surfaces as a real error.