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

Utility module for building JSON-RPC 2.0 responses in MCP.

This module centralizes all response building logic to ensure consistency
across the codebase and reduce duplication.

# `build_batch_error`

```elixir
@spec build_batch_error(String.t()) :: map()
```

Builds a batch response error (when batch requests are not supported).

## Examples

    iex> ResponseBuilder.build_batch_error("2025-06-18")
    %{
      "jsonrpc" => "2.0",
      "id" => nil,
      "error" => %{
        "code" => -32600,
        "message" => "Batch requests are not supported in protocol version 2025-06-18"
      }
    }

# `build_error_response`

Builds an error JSON-RPC response.

Accepts either raw parameters or an ExMCP.Error struct.

## Examples

    iex> ResponseBuilder.build_error_response(-32601, "Method not found", nil, 123)
    %{
      "jsonrpc" => "2.0",
      "id" => 123,
      "error" => %{
        "code" => -32601,
        "message" => "Method not found"
      }
    }
    
    iex> ResponseBuilder.build_error_response(-32602, "Invalid params", %{"expected" => "string"}, 123)
    %{
      "jsonrpc" => "2.0",
      "id" => 123,
      "error" => %{
        "code" => -32602,
        "message" => "Invalid params",
        "data" => %{"expected" => "string"}
      }
    }
    
    iex> error = %ExMCP.Error.ProtocolError{code: -32601, message: "Method not found"}
    iex> ResponseBuilder.build_error_response(error, 123)
    %{
      "jsonrpc" => "2.0",
      "id" => 123,
      "error" => %{
        "code" => -32601,
        "message" => "Method not found"
      }
    }

# `build_error_response`

```elixir
@spec build_error_response(integer() | struct(), String.t() | any(), any(), any()) ::
  map()
```

# `build_mcp_error`

```elixir
@spec build_mcp_error(atom(), any(), String.t() | nil, any()) :: map()
```

Builds a standard MCP error response using error code atoms.

## Examples

    iex> ResponseBuilder.build_mcp_error(:method_not_found, 123)
    %{
      "jsonrpc" => "2.0",
      "id" => 123,
      "error" => %{
        "code" => -32601,
        "message" => "Method not found"
      }
    }
    
    iex> ResponseBuilder.build_mcp_error(:invalid_params, 123, "Missing required field")
    %{
      "jsonrpc" => "2.0",
      "id" => 123,
      "error" => %{
        "code" => -32602,
        "message" => "Missing required field"
      }
    }

# `build_notification`

```elixir
@spec build_notification(String.t(), map()) :: map()
```

Builds a JSON-RPC notification (no id field).

## Examples

    iex> ResponseBuilder.build_notification("resources/list_changed", %{})
    %{
      "jsonrpc" => "2.0",
      "method" => "resources/list_changed",
      "params" => %{}
    }

# `build_request`

```elixir
@spec build_request(String.t(), map(), any()) :: map()
```

Builds a JSON-RPC request for legacy or compatibility paths.

Independent server-to-client requests belong to initialize-based MCP
revisions. A modern MCP 2026-07-28 server should return an `input_required`
MRTR result when it needs client input.

## Examples

    iex> ResponseBuilder.build_request("tools/call", %{"name" => "test"}, "req-123")
    %{
      "jsonrpc" => "2.0",
      "id" => "req-123",
      "method" => "tools/call",
      "params" => %{"name" => "test"}
    }

# `build_success_response`

```elixir
@spec build_success_response(any(), any()) :: map()
```

Builds a successful JSON-RPC response.

## Examples

    iex> ResponseBuilder.build_success_response(%{"tools" => []}, 123)
    %{
      "jsonrpc" => "2.0",
      "id" => 123,
      "result" => %{"tools" => []}
    }

# `build_tool_error`

```elixir
@spec build_tool_error(String.t(), boolean(), any()) :: map()
```

Builds a tool error response with proper MCP structure.

## Examples

    iex> ResponseBuilder.build_tool_error("Tool execution failed", true, 123)
    %{
      "jsonrpc" => "2.0",
      "id" => 123,
      "result" => %{
        "content" => [
          %{
            "type" => "text",
            "text" => "Tool execution failed"
          }
        ],
        "isError" => true
      }
    }

# `error_response?`

```elixir
@spec error_response?(map()) :: boolean()
```

Checks if a response is an error response.

## Examples

    iex> ResponseBuilder.error_response?(%{"error" => %{"code" => -32601}})
    true
    
    iex> ResponseBuilder.error_response?(%{"result" => %{}})
    false

# `notification?`

```elixir
@spec notification?(map()) :: boolean()
```

Checks if a response is a notification (has no id).

## Examples

    iex> ResponseBuilder.notification?(%{"jsonrpc" => "2.0", "method" => "test"})
    true
    
    iex> ResponseBuilder.notification?(%{"jsonrpc" => "2.0", "id" => 1, "method" => "test"})
    false

---

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