Phantom.Tasks (phantom_mcp v0.7.3)

Copy Markdown View Source

A task from the MCP Tasks extension (io.modelcontextprotocol/tasks), available under MCP 2026-07-28.

A tool handler may answer a call with a task instead of a result, and the client polls for the outcome. Return one from the handler and Phantom responds with a CreateTaskResult:

def export_report(params, session) do
  task = MyApp.MCPTasks.create!(session, params)
  {:reply, Phantom.Tasks.new(id: task.id, status: :working, created_at: task.inserted_at), session}
end

Phantom does not store tasks. You store them, run the work, and move them through their statuses; Phantom asks your router for them when the client polls. Check Phantom.Session.tasks_supported?/1 before returning a task, since a client that did not declare the extension cannot receive one.

Return the task from the handler. Phantom.Session.respond/2 does not accept one, since the task is already the asynchronous answer. Only tools answer with tasks.

Fields

  • :id - (required) The task ID. It acts as a bearer token, so it must be unguessable; see generate_id/0.
  • :status - (required) One of :working, :input_required, :completed, :failed, or :cancelled. Strings are accepted.
  • :created_at - (required) A DateTime.
  • :last_updated_at - A DateTime. Defaults to :created_at.
  • :status_message - An optional message describing the current status.
  • :ttl_ms - Milliseconds from creation that the task is kept, or nil for unlimited.
  • :poll_interval_ms - Suggested milliseconds between client polls.
  • :input_requests - Required when :input_required. A map of keys to Phantom.Elicit structs or embedded request maps. Keys must not be reused over the task's lifetime.
  • :result - Required when :completed. The final CallToolResult, such as Phantom.Tool.response(Phantom.Tool.text("Done")). A tool error is still :completed.
  • :error - Required when :failed. A JSON-RPC error with :code and :message, such as Phantom.Request.internal_error("Timed out").

Summary

Functions

Generate an unguessable, URL-safe task ID with 256 bits of entropy.

Build a task. Raises ArgumentError when the fields do not describe a valid task for its status.

Types

status()

@type status() :: :working | :input_required | :completed | :failed | :cancelled

t()

@type t() :: %Phantom.Tasks{
  created_at: DateTime.t(),
  error: map() | nil,
  id: String.t(),
  input_requests: %{required(String.t()) => map()},
  last_updated_at: DateTime.t(),
  poll_interval_ms: pos_integer() | nil,
  result: map() | nil,
  status: status(),
  status_message: String.t() | nil,
  ttl_ms: non_neg_integer() | nil
}

Functions

generate_id()

@spec generate_id() :: String.t()

Generate an unguessable, URL-safe task ID with 256 bits of entropy.

new(attrs)

@spec new(map() | Keyword.t()) :: t()

Build a task. Raises ArgumentError when the fields do not describe a valid task for its status.