## Motivation and Context
PR #347 introduced a single JSON-RPC error envelope response for
unsupported `MCP-Protocol-Version` headers, while the rest of the
transport-level error responses (Accept, Content-Type, Invalid JSON,
session management, method not allowed, internal server error) still
returned plain JSON of the form `{ "error": "..." }`. The Python SDK
(`src/mcp/server/streamable_http.py`) and TypeScript SDK
(`packages/server/src/server/streamableHttp.ts`) consistently use
a JSON-RPC error envelope for all transport-level errors.
Unify the Ruby SDK with them.
## Behavior
All transport-level error responses now return a JSON-RPC error envelope:
```json
{
"jsonrpc": "2.0",
"id": null,
"error": {
"code": -32600,
"message": "..."
}
}
```
Affected helpers in `lib/mcp/server/transports/streamable_http_transport.rb`:
- `validate_content_type` (HTTP 415)
- `not_acceptable_response` (HTTP 406)
- `parse_request_body` error (HTTP 400, `PARSE_ERROR` `-32700`)
- `method_not_allowed_response` (HTTP 405)
- `missing_session_id_response` (HTTP 400)
- `session_not_found_response` (HTTP 404)
- `session_already_connected_response` (HTTP 409)
- Internal server error fallback in `handle_post` (HTTP 500, `INTERNAL_ERROR` `-32603`)
- `validate_protocol_version_header` (HTTP 400, dedup with shared helper)
A new private helper `json_rpc_error_response(status:, code:, message:)`
centralizes the envelope construction.
The "Invalid JSON" message wording is updated to "Parse error: Invalid JSON"
to match the JSON-RPC 2.0 `PARSE_ERROR` semantics.
## How Has This Been Tested?
Updated all affected tests in `test/mcp/server/transports/streamable_http_transport_test.rb` to
assert the new envelope shape (`body["error"]["message"]` instead of `body["error"]`).
## Breaking Changes
Clients that parsed the previous plain `{"error": "..."}` shape will need to read
`body["error"]["message"]` (or `body["error"]["code"]`).
The HTTP status codes are unchanged, only the response body structure changed.