From 7adf6791e9558883f85f7b714eb584e61bae95c9 Mon Sep 17 00:00:00 2001 From: Drew Cain Date: Mon, 30 Jun 2025 23:12:28 -0500 Subject: [PATCH] fix: #190 MCP Hub tool validation Signed-off-by: Drew Cain --- docs/Docker.md | 8 ++++---- src/basic_memory/mcp/tools/__init__.py | 8 ++++---- src/basic_memory/mcp/tools/move_note.py | 4 ++-- src/basic_memory/mcp/tools/project_management.py | 12 ++++++------ src/basic_memory/mcp/tools/search.py | 8 ++++---- test-int/mcp/test_move_note_integration.py | 2 +- tests/mcp/test_server.py | 2 +- 7 files changed, 22 insertions(+), 22 deletions(-) diff --git a/docs/Docker.md b/docs/Docker.md index 4054e6f4..173f86da 100644 --- a/docs/Docker.md +++ b/docs/Docker.md @@ -129,10 +129,10 @@ When using Docker volumes, you'll need to configure projects to point to your mo 2. **Add a project for your mounted volume:** ```bash # If you mounted /path/to/your/vault to /app/data - docker exec basic-memory-server basic-memory project create my-vault /app/data + docker exec basic-memory-server basic-memory project add my-vault /app/data # Set it as default - docker exec basic-memory-server basic-memory project set-default my-vault + docker exec basic-memory-server basic-memory project default my-vault ``` 3. **Sync the new project:** @@ -151,10 +151,10 @@ volumes: Then configure it: ```bash # Create project pointing to mounted vault -docker exec basic-memory-server basic-memory project create obsidian /app/data +docker exec basic-memory-server basic-memory project add obsidian /app/data # Set as default -docker exec basic-memory-server basic-memory project set-default obsidian +docker exec basic-memory-server basic-memory project default obsidian # Sync to index all files docker exec basic-memory-server basic-memory sync diff --git a/src/basic_memory/mcp/tools/__init__.py b/src/basic_memory/mcp/tools/__init__.py index b49997ca..f587efe0 100644 --- a/src/basic_memory/mcp/tools/__init__.py +++ b/src/basic_memory/mcp/tools/__init__.py @@ -20,24 +20,24 @@ from basic_memory.mcp.tools.edit_note import edit_note from basic_memory.mcp.tools.move_note import move_note from basic_memory.mcp.tools.sync_status import sync_status from basic_memory.mcp.tools.project_management import ( - list_projects, + list_memory_projects, switch_project, get_current_project, set_default_project, - create_project, + create_memory_project, delete_project, ) __all__ = [ "build_context", "canvas", - "create_project", + "create_memory_project", "delete_note", "delete_project", "edit_note", "get_current_project", "list_directory", - "list_projects", + "list_memory_projects", "move_note", "read_content", "read_note", diff --git a/src/basic_memory/mcp/tools/move_note.py b/src/basic_memory/mcp/tools/move_note.py index 3fdfbb7c..34bd5277 100644 --- a/src/basic_memory/mcp/tools/move_note.py +++ b/src/basic_memory/mcp/tools/move_note.py @@ -109,7 +109,7 @@ def _format_cross_project_error_response( ``` ## Available projects: - Use `list_projects()` to see all available projects and `switch_project("project-name")` to change projects. + Use `list_memory_projects()` to see all available projects and `switch_project("project-name")` to change projects. """).strip() @@ -153,7 +153,7 @@ def _format_potential_cross_project_guidance( ### To see all projects: ``` - list_projects() + list_memory_projects() ``` """).strip() diff --git a/src/basic_memory/mcp/tools/project_management.py b/src/basic_memory/mcp/tools/project_management.py index 6e57bef9..1c4b29ad 100644 --- a/src/basic_memory/mcp/tools/project_management.py +++ b/src/basic_memory/mcp/tools/project_management.py @@ -19,7 +19,7 @@ from basic_memory.utils import generate_permalink @mcp.tool("list_memory_projects") -async def list_projects(ctx: Context | None = None) -> str: +async def list_memory_projects(ctx: Context | None = None) -> str: """List all available projects with their status. Shows all Basic Memory projects that are available, indicating which one @@ -29,7 +29,7 @@ async def list_projects(ctx: Context | None = None) -> str: Formatted list of projects with status indicators Example: - list_projects() + list_memory_projects() """ if ctx: # pragma: no cover await ctx.info("Listing all available projects") @@ -150,7 +150,7 @@ async def switch_project(project_name: str, ctx: Context | None = None) -> str: 4. **Try again**: The error might be temporary ## Available options: - - See all projects: `list_projects()` + - See all projects: `list_memory_projects()` - Stay on current project: `get_current_project()` - Try different project: `switch_project("correct-project-name")` @@ -231,7 +231,7 @@ async def set_default_project(project_name: str, ctx: Context | None = None) -> @mcp.tool("create_memory_project") -async def create_project( +async def create_memory_project( project_name: str, project_path: str, set_default: bool = False, ctx: Context | None = None ) -> str: """Create a new Basic Memory project. @@ -248,8 +248,8 @@ async def create_project( Confirmation message with project details Example: - create_project("my-research", "~/Documents/research") - create_project("work-notes", "/home/user/work", set_default=True) + create_memory_project("my-research", "~/Documents/research") + create_memory_project("work-notes", "/home/user/work", set_default=True) """ if ctx: # pragma: no cover await ctx.info(f"Creating project: {project_name} at {project_path}") diff --git a/src/basic_memory/mcp/tools/search.py b/src/basic_memory/mcp/tools/search.py index a39f42fd..d6d5c5fa 100644 --- a/src/basic_memory/mcp/tools/search.py +++ b/src/basic_memory/mcp/tools/search.py @@ -67,13 +67,13 @@ def _format_search_error_response(error_message: str, query: str, search_type: s The current project is not accessible or doesn't exist: {error_message} ## How to resolve: - 1. **Check available projects**: `list_projects()` + 1. **Check available projects**: `list_memory_projects()` 2. **Switch to valid project**: `switch_project("valid-project-name")` 3. **Verify project setup**: Ensure your project is properly configured ## Current session info: - Check current project: `get_current_project()` - - See available projects: `list_projects()` + - See available projects: `list_memory_projects()` """).strip() # No results found @@ -162,7 +162,7 @@ You don't have permission to search in the current project: {error_message} 3. **Check authentication**: You might need to re-authenticate ## Alternative actions: -- List available projects: `list_projects()` +- List available projects: `list_memory_projects()` - Switch to accessible project: `switch_project("project-name")` - Check current project: `get_current_project()`""" @@ -189,7 +189,7 @@ Error searching for '{query}': {error_message} - **Browse files**: `list_directory("/")` - See all available content - **Recent activity**: `recent_activity(timeframe="7d")` - Check what's been updated - **Project info**: `get_current_project()` - Verify current project -- **All projects**: `list_projects()` - Switch to different project if needed +- **All projects**: `list_memory_projects()` - Switch to different project if needed ## Search syntax reference: - **Basic**: `keyword` or `multiple words` diff --git a/test-int/mcp/test_move_note_integration.py b/test-int/mcp/test_move_note_integration.py index 8c0895e9..647e97a8 100644 --- a/test-int/mcp/test_move_note_integration.py +++ b/test-int/mcp/test_move_note_integration.py @@ -594,7 +594,7 @@ async def test_move_note_potential_cross_project_guidance(mcp_server, app): error_message = move_result[0].text assert "Check Project Context" in error_message assert "workspace-docs" in error_message # Should mention other available projects - assert "list_projects" in error_message + assert "list_memory_projects" in error_message assert "switch_project" in error_message diff --git a/tests/mcp/test_server.py b/tests/mcp/test_server.py index b517e973..bc453e28 100644 --- a/tests/mcp/test_server.py +++ b/tests/mcp/test_server.py @@ -93,7 +93,7 @@ class TestMCPServer: # Missing SUPABASE_ANON_KEY } - with patch.dict(os.environ, env_vars): + with patch.dict(os.environ, env_vars, clear=True): with pytest.raises(ValueError, match="SUPABASE_URL and SUPABASE_ANON_KEY must be set"): create_auth_config()