diff --git a/src/basic_memory/mcp/tools/activity.py b/src/basic_memory/mcp/tools/activity.py index 0adb2f21..621ccd69 100644 --- a/src/basic_memory/mcp/tools/activity.py +++ b/src/basic_memory/mcp/tools/activity.py @@ -10,24 +10,7 @@ from basic_memory.schemas.activity import ActivityType, RecentActivity @mcp.tool( - description=""" - Get recent activity across your knowledge base. - - This tool provides a comprehensive view of changes across your knowledge base, - including document modifications, entity updates, and relationship changes. - It supports flexible time ranges and filtering by activity type. - - The activity log helps you: - - Track recent changes to your knowledge base - - Monitor document and entity modifications - - Understand system usage patterns - - Identify most active areas - - Activity is tracked for: - - Document changes (creation, updates, deletion) - - Entity modifications - - Relation changes between entities - """, + description="Track recent changes to documents, entities, and relations", examples=[ { "name": "Daily Changes Overview", @@ -89,9 +72,7 @@ async def get_recent_activity( timeframe: str = "1d", activity_types: Optional[List[ActivityType]] = None, ) -> RecentActivity: - """ - Get recent activity across your knowledge base. - """ + """Get recent activity across your knowledge base.""" logger.debug(f"Getting recent activity (timeframe={timeframe}, types={activity_types})") # Build params @@ -103,4 +84,4 @@ async def get_recent_activity( # Get activity response = await client.get("/activity/recent", params=params) - return RecentActivity.model_validate(response.json()) + return RecentActivity.model_validate(response.json()) \ No newline at end of file diff --git a/src/basic_memory/mcp/tools/discovery.py b/src/basic_memory/mcp/tools/discovery.py index 242bfbdf..f9823798 100644 --- a/src/basic_memory/mcp/tools/discovery.py +++ b/src/basic_memory/mcp/tools/discovery.py @@ -10,20 +10,7 @@ from basic_memory.mcp.async_client import client @mcp.tool( - description=""" - List all unique entity types in use across the knowledge graph. - - This tool helps understand the structure of your knowledge base by showing: - - All entity types currently in use - - Custom types you've created - - System-defined types - - Useful for: - - Understanding knowledge organization - - Finding available entity types - - Discovering custom types - - Planning knowledge structure - """, + description="List all unique entity types in use across the knowledge graph", examples=[ { "name": "List Entity Types", @@ -66,20 +53,7 @@ async def get_entity_types() -> List[str]: @mcp.tool( - description=""" - List all unique observation categories used in the knowledge graph. - - Categories help organize different types of observations like: - - Technical details (tech) - - Design decisions (design) - - Features (feature) - - General notes (note) - - Issues/bugs (issue) - - Todo items (todo) - - This helps understand how knowledge is categorized and find - specific types of information. - """, + description="List all unique observation categories used for organizing information", examples=[ { "name": "List Categories", @@ -119,21 +93,7 @@ async def get_observation_categories() -> List[str]: @mcp.tool( - description=""" - List all entities of a specific type with optional related entities. - - This tool provides: - - All entities of a given type - - Optional related entities - - Sorting options - - Complete entity information - - Useful for: - - Exploring entity collections - - Finding related entities - - Understanding entity relationships - - Analyzing knowledge structure - """, + description="List all entities of a specific type with optional sorting and relations", examples=[ { "name": "List Components", @@ -190,4 +150,4 @@ async def list_by_type( url = f"/discovery/entities/{entity_type}" response = await client.get(url, params=params) - return TypedEntityList.model_validate(response.json()) + return TypedEntityList.model_validate(response.json()) \ No newline at end of file diff --git a/src/basic_memory/mcp/tools/documents.py b/src/basic_memory/mcp/tools/documents.py index 1da5ec4b..35d6cb4c 100644 --- a/src/basic_memory/mcp/tools/documents.py +++ b/src/basic_memory/mcp/tools/documents.py @@ -9,19 +9,7 @@ from basic_memory.mcp.async_client import client @mcp.tool( - description=""" - Create a new markdown document in the knowledge base. - - This tool stores markdown documents with: - - Structured frontmatter metadata - - Rich markdown content - - Version tracking via checksums - - Automatic timestamp management - - Optional custom metadata - - Documents are stored in a git-friendly format and can be - edited either through the API or directly in the filesystem. - """, + description="Create a new markdown document with frontmatter metadata and content", examples=[ { "name": "Create Technical Spec", @@ -92,18 +80,7 @@ async def create_document(request: DocumentRequest) -> DocumentCreateResponse: @mcp.tool( - description=""" - Update an existing document while preserving its history. - - This tool handles: - - Content updates - - Metadata changes - - Version tracking - - Timestamp management - - The update preserves document history and maintains - consistency with any linked knowledge graph entities. - """, + description="Update an existing markdown document while preserving its history", examples=[ { "name": "Update Content", @@ -146,18 +123,7 @@ async def update_document(request: DocumentRequest) -> DocumentResponse: @mcp.tool( - description=""" - Retrieve a document's content and metadata. - - This tool provides access to: - - Full document content - - Current metadata - - Version information - - Timestamps - - Documents are returned with their complete context, useful - for reading or preparing updates. - """, + description="Retrieve a document's content and metadata by path", examples=[ { "name": "Read Documentation", @@ -184,17 +150,7 @@ async def get_document(path: DocumentPathId) -> DocumentResponse: @mcp.tool( - description=""" - List all documents in the knowledge base. - - Provides an overview of the document collection including: - - Document paths and names - - Metadata for each document - - Version information - - Timestamps - - Useful for browsing content or finding specific documents. - """, + description="List all documents with their metadata and version information", examples=[ { "name": "List All Documents", @@ -219,7 +175,7 @@ for status, items in by_status.items(): """ } ], - output_model=List[DocumentCreateResponse] #TODO + output_model=List[DocumentCreateResponse] ) async def list_documents() -> List[DocumentCreateResponse]: """List all documents in the system.""" @@ -229,17 +185,7 @@ async def list_documents() -> List[DocumentCreateResponse]: @mcp.tool( - description=""" - Delete a document from the knowledge base. - - This tool: - - Removes the document file - - Updates related indexes - - Maintains consistency - - Note that deletion is permanent and cannot be undone - through the API (though git history may preserve it). - """, + description="Delete a document and update related indexes", examples=[ { "name": "Remove Document", @@ -252,7 +198,7 @@ if result['deleted']: """ } ], - output_model=Dict[str, bool] #TODO + output_model=Dict[str, bool] ) async def delete_document(path: DocumentPathId) -> Dict[str, bool]: """Delete a document.""" @@ -260,4 +206,4 @@ async def delete_document(path: DocumentPathId) -> Dict[str, bool]: response = await client.delete(url) if response.status_code == 204: return {"deleted": True} - return response.json() + return response.json() \ No newline at end of file diff --git a/src/basic_memory/mcp/tools/help.py b/src/basic_memory/mcp/tools/help.py index f7970cac..b1752631 100644 --- a/src/basic_memory/mcp/tools/help.py +++ b/src/basic_memory/mcp/tools/help.py @@ -57,24 +57,7 @@ class SchemaCatalog(BaseModel): @mcp.tool( category="system", - description=""" - Get schema information about available tools. - - This tool provides access to the MCP schema catalog, showing: - - Available tools and their capabilities - - Input/output type definitions - - Example usage patterns - - Related schema models - - You can: - - Get the full tool catalog - - Look up specific tools - - Control example inclusion - - Access referenced models - - The schema information helps understand tool capabilities - and ensure correct usage. - """, + description="Get schema information about available tools and their capabilities", examples=[ { "name": "View All Tools", @@ -165,4 +148,4 @@ async def get_schema( for tool in result["tools"].values(): tool.pop("examples", None) - return SchemaCatalog.model_validate(result).model_dump() + return SchemaCatalog.model_validate(result).model_dump() \ No newline at end of file diff --git a/src/basic_memory/mcp/tools/knowledge.py b/src/basic_memory/mcp/tools/knowledge.py index 251165fc..e405af5c 100644 --- a/src/basic_memory/mcp/tools/knowledge.py +++ b/src/basic_memory/mcp/tools/knowledge.py @@ -23,23 +23,7 @@ from basic_memory.services.exceptions import EntityNotFoundError @mcp.tool( category="knowledge", - description=""" - Create new entities in the knowledge graph. - - Entities are the core building blocks of the knowledge graph. Each entity: - - Has a unique name and type - - Can have multiple observations - - Can have relations to other entities - - Maintains creation/update timestamps - - Supports optional descriptions - - Entity types help organize knowledge and enable patterns like: - - Components for technical implementations - - Features for user-facing capabilities - - Concepts for abstract ideas - - Decisions for architectural choices - - Documents for detailed writeups - """, + description="Create new entities in the knowledge graph with names, types, and observations", examples=[ { "name": "Create Component", @@ -91,21 +75,7 @@ async def create_entities(request: CreateEntityRequest) -> EntityListResponse: @mcp.tool( category="knowledge", - description=""" - Create relations between existing entities. - - Relations form the edges of the knowledge graph, connecting entities with: - - Directional relationships (from_id -> to_id) - - Typed connections (implements, depends_on, etc.) - - Optional context notes - - Automatic timestamp tracking - - Common relation patterns: - - Component implements Feature - - Component depends_on Component - - Test validates Component - - Document describes Feature - """, + description="Create typed relationships between existing entities", examples=[ { "name": "Add Dependency", @@ -149,15 +119,7 @@ async def create_relations(request: CreateRelationsRequest) -> EntityListRespons @mcp.tool( category="knowledge", - description=""" - Get complete information about a specific entity. - - Returns the full entity context including: - - Basic entity details (name, type, description) - - All observations with categories - - All relations (both incoming and outgoing) - - Timestamps and metadata - """, + description="Get complete information about a specific entity including observations and relations", examples=[ { "name": "View Component Details", @@ -200,23 +162,7 @@ async def get_entity(path_id: PathId) -> EntityResponse: @mcp.tool( - description=""" - Add new observations to an existing entity. - - Observations capture atomic pieces of knowledge about an entity: - - Technical details - - Design decisions - - Feature specifications - - Implementation notes - - Issues or concerns - - Todo items - - Each observation has: - - A category for organization - - Content describing the observation - - Optional context for additional detail - - Automatic timestamp tracking - """, + description="Add categorized observations to an existing entity", examples=[ { "name": "Add Implementation Notes", @@ -256,19 +202,7 @@ async def add_observations(request: AddObservationsRequest) -> EntityResponse: @mcp.tool( - description=""" - Delete specific observations from an entity. - - This tool: - - Removes selected observations - - Maintains entity history - - Updates timestamps - - Preserves relations - - Observations must match exactly for deletion. - The operation is selective - only specified - observations are removed. - """, + description="Delete specific observations from an entity while preserving other content", examples=[ { "name": "Remove Obsolete Notes", @@ -297,19 +231,7 @@ async def delete_observations(request: DeleteObservationsRequest) -> EntityRespo @mcp.tool( - description=""" - Delete relations between entities. - - This tool: - - Removes specific relationships - - Updates both source and target entities - - Maintains entity history - - Preserves observations - - Relations must match exactly (from_id, to_id, and type) - for deletion. The operation only affects the specified - relations, leaving other connections intact. - """, + description="Delete relationships between entities while preserving the entities themselves", examples=[ { "name": "Remove Dependency", @@ -338,18 +260,7 @@ async def delete_relations(request: DeleteRelationsRequest) -> EntityListRespons @mcp.tool( - description=""" - Delete entities from the knowledge graph. - - This operation: - 1. Removes the entity completely - 2. Deletes all its observations - 3. Removes all relations (both ways) - 4. Updates related indexes - - This is a permanent operation that cannot be - undone through the API. Use with caution. - """, + description="Permanently delete entities and all related content (observations and relations)", examples=[ { "name": "Remove Old Components", @@ -373,4 +284,4 @@ async def delete_entities(request: DeleteEntitiesRequest) -> DeleteEntitiesRespo """Delete entities from the knowledge graph.""" url = "/knowledge/entities/delete" response = await client.post(url, json=request.model_dump()) - return DeleteEntitiesResponse.model_validate( response.json()) + return DeleteEntitiesResponse.model_validate(response.json()) diff --git a/src/basic_memory/mcp/tools/search.py b/src/basic_memory/mcp/tools/search.py index 9c665d29..37af497c 100644 --- a/src/basic_memory/mcp/tools/search.py +++ b/src/basic_memory/mcp/tools/search.py @@ -2,32 +2,12 @@ from basic_memory.mcp.server import mcp from basic_memory.schemas.request import SearchNodesRequest, OpenNodesRequest -from basic_memory.schemas.response import SearchNodesResponse, EntityResponse +from basic_memory.schemas.response import SearchNodesResponse, EntityListResponse from basic_memory.mcp.async_client import client @mcp.tool( - description=""" - Search for entities in the knowledge graph. - - This is a powerful semantic search that looks across: - - Entity names and types - - Descriptions and metadata - - Observation content - - Relation contexts - - Features: - - Case-insensitive matching - - Partial word matches - - Category filtering - - Returns full entity context - - Natural language friendly - - The search combines multiple approaches to find relevant entities, - including text matching, category filtering, and context awareness. - Results include complete entity information with observations - and relations to help understand the context. - """, + description="Search for entities across names, descriptions, observations, and relations", examples=[ { "name": "Basic Text Search", @@ -100,22 +80,7 @@ async def search_nodes(request: SearchNodesRequest) -> SearchNodesResponse: @mcp.tool( - description=""" - Load multiple entities by their path_ids. - - This tool efficiently loads multiple entities in a single request, - retrieving their complete information including observations - and relations. It's particularly useful for: - - - Following relation chains - - Loading related entities - - Batch entity retrieval - - Context building - - The response maps each path_id to its full entity data, - making it easy to access specific entities while maintaining - their relationships. - """, + description="Load multiple entities by their path_ids in a single request", examples=[ { "name": "Load Related Components", @@ -167,17 +132,10 @@ print(f"Test Status: {'test' in [r.relation_type for r in test.relations]}") """, }, ], - output_schema={ - "description": "Map of path_ids to their complete entity data", - "type": "object", - "additionalProperties": { - "$ref": "#/definitions/EntityResponse", - "description": "Full entity data including observations and relations", - }, - }, + output_model=EntityListResponse, ) -async def open_nodes(request: OpenNodesRequest) -> EntityResponse: +async def open_nodes(request: OpenNodesRequest) -> EntityListResponse: """Load multiple entities by their path_ids.""" url = "/knowledge/nodes" response = await client.post(url, json=request.model_dump()) - return EntityResponse.model_validate(response.json()) + return EntityListResponse.model_validate(response.json())