Problem
When projects of the same name exist in different workspaces (Teams vs. local vs. other cloud workspaces), agents (e.g. Codex) can't figure out how to target the right one with write_note. They expect a workspace argument or automatic selection, and can't intuit that the routing pattern is <workspace>/<project>.
The routing machinery already supports this — it's a tool-surface/documentation gap, and write_note is inconsistent with edit_note.
Details
write_note has no workspace parameter and doesn't document the qualified syntax. Its project docstring only says "Project name to write to… server will resolve using the hierarchy" and points at project_id for collisions (src/basic_memory/mcp/tools/write_note.py:25-41, docstring :82-87). Nothing tells the agent that project accepts workspace/project.
edit_note already does it right. It has a dedicated workspace parameter and documents the pattern: "Use workspace/project to route to a project in a specific cloud workspace" (src/basic_memory/mcp/tools/edit_note.py:284-291).
- The resolver supports
<workspace>/<project> (mcp/project_context.py:398-407 _split_qualified_project_identifier, :801-868 resolve_workspace_project_identifier), and list_memory_projects already returns qualified_name (workspace-slug/project-name), workspace_slug, and external_id (mcp/tools/project_management.py:163-181) — the agent just isn't told to use them.
- Silent collision fallback adds to the confusion: on an ambiguous bare name, the resolver silently prefers the project in the default workspace and only errors if there's no default (
mcp/project_context.py:893-906). So an agent intending a Teams-workspace project can have its note land in the default/local workspace with no signal.
Suggested fix
Bring write_note to parity with edit_note (and ideally audit the other note tools — read_note, move_note, delete_note — for the same gap):
- Add a
workspace parameter to write_note, mirroring edit_note (workspace slug/name/tenant_id; combines with project as workspace/project; mutually exclusive with project_id).
- Document the
workspace/project syntax in the project docstring, matching edit_note's wording.
- Reconsider the silent default-workspace fallback on collisions: when a bare name is ambiguous, prefer raising the disambiguation error (with
qualified_name choices) over silently picking the default workspace — or at least surface which workspace was chosen in the success response so the agent can detect a mismatch.
Related
Problem
When projects of the same name exist in different workspaces (Teams vs. local vs. other cloud workspaces), agents (e.g. Codex) can't figure out how to target the right one with
write_note. They expect aworkspaceargument or automatic selection, and can't intuit that the routing pattern is<workspace>/<project>.The routing machinery already supports this — it's a tool-surface/documentation gap, and
write_noteis inconsistent withedit_note.Details
write_notehas noworkspaceparameter and doesn't document the qualified syntax. Itsprojectdocstring only says "Project name to write to… server will resolve using the hierarchy" and points atproject_idfor collisions (src/basic_memory/mcp/tools/write_note.py:25-41, docstring:82-87). Nothing tells the agent thatprojectacceptsworkspace/project.edit_notealready does it right. It has a dedicatedworkspaceparameter and documents the pattern: "Useworkspace/projectto route to a project in a specific cloud workspace" (src/basic_memory/mcp/tools/edit_note.py:284-291).<workspace>/<project>(mcp/project_context.py:398-407_split_qualified_project_identifier,:801-868resolve_workspace_project_identifier), andlist_memory_projectsalready returnsqualified_name(workspace-slug/project-name),workspace_slug, andexternal_id(mcp/tools/project_management.py:163-181) — the agent just isn't told to use them.mcp/project_context.py:893-906). So an agent intending a Teams-workspace project can have its note land in the default/local workspace with no signal.Suggested fix
Bring
write_noteto parity withedit_note(and ideally audit the other note tools —read_note,move_note,delete_note— for the same gap):workspaceparameter towrite_note, mirroringedit_note(workspace slug/name/tenant_id; combines withprojectasworkspace/project; mutually exclusive withproject_id).workspace/projectsyntax in theprojectdocstring, matchingedit_note's wording.qualified_namechoices) over silently picking the default workspace — or at least surface which workspace was chosen in the success response so the agent can detect a mismatch.Related
move_notefalsely reports success for unsupported cross-workspace/cross-project moves #881 (move_notefalse success on cross-workspace moves — same workspace-routing confusion)