Skip to main content

Schema enforcement and CRUD integrity layer for Obsidian vault folders

Project description

Sigil

Schema enforcement and CRUD integrity layer for Obsidian vault folders — built for agents.

License: MIT PyPI Python

Sigil


Sigil came to life when I saw the notification that the backend I was using for structured data was going to stop working. I realized that that old backend had never really worked decently at all. Half of the time it worked well, the rest of the time, all sorts of chaos happened. It annoyed me at every contact point, and ended up more of a nuisance than a help. Yet, it did fix an important point for me — I need structured data, where the agents working with it can't just forget about the structure and make a big inconsistent mess.

I am, like we all are, a big fan of Obsidian vaults, and on a friction level, those really work best for me. It's accessible, readable, and it has that exciting Bases view, that just looks like it'll do magic. Obsidian is spread over all my devices though, so the ample plugins weren't exactly an easy answer either.

And the answer is ultimately simple — I just need schema enforcement; an integrity layer for when the agents are writing to my Obsidian vault. (And if I make a mess, they can fix it too.) And I like building things 🙂 So I wrote a briefing, and half a day of agents running, we now have Sigil ready for all of us to escape the dread of having to use anything other than Obsidian. Point your agents here, and enjoy the structure! (And join us in dev and debugging, this is very much an alive project!)

Gert Schepens


$ sigil check projects/

✓ projects/ — 12 files checked

  ✗ acme-proposal.md
    · Status: missing (required)
    · Created: invalid format — expected ISO 8601, got "June 3"

  ✗ old-contact.md
    · Title: missing (required)

2 files with violations · 10 files clean

Install

pip install sigil-obsidian

Usage

sigil sources                        # see all known vaults and managed folders
sigil init projects/                 # declare a folder as Sigil-managed
sigil schema projects/               # show required fields before writing
sigil create projects/               # create a validated file
sigil check projects/                # audit all files, list violations
sigil check projects/ --fix          # auto-repair what Sigil can
sigil check projects/note.md         # validate a single file
sigil read projects/ --final         # list only records in a final/done state
sigil stats projects/                # counts and breakdowns by schema field
sigil base projects/                 # regenerate Obsidian .base (after moving folder)

How it works

Sigil is initialized per-folder. Each managed folder carries a sigil.schema.md file that defines the schema for every file in that folder. From there, all reads and writes go through Sigil.

Initialization

sigil init /path/to/vault/projects

Sigil walks you through schema selection (built-in templates or custom), writes sigil.schema.md, and generates an Obsidian Bases view (📖 overview.base) scoped to the schema. The folder is registered in ~/.sigil.config.

Built-in schema templates: task, contact, note, project.

Skip Obsidian-specific files with --no-obsidian.

Schema file: sigil.schema.md

Each managed folder has one schema file at <folder>/sigil.schema.md:

---
sigil: https://gitlab.com/DigitalGert/sigil
sigil_version: 1.3.0
sigil_install: pip install sigil-obsidian
sigil_skill: https://gitlab.com/DigitalGert/sigil/-/raw/main/skill.md
---

This folder is managed by Sigil ...

\```json
{
  "filename": "{Title}",
  "fields": {
    "Title":       { "required": true,  "type": "string",   "obsidian_property": true },
    "Status":      { "required": true,  "type": "enum",
                     "values": ["Open", "In Progress", "Done", "Cancelled"],
                     "finals": ["Done", "Cancelled"] },
    "Created":     { "required": false, "type": "datetime", "obsidian_property": true },
    "Description": { "required": false, "type": "text" }
  }
}
\```

Fields not listed in the schema are ignored. Fields marked obsidian_property: true are written as Obsidian frontmatter properties. Fields without it become ## FieldName sections in the note body — readable in Obsidian as normal content.

filename — template for filenames using {FieldName} tokens. Dates render as YYYY-MM-DD. Plain tokens are filesystem-sanitized (spaces and unicode preserved); {Field.slug} produces a lowercase-hyphenated slug. Example: "{Started}_{Title.slug}"2026-06-01_senior-pm-bnp.md. If field values are missing, the rename is skipped.

finals — enum values that represent a terminal state. Used by sigil read --final and shown as a separate count in sigil stats. Every value in finals must also appear in values.

Supported field types:

Type Description
string Single-line text
text Multiline text / body content
integer Whole number
float Decimal number
boolean true / false
date ISO 8601 date — YYYY-MM-DD
datetime ISO 8601 datetime — YYYY-MM-DDThh:mm:ss
enum Fixed set of values — requires a values array
url Valid URL
email Valid email address
list Array of strings
tags Obsidian-style tags — array
reference Obsidian [[wikilink]] to another note

Check

sigil check projects/            # audit folder
sigil check projects/ --fix      # auto-apply non-destructive fixes
sigil check projects/ --json     # machine-readable output
sigil check projects/note.md     # validate a single file

Reports every violation per file with a proposed fix. The --fix flag applies fixes that don't require user input — enum fuzzy corrections, file renames, body-field placement, and sigil_schema breadcrumbs. Violations requiring a value decision are always surfaced for human or agent input.

Version gate: Every sigil.schema.md records which Sigil version last wrote it (sigil_version). On check, Sigil compares installed vs recorded version and warns when the schema was written with a newer release. If network access is available, Sigil also checks PyPI for the latest published version.

Schema

sigil schema projects/
sigil schema projects/ --json

Shows exactly what data a file must contain to pass validation. Use this before create or update to know what to provide.

CRUD

sigil create projects/ --data '{"Title": "Acme Proposal", "Status": "New"}'
sigil read projects/
sigil read projects/ acme-proposal.md
sigil read projects/ --final            # only records in a final/done state
sigil update projects/ acme-proposal.md --data '{"Status": "Done"}'
sigil delete projects/ acme-proposal.md

create and update enforce the schema. Non-compliant input is rejected with clear, field-level error messages. read returns structured content; with --json it returns a clean array of file objects. When finals are defined, --json output includes _is_final: true/false per record.

Stats

sigil stats projects/
sigil stats projects/ --json

Counts and breakdowns derived from the schema and file contents — total files, files by Status value, files missing a required field, enum distributions with bar charts.

Sources

sigil sources
sigil sources --json

Lists all vaults and managed folders Sigil knows about, with schema name and file count. The agent's entry point for discovery in a new session.


Config

Global config lives at ~/.sigil.config (YAML). Created on first init.

Multiple vaults are supported, each with an optional human-readable name:

debug: false
log_path: ~/debug.log/
vaults:
  - path: /home/user/Documents/Obsidian/Personal
    name: Personal
  - path: /home/user/Documents/Obsidian/Work
    name: Work
managed_folders:
  - path: /home/user/Documents/Obsidian/Personal/projects
    schema: task
    vault: Personal
    initialized: 2026-06-17

Override the config location:

export SIGIL_CONFIG=/path/to/config    # environment variable
sigil --config /path/to/config ...     # per-command flag

When running as an agent skill, set SIGIL_CONFIG to a path inside the skills folder to keep config portable and isolated.

Enable debug logging (writes dated log files to log_path):

debug: true
log_path: ~/debug.log/

As an agent skill

Sigil is a general-purpose tool — it works from the terminal, in scripts, in CI, or as a skill loaded by any AI agent. It has no dependency on a specific agent platform.

Sigil ships with skill.md — a compact command reference that any agent can load as context. Tested with Claude Code and OpenClaw, and compatible with any tool that can read a Markdown skill file.

Install or update the skill file:

# Via sigil (recommended — keeps skill.md in sync with the installed version)
sigil install-skill

# Or to a custom skills directory
sigil install-skill ~/.openclaw/workspace/skills/

# Or manually
curl -o ~/.claude/skills/sigil.md \
  https://gitlab.com/DigitalGert/sigil/-/raw/main/skill.md

Output and exit codes

All commands support --json for clean, agent-parseable output.

Exit code Meaning
0 Clean — no violations
1 Violations found
2 Tool error

Contributing

This is a live project. Bug reports, schema template ideas, and pull requests are welcome.


License

MIT — see LICENSE.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

sigil_obsidian-1.3.5.tar.gz (35.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

sigil_obsidian-1.3.5-py3-none-any.whl (35.1 kB view details)

Uploaded Python 3

File details

Details for the file sigil_obsidian-1.3.5.tar.gz.

File metadata

  • Download URL: sigil_obsidian-1.3.5.tar.gz
  • Upload date:
  • Size: 35.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.2.0 CPython/3.12.13

File hashes

Hashes for sigil_obsidian-1.3.5.tar.gz
Algorithm Hash digest
SHA256 9c249225e6555b8ca71b30e420d686e73e322963812378c2771131eec47f3098
MD5 add29c9876db8b49dd8ffd9149ab04bf
BLAKE2b-256 a02ced97fc71747cce7f876ab3dda28279d865985b997bfb36e0ee70baf05816

See more details on using hashes here.

File details

Details for the file sigil_obsidian-1.3.5-py3-none-any.whl.

File metadata

  • Download URL: sigil_obsidian-1.3.5-py3-none-any.whl
  • Upload date:
  • Size: 35.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.2.0 CPython/3.12.13

File hashes

Hashes for sigil_obsidian-1.3.5-py3-none-any.whl
Algorithm Hash digest
SHA256 ac0426466f63b4bebc4ab2c90d143fa3a7570a0662fcd0a3e39efee121eaa896
MD5 3d3723ba1f2dcee77628227916526a3f
BLAKE2b-256 b787998f1d4c44c2650bfea0377ba81a9551a01cb020c5c63e4165fd8a3750e7

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page