# `Phantom.Session`
[🔗](https://github.com/dbernheisel/phantom_mcp/blob/main/lib/phantom/session.ex#L1)

Represents the state of the MCP session. This is the state across the conversation
and is the bridge between the various transports (HTTP, stdio) to persistence,
even if stateless.

# `t`

```elixir
@type t() :: %Phantom.Session{
  allowed_prompts: [String.t()],
  allowed_resource_templates: [String.t()],
  allowed_tools: [String.t()],
  assigns: map(),
  client_capabilities: %{
    elicitation: false | map(),
    sampling: false | map(),
    roots: false | map()
  },
  client_info: map(),
  close_after_complete: boolean(),
  elicit:
    (Phantom.Elicit.t(), timeout :: pos_integer() -&gt;
       {:ok, map()} | :error | :timeout)
    | nil,
  id: binary(),
  last_event_id: String.t() | nil,
  pid: pid() | nil,
  pubsub: module(),
  request: Phantom.Request.t() | nil,
  requests: map(),
  router: module(),
  stream_fun: fun(),
  tracker: term(),
  transport_pid: pid()
}
```

# `allow_prompts`

Set an allow-list of usable Prompts for the session

# `allow_resource_templates`

Set an allow-list of usable Resource Templates for the session

# `allow_tools`

Set an allow-list of usable Tools for the session

# `assign`

```elixir
@spec assign(t(), map()) :: t()
```

Assign state to the session.

# `assign`

```elixir
@spec assign(t(), atom(), any()) :: t()
```

Assign state to the session.

# `elicit`

```elixir
@spec elicit(t(), Phantom.Elicit.t(), keyword()) ::
  {:ok, response :: map()} | :not_supported | :error | :timeout
```

Elicit input from the client.

Blocks until the client responds or timeout is reached. Returns
`{:ok, response}` where response is the client's JSON response map
(with `"action"` and `"content"` keys).

Options:
  - `:timeout` - max time to wait in ms (default: 5 minutes)

# `elicit_url`

```elixir
@spec elicit_url(t(), url :: String.t(), message :: String.t(), keyword()) ::
  {:ok, response :: map()} | :not_supported | :error | :timeout
```

Convenience to elicit a URL mode interaction. Blocks until the client responds.

# `finish`

```elixir
@spec finish(t() | pid()) :: :ok
```

Closes the connection for the session

# `list_resource_subscriptions`

# `new`

```elixir
@spec new(String.t() | nil, Keyword.t() | map()) :: t()
```

Builds a new session with the provided session ID.

This is used for adapters such as `Phantom.Plug`. If a
session ID is not provided, it will generate one using `UUIDv7`.

# `notify`

```elixir
@spec notify(t() | pid(), payload :: any()) :: :ok
```

Send a notification to the client

# `notify_progress`

```elixir
@spec notify_progress(t(), number(), nil | number()) :: :ok
```

Send a progress notification to the client

the `progress` and `total` can be a integer or float, but must be ever-increasing.
the `total` is optional.

https://modelcontextprotocol.io/specification/2025-06-18/basic/utilities/progress

# `notify_progress`

# `ping`

```elixir
@spec ping(t() | pid()) :: :ok
```

Send a ping to the client

# `progress_token`

Fetch the current progress token if provided by the client

# `respond`

Sends response back to the stream

This should likely be used in conjunction with:

- `Phantom.Tool.response(payload)`
- `Phantom.Resource.response(payload)`
- `Phantom.Prompt.response(payload)`

For example:

```elixir
session_pid = session.pid
request_id = request.id

Task.async(fn ->
  Session.respond(
    session_pid,
    request_id,
    Phantom.Tool.audio(
      File.read!("priv/static/game-over.wav"),
      mime_type: "audio/wav"
    )
  )
end)
```

# `respond`

See `respond/2`

# `set_log_level`

```elixir
@spec set_log_level(t(), Phantom.Request.t(), String.t()) :: :ok
```

Sets the log level for the SSE stream.
Sets both for the current request for async tasks and the SSE stream

# `subscribe_to_resource`

```elixir
@spec subscribe_to_resource(t(), string_uri :: String.t()) :: :ok | :error
```

Subscribe the session to a resource.

This is used by the MCP Router when the client requests to subscribe to the provided resource.

# `unsubscribe_to_resource`

```elixir
@spec unsubscribe_to_resource(t(), string_uri :: String.t()) :: :ok | :error
```

Unsubscribe the session to a resource.

This is used by the MCP Router when the client requests to subscribe to the provided resource.

---

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