Replace FileResource.is_binary with an encoding field

Merged
MA
3mo ago
+240-98

FileResource guessed is_binary from mime_type with a text/* prefix check, and because False doubled as the "not given" sentinel an explicit is_binary=False could never take effect, so mime_type="application/json" was always served as a base64 blob. Text reads also called Path.read_text() with no encoding, i.e. the platform locale (cp1252 on Windows).

Motivation and Context

Rather than adding a None sentinel on top of the boolean, this replaces it with encoding: str | None, the single field the read path actually consults, mirroring how the sibling SDKs let the return type (string vs bytes) carry the text-vs-blob decision:

  • a string decodes the file with that encoding and serves it as text
  • None reads bytes and serves a blob
  • when omitted, the default comes from mime_type: the declared charset= if there is one, else "utf-8" for textual types (text/*, application/json/xml/javascript, any +json/+xml suffix), else None

So JSON and XML files come back as text with no configuration, the locale is never consulted, and the ambiguous state is gone rather than special-cased.

Resource models now reject unknown keyword arguments (extra="forbid"), so passing the removed is_binary= fails at construction instead of being silently swallowed and blowing up later at read time.

How Has This Been Tested?

Unit tests cover the new default matrix (textual/binary mime types, declared charset, explicit override, rejection of is_binary). Also drove it end-to-end through an in-memory Client reading FileResources off an MCPServer:

file:///data.json      -> TextResourceContents  application/json          '{"answer": 42}\n'
file:///logo.png       -> BlobResourceContents  image/png                 <16 bytes>
file:///notes.txt      -> TextResourceContents  text/plain                'héllo wörld\n'
file:///data-blob.json -> BlobResourceContents  application/json          (explicit encoding=None)
file:///legacy.txt     -> TextResourceContents  text/plain                'naïve café'  (encoding="latin-1")
file:///vendor.json    -> TextResourceContents  application/vnd.api+json; charset=utf-8

Breaking Changes

Yes: FileResource.is_binary is removed in favour of encoding, and Resource classes now reject unknown kwargs. Documented in docs/migration.md with before/after examples.

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Documentation update

Checklist

  • I have read the MCP Documentation
  • My code follows the repository's style guidelines
  • New and existing tests pass locally
  • I have added appropriate error handling
  • I have added or updated documentation as needed

AI Disclaimer