Emanuell121 downloadsDeterministic Markdown templates for AI agents. Fill a template with JSON and get aligned tables, images in your attachment folder and notes saved where you want.
Deterministic Markdown templates for AI agents in Obsidian. Send structured JSON to a template note and get aligned Markdown tables, attachments saved in your vault's attachment folder, and notes written to the right destination path—or rendered as HTML for Telegram.
AI Templates is a companion module of the AI Ecosystem plugin. It does not open a network port of its own; instead, it registers its MCP tools, REST routes and the templates service on the AI Ecosystem Service Bus.
When AI agents write long Markdown notes or tables directly, they spend hundreds of output tokens on formatting, misalign columns, forget to escape | pipes or newlines inside cells, and struggle with binary attachments.
With AI Templates:
liquidjs in pure interpreter mode: no eval, no new Function, no filesystem tags).{ headers, rows } or an array of objects, and the plugin pads columns, escapes pipes (\|), converts line breaks to <br> and fills empty cells.getAvailablePathForAttachment and embedded as ![[file|width]] or classic Markdown links."obsidian" (standard Markdown) and "telegram" (HTML with <pre> monospace tables for the Telegram AI Gateway).ai-ecosystem plugin. If AI Ecosystem is not installed, a prompt offers a one-click download from EmanuellCarvalhoPires/obsidian-ai-ecosystem on GitHub.image field, the plugin reads the file from disk only if its resolved real path (fs.realpath) is inside one of the folders configured under Allowed local image folders (by default {tmpdir} and {tmpdir}/claude).Templates/AI), or open the AI Templates manager (ribbon icon or command) and click Create starter template.On the first load the plugin installs a kit of generic templates in your templates folder, in the language of Obsidian (English or Portuguese, same template_id): nota_reuniao (meeting), nota_diaria (daily note), revisao_semanal (weekly review), nota_pessoa (person), registro_decisao (decision record), receita_processo (process recipe, ready to become a skill or flow) and briefing_ia (briefing to paste into a new AI conversation). They need no plugin besides Obsidian core.
A template is a regular Markdown note inside Templates/AI (or subfolders) with template_id and description in its YAML frontmatter:
---
template_id: sprint_report
description: Weekly sprint report with a task table and architecture diagram
target_path: Reports/Sprint-{{ sprint }} - {{ title | slug }}.md
collision_rule: incremental
fields:
title:
type: string
required: true
description: Report title
sprint:
type: number
required: true
diagram:
type: image
required: false
description: Optional architecture diagram
tasks:
type: table
required: true
columns: [Ticket, Summary, Status]
description: Tasks from the sprint
notes:
type: string
required: false
default: No blocking issues.
---
# Sprint {{ sprint }} — {{ title }}
Generated on {{ today }}.
{% if diagram %}
## Diagram
{{ diagram | obsidian_image: 600 }}
{% endif %}
## Tasks
{{ tasks | markdown_table }}
## Notes
{{ notes }}
| Type | Accepted JSON input |
|---|---|
string |
String (or number/boolean converted to string). |
number |
Finite number (or numeric string). |
boolean |
true / false (or "true" / "false"). |
date |
ISO-8601 string, YYYY-MM-DD, epoch milliseconds, or "now" / "today". |
table |
{ "headers": [...], "rows": [[...]] } or an array of row objects [{ ... }] (ordered by columns when declared). |
image |
Local file path (preferred), existing vault file name, Base64 / data URI, or { "path" | "vault" | "base64", "filename"? }. |
list |
JSON array. |
object |
Plain JSON object. |
{{ today }} (YYYY-MM-DD) and {{ now_iso }} (ISO timestamp).{% now "YYYY-MM-DD HH:mm" %} formats the current date/time.markdown_table — formats a table field as an aligned GFM table in Obsidian or a <pre> monospace table in Telegram.obsidian_image — embeds an image field ({{ foto | obsidian_image: 500 }} or {{ foto | obsidian_image: "600x400", "Caption" }}).date_fmt: "DD/MM/YYYY HH:mm" — formats a date value.slug — lowercase ASCII slug ("Sprint 42!" → "sprint-42").safe_filename — strips characters forbidden in file names (\ / : * ? " < > |).md_escape — escapes Markdown punctuation.wikilink — builds [[target]] or [[target|alias]].bullet_list — renders an array as a Markdown - list.All REST routes are mounted under /api/v1/ai-templates.
| MCP tool | REST route | Description |
|---|---|---|
list_templates |
GET /templates |
Lists available templates (id, description) and any errors/warnings in template notes. |
get_template_schema |
GET /templates/:id |
Returns field definitions, collision rule, usage notes and a ready-to-fill JSON example. |
preview_template |
POST /render |
Renders a template without writing files (channel: "obsidian" or "telegram"). |
create_note_from_template |
POST /notes |
Validates input, saves attachments, renders the template and writes the note in the vault. |
create_template |
— | Validates and creates (or updates) a template note in the templates folder. |
When connected to AI Ecosystem, AI Templates registers the "templates" service so other plugins (such as Telegram AI Gateway) can render templates directly:
const templates = api.getService<TemplatesService>("templates");
const html = await templates.render("sprint_report", data, "telegram");
The AI Ecosystem core can install Claude Code hooks and a setup skill for this module in the vault's .claude/ folder:
.claude/skills/configurar-ai-templates/, hook entries in .claude/settings.local.json (or settings.json), state in .claude/ai-ecosystem/, and a block in GEMINI.md for Antigravity..claude/ entries is overwritten.Protection hook: a Write of a new note (the file does not exist yet) whose path matches a template target is redirected to create_note_from_template. Edit is never blocked. AI Templates feeds the core with the target globs of its templates (each {{ ... }} becomes *).
Setup keys: pasta_de_templates, regra_de_colisao, pastas_de_imagens_permitidas, limite_base64_mb, links_markdown_classicos.
Environment Keys values: {{secret:NAME}} placeholders that point to Environment Keys values inside template data are resolved only when a note is created (not in preview_template), and the outputs returned to the agent are redacted.
npm install
npm run dev # esbuild in watch mode
npm test # vitest suite
npm run lint # eslint with eslint-plugin-obsidianmd
npm run typecheck # tsc --noEmit
npm run build # type-check + production bundle (main.js and styles.css)
Templates Markdown determinísticos para agentes de IA no Obsidian. Envie um JSON estruturado para uma nota de template e obtenha tabelas Markdown alinhadas, anexos salvos na pasta de anexos do cofre e notas criadas no caminho certo — ou renderizadas em HTML para o Telegram.
O AI Templates é um módulo complementar do plugin AI Ecosystem. Ele não abre porta de rede própria: registra suas tools MCP, rotas REST e o serviço templates no Service Bus do AI Ecosystem.
Quando agentes de IA escrevem notas longas ou tabelas Markdown diretamente, gastam centenas de tokens com formatação, desalinham colunas, esquecem de escapar | ou quebras de linha dentro de células e têm dificuldade para anexar imagens.
Com o AI Templates:
liquidjs em modo interpretado puro: sem eval, sem new Function, sem acesso a arquivos pelo template).{ headers, rows } ou uma lista de objetos e o plugin alinha colunas, escapa pipes (\|), converte quebras de linha em <br> e preenche células vazias.getAvailablePathForAttachment do Obsidian e inseridos como ![[arquivo|largura]] ou link Markdown clássico."obsidian" (Markdown padrão) e "telegram" (HTML com tabelas monoespaçadas em <pre> para o Telegram AI Gateway).ai-ecosystem. Caso o AI Ecosystem não esteja instalado, uma janela oferece a instalação em 1 clique a partir de EmanuellCarvalhoPires/obsidian-ai-ecosystem no GitHub.image, o plugin só lê o arquivo se o caminho real resolvido (fs.realpath) estiver dentro de uma das pastas configuradas em Pastas permitidas para imagens locais (por padrão {tmpdir} e {tmpdir}/claude).Templates/AI), ou abra o Gerenciador do AI Templates (ícone na barra lateral ou comando) e clique em Criar template de exemplo.Na primeira carga o plugin instala na pasta de templates um kit de templates genéricos, no idioma do Obsidian (português ou inglês, mesmo template_id): nota_reuniao, nota_diaria, revisao_semanal, nota_pessoa, registro_decisao, receita_processo (receita de processo, pronta para virar skill ou fluxo) e briefing_ia (briefing para colar numa conversa nova com a IA). Não precisam de nenhum plugin além do núcleo do Obsidian.
Todas as rotas REST ficam sob /api/v1/ai-templates.
| Tool MCP | Rota REST | O que faz |
|---|---|---|
list_templates |
GET /templates |
Lista os templates disponíveis (id, description) e eventuais erros/avisos nas notas de template. |
get_template_schema |
GET /templates/:id |
Retorna os campos declarados, regra de colisão, notas de uso e um example JSON pronto para preencher. |
preview_template |
POST /render |
Renderiza um template sem salvar arquivos (channel: "obsidian" ou "telegram"). |
create_note_from_template |
POST /notes |
Valida os dados, salva anexos, renderiza o template e grava a nota no cofre. |
create_template |
— | Valida e cria (ou atualiza) uma nota de template na pasta de templates. |
O núcleo AI Ecosystem pode instalar hooks do Claude Code e uma skill de configuração para este módulo na pasta .claude/ do cofre:
.claude/skills/configurar-ai-templates/, entradas de hook em .claude/settings.local.json (ou settings.json), estado em .claude/ai-ecosystem/ e um bloco no GEMINI.md para o Antigravity..claude/ é sobrescrito.Hook de proteção: um Write de nota nova (o arquivo ainda não existe) cujo caminho case com o destino de algum template é redirecionado para create_note_from_template. O Edit nunca é bloqueado. O AI Templates envia ao núcleo os globs de destino dos templates (cada {{ ... }} vira *).
Chaves da configuração: pasta_de_templates, regra_de_colisao, pastas_de_imagens_permitidas, limite_base64_mb, links_markdown_classicos.
Valores do Environment Keys: placeholders {{secret:NOME}} que apontam para valores do Environment Keys dentro dos dados do template só são resolvidos na criação da nota (não no preview_template), e as saídas devolvidas ao agente são mascaradas.
MIT