Skip to content

feat: a task belongs to the space of its project for agent users' tool calls, and the task tools declare it EXO-91174 - #671

Draft
bmestrallet wants to merge 2 commits into
feature/ai-contributionfrom
feat/EXO-91174-task-space-scope
Draft

bmestrallet wants to merge 2 commits into
feature/ai-contributionfrom
feat/EXO-91174-task-space-scope

Conversation

@bmestrallet

Copy link
Copy Markdown
Contributor

Why

Agent users answer in a space with the asker's rights, and the MCP server's space scope is the only guard of what such a run may reach (a call limited to one space is refused for any tool that declares no space scope). Task tools declare none today, so an agent user can't read a task of its space, and an approved proposal to change a task's status would be refused. This gives the task add-on its space scope: which space a task belongs to, and how each task tool maps to it.

How

  • TaskSpaceScopeResolver (io.meeds.task.mcp, resolver name task, the server's SpaceScopeResolver SPI): a task's space is the space of its project, only when every manager of the project is a role of one and the same /spaces/<x> group and that space exists. A personal task, a personal project, a manager that is a user or another group, two spaces, or a gone space give no space, and the server refuses the call (fail closed). Participants are not considered. Read as the system (TaskService.getTask), like the server's activity resolver.
  • space_scope declarations in services/src/main/resources/ai-tool-definitions.json, all {object_arg: task_id, resolver: task}: get_task_by_id, list_task_comments_by_id (+ offset, limit), update_task_status (+ status_id), complete_task. Every other task tool stays undeclared, hence refused under a space scope. update_task_status's status_id is the one reference-shaped argument a write declares: TaskMcpTool.updateTaskStatus refuses a status of another project than the task's, so it can't leave the task's space.

Dependencies — merge order

Compiles only against mcp-server's space-scope SPI (SpaceScopeResolver, SpaceScopeDeclaration), which is on Meeds-io/mcp-server#46/#47 and not yet on feature/ai-contribution: the PR Build fails until they land and a snapshot is published. Merge after mcp-server#46 and #47. An older server ignores the space_scope field (unknown property), so the definitions alone are harmless.

Verification

  • mvn test javadoc:javadoc -pl services against mcp-server 826b8fd (local, not installed) at 5efd0a9: BUILD SUCCESS, 257 tests, 0 failures.
  • TaskSpaceScopeResolverTest (16): the one-space case and each no-space case. Mutants killed: first match instead of exactly one; a non-space manager ignored; a personal project read as a space; the not-found guard removed.
  • TaskToolDefinitionSpaceScopeTest (2): the shipped definitions parsed with the server's own parser, exactly the four declarations, each well formed for its kind (read/write) with accepted arguments that are schema properties. Mutant: an extra allowed argument on update_task_status fails it.

For the reviewer

  • mcp-server's contract test (ToolDefinitionSpaceScopeTest.writesAcceptNoReferenceBesidesTheirPlace) reads only mcp-server's own definitions, so it can't see this status_id exception; it is pinned here instead.
  • The project-to-space lookups already in the add-on (StorageUtil, TaskMcpTool, notification and attachment plugins) are left as they are: they pick the last space and serve other callers; the exactly-one rule is the resolver's own.

Part of E7b (agent users answer on tasks); the ai side follows in its own PR.

Classification: N1 — a new resolver deciding the server-side scope of tool calls (ACL), and changed definitions of existing MCP tools (classification.md §1). Computed on 51aaba5d8...5efd0a96d at 5efd0a9.
Knowledge: pending — EXO-91174

🤖 Generated with Claude Code

bmestrallet and others added 2 commits October 13, 2026 09:53
… task's space EXO-91174

TaskSpaceScopeResolver tells which space a task belongs to (the one space
group the project's managers name, else none), so a call limited to one
space may run get_task_by_id, list_task_comments_by_id, update_task_status
and complete_task on a task of that space only. Their ai-tool-definitions
entries declare the space scope; the other task tools stay refused.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ole of that one space group EXO-91174

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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.

1 participant