Skip to main content
Glama
nojiritakeshi

Obsidian Translation MCP Server

create_obsidian_note

Create Obsidian notes programmatically by specifying path, title, content, and tags, with optional template support for structured frontmatter.

Instructions

Create a new Obsidian note with optional frontmatter and tags

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
pathYesPath for the new note (relative to vault root, e.g., "folder/note.md")
titleYesTitle of the note
contentYesContent of the note
tagsNoTags to add to the note
templateNoTemplate to use for the note (optional)

Implementation Reference

  • The handleCreateNote method in ObsidianMCPServer class that orchestrates the tool execution - extracts args, calls notesTool.createNote(), and formats the response.
    /**
     * ノート作成の処理
     */
    private async handleCreateNote(args: any) {
      const { path, title, content, tags, template } = args;
      
      if (!path || !title || !content) {
        throw new McpError(ErrorCode.InvalidParams, 'Path, title, and content are required');
      }
    
      const result = await this.notesTool.createNote(path, title, content, tags, template);
    
      return {
        content: [
          {
            type: 'text',
            text: `✅ ノートが作成されました\\n\\n` +
                  `📁 パス: ${result.path}\\n` +
                  `📝 タイトル: ${result.title}\\n` +
                  `🏷️ タグ: ${result.tags.join(', ') || 'なし'}\\n` +
                  `📅 作成日時: ${result.created.toISOString()}`
          }
        ]
      };
    }
  • The createNote method in NotesTool class that executes the core logic: checks file existence, appends .md extension, builds frontmatter with title/dates/tags, applies optional template, writes file via fileSystem.writeFile, and returns NoteMetadata.
    /**
     * 新しいノートを作成
     * @param path ノートのパス
     * @param title ノートのタイトル
     * @param content ノートの内容
     * @param tags タグ(オプション)
     * @param template テンプレート(オプション)
     * @returns 作成されたノートの情報
     */
    async createNote(
      path: string,
      title: string,
      content: string,
      tags: string[] = [],
      template?: string
    ): Promise<NoteMetadata> {
      try {
        // ファイルが既に存在するかチェック
        if (await this.fileSystem.exists(path)) {
          throw new Error(`${ErrorCode.FILE_NOT_FOUND}: File '${path}' already exists`);
        }
    
        // .mdの拡張子を確認
        if (!path.endsWith('.md')) {
          path += '.md';
        }
    
        // Frontmatterを作成
        const frontmatter: any = {
          title,
          created: new Date().toISOString(),
          modified: new Date().toISOString()
        };
    
        if (tags.length > 0) {
          frontmatter.tags = tags;
        }
    
        // テンプレートが指定されている場合は適用
        let finalContent = content;
        if (template) {
          finalContent = template.replace('{{content}}', content);
        }
    
        // Frontmatterとコンテンツを結合
        const noteContent = matter.stringify(finalContent, frontmatter);
    
        // ファイルを作成
        await this.fileSystem.writeFile(path, noteContent);
    
        return {
          title,
          path,
          tags,
          lastModified: new Date(),
          created: new Date()
        };
      } catch (error) {
        if (error instanceof Error) {
          throw error;
        }
        throw new Error(`${ErrorCode.PERMISSION_DENIED}: Failed to create note '${path}'`);
      }
    }
  • The getCreateNoteToolDefinition static method that defines the tool's name ('create_obsidian_note'), description, and inputSchema with required fields (path, title, content) and optional fields (tags, template).
    static getCreateNoteToolDefinition(): Tool {
      return {
        name: 'create_obsidian_note',
        description: 'Create a new Obsidian note with optional frontmatter and tags',
        inputSchema: {
          type: 'object',
          properties: {
            path: {
              type: 'string',
              description: 'Path for the new note (relative to vault root, e.g., "folder/note.md")'
            },
            title: {
              type: 'string',
              description: 'Title of the note'
            },
            content: {
              type: 'string',
              description: 'Content of the note'
            },
            tags: {
              type: 'array',
              items: { type: 'string' },
              description: 'Tags to add to the note'
            },
            template: {
              type: 'string',
              description: 'Template to use for the note (optional)'
            }
          },
          required: ['path', 'title', 'content']
        }
      };
  • src/index.ts:87-99 (registration)
    The setupRequestHandlers method where the tool is registered - NotesTool.getCreateNoteToolDefinition() is listed in the ListToolsRequestSchema handler, and the 'create_obsidian_note' case in the CallToolRequestSchema switch dispatches to handleCreateNote.
    private setupRequestHandlers(): void {
      // ツール一覧の取得
      this.server.setRequestHandler(ListToolsRequestSchema, async () => {
        return {
          tools: [
            TranslateTool.getToolDefinition(),
            NotesTool.getCreateNoteToolDefinition(),
            NotesTool.getReadNoteToolDefinition(),
            NotesTool.getUpdateNoteToolDefinition(),
            SearchTool.getSearchToolDefinition(),
            SearchTool.getSearchByTagsToolDefinition(),
          ],
        };
  • The writeFile method in FileSystemHelper that handles the actual file writing with recursive directory creation, used by createNote to persist the note to disk.
    /**
     * ファイルを書き込み
     * @param filePath ファイルパス
     * @param content ファイル内容
     */
    async writeFile(filePath: string, content: string): Promise<void> {
      try {
        const absolutePath = this.getAbsolutePath(filePath);
        
        // ディレクトリが存在しない場合は作成
        await fs.mkdir(dirname(absolutePath), { recursive: true });
        
        await fs.writeFile(absolutePath, content, 'utf-8');
      } catch (error) {
        throw new Error(`${ErrorCode.PERMISSION_DENIED}: Cannot write file '${filePath}': ${error}`);
      }
    }
Behavior2/5

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

With no annotations, the description must bear the full burden of transparency. It does not disclose key behaviors: what happens if the path exists, how frontmatter is handled (frontmatter is mentioned but not a parameter), whether the vault must exist, or any rate limits. This is a significant gap.

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

Conciseness3/5

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

The description is a single sentence, which is concise, but it omits critical details for a 5-parameter tool with no annotations. It is front-loaded with the main action but sacrifices completeness.

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

Completeness2/5

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

Given the complexity (5 parameters, no output schema, no annotations), the description is insufficient. It does not explain the creation process, prerequisites, or expected behavior when a note already exists. The mention of frontmatter misaligns with the schema.

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

Parameters2/5

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

The schema covers all parameters with descriptions (100% coverage), so baseline is 3. However, the description mentions 'frontmatter' which is not a parameter in the schema, causing confusion. It adds no meaningful semantics beyond the param descriptions.

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

Purpose4/5

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

The description clearly identifies the tool as creating an Obsidian note, with optional frontmatter and tags. The verb 'Create' and resource 'a new Obsidian note' are specific, but it does not differentiate from sibling tools like update_obsidian_note.

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

Usage Guidelines2/5

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

No guidance is given on when to use this tool versus alternatives. For example, it does not state that this tool is for new notes while update_obsidian_note is for modifying existing ones. The description only implies usage via the action verb.

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

Install Server

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/nojiritakeshi/obsidian-translate-mcp-server'

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