Description
The MCP server maintains an in-memory currentTag state that becomes stale across operations. When mutation tools like expand_task or update_task are called with a tag: parameter, the server reads parent task metadata from in-memory state rather than from the specified tag parameter. This causes cross-tag data corruption — parent task titles, descriptions, priorities, and dependencies get overwritten with data from the wrong tag.
Steps to Reproduce
- Start MCP server (stdio mode)
- Call
use_tag({name: "tag-a"}) — sets in-memory state to tag-a
- Call
expand_task({id: 15, tag: "tag-b"}) — intending to expand task 15 on tag-b
- Observe: Subtasks are correctly generated from tag-b's task 15 prompt
- BUT: Parent task 15's metadata (title, description, priority, dependencies) is overwritten with tag-a's task 15 data
Expected Behavior
All mutation operations should use the explicit tag: parameter for ALL data resolution — both parent metadata and subtask generation. The tag: parameter should be the single source of truth.
Actual Behavior
The MCP server reads parent task metadata from currentTag in-memory state, not from the tag: parameter. This creates a split where subtasks come from the correct tag but parent metadata comes from whatever tag was last active via use_tag().
Workaround
We implemented a Python MCP server replacement (TaskMaster-Lite) that resolves the tag from the explicit parameter on every call, with no persistent in-memory tag state. For users of the Node.js server, calling use_tag() before every mutation operation is the only workaround.
Environment
- Task Master version: 0.43.0
- Node.js version: v24.13.0
- Operating system: Ubuntu 24.04
- IDE: Claude Code CLI (multi-session, 15+ concurrent MCP processes)
Additional Context
This is particularly severe in multi-agent environments where multiple Claude Code sessions share the same tasks.json. Each session's MCP process has its own in-memory state that can diverge. We tracked this to commit 97c0a4e04 (2026-02-16) where btcstampsexplorer tag was overwritten with polyedge data during a get_task call on iig-kevin-market-making.
Related: The use_tag() requirement is documented but not enforced — the server should either (a) always use the explicit tag parameter, or (b) reject mutations when tag: parameter differs from currentTag.
Description
The MCP server maintains an in-memory
currentTagstate that becomes stale across operations. When mutation tools likeexpand_taskorupdate_taskare called with atag:parameter, the server reads parent task metadata from in-memory state rather than from the specified tag parameter. This causes cross-tag data corruption — parent task titles, descriptions, priorities, and dependencies get overwritten with data from the wrong tag.Steps to Reproduce
use_tag({name: "tag-a"})— sets in-memory state to tag-aexpand_task({id: 15, tag: "tag-b"})— intending to expand task 15 on tag-bExpected Behavior
All mutation operations should use the explicit
tag:parameter for ALL data resolution — both parent metadata and subtask generation. Thetag:parameter should be the single source of truth.Actual Behavior
The MCP server reads parent task metadata from
currentTagin-memory state, not from thetag:parameter. This creates a split where subtasks come from the correct tag but parent metadata comes from whatever tag was last active viause_tag().Workaround
We implemented a Python MCP server replacement (TaskMaster-Lite) that resolves the tag from the explicit parameter on every call, with no persistent in-memory tag state. For users of the Node.js server, calling
use_tag()before every mutation operation is the only workaround.Environment
Additional Context
This is particularly severe in multi-agent environments where multiple Claude Code sessions share the same tasks.json. Each session's MCP process has its own in-memory state that can diverge. We tracked this to commit
97c0a4e04(2026-02-16) wherebtcstampsexplorertag was overwritten withpolyedgedata during aget_taskcall oniig-kevin-market-making.Related: The
use_tag()requirement is documented but not enforced — the server should either (a) always use the explicit tag parameter, or (b) reject mutations whentag:parameter differs fromcurrentTag.