Skip to content

Commit a8d034b

Browse files
authored
fix(mcp): point move mismatch guidance at landing path (#916)
Signed-off-by: phernandez <paul@basicmachines.co>
1 parent 7c0937f commit a8d034b

2 files changed

Lines changed: 53 additions & 2 deletions

File tree

src/basic_memory/mcp/tools/move_note.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -941,9 +941,9 @@ async def _ensure_resolved_entity_id() -> str:
941941
moved within the same project. To move content between projects:
942942
943943
```
944-
read_note("{identifier}")
944+
read_note("{result.file_path}")
945945
write_note("Title", "content", "folder", project="target-project")
946-
delete_note("{identifier}", project="{active_project.name}")
946+
delete_note("{result.file_path}", project="{active_project.name}")
947947
```
948948
""").strip()
949949

test-int/bughunt_fixes/test_move_note_edge_cases.py

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,3 +166,54 @@ async def test_move_into_nested_projects_folder_not_flagged(mcp_server, app, tes
166166
"Legit nested 'projects' folder wrongly flagged as cross-project move"
167167
)
168168
assert result["moved"] is True, result.get("error")
169+
170+
171+
@pytest.mark.asyncio
172+
async def test_move_outcome_mismatch_guidance_uses_actual_landing_path(
173+
mcp_server, app, test_project, monkeypatch
174+
):
175+
"""The text guidance should point agents at the actual post-move path.
176+
177+
The real move service stores the requested destination verbatim today, so the
178+
mismatch backstop is exercised by returning a divergent file_path after the real
179+
move completes.
180+
"""
181+
async with Client(mcp_server) as client:
182+
await client.call_tool(
183+
"write_note",
184+
{
185+
"project": test_project.name,
186+
"title": "Outcome Guidance Note",
187+
"directory": "source",
188+
"content": "# Outcome Guidance Note\n\nbody",
189+
"output_format": "json",
190+
},
191+
)
192+
193+
from basic_memory.mcp.clients import KnowledgeClient
194+
195+
real_move_entity = KnowledgeClient.move_entity
196+
actual_landing_path = "unexpected/outcome-guidance-note.md"
197+
198+
async def diverging_move_entity(self, entity_id, destination_path):
199+
result = await real_move_entity(self, entity_id, destination_path)
200+
return result.model_copy(update={"file_path": actual_landing_path})
201+
202+
monkeypatch.setattr(KnowledgeClient, "move_entity", diverging_move_entity)
203+
204+
move = await client.call_tool(
205+
"move_note",
206+
{
207+
"project": test_project.name,
208+
"identifier": "source/outcome-guidance-note",
209+
"destination_path": "target/outcome-guidance-note.md",
210+
},
211+
)
212+
213+
guidance = move.content[0].text
214+
stale_identifier = "source/outcome-guidance-note"
215+
assert "Unexpected Result Location" in guidance
216+
assert f'read_note("{actual_landing_path}")' in guidance
217+
assert f'delete_note("{actual_landing_path}", project="{test_project.name}")' in guidance
218+
assert f'read_note("{stale_identifier}")' not in guidance
219+
assert f'delete_note("{stale_identifier}", project="{test_project.name}")' not in guidance

0 commit comments

Comments
 (0)