Agent skill
obsidian-base-create
Generates Obsidian .base files from natural language descriptions. Translates requests like "show me all active project notes sorted by date" into valid .base YAML with filters, formulas, views, and summaries. Activates on "create base", "make a view", "show me all notes where", "dashboard", or when user wants structured views of their vault.
Install this agent skill to your Project
npx add-skill https://github.com/majiayu000/claude-skill-registry/tree/main/skills/other/other/obsidian-base-create
SKILL.md
Obsidian Base Create
When To Activate
Do NOT trigger for:
- Editing existing .base files (edit directly)
- Simple search queries (use obsidian-vault-search)
- Views that don't depend on frontmatter properties
Instructions
Step 1: Understand What the User Wants to See
| Request | View Type | Key Filter | Sort |
|---|---|---|---|
| "All my meetings" | table | type == meeting | date desc |
| "Active projects" | cards | type == project AND status == active | name asc |
| "Tasks this week" | table | type == task AND date >= week start | date asc |
| "Recent notes" | table | (none or date-based) | file.mtime desc |
| "Reading list" | cards | type == reference AND status == draft | created desc |
Ask if not obvious:
- What properties should show as columns?
- How should it be sorted?
- Table, cards, or list view?
Step 2: Check Available Properties
# Find all frontmatter properties used in the vault
grep -rh "^[a-z].*:" "$VAULT_PATH" --include="*.md" | \
grep -v "^#\|^-\|^ " | sort | uniq -c | sort -rn | head -20
Common properties from the vault schema (check CLAUDE.md):
type: note, meeting, project, daily, reference, taskstatus: draft, active, completed, archiveddate: YYYY-MM-DDcreated: YYYY-MM-DDproject: project nametags: array of tagsattendees: list (meetings)
Don't create filters on properties that don't exist in the vault.
Step 3: Build the Base YAML
# Global filter (applies to all views)
filter:
- property: <name>
operator: "<op>"
value: "<value>"
# Computed properties
formulas:
formula-name: '<expression>'
# View configurations
views:
- name: "View Name"
type: table # table, cards, list, map
properties:
- file.name
- property-name
sort:
- property: <name>
order: asc # or desc
filter: # view-specific filter (in addition to global)
- property: <name>
operator: "<op>"
value: "<value>"
Filter operators:
| Operator | Meaning |
|---|---|
== |
equals |
!= |
not equals |
> |
greater than |
< |
less than |
>= |
greater or equal |
<= |
less or equal |
Compound filters (AND/OR/NOT):
filter:
# AND (default — sequential conditions)
- property: type
operator: "=="
value: meeting
- property: status
operator: "=="
value: active
# OR (explicit)
- operator: OR
conditions:
- property: type
operator: "=="
value: meeting
- property: type
operator: "=="
value: project
# NOT
- operator: NOT
conditions:
- property: status
operator: "=="
value: archived
File metadata properties:
file.name — Note filename without extension
file.path — Full path from vault root
file.mtime — Last modified time
file.ctime — Creation time
file.size — File size in bytes
file.folder — Parent folder path
file.ext — File extension
Step 4: Add Formulas (if needed)
formulas:
# Days since creation
age: '(now() - this.created).days'
# Status badge
badge: 'if(this.status == "active", "🟢", if(this.status == "draft", "🟡", "⚪"))'
# Overdue check
overdue: 'if(this.date < today(), "⚠️ Overdue", "On track")'
# Tag count
tag-count: 'this.tags.length'
# Full name from path
display: 'this.file.name'
Useful formula functions:
- Date:
now(),today(),date("YYYY-MM-DD"),format(date, "MMM DD"),relative(date) - String:
contains(str, substr),replace(str, old, new),lower(str),trim(str) - Number:
abs(),ceil(),floor(),round() - List:
filter(),map(),join(),sort(),.length - File:
hasTag(tag),hasProperty(prop),inFolder(path),asLink() - Logic:
if(condition, then, else)
The this keyword refers to the current row's note.
Step 5: Configure View
Cards view (best for visual browsing):
views:
- name: "Active Projects"
type: cards
properties:
- file.name
- status
- tags
sort:
- property: file.name
order: asc
List view (best for simple lists):
views:
- name: "Quick List"
type: list
properties:
- file.name
sort:
- property: file.mtime
order: desc
Multiple views (same base, different perspectives):
views:
- name: "Table"
type: table
properties: [file.name, status, date]
sort: [{property: date, order: desc}]
- name: "Cards"
type: cards
properties: [file.name, status]
sort: [{property: status, order: asc}]
Summaries (aggregate values shown at column bottom):
views:
- name: "Project Budget"
type: table
properties:
- file.name
- budget
- spent
summaries:
budget: sum
spent: sum
Summary types: average, min, max, sum, range, median, count,
earliest, latest, checked, unchecked, empty, filled, unique
Step 6: Write and Verify
Write the YAML. Then verify by checking the YAML is valid:
python3 -c "import yaml; yaml.safe_load(open('$BASE_PATH'))" && echo "Valid YAML"
Confirm:
Base created: base-name.base
View: [table / cards / list]
Filter: [what's filtered]
Columns: [listed properties]
Sort: [sort order]
Open in Obsidian to see your data.
Output Format
## Base Created
**File:** base-name.base
**View:** [table / cards / list / map]
**Filter:** [description of filter logic]
**Columns:** [list of shown properties]
**Sort:** [property, direction]
**Formulas:** [any computed properties]
Open in Obsidian to interact with the view.
NEVER
- Create filters on properties that don't exist in the vault
- Write invalid YAML (always validate)
- Skip checking what properties exist first
- Use complex formulas without explaining what they compute
- Create a base without at least one view configured
- Assume property names — check CLAUDE.md or scan existing notes
ALWAYS
- Check what frontmatter properties exist in the vault first
- Validate the YAML output
- Include at least
file.namein every view's properties - Use descriptive view names
- Explain the filter logic in plain English
- Suggest additional views or formulas that might be useful
Example
User: "Make me a dashboard showing all active projects with their status and last modified date"
filter:
- property: type
operator: "=="
value: project
- property: status
operator: "!="
value: archived
formulas:
last-active: 'relative(this.file.mtime)'
views:
- name: "Active Projects"
type: table
properties:
- file.name
- status
- project
- tags
- last-active
sort:
- property: file.mtime
order: desc
- name: "Project Cards"
type: cards
properties:
- file.name
- status
- last-active
sort:
- property: status
order: asc
Base created: project-dashboard.base
View 1: "Active Projects" (table)
Filter: type == project AND status != archived
Columns: name, status, project, tags, last active (relative time)
Sort: last modified (newest first)
View 2: "Project Cards" (cards)
Same filter, card layout for visual browsing
Open in Obsidian to see your projects.
Recommended Agent Skills
Expand your agent's capabilities with these related and highly-rated skills.
agent-ops-spec
Manage specification documents in .agent/specs/. Use when user provides requirements, acceptance criteria, or feature descriptions that need to be tracked and validated against implementation.
agent-ops-state
Maintain .agent state files. Use at session start, after meaningful steps, and before concluding: read/update constitution/memory/focus/issues/baseline consistently.
agent-ops-spec
Manage specification documents in .agent/specs/. Use when user provides requirements, acceptance criteria, or feature descriptions that need to be tracked and validated against implementation.
agent-ops-testing
Test strategy, execution, and coverage analysis. Use when designing tests, running test suites, or analyzing test results beyond baseline checks.
agent-ops-testing
Test strategy, execution, and coverage analysis. Use when designing tests, running test suites, or analyzing test results beyond baseline checks.
agent-ops-state
Maintain .agent state files. Use at session start, after meaningful steps, and before concluding: read/update constitution/memory/focus/issues/baseline consistently.
Didn't find tool you were looking for?