Skip to main content
Glama
maxkuminov

Obsidian MCP (pgvector + Ollama, self-hosted)

create_note

Create a new markdown note in an Obsidian vault. Specify the vault-relative path and full markdown content including frontmatter.

Instructions

Create a new markdown note in the Obsidian vault. Requires a readwrite API key.

See get_vault_guide for Obsidian syntax and any vault-specific conventions (naming, folder placement, frontmatter, tags).

Args: path: Vault-relative path for the new note (e.g. "Cards/New Topic.md"). The .md extension is added if missing. content: Full markdown content for the note, including any frontmatter.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
pathYes
contentYes

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault
resultYes

Implementation Reference

  • Core implementation of create_note tool. Validates write permission, checks content size (max 10MB), appends .md extension if missing, validates path, checks for existing note, and writes the file.
    @_tracked("create_note", ["path"])
    async def create_note_impl(path: str, content: str) -> str:
        """Create a new note in the vault."""
        if err := _require_write():
            return err
        encoded = content.encode("utf-8")
        if len(encoded) > MAX_NOTE_BYTES:
            return f"Content too large ({len(encoded)} bytes, max {MAX_NOTE_BYTES})"
        if not path.endswith(".md"):
            path += ".md"
        uid = current_user_id.get()
        try:
            from src.services.vault import validate_path
            full_path = validate_path(path, user_id=uid)
            if full_path.exists():
                return f"Note already exists: {path}. Use edit_note to modify it."
            write_file(path, content, user_id=uid)
            return f"Created note: {path}"
        except ValueError as e:
            return str(e)
  • MCP tool decorator that exposes create_note as a tool. It is the public-facing endpoint that delegates to create_note_impl.
    @mcp.tool()
    async def create_note(path: str, content: str) -> str:
        """Create a new markdown note in the Obsidian vault. Requires a readwrite API key.
    
        See `get_vault_guide` for Obsidian syntax and any vault-specific conventions
        (naming, folder placement, frontmatter, tags).
    
        Args:
            path: Vault-relative path for the new note (e.g. "Cards/New Topic.md"). The .md extension is added if missing.
            content: Full markdown content for the note, including any frontmatter.
        """
        return await create_note_impl(path, content)
  • Import of create_note_impl from tools module into the server, making it available for the MCP tool registration.
    from src.mcp_server.tools import (
        create_note_impl,
  • Helper function that checks if the current API key has write permission. Returns an error string if read-only.
    def _require_write() -> str | None:
        """Return an error message if current key lacks write permission."""
        if current_permission.get() != "readwrite":
            return "Permission denied: this API key has read-only access. A 'readwrite' key is required."
        return None
  • Constant defining the maximum note size: 10 MB.
    MAX_NOTE_BYTES = 10 * 1024 * 1024  # 10 MB
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations provided, so description carries full burden. Discloses .md extension addition and auth requirement, but doesn't discuss success/failure behavior. Adequate for a create operation.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Concise description in ~3 sentences plus parameter docs, front-loaded with core action. No unnecessary words.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Covers purpose, auth, conventions, param details. Output schema exists to handle return values. Complete for a simple create tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Adds significant meaning beyond schema: explains path is vault-relative, provides example, notes .md extension addition; describes content as full markdown including frontmatter. Compensates for 0% schema coverage.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Clearly states 'Create a new markdown note in the Obsidian vault', specifying verb, resource, and location. Distinguishes from siblings like edit_note and delete_note.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Mentions requirement for readwrite API key and references get_vault_guide for conventions, providing context for use and alternative. Lacks explicit when-not-to-use, but overall clear.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Other Tools

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/maxkuminov/obsidian-mcp'

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