Module: ActionMCP::Server::Tasks

Included in:
TransportHandler
Defined in:
lib/action_mcp/server/tasks.rb

Overview

Tasks module for MCP 2025-11-25 specification Provides methods for handling task-related requests:

  • tasks/get: Get task status and data

  • tasks/result: Get task result (blocking until terminal state)

  • tasks/list: List tasks for the session

  • tasks/cancel: Cancel a task

Instance Method Summary collapse

Instance Method Details

#send_task_status_notification(task) ⇒ Object

Send task status notification

Parameters:



105
106
107
108
109
110
# File 'lib/action_mcp/server/tasks.rb', line 105

def send_task_status_notification(task)
  send_jsonrpc_notification(
    JsonRpcHandlerBase::Methods::NOTIFICATIONS_TASKS_STATUS,
    { task: task.to_task_data }
  )
end

#send_tasks_cancel(request_id, task_id) ⇒ Object

Cancel a task

Parameters:

  • request_id (String, Integer)

    JSON-RPC request ID

  • task_id (String)

    Task ID to cancel



64
65
66
67
68
69
70
71
72
73
74
75
76
# File 'lib/action_mcp/server/tasks.rb', line 64

def send_tasks_cancel(request_id, task_id)
  task = find_task(task_id)
  return unless task

  if task.terminal?
    send_jsonrpc_error(request_id, :invalid_params,
                       "Cannot cancel task in terminal status: #{task.status}")
    return
  end

  task.cancel!
  send_jsonrpc_response(request_id, result: { task: task.to_task_data })
end

#send_tasks_get(request_id, task_id) ⇒ Object

Get task status and metadata

Parameters:

  • request_id (String, Integer)

    JSON-RPC request ID

  • task_id (String)

    Task ID to retrieve



15
16
17
18
19
20
# File 'lib/action_mcp/server/tasks.rb', line 15

def send_tasks_get(request_id, task_id)
  task = find_task(task_id)
  return unless task

  send_jsonrpc_response(request_id, result: { task: task.to_task_data })
end

#send_tasks_list(request_id, cursor: nil) ⇒ Object

List tasks for the session with optional pagination

Parameters:

  • request_id (String, Integer)

    JSON-RPC request ID

  • cursor (String, nil) (defaults to: nil)

    Pagination cursor



43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
# File 'lib/action_mcp/server/tasks.rb', line 43

def send_tasks_list(request_id, cursor: nil)
  # Parse cursor if provided
  offset = cursor.to_i if cursor.present?
  offset ||= 0
  limit = 50

  tasks = session.tasks.recent.offset(offset).limit(limit + 1)
  has_more = tasks.length > limit
  tasks = tasks.first(limit)

  result = {
    tasks: tasks.map(&:to_task_data)
  }
  result[:nextCursor] = (offset + limit).to_s if has_more

  send_jsonrpc_response(request_id, result: result)
end

#send_tasks_result(request_id, task_id) ⇒ Object

Get task result, blocking until task reaches terminal state

Parameters:

  • request_id (String, Integer)

    JSON-RPC request ID

  • task_id (String)

    Task ID to get result for



25
26
27
28
29
30
31
32
33
34
35
36
37
38
# File 'lib/action_mcp/server/tasks.rb', line 25

def send_tasks_result(request_id, task_id)
  task = find_task(task_id)
  return unless task

  # If task is not in terminal state, wait for it
  # In async execution, client should poll or use SSE for notifications
  unless task.terminal?
    send_jsonrpc_error(request_id, :invalid_request,
                       "Task is not yet complete. Current status: #{task.status}")
    return
  end

  send_jsonrpc_response(request_id, result: task.to_task_result)
end

#send_tasks_resume(request_id, task_id, input) ⇒ Object

Resume a task from input_required state

Parameters:

  • request_id (String, Integer)

    JSON-RPC request ID

  • task_id (String)

    Task ID to resume

  • input (Object)

    Input data for the task



82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
# File 'lib/action_mcp/server/tasks.rb', line 82

def send_tasks_resume(request_id, task_id, input)
  task = find_task(task_id)
  return unless task

  unless task.input_required?
    send_jsonrpc_error(request_id, :invalid_params,
                       "Task is not awaiting input. Current status: #{task.status}")
    return
  end

  # Store input in continuation state
  continuation = task.continuation_state || {}
  continuation[:input] = input
  task.update!(continuation_state: continuation)

  # Resume task and re-enqueue job
  task.resume_from_continuation!

  send_jsonrpc_response(request_id, result: { task: task.to_task_data })
end