Tips & Tricks (Actualizado: 3/6/2026)

Claude Code x Obsidian: estructura del Vault, permisos, plantillas y auditoría de enlaces

Workflow práctico para Obsidian y Claude Code: notas diarias, handoff, snippets, content ops y auditoría de enlaces.

Claude Code x Obsidian: estructura del Vault, permisos, plantillas y auditoría de enlaces

Un Vault de Obsidian gana valor con el tiempo, pero también acumula mantenimiento. Las notas diarias crecen, los proyectos pierden estado, los snippets de código se quedan sin contexto y las ideas de contenido dejan de apuntar a los enlaces internos o a la CTA correcta. Claude Code puede ayudar porque, en la práctica, un Vault es una carpeta de archivos Markdown.

El enfoque seguro no es pedirle a la IA que reorganice todo. El workflow útil es limitado: una estructura de carpetas pequeña, permisos estrictos, plantillas repetibles y una auditoría de enlaces al final. Para principiantes: el Vault es la carpeta de conocimiento; el harness es la base de trabajo que indica al agente dónde puede leer, dónde puede escribir y qué verificación debe ejecutar.

Esta guía cubre cuatro use case concretos: daily logs, project handoff, snippets de código y content operations. También marca cada pitfall importante, porque el risk real no es un párrafo poco elegante, sino un enlace roto, una propiedad YAML mal escrita o un archivo privado leído sin necesidad.

Modelo de integración

La ayuda oficial de Obsidian explica que los enlaces internos pueden escribirse como Wikilinks, por ejemplo [[Nombre de nota]], o como enlaces Markdown. Daily notes es un plugin principal para notas con fecha. Templates permite insertar valores como {{date}}, y Properties usa YAML al inicio de la nota. Revisa las páginas oficiales sobre internal links, Daily notes, Templates, Properties y Web Clipper templates.

En Claude Code, la frontera de seguridad está en settings y permissions. CLAUDE.md describe las reglas del Vault. .claude/settings.json limita las operaciones.

flowchart LR
  A["Inbox"] --> B["Claude Code review"]
  B --> C["Daily logs"]
  B --> D["Projects"]
  B --> E["Content ops"]
  C --> F["Obsidian links"]
  D --> F
  E --> F
  F --> G["Link audit"]

La fuente de verdad sigue siendo Markdown en Obsidian. Claude Code ordena, resume, crea borradores y revisa enlaces; no debe convertirse en dueño del Vault.

Empieza con una estructura pequeña

No crees veinte carpetas al principio. Usa una estructura que represente trabajo real.

mkdir -p inbox daily projects content-ops snippets templates scripts archive private
CarpetaUsoTrabajo seguro para Claude Code
inbox/capturas sin ordenar y Web Clippercrear y clasificar
daily/registro diario y memoria de trabajocrear, añadir, resumir ayer
projects/handoff y decisiones activasactualizar notas de proyecto
content-ops/ideas de artículos, CTA, publicaciónordenar borradores y enlaces
snippets/comandos y ejemplos de códigoañadir contexto y etiquetas
templates/plantillas de Obsidianleer; editar solo con aprobación
archive/notas cerradasno editar
private/datos personales o secretosno leer

Con esto aparecen flujos útiles. Las notas diarias arrastran tareas pendientes. Las notas de project handoff explican estado, siguiente acción y risk. Los snippets guardan comando, versión y failure case. Las notas de content operations comprueban enlaces oficiales, enlaces internos, /products/ y /training/.

Añade CLAUDE.md en la raíz del Vault

Este archivo debe ser operativo y concreto.

# Obsidian Vault Rules

## Purpose
- This vault stores daily logs, project handoffs, code snippets, and content operations notes.
- Keep notes useful in Obsidian without requiring Claude Code to read private files.

## Directory policy
- `daily/`: create or update daily notes in `YYYY-MM-DD.md`.
- `projects/`: maintain one handoff note per active project.
- `content-ops/`: maintain article plans, CTA checks, and publishing notes.
- `snippets/`: store runnable commands and code examples with context.
- `templates/`: read freely, but ask before editing.
- `archive/` and `private/`: do not edit. Do not summarize private files.

## Note rules
- Use Wikilinks like `[[Project name]]` for internal links.
- Use YAML properties at the top of notes.
- Keep one paragraph under five lines.
- Add a `source:` property when a note comes from a URL.
- Add `status: draft`, `status: active`, or `status: done`.

## Safety rules
- Never rename existing notes without asking first.
- Never rewrite `.obsidian/` settings.
- Before bulk edits, list the target files and wait for approval.
- After changes, run `node scripts/audit-wikilinks.cjs .`.

El pitfall habitual es escribir una regla vaga como “organiza mi Vault”. Claude Code tendrá que inventar carpetas, títulos y tags. Esa inferencia puede sonar razonable, pero romper búsqueda, Graph view y enlaces.

Configura permisos estrechos

Guarda este ejemplo como .claude/settings.json.

{
  "$schema": "https://json.schemastore.org/claude-code-settings.json",
  "permissions": {
    "allow": [
      "Read(./CLAUDE.md)",
      "Read(./daily/**)",
      "Read(./projects/**)",
      "Read(./content-ops/**)",
      "Read(./snippets/**)",
      "Read(./templates/**)",
      "Read(./scripts/**)",
      "Edit(./daily/**)",
      "Edit(./projects/**)",
      "Edit(./content-ops/**)",
      "Edit(./snippets/**)",
      "Write(./inbox/**)",
      "Write(./daily/**)",
      "Write(./projects/**)",
      "Write(./content-ops/**)",
      "Write(./snippets/**)",
      "Bash(node scripts/audit-wikilinks.cjs .)"
    ],
    "ask": [
      "Edit(./templates/**)",
      "Bash(git *)",
      "WebFetch"
    ],
    "deny": [
      "Read(./private/**)",
      "Read(./**/.env)",
      "Read(./**/.env.*)",
      "Edit(./.obsidian/**)",
      "Edit(./archive/**)",
      "Write(./archive/**)",
      "Bash(rm *)",
      "Bash(del *)"
    ]
  }
}

La idea es permitir trabajo frecuente sin abrir todo el Vault. Si necesitas revisar fuentes web o limpiar capturas, aprueba WebFetch cuando corresponda. Evita modos de bypass en un Vault real.

Tres plantillas de Obsidian

La plantilla diaria debe ser ligera.

---
date: "{{date:YYYY-MM-DD}}"
status: active
tags:
  - daily
---

# {{date:YYYY-MM-DD}}

## Today
- [ ]

## Learned
-

## Questions
-

## Links
- [[Weekly review]]

La plantilla de project handoff prioriza la próxima acción.

---
status: active
owner: Masa
tags:
  - project
  - handoff
updated: "{{date:YYYY-MM-DD}}"
---

# Project handoff: {{title}}

## Goal

## Current state

## Next action
- [ ]

## Decisions
-

## Risks and pitfall
-

## Links
- [[Daily note]]
- [[Related snippet]]

La plantilla de content operations incluye monetización desde el inicio.

---
status: draft
channel: blog
source:
target_cta:
  - /products/
  - /training/
tags:
  - content-ops
---

# Content ops note: {{title}}

## Search intent

## Reader problem

## Outline

## Internal links
- [[Claude Code approval sandbox guide]]
- [[Claude Code documentation generation]]

## Monetization CTA
- Product CTA:
- Training CTA:

## Publish checklist
- [ ] Official links checked
- [ ] Code examples tested
- [ ] Broken internal links audited

Para profundizar, enlaza con approval y sandbox, generación de documentación y content funnel audit. Los materiales reutilizables van a products y la adopción de equipo a training.

Audita enlaces internos con Node

Guarda esto como scripts/audit-wikilinks.cjs.

#!/usr/bin/env node
const fs = require("node:fs");
const path = require("node:path");

const vaultRoot = path.resolve(process.argv[2] || ".");
const ignoredDirs = new Set([".git", ".obsidian", ".trash", "node_modules"]);
const allFiles = [];
const markdownFiles = [];

function walk(dir) {
  for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
    if (ignoredDirs.has(entry.name)) continue;
    const full = path.join(dir, entry.name);
    if (entry.isDirectory()) {
      walk(full);
    } else if (entry.isFile()) {
      allFiles.push(full);
      if (entry.name.toLowerCase().endsWith(".md")) markdownFiles.push(full);
    }
  }
}

function toPosix(filePath) {
  return filePath.split(path.sep).join("/");
}

function withoutMd(value) {
  return value.replace(/\.md$/i, "");
}

function stripTarget(raw) {
  return raw.split("|")[0].split("#")[0].split("^")[0].trim();
}

function safeDecode(value) {
  try {
    return decodeURIComponent(value);
  } catch {
    return value;
  }
}

function isExternal(target) {
  return /^(https?:|mailto:|obsidian:|#|\/)/i.test(target);
}

function candidateKeys(target, fromFile) {
  const clean = safeDecode(stripTarget(target));
  if (!clean) return [];
  const keys = new Set();
  const normalized = toPosix(path.normalize(clean));
  keys.add(normalized);
  keys.add(withoutMd(normalized));

  if (clean.includes("/") || clean.includes("\\")) {
    const fromDir = path.dirname(toPosix(path.relative(vaultRoot, fromFile)));
    const relative = toPosix(path.normalize(path.join(fromDir, clean)));
    keys.add(relative);
    keys.add(withoutMd(relative));
  } else {
    keys.add(withoutMd(path.posix.basename(normalized)));
    keys.add(path.posix.basename(normalized));
  }

  return [...keys].filter(Boolean);
}

walk(vaultRoot);

const byPath = new Map();
const byBase = new Map();

for (const file of allFiles) {
  const rel = toPosix(path.relative(vaultRoot, file));
  const lowerRel = rel.toLowerCase();
  byPath.set(lowerRel, file);
  if (rel.toLowerCase().endsWith(".md")) byPath.set(withoutMd(lowerRel), file);

  const base = rel.toLowerCase().endsWith(".md")
    ? withoutMd(path.posix.basename(rel)).toLowerCase()
    : path.posix.basename(rel).toLowerCase();
  const list = byBase.get(base) || [];
  list.push(file);
  byBase.set(base, list);
}

const problems = [];
const wikilink = /!?\[\[([^\]]+)\]\]/g;
const markdownLink = /!?\[[^\]]*\]\(([^)]+)\)/g;

for (const file of markdownFiles) {
  const text = fs.readFileSync(file, "utf8");
  const rel = toPosix(path.relative(vaultRoot, file));
  const targets = [];
  let match;

  while ((match = wikilink.exec(text))) targets.push(match[1]);
  while ((match = markdownLink.exec(text))) {
    const target = match[1].replace(/^<|>$/g, "").trim();
    if (!isExternal(target)) targets.push(target);
  }

  for (const target of targets) {
    const clean = stripTarget(target);
    if (!clean || isExternal(clean)) continue;
    const keys = candidateKeys(clean, file);
    const pathHit = keys.some((key) => byPath.has(key.toLowerCase()));
    const baseHits = keys.flatMap((key) => byBase.get(path.posix.basename(key).toLowerCase()) || []);

    if (!pathHit && baseHits.length === 0) {
      problems.push(`${rel} -> missing [[${clean}]]`);
    } else if (!pathHit && baseHits.length > 1) {
      problems.push(`${rel} -> ambiguous [[${clean}]] (${baseHits.length} matches)`);
    }
  }
}

if (problems.length) {
  console.error("Broken or ambiguous internal links:");
  for (const problem of problems) console.error(`- ${problem}`);
  process.exit(1);
}

console.log(`OK: checked ${markdownFiles.length} Markdown files in ${vaultRoot}`);

Ejecútalo desde la raíz:

node scripts/audit-wikilinks.cjs .

Prompt recomendado:

Read `daily/2026-06-02.md` and `projects/site-refresh.md`.
Create `daily/2026-06-03.md` from `templates/daily.md`.
Carry over unfinished tasks only when they still have an owner.
Do not edit `.obsidian/`, `archive/`, or `private/`.
After editing, run `node scripts/audit-wikilinks.cjs .` and report the result.

Errores típicos

Primer pitfall: permitir edición de .obsidian/. Configuración de plugins, temas y hotkeys no es contenido normal.

Segundo: renombrar notas fuera de Obsidian. Puede romper backlinks.

Tercero: Properties YAML mal escritas. Si una propiedad contiene un enlace interno, usa comillas: related: "[[Project name]]".

Cuarto: notas diarias demasiado pesadas. Una plantilla que nadie completa se convierte en ruido.

Quinto: tratar content operations como solo redacción. Un artículo público necesita fuentes oficiales, enlaces internos, CTA y verificación.

Lo que probó Masa

En el Vault de prueba de Masa, los mejores resultados vinieron de dos flujos: pasar tareas pendientes al daily log siguiente y auditar enlaces antes de publicar notas de contenido. El peor experimento fue pedir “limpia todo el Vault”; Claude Code creó demasiadas etiquetas y títulos. Permisos estrechos, plantillas pequeñas y auditoría con Node dieron un workflow más estable.

#claude-code #obsidian #pkm #markdown #automation #second-brain
Gratis

PDF gratis: cheatsheet de Claude Code

Introduce tu email y descarga una hoja con comandos, hábitos de revisión y flujos seguros.

Cuidamos tus datos y no enviamos spam.

Masa

Sobre el autor

Masa

Ingeniero enfocado en workflows prácticos con Claude Code.