Skip to main content
Glama
cwente25

Knowledge Base MCP Server

by cwente25

add_note

Create a new note in a knowledge base with hierarchical categories, supporting markdown content and optional tags for organization.

Instructions

Create a new note in the knowledge base (supports hierarchical categories)

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
category_pathYesCategory path (e.g., 'work', 'work/clients/acme', 'personal/spiritual'). Category will be created if it doesn't exist.
titleYesNote title (becomes filename)
contentYesMarkdown content of the note
tagsNoComma-separated tags (optional)

Implementation Reference

  • The handler function that executes the add_note tool: extracts parameters, parses tags, calls storage.create_note, formats success/error response.
    async def handle_add_note(arguments: dict) -> list[TextContent]:
        """Handle add_note tool call."""
        try:
            category_path = arguments["category_path"]
            title = arguments["title"]
            content = arguments["content"]
            tags_str = arguments.get("tags", "")
    
            # Parse tags
            tags = [tag.strip() for tag in tags_str.split(",") if tag.strip()]
    
            # Create note (will auto-create category if needed)
            note = storage.create_note(
                category_path=category_path,
                title=title,
                content=content,
                tags=tags,
                create_category=True
            )
    
            filename = storage.sanitize_filename(title)
            result = f"✓ Note '{title}' created in {category_path or 'root'}/\n"
            result += f"  File: {filename}.md\n"
            if tags:
                result += f"  Tags: {', '.join(tags)}"
    
            return [TextContent(type="text", text=result)]
        except (DuplicateNoteError, CategoryNotFoundError, InvalidPathError, StorageError) as e:
            return [TextContent(type="text", text=str(e))]
        except Exception as e:
            return [TextContent(type="text", text=f"❌ Error: {str(e)}")]
  • Input schema definition for the add_note tool in the list_tools() response.
    Tool(
        name="add_note",
        description="Create a new note in the knowledge base (supports hierarchical categories)",
        inputSchema={
            "type": "object",
            "properties": {
                "category_path": {
                    "type": "string",
                    "description": "Category path (e.g., 'work', 'work/clients/acme', 'personal/spiritual'). Category will be created if it doesn't exist.",
                },
                "title": {
                    "type": "string",
                    "description": "Note title (becomes filename)",
                },
                "content": {
                    "type": "string",
                    "description": "Markdown content of the note",
                },
                "tags": {
                    "type": "string",
                    "description": "Comma-separated tags (optional)",
                    "default": "",
                },
            },
            "required": ["category_path", "title", "content"],
        },
    ),
  • Tool call dispatcher registers and routes 'add_note' calls to the handle_add_note function.
    elif name == "add_note":
        return await handle_add_note(arguments)
  • Core helper method in storage layer that creates the note file, handles path validation, frontmatter generation, and file writing. Called by the handler.
    def create_note(
        self,
        category_path: str,
        title: str,
        content: str,
        tags: list[str],
        metadata: Optional[dict] = None,
        create_category: bool = True
    ) -> Note:
        """
        Create a new note.
    
        Args:
            category_path: Category path (e.g., "work/clients/acme")
            title: Note title
            content: Markdown content
            tags: List of tags
            metadata: Additional metadata fields
            create_category: If True, create category if it doesn't exist
    
        Returns:
            Created Note object
    
        Raises:
            DuplicateNoteError: If note already exists
            InvalidPathError: If category path is invalid
            StorageError: If write fails
        """
        # Normalize and validate path
        normalized = normalize_path(category_path)
        is_valid, error_msg = validate_path(normalized) if normalized else (True, None)
        if not is_valid:
            raise InvalidPathError(error_msg)
    
        # Create category if needed
        if normalized and not self._category_exists(normalized):
            if create_category:
                self.create_category(normalized, create_parents=True)
            else:
                raise CategoryNotFoundError(
                    f"❌ Error: Category '{normalized}' does not exist\n"
                    f"💡 Tip: Use create_category first or set create_category=True"
                )
    
        file_path = self._get_note_path(normalized, title)
    
        if file_path.exists():
            raise DuplicateNoteError(
                f"❌ Error: Note '{title}' already exists in {normalized or 'root'}/\n"
                f"💡 Tip: Use update_note to modify existing notes"
            )
    
        # Create frontmatter
        frontmatter = NoteFrontmatter(
            tags=tags,
            category=normalized,
            metadata=metadata or {}
        )
    
        # Create note object
        note = Note(
            title=title,
            category=normalized,
            frontmatter=frontmatter,
            content=content,
            file_path=str(file_path)
        )
    
        # Write to file
        self._write_note_file(note, file_path, backup=False)
    
        return note

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/cwente25/KnowledgeBaseMCP'

If you have feedback or need assistance with the MCP directory API, please join our Discord server