# `ExMCP.Protocol.ErrorCodes`
[🔗](https://github.com/azmaveth/ex_mcp/blob/v1.0.0/lib/ex_mcp/protocol/error_codes.ex#L1)

JSON-RPC 2.0 and MCP-specific error codes.

This module provides constants and helper functions for working with
error codes in the MCP protocol. All error codes follow the JSON-RPC 2.0
specification with MCP-specific extensions.

## Standard JSON-RPC 2.0 Error Codes

- `-32700` - Parse error: Invalid JSON was received
- `-32600` - Invalid Request: The JSON sent is not a valid Request object
- `-32601` - Method not found: The method does not exist or is not available
- `-32602` - Invalid params: Invalid method parameter(s)
- `-32603` - Internal error: Internal JSON-RPC error

## MCP-Specific Error Codes

- `-32001` - Request cancelled: The request was cancelled by the client
- `-32002` - Resource not found on legacy MCP versions
- `-32003` - Consent denied: User denied consent for the operation
- `-32020` - Header mismatch
- `-32021` - Missing required client capability
- `-32022` - Unsupported protocol version
- `-32000` - Generic server error: Catch-all for server-side errors

## ExMCP-local Error Codes

- `-31002` - Consent required
- `-31003` - Prompt processing error

> #### Compatibility note {: .warning}
>
> `-32002` and `-32042` are historical MCP codes. Legacy peers remain
> decodable, but modern emitters use `-32602` for a missing resource and must
> not emit `-32042`. ExMCP-local consent and prompt errors live outside the
> JSON-RPC reserved range so they cannot be confused with peer protocol
> errors.

## Usage

    iex> ExMCP.Protocol.ErrorCodes.invalid_params()
    -32602

    iex> ExMCP.Protocol.ErrorCodes.error_message(:invalid_params)
    "Invalid params"

    iex> ExMCP.Protocol.ErrorCodes.is_protocol_error?(-32602)
    true

# `application_error?`

```elixir
@spec application_error?(integer()) :: boolean()
```

Checks if the code is an ExMCP-local application error.

# `code_for`

```elixir
@spec code_for(atom(), :legacy | :modern | String.t()) ::
  integer() | {:error, :retired_error_code}
```

Returns an error code using the negotiated version for era-sensitive errors.

# `consent_denied`

Consent denied: User denied consent for the operation

# `consent_required`

Consent required: User consent is required for the operation.

This is an ExMCP-local application error, not an MCP protocol error.

# `error_message`

```elixir
@spec error_message(integer() | atom()) :: String.t()
```

Returns a human-readable error message for the given error code or atom.

## Examples

    iex> ExMCP.Protocol.ErrorCodes.error_message(-32602)
    "Invalid params"

    iex> ExMCP.Protocol.ErrorCodes.error_message(:invalid_params)
    "Invalid params"

# `error_response`

```elixir
@spec error_response(atom() | integer(), String.t() | nil) :: map()
```

Creates an error response map with the given code and message.

## Examples

    iex> ExMCP.Protocol.ErrorCodes.error_response(:invalid_params, "Missing required field: name")
    %{code: -32602, message: "Invalid params: Missing required field: name"}

# `error_response_for_version`

```elixir
@spec error_response_for_version(
  atom(),
  :legacy | :modern | String.t(),
  String.t() | nil
) ::
  map() | {:error, :retired_error_code}
```

Builds a version-aware error response for era-sensitive MCP errors.

# `header_mismatch`

Header mismatch between negotiated protocol state and the request

# `internal_error`

Internal error: Internal JSON-RPC error

# `invalid_params`

Invalid params: Invalid method parameter(s)

# `invalid_request`

Invalid Request: The JSON sent is not a valid Request object

# `is_mcp_error?`

```elixir
@spec is_mcp_error?(integer()) :: boolean()
```

Checks if the given error code is an MCP-specific error.

## Examples

    iex> ExMCP.Protocol.ErrorCodes.is_mcp_error?(-32001)
    true

    iex> ExMCP.Protocol.ErrorCodes.is_mcp_error?(-32602)
    false

# `is_protocol_error?`

```elixir
@spec is_protocol_error?(integer()) :: boolean()
```

Checks if the given error code is a standard JSON-RPC protocol error.

## Examples

    iex> ExMCP.Protocol.ErrorCodes.is_protocol_error?(-32602)
    true

    iex> ExMCP.Protocol.ErrorCodes.is_protocol_error?(-32001)
    false

# `legacy_consent_required`

> This function is deprecated. Use consent_required/0; -32002 is reserved as a historical MCP code.

Legacy ExMCP consent-required code retained only for decoding old local errors.

# `method_not_found`

Method not found: The method does not exist or is not available

# `missing_required_client_capability`

A required client capability was not declared

# `parse_error`

Parse error: Invalid JSON was received by the server

# `prompt_error`

ExMCP-local prompt processing error

# `request_cancelled`

Request cancelled: The request was cancelled by the client

# `resource_not_found`

> This function is deprecated. Use resource_not_found/1 so modern peers receive -32602.

Legacy resource-not-found code used by MCP 2025-11-25 and earlier.

New code should call `resource_not_found/1` with the negotiated version or
protocol era.

# `resource_not_found`

```elixir
@spec resource_not_found(:legacy | :modern | String.t()) :: integer()
```

Returns the resource-not-found code appropriate for a protocol era or version.

# `resource_not_found_code?`

```elixir
@spec resource_not_found_code?(integer(), :legacy | :modern | :unknown | String.t()) ::
  boolean()
```

Returns whether a code represents resource-not-found for the given era.

`:unknown` accepts both encodings for clients that have not established the
peer's protocol era yet.

# `server_error`

Generic server error: Catch-all for server-side errors

# `unsupported_protocol_version`

The requested protocol version is not supported

# `url_elicitation_required`

> This function is deprecated. MCP 2026-07-28 retired -32042; use MRTR for modern peers.

Legacy URL-elicitation-required code from MCP 2025-11-25.

# `url_elicitation_required`

```elixir
@spec url_elicitation_required(:legacy | :modern | String.t()) ::
  integer() | {:error, :retired_error_code}
```

Returns the URL-elicitation code for legacy peers and rejects modern emission.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
