mirror of
https://github.com/basicmachines-co/basic-memory
synced 2026-06-21 13:47:35 +00:00
Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| c51b70a217 |
@@ -371,6 +371,7 @@ async def create_memory_project(
|
||||
project_name: str,
|
||||
project_path: str,
|
||||
set_default: bool = False,
|
||||
workspace_id: str | None = None,
|
||||
output_format: Literal["text", "json"] = "text",
|
||||
context: Context | None = None,
|
||||
) -> str | dict:
|
||||
@@ -383,6 +384,9 @@ async def create_memory_project(
|
||||
project_name: Name for the new project (must be unique)
|
||||
project_path: File system path where the project will be stored
|
||||
set_default: Whether to set this project as the default (optional, defaults to False)
|
||||
workspace_id: Target workspace tenant_id for cloud deployments. When omitted the
|
||||
connection's default workspace is used. Discover available values via
|
||||
list_workspaces() which returns tenant_id for each workspace.
|
||||
output_format: "text" returns the existing human-readable result text.
|
||||
"json" returns structured project creation metadata.
|
||||
context: Optional FastMCP context for progress/status logging.
|
||||
@@ -393,8 +397,9 @@ async def create_memory_project(
|
||||
Example:
|
||||
create_memory_project("my-research", "~/Documents/research")
|
||||
create_memory_project("work-notes", "/home/user/work", set_default=True)
|
||||
create_memory_project("team-notes", "/home/user/team", workspace_id="ws-uuid-here")
|
||||
"""
|
||||
async with get_client() as client:
|
||||
async with get_client(workspace=workspace_id) as client:
|
||||
# Check if server is constrained to a specific project
|
||||
constrained_project = os.environ.get("BASIC_MEMORY_MCP_PROJECT")
|
||||
if constrained_project:
|
||||
|
||||
@@ -133,6 +133,55 @@ async def test_create_and_delete_project_and_name_match_branch(
|
||||
assert delete_result.startswith("✓")
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_create_memory_project_passes_workspace_id(app, tmp_path_factory):
|
||||
"""workspace_id is forwarded to get_client(workspace=...) for cloud workspace targeting."""
|
||||
from contextlib import asynccontextmanager
|
||||
import httpx
|
||||
|
||||
from basic_memory.mcp.clients import ProjectClient
|
||||
from basic_memory.schemas.project_info import ProjectStatusResponse
|
||||
|
||||
project_root = tmp_path_factory.mktemp("ws-project-home")
|
||||
captured_workspace = {}
|
||||
|
||||
fake_list = _make_list([], default=None)
|
||||
fake_status = ProjectStatusResponse(
|
||||
message="Project created",
|
||||
status="success",
|
||||
default=False,
|
||||
new_project=_make_project("WS Project", str(project_root)),
|
||||
)
|
||||
|
||||
@asynccontextmanager
|
||||
async def fake_get_client(*, workspace=None, project_name=None):
|
||||
captured_workspace["workspace"] = workspace
|
||||
async with httpx.AsyncClient(base_url="http://testserver") as client:
|
||||
yield client
|
||||
|
||||
with (
|
||||
patch(
|
||||
"basic_memory.mcp.tools.project_management.get_client",
|
||||
new=fake_get_client,
|
||||
),
|
||||
patch.object(ProjectClient, "list_projects", new_callable=AsyncMock, return_value=fake_list),
|
||||
patch.object(
|
||||
ProjectClient, "create_project", new_callable=AsyncMock, return_value=fake_status
|
||||
),
|
||||
patch(
|
||||
"basic_memory.mcp.project_context.invalidate_workspace_project_index",
|
||||
new_callable=AsyncMock,
|
||||
),
|
||||
):
|
||||
await create_memory_project(
|
||||
project_name="WS Project",
|
||||
project_path=str(project_root),
|
||||
workspace_id="tenant-abc-123",
|
||||
)
|
||||
|
||||
assert captured_workspace["workspace"] == "tenant-abc-123"
|
||||
|
||||
|
||||
# --- Cloud merge tests ---
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user