Skip to main content
Glama
sureshsankaran

Obsidian Tools MCP Server

create_from_template

Create new Obsidian notes from templates by specifying paths and variables for content replacement.

Instructions

Create a new note from an existing template note

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
templatePathYesPath to the template note
newPathYesPath for the new note
variablesNoVariables to replace in template (e.g., {{title}} -> 'My Note')

Implementation Reference

  • The main handler function `handleCreateFromTemplate` that reads the content from a template note, replaces user-provided variables (e.g., {{title}}) and built-in variables like {{date}}, {{time}}, {{datetime}}, ensures the target directory exists, and writes the processed content to the new note path.
    async function handleCreateFromTemplate(args: {
      templatePath: string;
      newPath: string;
      variables?: Record<string, string>;
    }): Promise<string> {
      const templateFullPath = resolvePath(args.templatePath);
      const newFullPath = resolvePath(args.newPath);
    
      if (!(await fileExists(templateFullPath))) {
        throw new Error(`Template not found at ${args.templatePath}`);
      }
    
      if (await fileExists(newFullPath)) {
        throw new Error(`Note already exists at ${args.newPath}`);
      }
    
      let content = await fs.readFile(templateFullPath, "utf-8");
    
      // Replace variables
      if (args.variables) {
        for (const [key, value] of Object.entries(args.variables)) {
          const pattern = new RegExp(`\\{\\{${key}\\}\\}`, "g");
          content = content.replace(pattern, value);
        }
      }
    
      // Replace built-in variables
      const now = new Date();
      content = content
        .replace(/\{\{date\}\}/g, now.toISOString().split("T")[0])
        .replace(/\{\{time\}\}/g, now.toTimeString().split(" ")[0])
        .replace(/\{\{datetime\}\}/g, now.toISOString());
    
      await ensureDir(newFullPath);
      await fs.writeFile(newFullPath, content, "utf-8");
    
      return `Successfully created note at ${args.newPath} from template ${args.templatePath}`;
    }
  • The JSON schema defining the input parameters for the tool: required templatePath and newPath, optional variables object.
    inputSchema: {
      type: "object",
      properties: {
        templatePath: {
          type: "string",
          description: "Path to the template note",
        },
        newPath: {
          type: "string",
          description: "Path for the new note",
        },
        variables: {
          type: "object",
          description:
            "Variables to replace in template (e.g., {{title}} -> 'My Note')",
        },
      },
      required: ["templatePath", "newPath"],
    },
  • src/index.ts:319-341 (registration)
    Tool registration in the `tools` array used for ListTools response, specifying name, description, and inputSchema.
    {
      name: "create_from_template",
      description: "Create a new note from an existing template note",
      inputSchema: {
        type: "object",
        properties: {
          templatePath: {
            type: "string",
            description: "Path to the template note",
          },
          newPath: {
            type: "string",
            description: "Path for the new note",
          },
          variables: {
            type: "object",
            description:
              "Variables to replace in template (e.g., {{title}} -> 'My Note')",
          },
        },
        required: ["templatePath", "newPath"],
      },
    },
  • src/index.ts:935-943 (registration)
    Dispatch case in the CallTool request handler switch statement that invokes the handler function with properly typed arguments.
    case "create_from_template":
      result = await handleCreateFromTemplate(
        args as {
          templatePath: string;
          newPath: string;
          variables?: Record<string, string>;
        }
      );
      break;
Behavior2/5

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

With no annotations provided, the description carries the full burden of behavioral disclosure. It states the tool creates a new note, implying a write operation, but doesn't mention permissions, side effects (e.g., whether it overwrites existing files), error handling, or output format. This is inadequate for a mutation tool with zero annotation coverage.

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?

The description is a single, efficient sentence that directly states the tool's purpose without unnecessary words. It's front-loaded with the core action, making it easy to parse, and every part of the sentence contributes essential information.

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 of a note-creation tool with template variables and no output schema, the description is insufficient. It doesn't explain what the tool returns (e.g., success/failure, the new note's content), how variables are processed, or error conditions, leaving significant gaps for the agent to operate effectively.

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

Parameters3/5

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

The input schema has 100% description coverage, so the schema fully documents all three parameters. The description adds no additional meaning beyond what's in the schema (e.g., it doesn't explain path formats or variable syntax further), meeting the baseline score of 3 for high schema coverage.

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 states the action ('Create a new note') and the resource ('from an existing template note'), making the purpose immediately understandable. However, it doesn't explicitly distinguish this tool from 'create_note' (a sibling tool), which appears to create notes without templates, leaving some ambiguity about when to choose one over the other.

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?

The description provides no guidance on when to use this tool versus alternatives like 'create_note' or other sibling tools. It lacks context about prerequisites (e.g., needing an existing template), exclusions, or typical use cases, leaving the agent to infer usage from the tool name alone.

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

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