You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Let an MCP-compatible assistant find and classify projects by the tags assigned
directly to those projects without loading the entire project catalog or
confusing identically named tags in different tag hierarchies.
Example requests:
Which active projects are tagged Waiting?
Show me the projects associated with People / Richard.
Which of these projects have no direct project tags?
Motivation and contributor evidence
The project-tag return-field idea was independently implemented in the Lumenbeing/FocusRelayMCP fork:
70692ae
added project tag names and IDs in the Omni Automation bridge.
b0d3715
carried those values through the Swift models and output layer.
Those commits demonstrate the user need and the documented project.tags API,
but they are design evidence rather than code to import: the fork is based on an
older architecture, combines tags with folder membership, and does not include
tests or server-side filtering. Thanks to @Lumenbeing / @Defiantweb for surfacing
the workflow.
Preserve compact defaults: no tag fields are read or returned unless requested
or required by a tag filter.
Use repository field naming (tagIDs, not tagIds).
Unknown project field names or malformed filters fail clearly rather than
disappearing silently.
Architecture and API constraints
Use only the documented project.tags, tag.parent, and stable id.primaryKey APIs.
Build ID-bearing paths so duplicate tag names remain distinguishable.
Keep the Bridge plug-in as the only production automation path.
Carry optional values through bridge payload, core model, and selected output
without converting a missing requested wire field into a trustworthy empty
array. A plugin/schema mismatch must produce an error or explicit warning.
Add new filter values to project cache keys, or deliberately bypass the cache
with documented evidence. Results for different tag filters must never share a
cached page.
Do not add tag assignment, creation, hierarchy mutation, transport changes, or
unrelated query optimization in this issue.
Performance and context expectations
The stable-ID filter should prevent the model from retrieving every project
merely to classify project tags.
Requesting only id, name, status, and direct tag fields should remain
materially smaller than an unfiltered full project catalog.
Record matching count, returned count, serialized response bytes, bridge time,
end-to-end latency, and model calls for a representative large project/tag
library.
Measurements guide tradeoffs; no isolated byte target overrides correct tag
identity or model routing.
Test plan
Use Swift Testing, deterministic JavaScriptCore contracts, and direct MCP/CLI
coverage for:
no tags, one tag, and multiple direct project tags;
direct project tags versus tags present only on child tasks;
tagIDs and tagNames order and association;
root and nested tag paths;
identical tag names under different parents;
any-of filtering with one and multiple stable IDs;
untaggedOnly behavior;
missing, dropped, and malformed tag IDs;
contradictory and empty filter validation;
active/onHold/dropped/done/all status composition;
a live Bridge read against projects with direct and child-only tags.
Add a controlled Kimi K2.7 Code and comparison-model journey. Each model must
use #70 to resolve an ambiguous tag name, query by stable ID, avoid retrieving
the full project catalog, and accurately distinguish direct project tags from
child-task tags.
Acceptance criteria
A user can retrieve projects carrying an unambiguous stable tag ID.
A user can retrieve projects with no directly assigned project tags.
Direct project tags are returned with stable IDs, names, and requestable
ID-bearing paths.
Duplicate names remain distinguishable and never cause name-based guessing.
Tag and status filters compose before pagination and counting.
Default list_projects responses remain compact.
Unknown fields, invalid filters, and missing requested wire data fail clearly.
Cache, CLI, MCP, JavaScriptCore, live query, and model-routing tests pass.
User outcome
Let an MCP-compatible assistant find and classify projects by the tags assigned
directly to those projects without loading the entire project catalog or
confusing identically named tags in different tag hierarchies.
Example requests:
Waiting?People / Richard.Motivation and contributor evidence
The project-tag return-field idea was independently implemented in the
Lumenbeing/FocusRelayMCPfork:70692aeadded project tag names and IDs in the Omni Automation bridge.
b0d3715carried those values through the Swift models and output layer.
Those commits demonstrate the user need and the documented
project.tagsAPI,but they are design evidence rather than code to import: the fork is based on an
older architecture, combines tags with folder membership, and does not include
tests or server-side filtering. Thanks to @Lumenbeing / @Defiantweb for surfacing
the workflow.
Validation impact and dependencies
querydisambiguation.
list_projectsandlist-projects; do not add another public tool.filtering in Add server-side project health filters to list_projects #87.
User-facing acceptance journey
list_tagssearch and obtains the intended stabletag ID and full path.
list_projectswith that stable tag ID, the appropriatestatus view, and compact requested fields.
tags.
before querying projects; FocusRelay never guesses by name.
Public query contract
Extend
list_projectswith requestable project fields:tagIDs— stable IDs of tags assigned directly to the project;tagNames— corresponding direct tag names in the same deterministic order;tagPaths— when requested, one entry per direct project tag containing thetag's
id,name, and an ordered root-to-tagpathof{id,name}elements.Add filters:
tagIDs— a non-empty array of stable tag IDs; a project matches when anyrequested ID is assigned directly to it;
untaggedOnly— when true, return projects with no directly assigned projecttags.
Rules:
tagIDscombined withuntaggedOnly=true.tagIDs; useuntaggedOnly=trueexplicitly.missing IDs instead of silently returning an empty result.
project.tags. Do not infer project membership from childtask tags and do not describe child-task tags as project tags.
calculation.
supported sort.
or required by a tag filter.
tagIDs, nottagIds).disappearing silently.
Architecture and API constraints
project.tags,tag.parent, and stableid.primaryKeyAPIs.without converting a missing requested wire field into a trustworthy empty
array. A plugin/schema mismatch must produce an error or explicit warning.
with documented evidence. Results for different tag filters must never share a
cached page.
unrelated query optimization in this issue.
Performance and context expectations
merely to classify project tags.
id,name,status, and direct tag fields should remainmaterially smaller than an unfiltered full project catalog.
end-to-end latency, and model calls for a representative large project/tag
library.
identity or model routing.
Test plan
Use Swift Testing, deterministic JavaScriptCore contracts, and direct MCP/CLI
coverage for:
tagIDsandtagNamesorder and association;untaggedOnlybehavior;Add a controlled Kimi K2.7 Code and comparison-model journey. Each model must
use #70 to resolve an ambiguous tag name, query by stable ID, avoid retrieving
the full project catalog, and accurately distinguish direct project tags from
child-task tags.
Acceptance criteria
ID-bearing paths.
list_projectsresponses remain compact.creation/assignment.
Release planning
Implement after #70 and before #128 so project-tag discovery and readback are
stable before create-and-assign mutations use them.