Exception: MCPClient::Errors::ServerError

Inherits:
MCPError
  • Object
show all
Defined in:
lib/mcp_client/errors.rb

Overview

Raised when the MCP server returns an error response. Carries the JSON-RPC error code and data so callers can distinguish protocol errors (e.g. -32602 resource not found) without parsing the message.

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from MCPError

#era_inconclusive?

Constructor Details

#initialize(message = nil, code: nil, data: nil) ⇒ ServerError

Returns a new instance of ServerError.

Parameters:

  • message (String, nil) (defaults to: nil) —

    error message

  • code (Integer, nil) (defaults to: nil) —

    JSON-RPC error code

  • data (Object, nil) (defaults to: nil) —

    JSON-RPC error data



153
154
155
156
157
# File 'lib/mcp_client/errors.rb', line 153

def initialize(message = nil, code: nil, data: nil)
  super(message)
  @code = code
  @data = data
end

Instance Attribute Details

#code ⇒ Integer? (readonly)

Returns the JSON-RPC error code, if the response carried one.

Returns:

  • (Integer, nil) —

    the JSON-RPC error code, if the response carried one



143
144
145
# File 'lib/mcp_client/errors.rb', line 143

def code
  @code
end

#data ⇒ Object? (readonly)

Returns the JSON-RPC error data member, if any.

Returns:

  • (Object, nil) —

    the JSON-RPC error data member, if any



145
146
147
# File 'lib/mcp_client/errors.rb', line 145

def data
  @data
end

#http_status ⇒ Integer?

Returns the HTTP status the error arrived with, when it was carried in an HTTP error response body.

Returns:

  • (Integer, nil) —

    the HTTP status the error arrived with, when it was carried in an HTTP error response body



148
149
150
# File 'lib/mcp_client/errors.rb', line 148

def http_status
  @http_status
end

Class Method Details

.from_jsonrpc(error) ⇒ MCPClient::Errors::ServerError

Build the most specific error for a JSON-RPC error object: the typed 2026-07-28 errors for the spec-reserved codes, a plain ServerError otherwise. The message is peer-supplied and passed through as-is.

A JSON-RPC 2.0 error object MUST carry a string message. One that does not is malformed at the JSON-RPC level, so it never earns a typed class — and so can never identify a modern server (see ModernProtocolError) — even though its code and data are still preserved on the plain ServerError for the caller to inspect.

Parameters:

  • error (Hash, nil) —

    the JSON-RPC error member ('code', 'message', 'data')

Returns:



170
171
172
173
174
175
176
177
178
179
# File 'lib/mcp_client/errors.rb', line 170

def self.from_jsonrpc(error)
  error = {} unless error.is_a?(Hash)
  message = error['message'] || error[:message]
  code = error['code'] || error[:code]
  code = nil unless code.is_a?(Integer)
  data = error.key?('data') ? error['data'] : error[:data]

  klass = wire_message?(message) ? error_class_for(code) : ServerError
  klass.new(message || 'Unknown server error', code: code, data: data)
end

Instance Method Details

#modern_http_protocol_error? ⇒ Boolean

Whether the error identifies a modern server on a Streamable HTTP POST. Beyond the transport-agnostic reserved codes, Streamable HTTP backward compatibility names one more recognized modern error: an unknown method answered with HTTP 404 and a JSON-RPC -32601 body. That pairing is why this predicate is separate rather than a wider code list — on stdio a bare -32601 is exactly what a legacy peer answers a modern probe with, so folding it into #modern_protocol_error? would suppress the initialize fallback that must happen there.

The JSON-RPC 2.0 envelope is already required upstream: only #jsonrpc_error_from_http_response sets http_status, and it assigns a code solely from a body that carried "jsonrpc": "2.0" and an error object. An error that never arrived over HTTP has no status and is therefore never recognized here. The 404 rule itself lives on MethodNotFoundError, which from_jsonrpc assigns only to a -32601 whose error object is well-formed (a string message): a 404 page dressed up as {"error": {"code": -32601}} is malformed at the JSON-RPC level and identifies nobody, exactly like a bare -3202x.

Returns:

  • (Boolean)


234
235
236
# File 'lib/mcp_client/errors.rb', line 234

def modern_http_protocol_error?
  modern_protocol_error?
end

#modern_protocol_error? ⇒ Boolean

Whether this is one of the 2026-07-28 spec-defined protocol errors, carrying the wire shape its schema mandates. Only such a well-formed error identifies a modern server: a legacy endpoint or intermediary that happens to emit a bare -3202x code must not suppress the fallback. A plain ServerError never does — including the one from_jsonrpc builds for an error object with no string message.

Returns:

  • (Boolean)


211
212
213
# File 'lib/mcp_client/errors.rb', line 211

def modern_protocol_error?
  false
end

#modern_protocol_error_for_probe? ⇒ Boolean

Whether a server/discover probe answered with this error identifies a modern server (a recognized modern error, or a malformed modern result). Non-error transport failures never do.

Returns:

  • (Boolean)


259
260
261
# File 'lib/mcp_client/errors.rb', line 259

def modern_protocol_error_for_probe?
  modern_protocol_error?
end

#protocol_error? ⇒ Boolean

Whether the error is protocol-level (a modern spec error or an invalid result) rather than an application-level failure. Public transport methods let these propagate instead of wrapping them. A 404 + -32601 is deliberately NOT one: it says the peer is modern, but "method not found" is an ordinary application failure that the calling wrapper should keep describing in its own terms.

Returns:

  • (Boolean)


245
246
247
# File 'lib/mcp_client/errors.rb', line 245

def protocol_error?
  modern_protocol_error?
end

#well_formed? ⇒ Boolean

Subclasses with a mandated data shape override this.

Returns:

  • (Boolean)


251
252
253
# File 'lib/mcp_client/errors.rb', line 251

def well_formed?
  true
end