From e0803734e69eeb6c6d7432eea323c7a264cb8347 Mon Sep 17 00:00:00 2001 From: phernandez Date: Sat, 15 Feb 2025 12:00:03 -0600 Subject: [PATCH] fix: handle memory:// url format in read_note tool --- src/basic_memory/cli/commands/mcp.py | 2 +- src/basic_memory/mcp/async_client.py | 2 +- src/basic_memory/mcp/tools/notes.py | 5 ++++- src/basic_memory/sync/utils.py | 3 +-- tests/mcp/test_tool_notes.py | 22 ++++++++++++++++++++++ uv.lock | 2 +- 6 files changed, 30 insertions(+), 6 deletions(-) diff --git a/src/basic_memory/cli/commands/mcp.py b/src/basic_memory/cli/commands/mcp.py index 2503263b..58726dc4 100644 --- a/src/basic_memory/cli/commands/mcp.py +++ b/src/basic_memory/cli/commands/mcp.py @@ -12,7 +12,7 @@ import basic_memory.mcp.tools # noqa: F401 # pragma: no cover @app.command() -def mcp(): +def mcp(): # pragma: no cover """Run the MCP server for Claude Desktop integration.""" home_dir = config.home logger.info("Starting Basic Memory MCP server") diff --git a/src/basic_memory/mcp/async_client.py b/src/basic_memory/mcp/async_client.py index 42c98248..4b81cc69 100644 --- a/src/basic_memory/mcp/async_client.py +++ b/src/basic_memory/mcp/async_client.py @@ -2,7 +2,7 @@ from httpx import ASGITransport, AsyncClient from basic_memory.api.app import app as fastapi_app -BASE_URL = "http://test" +BASE_URL = "memory://" # Create shared async client client = AsyncClient(transport=ASGITransport(app=fastapi_app), base_url=BASE_URL) diff --git a/src/basic_memory/mcp/tools/notes.py b/src/basic_memory/mcp/tools/notes.py index a337758e..07f653c6 100644 --- a/src/basic_memory/mcp/tools/notes.py +++ b/src/basic_memory/mcp/tools/notes.py @@ -13,6 +13,7 @@ from basic_memory.mcp.async_client import client from basic_memory.schemas import EntityResponse, DeleteEntitiesResponse from basic_memory.schemas.base import Entity from basic_memory.mcp.tools.utils import call_get, call_put, call_delete +from basic_memory.schemas.memory import memory_url_path @mcp.tool( @@ -96,7 +97,9 @@ async def read_note(identifier: str) -> str: Raises: ValueError: If the note cannot be found """ - response = await call_get(client, f"/resource/{identifier}") + logger.info(f"Reading note {identifier}") + url = memory_url_path(identifier) + response = await call_get(client, f"/resource/{url}") return response.text diff --git a/src/basic_memory/sync/utils.py b/src/basic_memory/sync/utils.py index 4c3f2502..bd5b5194 100644 --- a/src/basic_memory/sync/utils.py +++ b/src/basic_memory/sync/utils.py @@ -1,9 +1,8 @@ """Types and utilities for file sync.""" from dataclasses import dataclass, field -from typing import Set, Dict, Optional +from typing import Set, Dict -from watchfiles import Change diff --git a/tests/mcp/test_tool_notes.py b/tests/mcp/test_tool_notes.py index b2da6169..f0f55f70 100644 --- a/tests/mcp/test_tool_notes.py +++ b/tests/mcp/test_tool_notes.py @@ -236,3 +236,25 @@ async def test_write_note_verbose(app): assert entity.relations[0].from_id == "test/test-note" assert entity.relations[0].to_id is None assert entity.relations[0].to_name == "Knowledge" + + +@pytest.mark.asyncio +async def test_read_note_memory_url(app): + """Test reading a note using a memory:// URL. + + Should: + - Handle memory:// URLs correctly + - Normalize the URL before resolving + - Return the note content + """ + # First create a note + permalink = await notes.write_note( + title="Memory URL Test", + folder="test", + content="Testing memory:// URL handling", + ) + + # Should be able to read it with a memory:// URL + memory_url = f"memory://{permalink}" + content = await notes.read_note(memory_url) + assert "Testing memory:// URL handling" in content \ No newline at end of file diff --git a/uv.lock b/uv.lock index 3292aad2..a74555dd 100644 --- a/uv.lock +++ b/uv.lock @@ -70,7 +70,7 @@ wheels = [ [[package]] name = "basic-memory" -version = "0.2.19" +version = "0.2.20" source = { editable = "." } dependencies = [ { name = "aiosqlite" },