Context
PR #21 registered a Tasks surface that does not match 2026-07-28 (SEP-2663 needs tasks/get + tasks/update + tasks/cancel).
Today (nitrostack/core/app.py _register_task_handlers):
- Registers
tasks/list, tasks/get, tasks/cancel, tasks/result
- Sets
server.has_task_support = True unconditionally
- Discover advertises
io.modelcontextprotocol/tasks only if a tool has task_support optional/required (_advertise_tasks_extension) — so low-level capabilities and discover can disagree
- No
tasks/update
tasks/result and tasks/list are in MODERN_METHOD_CONTRACTS and only rejected when era is modern; auto still serves them
core/task.py TaskStatus includes expired; tasks/types.py terminal set is completed|failed|cancelled
TaskStatusRouter in nitrostack/tasks/notify.py has no production callers
InFlightRegistry is register/discard on tools/call; nothing handles notifications/cancelled so cancel is dead
create_task ids are task_ + 12 hex chars
InMemoryTaskStore is an unlocked dict
check_task_access(context=None) returns (isolation bypass if HTTP forgets request_ctx)
ttl_ms_to_seconds uses max(1, int(ttl_ms/1000)) (500ms → 1s)
- Tool
task_support == "required" raises INVALID_REQUEST, not -32021
Official Python mcp SDK skipped Tasks. Default for this issue: hide tasks on the 2026 wire. Do not implement full tasks/update unless product explicitly asks in this issue’s comments.
Handoff: #21 (comment)
Goal (Hide)
Auto/modern:
- Do not advertise tasks extension
- Do not register
tasks/*
tools/call with params.task → error (-32021 or invalid-params: server does not support tasks), not CreateTaskResult
Keep TaskManager / @tool(task_support=...) for in-process and era legacy if those tests still need them.
Probe
rg -n "add_request_handler\(\"tasks/|has_task_support|_advertise_tasks_extension|tasks/update" nitrostack
rg -n "TaskStatusRouter|notify_task_status" nitrostack
rg -n "InFlightRegistry|_in_flight" nitrostack
Read:
nitrostack/core/app.py — _register_task_handlers, _call_tool task branch, _advertise_tasks_extension
nitrostack/core/mcp_server.py — has_task_support → caps.tasks including list
nitrostack/protocol/method_contract.py — tasks rows
nitrostack/core/task.py vs nitrostack/tasks/types.py
nitrostack/tasks/notify.py, nitrostack/tasks/authorization.py, nitrostack/tasks/memory.py
tests/test_mcp20_tasks.py, tests/test_tasks.py, tests/test_mcp20_task_authorization.py
Implementation (Hide — do this)
has_task_support = False on auto/modern. Do not set True unconditionally.
- Do not register
tasks/list, tasks/result, tasks/get, tasks/cancel on auto/modern.
- Discover:
advertise_tasks=False on auto/modern (even if tools have task_support flags).
_call_tool: if era is auto/modern and task_metadata is present → -32021 (once WP2 adds the code) or -32602 with a clear message. Do not spawn TaskManager background work for HTTP 2026.
- Remove
tasks/result / tasks/list from any “live modern methods” table (WP2 owns the table; coordinate).
notify.py: delete if still unhooked, or leave unused only if Hide makes it obviously dead — prefer delete to avoid a fake fan-out.
InFlightRegistry: if cancel is still unwired, delete register/discard on the 2026 path or wire notifications/cancelled. Do not leave a registry tests poke that HTTP never cancels.
Legacy era: you may keep existing task handlers if tests/test_tasks.py depends on them. Do not expand 2025 task list onto 2026.
Do not do “Finish” in this issue
Finish would mean tasks/get + tasks/update + tasks/cancel, no list/result on modern, one status enum, store lock, UUID ids, access context always passed, notify hooked, -32021 for capability mismatches. That is a separate product epic. If you start Finish, you must complete it — do not ship half.
Test / verify
pytest tests/test_mcp20_tasks.py tests/test_tasks.py tests/test_mcp20_task_store.py tests/test_mcp20_task_authorization.py -q
Those files likely expect 2026 task RPCs. Update them to match Hide:
- HTTP
TestClient, era modern/auto: tasks/get / tasks/list / tasks/result → -32601
- Discover capabilities: no
io.modelcontextprotocol/tasks
tools/call with task: {} on modern → not a task result
- Keep in-process
TaskManager unit tests if the class remains
Add one test that get_capabilities does not include tasks for a modern/auto app.
Review
- No new task persistence backend.
- Discover and
has_task_support agree (both off on 2026).
- No silent
CreateTaskResult on modern.
Success
Related
Depends on WP0 (who handles /mcp) and WP2 (-32021, method table). Do not block on a full Tasks spec implementation.
Context
PR #21 registered a Tasks surface that does not match 2026-07-28 (SEP-2663 needs
tasks/get+tasks/update+tasks/cancel).Today (
nitrostack/core/app.py_register_task_handlers):tasks/list,tasks/get,tasks/cancel,tasks/resultserver.has_task_support = Trueunconditionallyio.modelcontextprotocol/tasksonly if a tool hastask_supportoptional/required (_advertise_tasks_extension) — so low-level capabilities and discover can disagreetasks/updatetasks/resultandtasks/listare inMODERN_METHOD_CONTRACTSand only rejected when era ismodern;autostill serves themcore/task.pyTaskStatusincludesexpired;tasks/types.pyterminal set iscompleted|failed|cancelledTaskStatusRouterinnitrostack/tasks/notify.pyhas no production callersInFlightRegistryisregister/discardontools/call; nothing handlesnotifications/cancelledso cancel is deadcreate_taskids aretask_+ 12 hex charsInMemoryTaskStoreis an unlocked dictcheck_task_access(context=None)returns (isolation bypass if HTTP forgetsrequest_ctx)ttl_ms_to_secondsusesmax(1, int(ttl_ms/1000))(500ms → 1s)task_support == "required"raisesINVALID_REQUEST, not-32021Official Python mcp SDK skipped Tasks. Default for this issue: hide tasks on the 2026 wire. Do not implement full
tasks/updateunless product explicitly asks in this issue’s comments.Handoff: #21 (comment)
Goal (Hide)
Auto/modern:
tasks/*tools/callwithparams.task→ error (-32021or invalid-params: server does not support tasks), notCreateTaskResultKeep
TaskManager/@tool(task_support=...)for in-process and eralegacyif those tests still need them.Probe
Read:
nitrostack/core/app.py—_register_task_handlers,_call_tooltask branch,_advertise_tasks_extensionnitrostack/core/mcp_server.py—has_task_support→caps.tasksincluding listnitrostack/protocol/method_contract.py— tasks rowsnitrostack/core/task.pyvsnitrostack/tasks/types.pynitrostack/tasks/notify.py,nitrostack/tasks/authorization.py,nitrostack/tasks/memory.pytests/test_mcp20_tasks.py,tests/test_tasks.py,tests/test_mcp20_task_authorization.pyImplementation (Hide — do this)
has_task_support = Falseon auto/modern. Do not set True unconditionally.tasks/list,tasks/result,tasks/get,tasks/cancelon auto/modern.advertise_tasks=Falseon auto/modern (even if tools havetask_supportflags)._call_tool: if era is auto/modern andtask_metadatais present →-32021(once WP2 adds the code) or-32602with a clear message. Do not spawnTaskManagerbackground work for HTTP 2026.tasks/result/tasks/listfrom any “live modern methods” table (WP2 owns the table; coordinate).notify.py: delete if still unhooked, or leave unused only if Hide makes it obviously dead — prefer delete to avoid a fake fan-out.InFlightRegistry: if cancel is still unwired, delete register/discard on the 2026 path or wirenotifications/cancelled. Do not leave a registry tests poke that HTTP never cancels.Legacy era: you may keep existing task handlers if
tests/test_tasks.pydepends on them. Do not expand 2025 task list onto 2026.Do not do “Finish” in this issue
Finish would mean
tasks/get+tasks/update+tasks/cancel, no list/result on modern, one status enum, store lock, UUID ids, access context always passed, notify hooked,-32021for capability mismatches. That is a separate product epic. If you start Finish, you must complete it — do not ship half.Test / verify
Those files likely expect 2026 task RPCs. Update them to match Hide:
TestClient, era modern/auto:tasks/get/tasks/list/tasks/result→-32601io.modelcontextprotocol/taskstools/callwithtask: {}on modern → not a task resultTaskManagerunit tests if the class remainsAdd one test that
get_capabilitiesdoes not include tasks for a modern/auto app.Review
has_task_supportagree (both off on 2026).CreateTaskResulton modern.Success
tasks/*handlers, no tasks extension in discovertools/calldoes not return TaskDatahas_task_supportnot unconditionally TrueTaskStatusRouternot advertised as liveRelated
Depends on WP0 (who handles
/mcp) and WP2 (-32021, method table). Do not block on a full Tasks spec implementation.