mirror of
https://github.com/basicmachines-co/basic-memory
synced 2026-06-21 13:47:35 +00:00
c9770375e9
Adds human-readable `title` and categorization `tags` to all ~24 @mcp.tool decorators across the MCP tools package. FastMCP 3.3.1 (pinned in pyproject.toml) supports both fields natively. Tags used: notes, search, projects, cloud, schema, navigation, canvas, ui. Extends test_tool_contracts.py with an async test that asserts every registered tool has a non-empty title and at least one tag to prevent future regressions. output_schema is explicitly deferred as a follow-up (phase 2): it requires per-tool design decisions about which tools reliably return structured JSON and how to handle tools that return str|dict depending on output_format. Co-Authored-By: Claude <noreply@anthropic.com> Signed-off-by: Drew Cain <groksrc@gmail.com>
84 lines
2.7 KiB
Python
84 lines
2.7 KiB
Python
"""View note tool for Basic Memory MCP server."""
|
|
|
|
from textwrap import dedent
|
|
from typing import Optional
|
|
|
|
from loguru import logger
|
|
from fastmcp import Context
|
|
|
|
from basic_memory.mcp.server import mcp
|
|
from basic_memory.mcp.tools.read_note import read_note
|
|
|
|
|
|
@mcp.tool(
|
|
title="View Note",
|
|
description="View a note as a formatted artifact for better readability.",
|
|
tags={"notes"},
|
|
annotations={"readOnlyHint": True, "openWorldHint": False},
|
|
)
|
|
async def view_note(
|
|
identifier: str,
|
|
project: Optional[str] = None,
|
|
project_id: Optional[str] = None,
|
|
context: Context | None = None,
|
|
) -> str:
|
|
"""View a markdown note as a formatted artifact.
|
|
|
|
This tool reads a note using the same logic as read_note but instructs Claude
|
|
to display the content as a markdown artifact in the Claude Desktop app.
|
|
Project parameter optional with server resolution.
|
|
|
|
Args:
|
|
identifier: The title or permalink of the note to view
|
|
project: Project name to read from. Optional - server will resolve using hierarchy.
|
|
If unknown, use list_memory_projects() to discover available projects.
|
|
project_id: Project external_id (UUID). Prefer this over `project` when known —
|
|
it routes to the exact project regardless of name collisions across cloud
|
|
workspaces. Takes precedence over `project`. Get from list_memory_projects().
|
|
context: Optional FastMCP context for performance caching.
|
|
|
|
Returns:
|
|
Instructions for Claude to create a markdown artifact with the note content.
|
|
|
|
Examples:
|
|
# View a note by title
|
|
view_note("Meeting Notes")
|
|
|
|
# View a note by permalink
|
|
view_note("meetings/weekly-standup")
|
|
|
|
# Explicit project specification
|
|
view_note("Meeting Notes", project="my-project")
|
|
|
|
Raises:
|
|
HTTPError: If project doesn't exist or is inaccessible
|
|
SecurityError: If identifier attempts path traversal
|
|
"""
|
|
logger.info(f"Viewing note: {identifier} in project: {project}")
|
|
|
|
# Call the existing read_note logic (default output_format="text" returns str)
|
|
content = str(
|
|
await read_note(
|
|
identifier=identifier,
|
|
project=project,
|
|
project_id=project_id,
|
|
context=context,
|
|
)
|
|
)
|
|
|
|
# Check if this is an error message (note not found)
|
|
if "# Note Not Found" in content:
|
|
return content # Return error message directly
|
|
|
|
# Return instructions for Claude to create an artifact
|
|
return dedent(f"""
|
|
Note retrieved: "{identifier}"
|
|
|
|
Display this note as a markdown artifact for the user.
|
|
|
|
Content:
|
|
---
|
|
{content}
|
|
---
|
|
""").strip()
|