# `Hermolaos.Client.Connection`
[🔗](https://github.com/nyo16/hermolaos/blob/v0.5.0/lib/hermolaos/client/connection.ex#L1)

GenServer managing a single MCP connection.

The Connection is the core component of the Hermolaos client. It manages:

- Transport lifecycle (stdio or HTTP)
- Protocol initialization handshake
- Request/response correlation
- Server notification handling
- Connection state machine

## State Machine

```
:disconnected --> :connecting --> :initializing --> :ready
      ^              |                |               |
      |              v                v               v
      +------------- (error) --------+---------------+
```

## Usage

Typically, you don't interact with Connection directly. Use the
`Hermolaos` module for a higher-level API.

## Example

    {:ok, conn} = Hermolaos.Client.Connection.start_link(
      transport: :stdio,
      command: "npx",
      args: ["-y", "@modelcontextprotocol/server-filesystem", "/tmp"]
    )

    {:ok, tools} = Hermolaos.Client.Connection.request(conn, "tools/list", %{})

# `option`

```elixir
@type option() ::
  {:transport, transport_type()}
  | {:command, String.t()}
  | {:args, [String.t()]}
  | {:url, String.t()}
  | {:headers, [{String.t(), String.t()}]}
  | {:client_info, map()}
  | {:capabilities, map()}
  | {:notification_handler, module() | {module(), term()}}
  | {:timeout, pos_integer()}
  | {:name, GenServer.name()}
```

# `state`

```elixir
@type state() :: %{
  status: status(),
  transport_type: transport_type(),
  transport_mod: module(),
  transport_pid: pid() | nil,
  transport_opts: keyword(),
  tracker_pid: pid() | nil,
  server_info: map() | nil,
  server_capabilities: map() | nil,
  server_instructions: String.t() | nil,
  client_capabilities: map(),
  client_info: map(),
  protocol_version: String.t() | nil,
  notification_handler: module() | {module(), term()} | nil,
  pending_init: GenServer.from() | nil,
  default_timeout: pos_integer()
}
```

# `status`

```elixir
@type status() :: :disconnected | :connecting | :initializing | :ready
```

# `t`

```elixir
@type t() :: GenServer.server()
```

# `transport_type`

```elixir
@type transport_type() :: :stdio | :http
```

# `child_spec`

Returns a specification to start this module under a supervisor.

See `Supervisor`.

# `disconnect`

```elixir
@spec disconnect(t()) :: :ok
```

Disconnects from the server.

# `instructions`

```elixir
@spec instructions(t()) ::
  {:ok, String.t()} | {:error, :not_initialized | :no_instructions}
```

Gets server instructions from the initialization response.

# `notify`

```elixir
@spec notify(t(), String.t(), map()) :: :ok | {:error, term()}
```

Sends a notification (no response expected).

## Parameters

- `conn` - The connection process
- `method` - JSON-RPC method name
- `params` - Notification parameters

## Examples

    :ok = Hermolaos.Client.Connection.notify(conn, "notifications/cancelled", %{requestId: 1})

# `request`

```elixir
@spec request(t(), String.t(), map(), keyword()) :: {:ok, map()} | {:error, term()}
```

Sends a request and waits for a response.

## Parameters

- `conn` - The connection process
- `method` - JSON-RPC method name
- `params` - Request parameters
- `opts` - Options:
  - `:timeout` - Override default timeout

## Returns

- `{:ok, result}` - Success with result map
- `{:error, reason}` - Error occurred

## Examples

    {:ok, %{"tools" => tools}} = Hermolaos.Client.Connection.request(conn, "tools/list", %{})

# `server_capabilities`

```elixir
@spec server_capabilities(t()) :: {:ok, map()} | {:error, :not_initialized}
```

Gets server capabilities from the initialization response.

# `server_info`

```elixir
@spec server_info(t()) :: {:ok, map()} | {:error, :not_initialized}
```

Gets server information from the initialization response.

# `start_link`

```elixir
@spec start_link(keyword()) :: {:ok, pid()} | {:error, term()}
```

Starts a new MCP connection.

## Options

### Transport Options (one required)

For stdio transport:
- `:transport` - Set to `:stdio`
- `:command` - Command to execute (required)
- `:args` - Command arguments (default: [])

For HTTP transport:
- `:transport` - Set to `:http`
- `:url` - Server URL (required)
- `:headers` - Additional HTTP headers (default: [])

### Common Options

- `:client_info` - Client identification (default: Hermolaos info)
- `:capabilities` - Client capabilities (default: standard capabilities)
- `:notification_handler` - Module or `{module, state}` for handling notifications
- `:timeout` - Default request timeout in ms (default: 30000)
- `:name` - GenServer name (optional)

## Examples

    # Stdio transport
    {:ok, conn} = Hermolaos.Client.Connection.start_link(
      transport: :stdio,
      command: "/usr/bin/python3",
      args: ["-m", "my_mcp_server"]
    )

    # HTTP transport
    {:ok, conn} = Hermolaos.Client.Connection.start_link(
      transport: :http,
      url: "http://localhost:3000/mcp"
    )

# `status`

```elixir
@spec status(t()) :: status()
```

Gets the current connection status.

## Returns

- `:disconnected` - Not connected
- `:connecting` - Transport starting
- `:initializing` - Performing MCP handshake
- `:ready` - Ready for requests

---

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