Invalid UTF-8 in `MCP-Protocol-Version`, `Mcp-Method` or `Mcp-Name` gives 500 instead of 400

Abierto Apto para principiantes
#663 0 comentarios 0 reacciones 0 asignados Ver en GitHub

Los mantenedores suelen responder en 1 día

@atesgoral ya está trabajando en esto.

Desde el 6/11/2026.

  • #670 de @atesgoral — abierto
  • #671 de @koic — abierto

Evaluación

Dificultad
2/5
Tiempo estimado
1-3 horas
Aptitud para principiantes
78/100
Tipo de issue
Error
Claridad
Bien especificado
Estado de actividad
Activo
Stack tecnológico
ruby

Línea de trabajo

Empieza por lib/mcp/server/transports/streamable_http_transport.rb, especialmente por el manejo de los encabezados citados y las rutas decode_header_value y json_rpc_error_response. Reproduce el problema con la solicitud Rack proporcionada y revisa las pruebas de transporte cercanas en busca de valores de encabezado no válidos. Se considera terminado cuando el UTF-8 no válido en estos encabezados devuelve la respuesta 400 esperada sin provocar una excepción del generador JSON ni un informe de excepción.

Escrito por el modelo de indexación a partir del texto del issue.

Descripción

bug

On the modern path, StreamableHTTPTransport puts raw header values into JSON error bodies:

Rack gives header values as binary strings. Also, decode_header_value tags a decoded =?base64?...?= value as UTF-8 without checking it (:1586-1592), so an all-ASCII Mcp-Name: =?base64?/w==?= also produces an invalid string. json_rpc_error_response then calls to_json (:2064-2070), which raises JSON::GeneratorError. The rescue at :968-974 reports the exception and answers 500.

Related: #629 (a reply that cannot be generated gets Internal error) and #609 (another header that caused a 500). Open #654 adds a strict UTF-8 check when it decodes Mcp-Param-* values, but it does not change decode_header_value or these error bodies.

Repro

Run from the repository root with bundle exec ruby -I lib repro.rb:

require "mcp"
require "rack"

reported = []
MCP.configure { |config| config.exception_reporter = ->(error, _context) { reported << error.class } }
server = MCP::Server.new(name: "example")
transport = MCP::Server::Transports::StreamableHTTPTransport.new(server)

env = Rack::MockRequest.env_for(
  "http://localhost/",
  method: "POST",
  input: JSON.generate(jsonrpc: "2.0", id: 1, method: "tools/list"),
  "CONTENT_TYPE" => "application/json",
  "HTTP_ACCEPT" => "application/json, text/event-stream",
  "HTTP_MCP_PROTOCOL_VERSION" => "2026-07-28\xFF".b,
)
status, _headers, body = transport.call(env)
p [status, body.join, reported]
transport.close

Expected: 400 with "Unsupported protocol version", and no exception report. For the Mcp-Method and Mcp-Name cases, 400 with the header mismatch error (-32020).

Actual:

[500, "{\"jsonrpc\":\"2.0\",\"error\":{\"code\":-32603,\"message\":\"Internal server error\"}}", [JSON::GeneratorError]]

The same 500 happens with invalid bytes in Mcp-Method or Mcp-Name on a modern tools/call, and with Mcp-Name: =?base64?/w==?=.

Suggested fix

Check header values with valid_encoding? (after tagging them as UTF-8) before using them. Leave invalid values out of error bodies, or scrub them. Make decode_header_value refuse a decoded value that is not valid UTF-8, the same way the codec in #654 does.

Lenguaje dominante
Ruby
Estrellas
940
Forks
143
Merge medio
1 d 3 h
PR fusionados (30 d)
47

Preparar el entorno

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Más de modelcontextprotocol/ruby-sdk

Todos los issues de modelcontextprotocol/ruby-sdk

Issues similares

Más issues de Ruby

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.