mirror of
https://github.com/basicmachines-co/basic-memory
synced 2026-06-21 13:47:35 +00:00
f3e46d7984
Signed-off-by: phernandez <paul@basicmachines.co>
78 lines
2.6 KiB
Python
78 lines
2.6 KiB
Python
"""Workspace discovery MCP tool."""
|
|
|
|
from typing import Literal
|
|
|
|
from fastmcp import Context
|
|
|
|
from basic_memory.mcp.project_context import get_available_workspaces
|
|
from basic_memory.mcp.server import mcp
|
|
from basic_memory.schemas.cloud import WorkspaceInfo, WorkspaceListResponse
|
|
|
|
|
|
def _personal_workspace() -> WorkspaceInfo:
|
|
"""Return a display-only personal workspace when discovery has no rows.
|
|
|
|
This keeps list_workspaces friendly for non-teams or local-only users. It is not
|
|
the cloud routing source of truth; project-scoped routing still depends on real
|
|
workspace discovery and the workspace project index in project_context.
|
|
"""
|
|
return WorkspaceInfo(
|
|
tenant_id="personal",
|
|
workspace_type="personal",
|
|
slug="personal",
|
|
name="Personal",
|
|
role="owner",
|
|
is_default=True,
|
|
has_active_subscription=True,
|
|
)
|
|
|
|
|
|
def _workspace_list_response(workspaces: list[WorkspaceInfo]) -> WorkspaceListResponse:
|
|
"""Build the structured MCP response from the shared cloud workspace schema."""
|
|
if not workspaces:
|
|
workspaces = [_personal_workspace()]
|
|
|
|
default_workspace_id = next(
|
|
(workspace.tenant_id for workspace in workspaces if workspace.is_default),
|
|
None,
|
|
)
|
|
return WorkspaceListResponse(
|
|
workspaces=workspaces,
|
|
count=len(workspaces),
|
|
default_workspace_id=default_workspace_id,
|
|
current_workspace_id=None,
|
|
)
|
|
|
|
|
|
@mcp.tool(
|
|
description="List available cloud workspaces (tenant_id, type, role, and name).",
|
|
annotations={"readOnlyHint": True, "openWorldHint": False},
|
|
)
|
|
async def list_workspaces(
|
|
output_format: Literal["text", "json"] = "text",
|
|
context: Context | None = None,
|
|
) -> str | dict:
|
|
"""List workspaces available to the current cloud user.
|
|
|
|
Args:
|
|
output_format: "text" returns human-readable workspace list.
|
|
"json" returns structured workspace metadata.
|
|
context: Optional FastMCP context for progress/status logging.
|
|
"""
|
|
workspaces = await get_available_workspaces(context=context)
|
|
response = _workspace_list_response(workspaces)
|
|
|
|
if output_format == "json":
|
|
return response.model_dump(mode="json")
|
|
|
|
lines = [f"# Available Workspaces ({response.count})", ""]
|
|
for workspace in response.workspaces:
|
|
default_label = ", default" if workspace.is_default else ""
|
|
lines.append(
|
|
f"- {workspace.name} "
|
|
f"(slug={workspace.slug}, type={workspace.workspace_type}, "
|
|
f"role={workspace.role}{default_label}, tenant_id={workspace.tenant_id})"
|
|
)
|
|
|
|
return "\n".join(lines)
|