Skip to content

feat(mcp): add MCP Tasks support at the SDK level (#21)#22

Merged
ezynda3 merged 3 commits into
masterfrom
feat/21-mcp-tasks-mvp
May 4, 2026
Merged

feat(mcp): add MCP Tasks support at the SDK level (#21)#22
ezynda3 merged 3 commits into
masterfrom
feat/21-mcp-tasks-mvp

Conversation

@ezynda3

@ezynda3 ezynda3 commented May 4, 2026

Copy link
Copy Markdown
Contributor

Description

Implements Phase 1 of MCP Tasks (spec) so long-running MCP tools can run asynchronously, survive HTTP/SSE proxy timeouts, and be cancelled mid-flight. The full design and motivation are in #21 — this PR delivers the MVP slice (capability handshake, polling-based execution, context-aware cancel) and the public SDK surface; Phase 2 push notifications and Phase 3 UX/extension hooks are deferred to follow-ups.

The connection pool now advertises mcp.NewTasksCapability() during initialize and captures the server's InitializeResult so we can detect per-server task support. MCPToolManager.ExecuteTool augments tools/call with TaskParams when policy + capability allow, polls tasks/get / tasks/result until the task reaches a terminal state, and best-effort tasks/cancels on context cancellation. Defaults to MCPTaskModeAuto so any server that doesn't advertise task support keeps its existing synchronous behaviour bit-for-bit.

The public SDK gets a clean dependency-agnostic surface (MCPTask, MCPTaskStatus, MCPTaskMode, MCPTaskProgress, MCPTaskProgressHandler) on pkg/kit/, six new Options fields (MCPTaskMode, MCPTaskTimeout, MCPTaskTTL, MCPTaskPollInterval, MCPTaskMaxPollInterval, MCPTaskProgress), and three Kit methods (ListMCPTasks, GetMCPTask, CancelMCPTask). mcp.json learns one new field, tasksMode (auto / never / always), recognised in both new and legacy formats.

// SDK consumer opt-in
host, _ := kit.New(ctx, &kit.Options{
    MCPTaskMode:     map[string]kit.MCPTaskMode{"build-server": kit.MCPTaskModeAlways},
    MCPTaskTimeout:  15 * time.Minute,
    MCPTaskProgress: func(p kit.MCPTaskProgress) { log.Printf("%s: %s", p.TaskID, p.Status) },
})

Fixes #21

Type of Change

  • New feature (non-breaking change which adds functionality)
  • Bug fix (non-breaking change which fixes an issue)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Documentation update

Checklist

  • My code follows the style guidelines of this project (go fmt, go vet, golangci-lint run all clean)
  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • My changes generate no new warnings
  • I have added tests that prove my fix is effective or that my feature works
  • New and existing unit tests pass locally with my changes (go test ./... -race)
  • I have made corresponding changes to the documentation (deferred — README/docs update will accompany the Phase 2/3 follow-ups when the user-facing UX lands)

Additional Information

Backward compatibility. Defaulting TasksMode to auto means servers that don't advertise task support during initialize get exactly the previous synchronous code path — no change in JSON wire shape, no change in result content typing. The new SDK fields are all zero-valued opt-ins.

Files added

  • internal/tools/mcp_tasks.go — task modes, config, low-level callToolWithTask, pollTaskUntilTerminal, fetchTaskResult
  • internal/tools/mcp_tasks_test.go — capability advertisement/detection, mode parsing, end-to-end polling against an in-process server, progress emission, "never" mode, list/get/cancel error paths
  • pkg/kit/mcp_tasks.go — public SDK types and Kit.{List,Get,Cancel}MCPTask methods
  • pkg/kit/mcp_tasks_test.go — terminality, options conversion, nil-Kit safety

Files modified

  • internal/config/config.go (+ test) — MCPServerConfig.TasksMode field, parsed in both new and legacy unmarshal paths
  • internal/tools/connection_pool.go — advertise tasks capability, capture InitializeResult, add SupportsToolTasks / ServerSupportsToolTasks
  • internal/tools/mcp.go — task-aware ExecuteTool, SetTaskConfig, ListServerTasks / GetServerTask / CancelServerTask
  • internal/agent/agent.go, internal/agent/factory.go, internal/kitsetup/setup.go — propagate MCPTaskConfig from SDK options through to the tool manager (including the lazy AddMCPServer path)
  • pkg/kit/kit.go — six new Options fields wired into setupOpts

Upstream workarounds (commented inline at the call sites)

  1. mcp.ParseCallToolResult requires a content field, so a CreateTaskResult response would error out — bypassed via raw transport SendRequest + manual decode.
  2. mcp.ParseTaskResultResult (mcp-go v0.51.0) looks for content under a nested "result" key that doesn't exist in the wire format, returning an empty Content slice — same workaround.
  3. mcp-go's in-process server cancels the request context immediately on the synchronous return, which would cancel any task goroutine spawned by AddTaskTool. Real-world transports (stdio, SSE, streamable HTTP) keep the connection's context alive across the async work, so this only affects the test fixture; documented in the test's helper comment.

Out of scope (per #21, deferred to follow-ups)

  • Phase 2 notifications/tasks/status event-driven updates (this PR uses polling).
  • Phase 3 /tasks slash command, _meta.modelImmediateResponse handling, and extension hooks (OnMCPTaskStarted/Completed/Cancelled).

Summary by CodeRabbit

Release Notes

  • New Features
    • Added support for task-augmented MCP tool execution with configurable modes (auto, never, always).
    • Introduced task management capabilities: list, retrieve, and cancel running server tasks.
    • Added progress callback support for monitoring long-running task operations.
    • New configuration options for task timing and execution behavior.

Implement Phase 1 of the MCP Tasks spec so long-running tools/call
requests can run asynchronously, survive proxy timeouts, and be
cancelled mid-flight.

- connection pool now advertises mcp.NewTasksCapability() during
  initialize and captures the InitializeResult so callers can detect
  per-server task support
- new MCPServerConfig.TasksMode (auto|never|always, default auto)
  parsed from both new and legacy mcp.json shapes
- ExecuteTool augments tools/call with TaskParams when policy and
  capability allow, polls tasks/get / tasks/result until terminal,
  and best-effort tasks/cancel on context cancellation
- new MCPToolManager methods: SetTaskConfig, ListServerTasks,
  GetServerTask, CancelServerTask
- public SDK surface in pkg/kit: MCPTask, MCPTaskStatus, MCPTaskMode,
  MCPTaskProgress, MCPTaskProgressHandler, plus Options fields
  (MCPTaskMode, MCPTaskTimeout, MCPTaskTTL, MCPTaskPollInterval,
  MCPTaskMaxPollInterval, MCPTaskProgress) and Kit.{List,Get,Cancel}
  MCPTask methods
- works around two upstream mcp-go v0.51.0 parser bugs
  (ParseCallToolResult rejects task responses; ParseTaskResultResult
  looks for content under a non-existent nested key) by decoding the
  wire shape directly via the transport
- defaults to MCPTaskModeAuto so servers that don't advertise task
  support behave exactly as before

Fixes #21
@mark-iii-labs-huly

Copy link
Copy Markdown

Connected to Huly®: KIT-23

@coderabbitai

coderabbitai Bot commented May 4, 2026

Copy link
Copy Markdown

Warning

Rate limit exceeded

@ezynda3 has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 46 minutes and 47 seconds before requesting another review.

To keep reviews running without waiting, you can enable usage-based add-on for your organization. This allows additional reviews beyond the hourly cap. Account admins can enable it under billing.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 4597fd8b-10f0-4fd8-9fec-76301365602f

📥 Commits

Reviewing files that changed from the base of the PR and between e6084b7 and 6e36053.

📒 Files selected for processing (10)
  • README.md
  • internal/config/config.go
  • internal/config/config_test.go
  • pkg/kit/README.md
  • pkg/kit/kit.go
  • pkg/kit/mcp_tasks.go
  • pkg/kit/mcp_tasks_test.go
  • www/pages/configuration.md
  • www/pages/sdk/options.md
  • www/pages/sdk/overview.md
📝 Walkthrough

Walkthrough

This PR adds MCP Tasks support to Kit's MCP client and SDK. It enables asynchronous, pollable tool execution via task-augmented tools/call requests, with configurable per-server modes, progress reporting, and task management APIs across the client, agent, and public SDK layers.

Changes

MCP Tasks Feature

Layer / File(s) Summary
Data Shape & Types
internal/tools/mcp_tasks.go, pkg/kit/mcp_tasks.go
Introduces MCPTaskMode (auto/never/always), MCPTaskInfo, MCPTaskProgress, MCPTaskConfig, and exported SDK types MCPTask, MCPTaskStatus, MCPTaskProgressHandler.
Configuration
internal/config/config.go, internal/config/config_test.go
MCPServerConfig gains TasksMode field; UnmarshalJSON parses it in both new and legacy formats.
Connection Capability Detection
internal/tools/connection_pool.go
Stores InitializeResult per connection; advertises task capability in Initialize; exposes SupportsToolTasks() and ServerSupportsToolTasks().
Task Execution & Polling
internal/tools/mcp_tasks.go, internal/tools/mcp_tasks_test.go
Implements task dispatch (callToolWithTask), polling loop (pollTaskUntilTerminal), result fetching (fetchTaskResult), cancellation, and task-info conversion. Tests verify polling, mode enforcement, progress callbacks, and task management operations.
MCP Tool Manager Integration
internal/tools/mcp.go
ExecuteTool resolves per-server task mode, conditionally routes through task path with polling, adds SetTaskConfig/TaskConfig accessors, and exposes task management helpers (ListServerTasks, GetServerTask, CancelServerTask).
Agent & Setup Wiring
internal/agent/agent.go, internal/agent/factory.go, internal/kitsetup/setup.go
Plumb MCPTaskConfig from AgentCreationOptions through Agent to MCPToolManager.SetTaskConfig() for both initial and lazily-added servers.
SDK Public API
pkg/kit/kit.go, pkg/kit/mcp_tasks.go, pkg/kit/mcp_tasks_test.go
Expose Options fields (MCPTaskMode, MCPTaskTTL, MCPTaskTimeout, MCPTaskPollInterval, MCPTaskMaxPollInterval, MCPTaskProgress); implement SDK methods ListMCPTasks, GetMCPTask, CancelMCPTask with status/progress conversion; tests validate configuration mapping, conversions, and error handling.

Sequence Diagram(s)

sequenceDiagram
    participant Client as Client<br/>(Kit Agent)
    participant Pool as Connection<br/>Pool
    participant Server as MCP Server
    participant Manager as Tool<br/>Manager
    
    rect rgba(0, 100, 200, 0.5)
    Note over Client,Server: Initialization: Advertise Task Capability
    Client->>Pool: Initialize with<br/>TasksCapability
    Pool->>Server: Initialize Request
    Server-->>Pool: InitializeResult with<br/>Tasks capability
    Pool->>Pool: Store InitializeResult<br/>Set SupportsToolTasks=true
    end
    
    rect rgba(100, 150, 100, 0.5)
    Note over Client,Manager: Tool Execution: Detect & Route
    Client->>Manager: ExecuteTool(toolName, args)
    Manager->>Pool: Check server<br/>task support
    Manager->>Manager: Resolve task mode<br/>(auto/never/always)
    end
    
    rect rgba(200, 100, 100, 0.5)
    Note over Manager,Server: Task Path: Async Dispatch & Poll
    Manager->>Server: tools/call with<br/>TaskParams{TTL}
    Server-->>Manager: CreateTaskResult<br/>{taskId, status}
    
    loop Poll Until Terminal
        Manager->>Server: tasks/get{taskId}
        Server-->>Manager: Task{status, TTL,<br/>pollInterval}
        Manager->>Manager: Emit Progress
        alt status is terminal
            Manager->>Server: tasks/result{taskId}
            Server-->>Manager: TaskResult
        end
    end
    end
    
    rect rgba(150, 100, 150, 0.5)
    Note over Manager,Client: Return & Progress
    Manager-->>Client: MCPToolResult with<br/>final content
    alt Progress Callback
        Manager->>Client: Progress(status,<br/>statusMessage)
    end
    end
Loading
sequenceDiagram
    participant Agent as Agent/Kit
    participant SDK as SDK Config
    participant Manager as Tool Manager
    participant Pool as Connection Pool
    
    rect rgba(100, 150, 200, 0.5)
    Note over Agent,Pool: Configuration Flow at Agent Setup
    Agent->>SDK: New(WithMCPTaskMode{...},<br/>WithMCPTaskTTL, ...)
    SDK->>SDK: toToolsConfig() converts<br/>SDK → internal types
    Agent->>Manager: SetTaskConfig(MCPTaskConfig)
    Manager->>Manager: Store taskCfg
    end
    
    rect rgba(150, 100, 100, 0.5)
    Note over Agent,Manager: Lazy Server Addition (AddMCPServer)
    Agent->>Manager: AddMCPServer(serverName)
    Manager->>Pool: Create new connection
    Pool->>Manager: SetTaskConfig(same cfg)
    end
    
    rect rgba(100, 100, 150, 0.5)
    Note over SDK,Manager: Task Management APIs (ListMCPTasks, etc.)
    SDK->>Manager: ListMCPTasks(ctx, serverName)
    Manager->>Pool: Get task client for server
    Manager->>Pool: Call tasks/list RPC
    Manager->>SDK: Convert MCPTaskInfo → MCPTask
    end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~75 minutes

Poem

🐰 Tasks hop where sync tools once crawled slow,
Polling loops now let long builds flow.
Progress callbacks emit with glee,
While async MCP sets agents free!
🌾✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 45.83% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main objective of the PR: adding MCP Tasks support at the SDK level, which matches the primary changes across all modified and new files.
Linked Issues check ✅ Passed All Phase 1 MVP objectives from issue #21 are implemented: capability advertisement with InitializeResult capture [internal/tools/connection_pool.go], per-server TasksMode config [internal/config/config.go, pkg/kit/kit.go], TaskParams augmentation and polling in ExecuteTool [internal/tools/mcp.go, internal/tools/mcp_tasks.go], and comprehensive SDK surface in pkg/kit/ with task types, options, and methods.
Out of Scope Changes check ✅ Passed All changes directly support Phase 1 MCP Tasks implementation: plumbing through agent/config/factory/setup layers, connection pool capability detection, tool execution with task polling, and SDK surface exposure. No extraneous modifications detected.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/21-mcp-tasks-mvp

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
Review rate limit: 0/1 reviews remaining, refill in 46 minutes and 47 seconds.

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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (3)
internal/tools/mcp_tasks.go (1)

304-363: 💤 Low value

Workaround for upstream mcp-go parsing issue is well-documented.

The custom fetchTaskResult decoder correctly works around the mcp-go v0.51.0 issue where ParseTaskResultResult looks for content under a nested "result" key that doesn't exist in the wire format.

Consider adding a TODO or tracking issue reference so this can be removed when mcp-go is fixed.

💡 Suggested improvement
 // fetchTaskResult issues tasks/result on the transport and parses the raw
 // response. The upstream client.TaskResult helper delegates to
 // mcp.ParseTaskResultResult which (as of mcp-go v0.51.0) looks for the
 // content array under a nested "result" key that never exists in the
 // wire format — leading to systematically empty Content. Doing the
 // parse here keeps the polling path working until that is fixed upstream.
+//
+// TODO: Remove this workaround when mcp-go fixes ParseTaskResultResult.
+// See: https://github.com/mark3labs/mcp-go/issues/XXX (file upstream issue)
 func fetchTaskResult(ctx context.Context, c *client.Client, taskID string) (*mcp.TaskResultResult, error) {
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@internal/tools/mcp_tasks.go` around lines 304 - 363, Add a TODO comment and
tracking issue reference to the custom fetchTaskResult implementation so future
maintainers know this is a temporary workaround for mcp-go v0.51.0's
ParseTaskResultResult bug; update the comment block above the fetchTaskResult
function to include a clear "TODO: remove when fixed" line plus either the
upstream issue URL or a placeholder (e.g. GH-xxxx) and the mcp-go version
(v0.51.0) so it can be removed once the upstream fix lands.
internal/tools/mcp.go (2)

726-729: 💤 Low value

Redundant progress handler parameter.

pollTaskUntilTerminal receives m.taskCfg which already contains the Progress handler, but it's also passed separately as the last argument. The function signature in mcp_tasks.go:221-228 shows both cfg MCPTaskConfig (which has cfg.Progress) and a separate progress MCPTaskProgressHandler parameter.

This redundancy could lead to confusion about which handler is used. Consider either:

  1. Using only cfg.Progress inside pollTaskUntilTerminal and removing the separate parameter, or
  2. Documenting that the explicit progress parameter overrides cfg.Progress
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@internal/tools/mcp.go` around lines 726 - 729, The call to
pollTaskUntilTerminal passes m.taskCfg and also m.taskCfg.Progress redundantly;
change pollTaskUntilTerminal (in mcp_tasks.go: function pollTaskUntilTerminal)
to remove the separate progress MCPTaskProgressHandler parameter and have the
function use cfg.Progress from the MCPTaskConfig type (MCPTaskConfig and
MCPTaskProgressHandler), then update all call sites (including this call that
currently passes mapping.serverName, taskResult.Task, m.taskCfg,
m.taskCfg.Progress) to omit the extra progress argument so only cfg is passed;
ensure any documentation/comments reflect that pollTaskUntilTerminal uses
cfg.Progress exclusively.

673-691: 💤 Low value

Consider logging when task capability is unavailable due to client type.

When conn.client is not a *client.Client, the code silently falls back to synchronous execution. This could surprise users who configured MCPTaskModeAlways but don't see task behavior.

A debug-level log would help diagnose such situations without breaking existing behavior.

💡 Suggested improvement
 	rawClient, ok := conn.client.(*client.Client)
 	if !ok {
 		// Older client implementations — fall back to the synchronous shape.
+		if m.debugLogger != nil && m.debugLogger.IsDebugEnabled() {
+			m.debugLogger.LogDebug(fmt.Sprintf("[DEBUG] Task mode enabled but client type %T does not support tasks; falling back to sync", conn.client))
+		}
 		callParams.Task = nil
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@internal/tools/mcp.go` around lines 673 - 691, When conn.client is not a
*client.Client the code silently falls back to synchronous execution; add a
debug-level log before the fallback that states the task capability is
unavailable and we are falling back to synchronous "tools/call" execution,
including identifying info such as mapping.serverName and the attempted task
setting (e.g., callParams.Task or the configured MCPTaskModeAlways), so
operators can see why tasks weren’t used; keep behavior identical otherwise and
use the existing logger used in this scope for the message.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@internal/config/config.go`:
- Around line 41-56: In Config.Validate(), add a check for the TasksMode field
to fail-fast on invalid values: verify TasksMode is either "" (empty), "auto",
"never", or "always" and return a validation error if it's anything else; update
the Config.Validate() method to perform this check early and produce a clear
error message mentioning the invalid TasksMode value so callers know which
setting is wrong.

In `@pkg/kit/kit.go`:
- Around line 1425-1432: The MCP task options set into MCPTaskConfig (via
mcpTaskOptions -> toToolsConfig) are only applied to the top-level Kit and not
carried into child agents; update Subagent() so when it constructs the child
Options (and its MCPConfig) it also copies/propagates the MCP task fields
(perServer/MCPTaskMode, defaultTTL/MCPTaskTTL, pollInterval/MCPTaskPollInterval,
maxPollInterval/MCPTaskMaxPollInterval, timeout/MCPTaskTimeout,
progress/MCPTaskProgress) — e.g., reuse mcpTaskOptions.toToolsConfig() or
explicitly copy those fields into the child Options.MCPConfig/MCPTaskConfig
construction so child subagents get the same task overrides as the parent Kit.

---

Nitpick comments:
In `@internal/tools/mcp_tasks.go`:
- Around line 304-363: Add a TODO comment and tracking issue reference to the
custom fetchTaskResult implementation so future maintainers know this is a
temporary workaround for mcp-go v0.51.0's ParseTaskResultResult bug; update the
comment block above the fetchTaskResult function to include a clear "TODO:
remove when fixed" line plus either the upstream issue URL or a placeholder
(e.g. GH-xxxx) and the mcp-go version (v0.51.0) so it can be removed once the
upstream fix lands.

In `@internal/tools/mcp.go`:
- Around line 726-729: The call to pollTaskUntilTerminal passes m.taskCfg and
also m.taskCfg.Progress redundantly; change pollTaskUntilTerminal (in
mcp_tasks.go: function pollTaskUntilTerminal) to remove the separate progress
MCPTaskProgressHandler parameter and have the function use cfg.Progress from the
MCPTaskConfig type (MCPTaskConfig and MCPTaskProgressHandler), then update all
call sites (including this call that currently passes mapping.serverName,
taskResult.Task, m.taskCfg, m.taskCfg.Progress) to omit the extra progress
argument so only cfg is passed; ensure any documentation/comments reflect that
pollTaskUntilTerminal uses cfg.Progress exclusively.
- Around line 673-691: When conn.client is not a *client.Client the code
silently falls back to synchronous execution; add a debug-level log before the
fallback that states the task capability is unavailable and we are falling back
to synchronous "tools/call" execution, including identifying info such as
mapping.serverName and the attempted task setting (e.g., callParams.Task or the
configured MCPTaskModeAlways), so operators can see why tasks weren’t used; keep
behavior identical otherwise and use the existing logger used in this scope for
the message.
🪄 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: defaults

Review profile: CHILL

Plan: Pro

Run ID: 740cd4b5-2a35-4ea9-a0bc-1e1273e45f2d

📥 Commits

Reviewing files that changed from the base of the PR and between 34d5abf and e6084b7.

📒 Files selected for processing (12)
  • internal/agent/agent.go
  • internal/agent/factory.go
  • internal/config/config.go
  • internal/config/config_test.go
  • internal/kitsetup/setup.go
  • internal/tools/connection_pool.go
  • internal/tools/mcp.go
  • internal/tools/mcp_tasks.go
  • internal/tools/mcp_tasks_test.go
  • pkg/kit/kit.go
  • pkg/kit/mcp_tasks.go
  • pkg/kit/mcp_tasks_test.go

Comment thread internal/config/config.go
Comment thread pkg/kit/kit.go
ezynda3 added 2 commits May 4, 2026 17:01
- README: add tasksMode YAML example and MCP Tasks subsection with
  SDK opt-in snippet
- pkg/kit/README: add MCP Tasks subsection covering MCPTaskMode,
  progress callbacks, and List/Get/Cancel methods
- www/configuration: document the tasksMode server field plus a
  per-mode behaviour table
- www/sdk/options: extend the Compaction & MCP table with the six
  new Options fields and add a top-level MCP Tasks section
- www/sdk/overview: add a brief MCP Tasks section between MCP
  prompts/resources and Context & compaction

All examples verified against the public symbols in pkg/kit/mcp_tasks.go;
docs site builds cleanly via npx tome build.
Address two review findings on the MCP Tasks PR.

- Config.Validate() now rejects unknown tasksMode values with a clear
  error naming the server and bad value. Without this a typo (e.g.
  "alwasy") was silently downgraded to "auto" by the runtime parser.
- Kit.Subagent() now propagates the parent's six MCP task options
  (mode map, timeout, TTL, poll interval, max poll interval, progress
  callback) onto the child via a new inheritMCPTaskOptions helper.
  Without this, child subagents always saw default polling and no
  progress feedback regardless of parent configuration.

The propagation logic lives in a helper so the test exercises the real
code path instead of duplicating it; future task fields only need to be
added in one place.
@ezynda3 ezynda3 merged commit d304805 into master May 4, 2026
3 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.

feat: add MCP Tasks support at the SDK level

1 participant