Phantom.Session (phantom_mcp v0.2.0)

View Source

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.

Summary

Functions

Set an allow-list of usable Prompts for the session

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

Set an allow-list of usable Tools for the session

Assign state to the session.

Assign state to the session.

Closes the connection for the session

Get the PID of the SSE stream for the session id

List all sessions with SSE streams open.

Notify the client with a log at level "alert" with domain "server". Note: this requires the session variable to be within scope

Notify the client with a log at level "alert"

Notify the client with a log at level "critical" with domain "server". Note: this requires the session variable to be within scope

Notify the client with a log at level "critical"

Notify the client with a log at level "debug" with domain "server". Note: this requires the session variable to be within scope

Notify the client with a log at level "debug"

Notify the client with a log at level "emergency" with domain "server". Note: this requires the session variable to be within scope

Notify the client with a log at level "emergency"

Notify the client with a log at level "error" with domain "server". Note: this requires the session variable to be within scope

Notify the client with a log at level "error"

Notify the client with a log at level "info" with domain "server". Note: this requires the session variable to be within scope

Notify the client with a log at level "info"

Notify the client with a log at level "notice" with domain "server". Note: this requires the session variable to be within scope

Notify the client with a log at level "notice"

Notify the client with a log at level "warning" with domain "server". Note: this requires the session variable to be within scope

Notify the client with a log at level "warning"

Builds a new session with the provided session ID.

Send a notification to the client

Send a progress notification to the client

Send a ping to the client

Fetch the current progress token if provided by the client

The PubSub topic Phantom will listen to for resource updates "phantom:resources"

Sends response back to the stream

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

Subscribe the session to a resource.

Types

log_level()

@type log_level() ::
  :emergency | :alert | :critical | :error | :warning | :notice | :info | :debug

t()

@type t() :: %Phantom.Session{
  allowed_prompts: [String.t()],
  allowed_resource_templates: [String.t()],
  allowed_tools: [String.t()],
  assigns: map(),
  close_after_complete: boolean(),
  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()
}

Functions

allow_prompts(session, prompts)

Set an allow-list of usable Prompts for the session

allow_resource_templates(session, resource_templates)

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

allow_tools(session, tools)

Set an allow-list of usable Tools for the session

assign(session, map)

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

Assign state to the session.

assign(session, key, value)

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

Assign state to the session.

finish(pid)

@spec finish(Session.t()) :: :ok

Closes the connection for the session

get_sse_pid(session)

Get the PID of the SSE stream for the session id

list_sse()

List all sessions with SSE streams open.

log(session, atom, domain, payload)

@spec log(Session.t(), log_level(), String.t(), structured_log :: map()) :: :ok

log_alert(payload)

(macro)
@spec log_alert(structured_log :: map()) :: :ok

Notify the client with a log at level "alert" with domain "server". Note: this requires the session variable to be within scope

log_alert(session, domain, payload)

@spec log_alert(t(), String.t(), structured_log :: map()) :: :ok

Notify the client with a log at level "alert"

log_critical(payload)

(macro)
@spec log_critical(structured_log :: map()) :: :ok

Notify the client with a log at level "critical" with domain "server". Note: this requires the session variable to be within scope

log_critical(session, domain, payload)

@spec log_critical(t(), String.t(), structured_log :: map()) :: :ok

Notify the client with a log at level "critical"

log_debug(payload)

(macro)
@spec log_debug(structured_log :: map()) :: :ok

Notify the client with a log at level "debug" with domain "server". Note: this requires the session variable to be within scope

log_debug(session, domain, payload)

@spec log_debug(t(), String.t(), structured_log :: map()) :: :ok

Notify the client with a log at level "debug"

log_emergency(payload)

(macro)
@spec log_emergency(structured_log :: map()) :: :ok

Notify the client with a log at level "emergency" with domain "server". Note: this requires the session variable to be within scope

log_emergency(session, domain, payload)

@spec log_emergency(t(), String.t(), structured_log :: map()) :: :ok

Notify the client with a log at level "emergency"

log_error(payload)

(macro)
@spec log_error(structured_log :: map()) :: :ok

Notify the client with a log at level "error" with domain "server". Note: this requires the session variable to be within scope

log_error(session, domain, payload)

@spec log_error(t(), String.t(), structured_log :: map()) :: :ok

Notify the client with a log at level "error"

log_info(payload)

(macro)
@spec log_info(structured_log :: map()) :: :ok

Notify the client with a log at level "info" with domain "server". Note: this requires the session variable to be within scope

log_info(session, domain, payload)

@spec log_info(t(), String.t(), structured_log :: map()) :: :ok

Notify the client with a log at level "info"

log_notice(payload)

(macro)
@spec log_notice(structured_log :: map()) :: :ok

Notify the client with a log at level "notice" with domain "server". Note: this requires the session variable to be within scope

log_notice(session, domain, payload)

@spec log_notice(t(), String.t(), structured_log :: map()) :: :ok

Notify the client with a log at level "notice"

log_warning(payload)

(macro)
@spec log_warning(structured_log :: map()) :: :ok

Notify the client with a log at level "warning" with domain "server". Note: this requires the session variable to be within scope

log_warning(session, domain, payload)

@spec log_warning(t(), String.t(), structured_log :: map()) :: :ok

Notify the client with a log at level "warning"

new(session_id, opts \\ [])

@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(pid, payload)

Send a notification to the client

notify_progress(session, progress, total \\ nil)

Send a progress notification to the client

notify_progress(pid, progress_token, progress, total)

ping(pid)

Send a ping to the client

progress_token(session)

Fetch the current progress token if provided by the client

resource_subscription_topic()

The PubSub topic Phantom will listen to for resource updates "phantom:resources"

respond(session, payload)

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:

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(pid, request_id, payload)

See respond/2

set_log_level(session, request, level)

@spec set_log_level(Session.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(session, uri)

@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.