Documentation
¶
Index ¶
- func Register(cfg Config)
- func WithTaskContext(ctx context.Context, tc *TaskContext) context.Context
- type Config
- type TaskContext
- func (tc *TaskContext) ProgressToken() any
- func (tc *TaskContext) SetStatus(status core.TaskStatus) error
- func (tc *TaskContext) TaskElicit(req core.ElicitationRequest) (core.ElicitationResult, error)
- func (tc *TaskContext) TaskID() string
- func (tc *TaskContext) TaskSample(req core.CreateMessageRequest) (core.CreateMessageResult, error)
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func Register ¶
func Register(cfg Config)
Register hooks up v2 tasks support on the given server:
- Advertises the io.modelcontextprotocol/tasks extension in initialize (replacing the v1 ServerCapabilities.Tasks declaration).
- Installs middleware that intercepts tools/call for task-eligible tools (server-directed, no client task param needed). Task creation is gated on the client supporting the extension — either at session level (initialize handshake) or per-request (SEP-2575 _meta).
- Registers tasks/get, tasks/update, and tasks/cancel handlers, gated on session-level extension support; otherwise the handlers return -32021 (Missing Required Client Capability, SEP-2575) with a machine-readable `requiredCapabilities` payload so unsupported clients can self-describe what to add.
- Does NOT register tasks/result or tasks/list (removed in v2).
- Does NOT call SetTasksCap — v2 tasks live under capabilities.extensions, not the v1 ServerCapabilities.Tasks slot.
Must be called before accepting connections.
func WithTaskContext ¶
func WithTaskContext(ctx context.Context, tc *TaskContext) context.Context
WithTaskContext returns a context carrying the TaskContext.
Types ¶
type Config ¶
type Config struct {
// Store is the task state backend. If nil, an InMemoryTaskStore is used.
Store server.TaskStore
// Server is the MCP server to register tasks on.
Server *server.Server
// DefaultTTLMs is the default task TTL in integer milliseconds. Per
// SEP-2663 the wire surfaces ttlMs and the store also uses ms, so this
// value flows through unchanged. Default: 300000 (5 minutes).
DefaultTTLMs int
// DefaultPollMs is the suggested poll interval in milliseconds,
// returned to clients in CreateTaskResult as pollIntervalMs. Default: 1000 (1 second).
DefaultPollMs int
// TracerProvider opts the runtime into SEP-414 P6 instrumentation of
// the async task lifecycle (issue 659). When set, spawnGoAsyncTask
// emits a `task.execute` span as a NEW root trace (so the long-running
// task work doesn't render as a multi-hour child under a few-ms create
// span) carrying a Link back to the originating tools/call create
// span. Each tasks/get / tasks/update / tasks/cancel dispatch span
// additionally Adds a Link to the originating create span so a backend
// can pivot from any poll into the whole task lifecycle.
//
// Span attributes:
// - `mcp.task.id` — task identifier
// - `mcp.task.status` — final status stamped at End (completed /
// failed / cancelled / input_required)
//
// On the failure paths (handler error, protocol error, panic recover)
// the span also gets RecordError so observability backends count it
// as an error trace and surface the underlying message.
//
// Nil or core.NoopTracerProvider{} (the default) skips the install —
// zero allocation, no spans emitted. ext/tasks depends on the core
// abstraction only; no compile-time dep on ext/otel.
TracerProvider core.TracerProvider
}
Config holds the options for registering v2 tasks support on an MCP server.
type TaskContext ¶
type TaskContext struct {
core.ToolContext
// contains filtered or unexported fields
}
TaskContext is the typed context for tool handlers running as a v2 background task. It embeds core.ToolContext and adds task-specific methods (TaskID, ProgressToken, TaskElicit, TaskSample, SetStatus).
Tool handlers retrieve this via GetTaskContext(ctx). It is nil for synchronous (non-task) tool invocations.
Usage:
func myToolHandler(ctx core.ToolContext, input MyInput) (string, error) {
tc := tasks.GetTaskContext(ctx)
if tc != nil {
result, err := tc.TaskElicit(core.ElicitationRequest{...})
}
return "done", nil
}
Distinct from server.TaskContext (which serves the v1 surface). A tool registered for both v1 and v2 (via RegisterHybrid) sees the appropriate type when invoked under each runtime.
func GetTaskContext ¶
func GetTaskContext(ctx core.ToolContext) *TaskContext
GetTaskContext retrieves the TaskContext from a tool handler's context, binding it to the provided ToolContext for elicitation/sampling. Returns nil if the tool was not invoked as a v2 task.
func (*TaskContext) ProgressToken ¶
func (tc *TaskContext) ProgressToken() any
ProgressToken returns the client's original _meta.progressToken from the tools/call request. Use this instead of TaskID() for EmitProgress so progress notifications correlate with what the client expects. Returns nil if the client didn't send a progressToken.
func (*TaskContext) SetStatus ¶
func (tc *TaskContext) SetStatus(status core.TaskStatus) error
SetStatus transitions the task to a new status and emits a notifications/tasks status event so polling/streaming clients pick up the new state.
func (*TaskContext) TaskElicit ¶
func (tc *TaskContext) TaskElicit(req core.ElicitationRequest) (core.ElicitationResult, error)
TaskElicit asks the client for elicitation input from inside a running v2 task. The request is stashed on the task's inputState under a monotonic key, the task transitions to input_required, and the goroutine blocks on a per-key waiter channel. The client observes the pending request via tasks/get's DetailedTask.InputRequests and resumes the task by sending the matching response via tasks/update. ctx cancellation unblocks the wait with the corresponding context error.
Status transitions: working → input_required → working.
func (*TaskContext) TaskID ¶
func (tc *TaskContext) TaskID() string
TaskID returns the task's unique identifier.
func (*TaskContext) TaskSample ¶
func (tc *TaskContext) TaskSample(req core.CreateMessageRequest) (core.CreateMessageResult, error)
TaskSample asks the client for a sampling/createMessage response from inside a running v2 task. See TaskElicit for the input-state flow.
Status transitions: working → input_required → working.