Help us shape the future of Go! Take the 2026 Go Developer Survey

mcptask

package
v1.149.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 22, 2026 License: Apache-2.0 Imports: 13 Imported by: 0

Documentation

Overview

Package mcptask is the platform's implementation of the MCP Tasks extension (io.modelcontextprotocol/tasks, protocol revision 2026-07-28; #2009).

A client that declares the extension on a tools/call may be answered with a task handle (resultType "task") instead of the tool's result, and follows the work with tasks/get and tasks/cancel. The SDK the platform is built on does not implement the extension, so this package carries it at the protocol level: the handle and the tasks/* answers are its own result types, the tasks/* methods are custom methods on the server, and the tool calls that become tasks are chosen by a receiving middleware.

A task is held by a Source, one per kind of work, addressed by the prefix of its id: a managed-script run is a task whose id is the run id, and a tool call executed apart from its request (an export) is a task kept in its own table. Nothing here stores a task; it routes each tasks/* request to the Source that owns the id and renders what the Source reports.

The extension's spec: https://github.com/modelcontextprotocol/ext-tasks/blob/main/specification/2026-07-28/tasks.md

Index

Constants

View Source
const (
	MethodGet    = "tasks/get"
	MethodUpdate = "tasks/update"
	MethodCancel = "tasks/cancel"
)

The extension's methods.

View Source
const (
	StatusWorking   = "working"
	StatusCompleted = "completed"
	StatusFailed    = "failed"
	StatusCancelled = "cancelled" //nolint:misspell // the extension's wire value
)

Task statuses.

View Source
const CodeMissingCapability = -32021

CodeMissingCapability is the JSON-RPC error a request that needs the extension is refused with when the client did not declare it.

View Source
const ExtensionID = "io.modelcontextprotocol/tasks"

ExtensionID is the extension's identifier, the key a client and the server declare it under.

Variables

View Source
var ErrNotDetached = errors.New("call not detached")

ErrNotDetached is what a Detacher answers for a call it declines to take on, one that is answered directly instead.

View Source
var ErrNotFound = errors.New("task not found")

ErrNotFound is what a Source answers for an id it does not hold, and for an id the caller may not read: the two are one answer, so a task's existence is never revealed to anybody but whoever may follow it.

Functions

func Complete

func Complete(ctx context.Context, res mcp.Result, err error)

Complete hands the outcome of a task's work to the receiver installed on ctx, if any.

func Declared

func Declared(req mcp.Request) bool

Declared reports whether the request itself declares the extension in its per-request client capabilities. Only the request counts: the spec forbids answering with a task a request that did not declare it, whatever the session declared before.

func EncodeResult

func EncodeResult(res *mcp.CallToolResult) (json.RawMessage, error)

EncodeResult renders a tool result in the wire form a client reads, the form tasks/get inlines. Structured content still held as a Go value is encoded by the platform's response encoder first, as the result-type layer does for a result answered directly (#1832), so an empty list reads [] here too.

func IsTask

func IsTask(res mcp.Result) bool

IsTask reports whether a tools/call answer is a task handle rather than the tool's result.

func Middleware

func Middleware(cfg Config) mcp.Middleware

Middleware answers a tools/call that declares the extension with a task, for the tools Config names, and identifies the caller of every tasks/* request. A call that does not declare the extension, and every other tool, passes through untouched: such a client sees exactly what it saw before.

It sits inside authorization, the gates and the consent prompts, so a call that is refused, or that needs the person's answer first, is answered directly before any task exists, as the extension requires.

func Register

func Register(server *mcp.Server, sources *Sources) error

Register adds the extension's methods to server, answered from sources.

func WithCompletion

func WithCompletion(ctx context.Context, fn CompletionFunc) context.Context

WithCompletion installs fn as the receiver of the outcome of a call that is answered with a task. The audit layer installs one: a task's answer is a handle, and the row it writes is for what the call did, which for a call executed apart from its request is known only when that work ends.

Types

type AckResult

type AckResult struct {
	mcp.ResultBase
	ResultType string `json:"resultType"`
}

AckResult is the empty acknowledgement tasks/update and tasks/cancel answer with.

type Claim

type Claim struct {
	// contains filtered or unexported fields
}

Claim is how a tool that keeps its own durable record (run_script) turns a call into a task: it finds a Claim on its context when the client declared the extension, starts its work without waiting for it, and accepts the claim with the id of the record it created. A call whose tool never accepts, a refusal for instance, is answered with the tool's own result.

func Requested

func Requested(ctx context.Context) *Claim

Requested returns the Claim a call to become a task carries, or nil when the call is to be answered with its result.

func (*Claim) Accept

func (c *Claim) Accept(id string)

Accept names the task the call became. The id must already resolve through its Source: the extension forbids handing out a task a tasks/get cannot find.

type CompletionFunc

type CompletionFunc func(ctx context.Context, res mcp.Result, err error)

CompletionFunc receives the outcome of a tools/call that was answered with a task, once the work behind it ends. ctx carries the PlatformContext the work ran under.

type Config

type Config struct {
	// Tools names the tools whose calls become tasks, and how.
	Tools map[string]Mode
	// Sources resolves a Native tool's accepted id to its seed state.
	Sources *Sources
	// Detacher executes a Detached tool's calls. With none, those calls
	// are answered directly.
	Detacher Detacher
	// Resolve identifies the caller of a tasks/* request.
	Resolve Resolver
}

Config is what the middleware needs.

type CreateResult

type CreateResult struct {
	mcp.ResultBase
	ResultType string `json:"resultType"`
	// contains filtered or unexported fields
}

CreateResult is the answer to a tools/call that became a task: the task's seed state under resultType "task".

func NewCreateResult

func NewCreateResult(s *Snapshot) *CreateResult

NewCreateResult renders a task's seed state as the tools/call answer.

type Detacher

type Detacher interface {
	Start(ctx context.Context, toolName string, run func(ctx context.Context) (mcp.Result, error)) (*Snapshot, error)
}

Detacher executes a tool call apart from the request that asked for it. Start creates the task durably, starts run on a context that outlives the request, and returns the task's seed state; run is the rest of the tools/call chain.

type GetResult

type GetResult struct {
	mcp.ResultBase
	ResultType string `json:"resultType"`

	Result json.RawMessage `json:"result,omitempty"`
	Error  *jsonrpc.Error  `json:"error,omitempty"`
	// contains filtered or unexported fields
}

GetResult is the answer to tasks/get: the task with its outcome inlined once it has one.

type Mode

type Mode int

Mode is how a tool's call becomes a task.

const (
	// Native is a tool that keeps its own record of the work and accepts the
	// call's Claim with that record's id (run_script and its run).
	Native Mode = iota + 1
	// Detached is a call executed apart from its request by the Detacher,
	// which keeps the task (the exports).
	Detached
)

type Resolver

type Resolver func(ctx context.Context, req mcp.Request) context.Context

Resolver attaches the caller's PlatformContext to a tasks/* request, which passes none of the tools/call layers that would.

type Snapshot

type Snapshot struct {
	ID            string
	Status        string
	StatusMessage string
	CreatedAt     time.Time
	UpdatedAt     time.Time
	// TTL is how long after CreatedAt the task may be discarded; zero is
	// unlimited.
	TTL time.Duration
	// PollInterval is how often a client should ask again.
	PollInterval time.Duration
	// Result is the tool's result on a completed task, in its wire form
	// (EncodeResult).
	Result json.RawMessage
	// Error is the JSON-RPC error on a failed task.
	Error *jsonrpc.Error
}

Snapshot is a task's state as its Source reports it.

func (*Snapshot) Terminal

func (s *Snapshot) Terminal() bool

Terminal reports whether the task has ended.

type Source

type Source interface {
	// Prefix is the id prefix of the tasks this Source holds.
	Prefix() string
	// Get reports a task's state.
	Get(ctx context.Context, id string) (*Snapshot, error)
	// Cancel asks for the task to stop. It is cooperative: the task may
	// still end another way if it finished first.
	Cancel(ctx context.Context, id string) error
}

Source holds one kind of task. Both calls run with the caller's PlatformContext on ctx and apply the Source's own reading rule, answering ErrNotFound for a task the caller may not follow.

type Sources

type Sources struct {
	// contains filtered or unexported fields
}

Sources routes a task id to the Source that holds it.

func NewSources

func NewSources(sources ...Source) *Sources

NewSources builds the routing over sources; a nil Source is skipped.

func (*Sources) Add

func (s *Sources) Add(src Source)

Add registers one more Source; a nil Source is skipped.

func (*Sources) For

func (s *Sources) For(id string) Source

For returns the Source holding id, or nil.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL