ExMCP.ProgressTracker (ex_mcp v0.9.0)
View SourceProgress tracking for MCP 2025-06-18 specification compliance.
This module manages progress tokens and sends progress notifications for long-running operations according to the MCP specification.
Features
- Progress token uniqueness validation
- Monotonic progress value enforcement
- Rate limiting to prevent notification flooding
- Automatic cleanup of completed operations
- Support for both string and integer progress tokens
Usage
# Start tracking a new operation
{:ok, tracker} = ProgressTracker.start_progress("abc123", sender_pid)
# Send progress updates
ProgressTracker.update_progress("abc123", 25, 100, "Processing...")
ProgressTracker.update_progress("abc123", 50, 100, "Half way there...")
ProgressTracker.update_progress("abc123", 100, 100, "Complete!")
# Clean up when operation completes
ProgressTracker.complete_progress("abc123")MCP Specification Compliance
This implementation follows the MCP 2025-06-18 specification:
- Progress tokens must be string or integer values
- Progress tokens must be unique across all active requests
- Progress values must increase with each notification
- Rate limiting prevents notification flooding
- Supports optional total and message fields
Summary
Functions
Returns a specification to start this module under a supervisor.
Clears all progress tracking state.
Marks a progress operation as complete and cleans up tracking state.
Gets the current state of a progress operation.
Lists all active progress tokens.
Starts the ProgressTracker GenServer.
Starts tracking progress for a new operation.
Updates progress for an active operation.
Types
@type progress_state() :: %ExMCP.ProgressTracker{ current_progress: number(), last_message: String.t() | nil, last_notification_time: integer(), notification_count: non_neg_integer(), progress_token: ExMCP.Types.progress_token(), sender_pid: pid(), start_time: integer(), total: number() | nil }
Functions
Returns a specification to start this module under a supervisor.
See Supervisor.
@spec clear_all() :: :ok
Clears all progress tracking state.
This is primarily useful for testing and cleanup.
@spec complete_progress(ExMCP.Types.progress_token()) :: :ok | {:error, :not_found}
Marks a progress operation as complete and cleans up tracking state.
Parameters
progress_token- Token for the operation to complete
Returns
:ok- Operation completed and cleaned up{:error, :not_found}- Progress token not found
@spec get_progress_state(ExMCP.Types.progress_token()) :: {:ok, progress_state()} | {:error, :not_found}
Gets the current state of a progress operation.
Parameters
progress_token- Token for the operation
Returns
{:ok, progress_state}- Current state of the operation{:error, :not_found}- Progress token not found
@spec list_active_tokens() :: [ExMCP.Types.progress_token()]
Lists all active progress tokens.
Returns
List of all currently active progress tokens.
Starts the ProgressTracker GenServer.
@spec start_progress(ExMCP.Types.progress_token(), pid()) :: {:ok, progress_state()} | {:error, :token_exists | :invalid_token}
Starts tracking progress for a new operation.
Parameters
progress_token- Unique token for this operation (string or integer)sender_pid- Process that will receive progress notifications
Returns
{:ok, progress_state}- Successfully started tracking{:error, :token_exists}- Progress token is already in use{:error, :invalid_token}- Progress token is not string or integer
@spec update_progress( ExMCP.Types.progress_token(), number(), number() | nil, String.t() | nil ) :: :ok | {:error, :not_found | :not_increasing | :rate_limited}
Updates progress for an active operation.
Parameters
progress_token- Token for the operationprogress- Current progress value (must be > previous value)total- Optional total value for the operationmessage- Optional human-readable progress message
Returns
:ok- Progress updated and notification sent{:error, :not_found}- Progress token not found{:error, :not_increasing}- Progress value must increase{:error, :rate_limited}- Too many notifications too quickly