Anubis.Server.Frame (anubis_mcp v1.0.0)

Copy Markdown

The Anubis Frame — pure user state + read-only context.

User fields

  • assigns - shared user data as a map. For HTTP transports, this inherits from Plug.Conn.assigns.

Component maps

Runtime-registered components are stored in typed maps keyed by name/URI:

  • tools - %{name => %Tool{}}
  • resources - %{uri => %Resource{}}
  • prompts - %{name => %Prompt{}}
  • resource_templates - %{name => %Resource{uri_template: ...}}

Pagination

  • pagination_limit - optional limit for listing operations

Context

  • context - read-only %Context{}, refreshed by Session before each callback

Summary

Functions

Assigns a value or multiple values to the frame.

Assigns a value to the frame only if the key doesn't already exist.

Clears all runtime-registered components

Reconstructs Frame from a previously saved map.

Retrieves all runtime-registered components as a flat list

Creates a new frame with optional initial assigns.

Sets the pagination limit for listing operations.

Registers a prompt definition at runtime.

Registers a resource definition with a fixed URI.

Registers a resource template definition using a URI template (RFC 6570).

Registers a tool definition at runtime.

Serializes Frame for persistent storage.

Types

server_component_t()

t()

@type t() :: %Anubis.Server.Frame{
  assigns: map(),
  context: Anubis.Server.Context.t(),
  pagination_limit: non_neg_integer() | nil,
  prompts: %{optional(String.t()) => Anubis.Server.Component.Prompt.t()},
  resource_templates: %{
    optional(String.t()) => Anubis.Server.Component.Resource.t()
  },
  resources: %{optional(String.t()) => Anubis.Server.Component.Resource.t()},
  tools: %{optional(String.t()) => Anubis.Server.Component.Tool.t()}
}

Functions

assign(frame, assigns)

@spec assign(t(), Enumerable.t()) :: t()

Assigns a value or multiple values to the frame.

Examples

frame = Frame.assign(frame, :status, :active)
frame = Frame.assign(frame, %{status: :active, count: 5})
frame = Frame.assign(frame, status: :active, count: 5)

assign(frame, key, value)

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

assign_new(frame, key, fun)

@spec assign_new(t(), key :: atom(), value_fun :: (-> term())) :: t()

Assigns a value to the frame only if the key doesn't already exist.

The value is computed lazily using the provided function.

Examples

frame = Frame.assign_new(frame, :timestamp, fn -> DateTime.utc_now() end)

clear_components(frame)

@spec clear_components(t()) :: t()

Clears all runtime-registered components

from_saved(map)

@spec from_saved(map()) :: t()

Reconstructs Frame from a previously saved map.

Only assigns and pagination_limit are restored. Runtime-only fields (tools, resources, prompts, resource_templates) are initialized empty — their validator functions are not serializable. context is left as the default struct and will be set by Session before each callback invocation.

get_components(frame)

@spec get_components(t()) :: [server_component_t()]

Retrieves all runtime-registered components as a flat list

new(assigns \\ %{})

@spec new(assigns :: map()) :: t()

Creates a new frame with optional initial assigns.

Examples

iex> Frame.new()
%Frame{assigns: %{}}

iex> Frame.new(%{user: "alice"})
%Frame{assigns: %{user: "alice"}}

put_pagination_limit(frame, limit)

@spec put_pagination_limit(t(), non_neg_integer()) :: t()

Sets the pagination limit for listing operations.

Examples

frame = Frame.put_pagination_limit(frame, 10)
frame.pagination_limit
# => 10

register_prompt(frame, name, opts)

@spec register_prompt(t(), String.t(), [prompt_opt]) :: t()
when prompt_opt:
       {:description, String.t() | nil}
       | {:arguments, map() | nil}
       | {:title, String.t() | nil}

Registers a prompt definition at runtime.

register_resource(frame, uri, opts)

@spec register_resource(t(), String.t(), [resource_opt]) :: t()
when resource_opt:
       {:title, String.t() | nil}
       | {:name, String.t() | nil}
       | {:description, String.t() | nil}
       | {:mime_type, String.t() | nil}

Registers a resource definition with a fixed URI.

For parameterized resources, use register_resource_template/3 instead.

register_resource_template(frame, uri_template, opts)

@spec register_resource_template(t(), String.t(), [resource_template_opt]) :: t()
when resource_template_opt:
       {:title, String.t() | nil}
       | {:name, String.t()}
       | {:description, String.t() | nil}
       | {:mime_type, String.t() | nil}

Registers a resource template definition using a URI template (RFC 6570).

Examples

frame = Frame.register_resource_template(frame, "file:///{path}",
  name: "project_files",
  title: "Project Files",
  description: "Access files in the project directory"
)

register_tool(frame, name, opts)

@spec register_tool(t(), String.t(), [tool_opt]) :: t()
when tool_opt:
       {:description, String.t() | nil}
       | {:input_schema, map() | nil}
       | {:output_schema, map() | nil}
       | {:title, String.t() | nil}
       | {:annotations, map() | nil}

Registers a tool definition at runtime.

to_saved(frame)

@spec to_saved(t()) :: map()

Serializes Frame for persistent storage.

Only assigns and pagination_limit are persisted. The following fields are runtime-only and excluded from serialization:

  • tools — runtime-registered tool definitions (includes validator functions)
  • resources — runtime-registered resource definitions
  • prompts — runtime-registered prompt definitions
  • resource_templates — runtime-registered resource template definitions
  • context — rebuilt by Session before each callback invocation

Compile-time components (registered via the component macro) are always available from the server module and do not need persistence.