ExMCP.Tasks.Task (ex_mcp v0.10.0)

View Source

Task struct and state machine validation for MCP Tasks (2025-11-25).

Tasks represent async operations initiated by tool calls. This module provides a pure data structure and state transition validation functions. It does NOT include any GenServer or process management - users implement task lifecycle management themselves via handler callbacks.

State Machine

Valid states: :working, :input_required, :completed, :failed, :cancelled

Valid transitions:

  • :working -> :input_required | :completed | :failed | :cancelled

  • :input_required -> :working | :cancelled

  • :completed -> (terminal state)
  • :failed -> (terminal state)
  • :cancelled -> (terminal state)

Usage

task = ExMCP.Tasks.Task.new("my-tool", %{"arg" => "value"})
{:ok, task} = ExMCP.Tasks.Task.transition(task, :completed)

Summary

Functions

Transitions and sets the result (for completed tasks).

Transitions to failed state with error info.

Creates a new task in the :working state.

Parses a state string to a state atom.

Returns all valid states.

Checks if the task is in a terminal state.

Returns all terminal states.

Converts a task to a map suitable for protocol serialization.

Attempts a state transition.

Checks if a transition from one state to another is valid.

Types

state()

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

t()

@type t() :: %ExMCP.Tasks.Task{
  arguments: map(),
  created_at: String.t(),
  id: String.t(),
  last_updated_at: String.t() | nil,
  metadata: map(),
  poll_interval: integer() | nil,
  result: map() | nil,
  state: state(),
  status_message: String.t() | nil,
  tool_name: String.t(),
  ttl: integer() | nil
}

Functions

complete(task, result)

@spec complete(t(), map()) :: {:ok, t()} | {:error, String.t()}

Transitions and sets the result (for completed tasks).

fail(task, error_result)

@spec fail(t(), map()) :: {:ok, t()} | {:error, String.t()}

Transitions to failed state with error info.

new(tool_name, arguments \\ %{}, opts \\ [])

@spec new(String.t(), map(), keyword()) :: t()

Creates a new task in the :working state.

Parameters

  • tool_name - Name of the tool this task is executing
  • arguments - Tool arguments
  • opts - Optional fields: :id, :ttl, :metadata

parse_state(other)

@spec parse_state(String.t()) :: {:ok, state()} | {:error, String.t()}

Parses a state string to a state atom.

states()

@spec states() :: [state()]

Returns all valid states.

terminal?(task)

@spec terminal?(t()) :: boolean()

Checks if the task is in a terminal state.

terminal_states()

@spec terminal_states() :: [state()]

Returns all terminal states.

to_map(task)

@spec to_map(t()) :: map()

Converts a task to a map suitable for protocol serialization.

transition(task, new_state)

@spec transition(t(), state()) :: {:ok, t()} | {:error, String.t()}

Attempts a state transition.

Returns {:ok, updated_task} if the transition is valid, {:error, reason} if invalid.

valid_transition?(from, to)

@spec valid_transition?(state(), state()) :: boolean()

Checks if a transition from one state to another is valid.