Skip to content

Implement tasks - #589

Open
0xKoller wants to merge 5 commits into
canaryfrom
feature/xmcp-421-implement-tasks
Open

Implement tasks#589
0xKoller wants to merge 5 commits into
canaryfrom
feature/xmcp-421-implement-tasks

Conversation

@0xKoller

Copy link
Copy Markdown
Contributor

Implements the MCP tasks utility (https://modelcontextprotocol.io/specification/2025-11-25/basic/utilities/tasks) (long-running, pollable tool calls) in xmcp, kept fully stateless all task state lives in an external store you provide, never in server memory. This works on serverless and matches the SEP-2663 (modelcontextprotocol/modelcontextprotocol#2663) non-blocking direction.

How it works

  • Enable tasks by adding a src/task-store.ts (default export). Its presence advertises the tasks capability and wires the store into the SDK's native tasks/get · tasks/result · tasks/list · tasks/cancel handlers.
  • Opt a tool in with taskSupport: "optional" | "required" in its metadata. xmcp auto-registers it as a task tool (no per-tool wrapping). The handler receives extra.task.taskId.
  • Execution is the user's. xmcp creates the task and serves status/result reads; it does not run background work. The handler kicks off work out-of-band (queue/worker/cron) and the worker writes the result back through the same store. State only ever crosses requests via that store.

createTaskStore

A createTaskStore(adapter, options?) factory builds a complete TaskStore from four tiny persistence methods (get / set / delete / list). It owns all the generic protocol logic id generation, timestamps, the working→terminal status machine, TTL evict-on-read, the public-task projection, and cursor pagination. Any KV/DB (Redis, Upstash, Postgres…) drops in by pointing those methods at it. Power users can still implement the raw TaskStore interface directly.

Key changes (packages/xmcp)

  • types/tool.ts: taskSupport on ToolMetadata, task?: { taskId } on ToolExtraArguments.
  • types/task.ts: public TaskStore / Task / TaskResult / TaskRecord / TaskStoreAdapter / CreateTaskStoreOptions + generateTaskId().
  • utils/create-task-store.ts: the factory.
  • Compiler: src/task-store.ts discovery + injection (mirrors the existing src/middleware.ts mechanism; no rewrites).
  • runtime/utils/server.ts: loads the store, passes it to McpServer, registers the tasks capability, and coerces primitive results on getTaskResult.
  • runtime/utils/tools.ts: auto-wraps task-enabled tools via experimental.tasks.registerToolTask; throws clearly if a tool declares taskSupport with no store present.

Example: examples/tasks-http/

A runnable stateless-HTTP server demonstrating the enqueue-here / execute-elsewhere model with two processes sharing only on-disk state:

  • src/task-store.ts — filesystem store via createTaskStore.
  • src/tools/long-job.ts — taskSupport: "required"; the tool only enqueues a job and returns (task stays working).
  • src/queue.ts + src/worker.ts — a separate worker process polls the queue, runs the job, and writes the result back through the shared store.
  • pnpm dev runs both the server and the worker; pnpm worker runs the worker standalone for the explicit two-terminal / production split.

@linear-code

linear-code Bot commented Jun 10, 2026

Copy link
Copy Markdown

XMCP-421

@vercel

vercel Bot commented Jun 10, 2026

Copy link
Copy Markdown
Contributor

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
xmcp-website Ready Ready Preview, Comment Jun 10, 2026 8:05pm

@0xKoller 0xKoller linked an issue Jun 10, 2026 that may be closed by this pull request
@github-actions

github-actions Bot commented Jun 10, 2026

Copy link
Copy Markdown

Rspack Bundle Analysis

Build Assets Total Size (MB) Build Time
Main Compiler 5 6.36 5.58s
Runtime Compiler 7 5.38 6.13s

Main Compiler

Source: stats-main.json

Asset Chunk Size (KB) Size (MB)
cli.js cli 6020.27 5.88
index.js index 389.86 0.38
cloudflare.js cloudflare 81.70 0.08
detached-flush.js detached-flush 15.18 0.01
host-bridge.js host-bridge 4.76 0.00

Total emitted JS: 6.36 MB

Runtime Compiler

Source: stats-runtime.json

Asset Chunk Size (KB) Size (MB)
http.js http 1052.33 1.03
adapter-nestjs.js adapter-nestjs 1028.54 1.00
adapter-nextjs.js adapter-nextjs 1022.61 1.00
adapter-express.js adapter-express 1020.84 1.00
adapter-fastify.js adapter-fastify 1020.73 1.00
stdio.js stdio 362.19 0.35
headers.js headers 1.73 0.00

Total emitted JS: 5.38 MB

Package Footprint (npm pack + npm install)

Item Size (KB) Size (MB)
Tarball (.tgz) 4124.66 4.03
dist/ 12111.25 11.83
node_modules/ 102414.55 100.01
dist + node_modules 114525.80 111.84

@0xKoller
0xKoller marked this pull request as ready for review June 10, 2026 20:04
@0xKoller
0xKoller requested a review from valebearzotti as a code owner June 10, 2026 20:04
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.

[Feature]: Add support for MCP Tasks

1 participant