Skip to content

fix(server): treat text/* mime types case-insensitively for FileResource#2918

Open
ly-wang19 wants to merge 2 commits into
modelcontextprotocol:mainfrom
ly-wang19:fix/file-resource-mime-type-case-insensitive
Open

fix(server): treat text/* mime types case-insensitively for FileResource#2918
ly-wang19 wants to merge 2 commits into
modelcontextprotocol:mainfrom
ly-wang19:fix/file-resource-mime-type-case-insensitive

Conversation

@ly-wang19

Copy link
Copy Markdown

Summary

FileResource.set_binary_from_mime_type decides whether to read a file as text or bytes from its mime_type via mime_type.startswith("text/"). Media types are case-insensitive (RFC 9110, §8.3.1), so a FileResource declared with an upper/mixed-case text type — e.g. mime_type="Text/Markdown" — is misclassified as binary and read with read_bytes instead of read_text, returning a bytes blob to clients instead of text.

Fix

Lower-case the mime type before the prefix check, consistent with the SDK's other media-type checks (transport_security, client streamable_http).

Test

Added test_uppercase_text_mime_type_is_treated_as_text: a FileResource(mime_type="Text/Markdown") keeps is_binary False.

Verified red→green: the new test fails on main (treated as binary) and passes with the fix. uv run pytest tests/server/mcpserver/resources/test_file_resources.py8 passed; ruff check / ruff format --check clean.

Media types are case-insensitive (RFC 9110, section 8.3.1), and
StreamableHTTPServerTransport._check_accept_headers already lowercases the
Accept media types before comparing. _check_content_type did not, so a
spec-valid request with a mixed/upper-case Content-Type (e.g.
"Application/JSON") was rejected with 415 Unsupported Media Type.

Lowercase the parsed Content-Type media type before comparing to
CONTENT_TYPE_JSON, consistent with _check_accept_headers. Adds a unit test for
case-insensitive matching (the _check_content_type path was previously no-cover).
FileResource.set_binary_from_mime_type decides whether to read a file as text
or bytes via `mime_type.startswith("text/")`, but media types are
case-insensitive (RFC 9110, section 8.3.1). A FileResource declared with an
upper/mixed-case text type (e.g. "Text/Markdown") was misclassified as binary
and read with read_bytes instead of read_text.

Normalize with .lower() before the prefix check, consistent with the other
media-type checks in the SDK (transport_security, client streamable_http).
Adds a regression test.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant