Skip to content

enhancement: client side 'task' functions for 'get', 'list', 'cancel' and 'result' operation #770

Merged
ezynda3 merged 3 commits intomark3labs:mainfrom
yuehaii:main
Apr 4, 2026
Merged

enhancement: client side 'task' functions for 'get', 'list', 'cancel' and 'result' operation #770
ezynda3 merged 3 commits intomark3labs:mainfrom
yuehaii:main

Conversation

@yuehaii
Copy link
Copy Markdown
Contributor

@yuehaii yuehaii commented Mar 28, 2026

Description

The 'tasks' functions for mcp client:
1. The 'GetTask' function will retrieve the task current status.
2. The 'ListTasks' function will list all tasks
3. The 'TaskResult' function will retrieve the finished task information.
4. The 'CancelTask' function will cancel the running task.

Type of Change

  • Bug fix (non-breaking change that fixes an issue)
  • New feature (non-breaking change that adds functionality)
  • MCP spec compatibility implementation
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Documentation update
  • Code refactoring (no functional changes)
  • Performance improvement
  • Tests only (no functional changes)
  • Other (please describe):

Checklist

  • My code follows the code style of this project
  • I have performed a self-review of my own code
  • I have added tests that prove my fix is effective or that my feature works
  • I have updated the documentation accordingly

MCP Spec Compliance

  • This PR implements a feature defined in the MCP specification
  • Link to relevant spec section: protocol-messages(request only)
  • Implementation follows the specification exactly

Additional Information

Tested with below code and those tasks client APIs worked as expected:

    req := mcp.GetTaskRequest{}
    req.Params.TaskId = taskid
    result, err := a.client.GetTask(a.ctx, req)
    if err != nil {
        fmt.Printf("Fail to get server task %s: %v", taskid, err)
    }

    reqL := mcp.ListTasksRequest{}
    resultL, errL := a.client.ListTasks(a.ctx, reqL)
    if errL != nil {
        log.Printf("Fail to list tasks %s: %v", taskid, errL)
    }

    reqC := mcp.CancelTaskRequest{}
    reqC.Params.TaskId = taskid
    resultC, err := a.client.CancelTask(a.ctx, reqC)
    if err != nil {
        fmt.Printf("Fail to cancel the task %s: %v", taskid, err)
    }
 
    reqR := mcp.TaskResultRequest{}
    reqR.Params.TaskId = taskid
    resultR, errR := a.client.TaskResult(a.ctx, reqR)
    if errR != nil {
        log.Printf("Fail to get the task result %s: %v", taskid, errR)
    }

Summary by CodeRabbit

  • New Features
    • Task management: cancel running tasks, list tasks with pagination (next-cursor), retrieve detailed task info (status, timestamps, metadata), and fetch task execution results (including error vs. content and structured result items).

…ations

Signed-off-by: hai.yue <20416005+yuehaii@users.noreply.github.com>
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Mar 28, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: a52fc57b-1c83-4098-9125-ef4141ea214f

📥 Commits

Reviewing files that changed from the base of the PR and between 4448033 and a28e0d8.

📒 Files selected for processing (1)
  • mcp/utils.go
🚧 Files skipped from review as they are similar to previous changes (1)
  • mcp/utils.go

Walkthrough

Adds four exported Client methods for task RPCs and four JSON parsing functions plus an internal helper to deserialize task-related MCP responses into typed result structures.

Changes

Cohort / File(s) Summary
Client Task Methods
client/client.go
Added CancelTask, ListTasks, TaskResult, and GetTask methods that send MCP JSON-RPC requests (via c.sendRequest(...)) and return typed results parsed by new mcp.Parse*Result functions.
Task Result Parsing Helpers
mcp/utils.go
Added internal jsonToTask to map generic JSON into GetTaskResult, and exported parsing functions ParseCancelTaskResult, ParseListTasksResult, ParseTaskResultResult, and ParseGetTaskResult to unmarshal json.RawMessage, populate _meta, convert fields (including numeric TTL/pollInterval to int64 pointers), parse task arrays, nextCursor, and result content/isError handling.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main change: adding four client-side task operation methods (get, list, cancel, result) to the MCP client.
Description check ✅ Passed The description follows the template with all key sections completed: clear description of the four task functions, appropriate type-of-change selections (new feature and MCP spec implementation), relevant checklist items marked, MCP spec compliance section with link provided, and example usage code demonstrating the implementation.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🧹 Nitpick comments (3)
mcp/utils.go (2)

1055-1056: GoDoc comments should start with the identifier name and use proper grammar.

Per coding guidelines, exported functions must have GoDoc comments starting with the identifier name. The current comments use lowercase "parse" instead of proper sentence structure.

✏️ Suggested improvements
-// ParseCancelTaskResult parse json message and convert to CancelTaskResult structure
+// ParseCancelTaskResult parses a JSON message and converts it to a CancelTaskResult.
 func ParseCancelTaskResult(rawMessage *json.RawMessage) (*CancelTaskResult, error) {

-// ParseListTasksResult parse json message and convert to ListTasksResult structure
+// ParseListTasksResult parses a JSON message and converts it to a ListTasksResult.
 func ParseListTasksResult(rawMessage *json.RawMessage) (*ListTasksResult, error) {

-// ParseTaskResultResult parse json message and convert to TaskResultResult structure
+// ParseTaskResultResult parses a JSON message and converts it to a TaskResultResult.
 func ParseTaskResultResult(rawMessage *json.RawMessage) (*TaskResultResult, error) {

-// ParseGetTaskResult parse json message and convert to GetTaskResult structure
+// ParseGetTaskResult parses a JSON message and converts it to a GetTaskResult.
 func ParseGetTaskResult(rawMessage *json.RawMessage) (*GetTaskResult, error) {

As per coding guidelines: "All exported types and functions must have GoDoc comments starting with the identifier name."

Also applies to: 1080-1081, 1123-1124, 1153-1154

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@mcp/utils.go` around lines 1055 - 1056, The GoDoc for the exported function
ParseCancelTaskResult does not start with the identifier name and uses incorrect
grammar; update its comment to start with "ParseCancelTaskResult" followed by a
proper sentence describing its behavior (e.g., "ParseCancelTaskResult parses a
JSON message and converts it to a CancelTaskResult.") and apply the same fix to
the other exported parser functions referenced in the review (the exported
functions at the other noted ranges) so each comment begins with the exact
function name and a concise, grammatically correct description.

1001-1053: Consider validating required task fields.

The jsonToTask function silently ignores missing required fields (taskId, status, createdAt, lastUpdatedAt). Callers may receive incomplete Task objects without any indication that the response was malformed. Consider returning an error if required fields are missing, consistent with how other parsers like ParseResourceContents handle missing required data.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@mcp/utils.go` around lines 1001 - 1053, The jsonToTask function currently
silently ignores missing required fields and should be changed to validate and
report errors: update the signature of jsonToTask to return error (e.g., func
jsonToTask(jsonContent map[string]any, result *GetTaskResult) error), check that
required keys ("taskId", "status", "createdAt", "lastUpdatedAt") exist and are
of the expected types, and return a descriptive error if any are missing or of
the wrong type; ensure you still populate optional fields like ttl and
pollInterval when present and mirror the error handling style used by
ParseResourceContents (construct and return errors rather than panicking or
silently omitting fields).
client/client.go (1)

735-746: Consider adding pagination support for ListTasks.

Other list methods in this file (ListResources, ListPrompts, ListTools) provide both a ListXByPage variant and an auto-paginating ListX method that loops until NextCursor is empty. ListTasks only provides the single-page variant. If the MCP spec supports pagination for task listing (which ListTasksResult with PaginatedResult suggests), consider adding ListTasksByPage and an auto-paginating ListTasks for consistency.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@client/client.go` around lines 735 - 746, Add pagination support for tasks by
implementing a ListTasksByPage(ctx, request) that calls c.sendRequest with
mcp.MethodTasksList and accepts/returns a single page (use
mcp.ParseListTasksResult to parse the response and preserve the
PaginatedResult/NextCursor), and then change/overload ListTasks to
auto-paginate: loop calling ListTasksByPage while the returned
PaginatedResult.NextCursor is non-empty, appending items into a cumulative
mcp.ListTasksResult (or slice) and returning the aggregated result; reference
symbols: Client.ListTasks, new Client.ListTasksByPage, c.sendRequest,
mcp.ParseListTasksResult, mcp.ListTasksResult, and PaginatedResult.NextCursor.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@mcp/utils.go`:
- Around line 1017-1022: The code is reading jsonContent["StatusMessage"]
(PascalCase) but the JSON uses "statusMessage" (camelCase), so update the key
lookup in the jsonContent map to "statusMessage" (or check both keys) so
result.StatusMessage is assigned correctly; locate the block that reads
jsonContent and assigns to result.StatusMessage and replace the key string
"StatusMessage" with "statusMessage" (or add a secondary lookup for
"StatusMessage" to maintain backward compatibility).
- Around line 1113-1118: The code is incorrectly asserting nextCursor from
jsonContent as type Cursor which will never succeed after JSON unmarshal; change
the logic in the block handling jsonContent["nextCursor"] (symbols: jsonContent,
nextCursor, Cursor, listTasksResult.PaginatedResult.NextCursor) to first assert
the value as the concrete JSON type (e.g., string or json.RawMessage), then
convert/unmarshal that into a Cursor (for example parse the string or call
json.Unmarshal into a Cursor) and only then assign it to
listTasksResult.PaginatedResult.NextCursor so the pagination value is correctly
extracted.
- Around line 1142-1148: The code currently attempts a type assertion
result.(TaskResultResult) which will always fail because json.Unmarshal into
map[string]any yields maps/primitives, not struct types; update the block that
reads jsonContent["result"] to assert result to map[string]any (e.g. resultMap),
then extract the "content" and "is_error" (or "IsError") fields from that map,
converting types safely (use string for content or reuse ParseCallToolResult
logic to parse nested content structures) and set resultResult.Content and
resultResult.IsError accordingly; ensure you handle absent keys and type
mismatches gracefully and mirror the parsing approach used in
ParseCallToolResult for nested content.

---

Nitpick comments:
In `@client/client.go`:
- Around line 735-746: Add pagination support for tasks by implementing a
ListTasksByPage(ctx, request) that calls c.sendRequest with mcp.MethodTasksList
and accepts/returns a single page (use mcp.ParseListTasksResult to parse the
response and preserve the PaginatedResult/NextCursor), and then change/overload
ListTasks to auto-paginate: loop calling ListTasksByPage while the returned
PaginatedResult.NextCursor is non-empty, appending items into a cumulative
mcp.ListTasksResult (or slice) and returning the aggregated result; reference
symbols: Client.ListTasks, new Client.ListTasksByPage, c.sendRequest,
mcp.ParseListTasksResult, mcp.ListTasksResult, and PaginatedResult.NextCursor.

In `@mcp/utils.go`:
- Around line 1055-1056: The GoDoc for the exported function
ParseCancelTaskResult does not start with the identifier name and uses incorrect
grammar; update its comment to start with "ParseCancelTaskResult" followed by a
proper sentence describing its behavior (e.g., "ParseCancelTaskResult parses a
JSON message and converts it to a CancelTaskResult.") and apply the same fix to
the other exported parser functions referenced in the review (the exported
functions at the other noted ranges) so each comment begins with the exact
function name and a concise, grammatically correct description.
- Around line 1001-1053: The jsonToTask function currently silently ignores
missing required fields and should be changed to validate and report errors:
update the signature of jsonToTask to return error (e.g., func
jsonToTask(jsonContent map[string]any, result *GetTaskResult) error), check that
required keys ("taskId", "status", "createdAt", "lastUpdatedAt") exist and are
of the expected types, and return a descriptive error if any are missing or of
the wrong type; ensure you still populate optional fields like ttl and
pollInterval when present and mirror the error handling style used by
ParseResourceContents (construct and return errors rather than panicking or
silently omitting fields).
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 05053549-ffad-4ce3-bb08-a2df1c3da63d

📥 Commits

Reviewing files that changed from the base of the PR and between 4713d74 and 695e73a.

📒 Files selected for processing (2)
  • client/client.go
  • mcp/utils.go

yuehaii added 2 commits March 28, 2026 13:43
Signed-off-by: hai.yue <20416005+yuehaii@users.noreply.github.com>
Signed-off-by: hai.yue <20416005+yuehaii@users.noreply.github.com>
@ezynda3 ezynda3 merged commit f89f21b into mark3labs:main Apr 4, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants