Obsidian Ontology Sync
by @parthpandya1729
Bidirectional sync between Obsidian PKM (human-friendly notes) and structured ontology (machine-queryable graph). Automatically extracts entities and relatio...
clawhub install obsidian-ontology-syncπ About This Skill
name: obsidian-ontology-sync description: Bidirectional sync between Obsidian PKM (human-friendly notes) and structured ontology (machine-queryable graph). Automatically extracts entities and relationships from markdown, maintains ontology graph, and provides feedback to improve note structure. Run sync every few hours via cron. metadata: { "tags": ["obsidian", "ontology", "knowledge-graph", "pkm", "automation"], "openclaw": { "requires": { "skills": ["obsidian", "ontology"] } } }
Obsidian-Ontology Sync
Philosophy: Obsidian is PRIMARY (human writes natural notes) β Ontology is DERIVED (machine extracts structure) β Feedback loop improves both
Core Concept
Obsidian Notes (Markdown)
β Extract (every 3 hours)
Ontology Graph (Structured)
β Query & Analyze
Insights & Suggestions
β Feedback
Improved Note Templates
When to Use
| Situation | Action | |-----------|--------| | After creating/updating contacts | Run sync to extract entities | | Before business queries | Sync then query ontology | | Weekly review | Sync + analyze + get suggestions | | New project setup | Extract entities + suggest structure | | Team status tracking | Sync daily-status β ontology β analytics |
What Gets Extracted
From Contact Notes (references/contacts/*.md)
Extracts:
Person entity (name, email, phone)works_at β Organizationmet_at β Eventassigned_to β Project (if mentioned)status β (prospect, warm_lead, client, etc.)Example:
# Alice JohnsonEmail: alice@company.com
Company: Acme Corp
Met At: Tech Conference 2026
Projects: Project Alpha
Notes
Great developer, responsive communication.
Becomes:
{
"entity": {
"id": "person_alice_johnson",
"type": "Person",
"properties": {
"name": "Alice Johnson",
"email": "alice@company.com",
"notes": "Great developer, responsive communication"
}
},
"relations": [
{"from": "person_alice_johnson", "rel": "works_at", "to": "org_acme"},
{"from": "person_alice_johnson", "rel": "met_at", "to": "event_tech_conference_2026"},
{"from": "person_alice_johnson", "rel": "assigned_to", "to": "project_alpha"}
]
}
From Client Notes (references/clients/*.md)
Extracts:
Organization entityhas_contract_value β numberprojects β Project entitiesprimary_contact β PersonFrom Team Notes (references/team/*.md)
Extracts:
Person entityworks_for β Organizationassigned_to β Project[]reports_to β Personresponse_pattern β (proactive, reactive, non-responsive)From Daily Status (daily-status/YYYY-MM-DD/*.md)
Extracts:
response_time property on Personstatus_update β Eventblockers β Issue entitiesbehavioral_pattern trackingFrom Project Notes (projects/*.md)
Extracts:
Project entityfor_client β Organizationteam β Person[]status, value, deadlineSync Process
1. Extract Phase (Markdown β Ontology)
# Run extraction
python3 skills/obsidian-ontology-sync/scripts/sync.py extractWhat it does:
1. Scan configured Obsidian directories
2. Parse markdown frontmatter + content
3. Extract entities (Person, Project, Organization, etc.)
4. Extract relationships (works_at, assigned_to, etc.)
5. Write to ontology using append-only operations
Detection Rules:
# Contact files
if file.startswith("references/contacts/"):
entity_type = "Person"
extract_email_from_content()
extract_company_from_property("Company:")
extract_projects_from_links([[Project]])
Client files
if file.startswith("references/clients/"):
entity_type = "Organization"
extract_contract_value()
extract_projects()
Team files
if file.startswith("references/team/"):
entity_type = "Person"
role = "team_member"
extract_assignments()
extract_response_patterns()
2. Analysis Phase (Ontology β Insights)
# Run analytics
python3 skills/obsidian-ontology-sync/scripts/sync.py analyzeGenerates insights like:
- "3 team members have no assigned projects"
- "Contact 'John Doe' missing email address"
- "Project 'X' has 5 people but no client linked"
- "10 contacts from AI Summit not linked to follow-up tasks"
3. Feedback Phase (Insights β Improve PKM)
# Get suggestions
python3 skills/obsidian-ontology-sync/scripts/sync.py feedbackCreates:
- Missing property suggestions
- Broken link reports
- Relationship suggestions
- Template improvements
Example Feedback:
# Sync Feedback - 2026-02-27Missing Information (10 items)
[ ] Alice Johnson missing phone number
[ ] Bob missing email in team file
[ ] Project Project Alpha missing deadline Suggested Links (5 items)
[ ] Link Jane Doe (TechHub) to organization TechHub
[ ] Link Eve to project (found in daily-status but not in team file) Relationship Insights
Project Alpha team: Alice, Carol, David (extracted from daily-status)
Suggest updating project file with team assignments Template Suggestions
Add Projects: [[]] field to contact template
Add Response Pattern: field to team template
Configuration
config.yaml
# /root/life/pkm/ontology-sync/config.yamlobsidian:
vault_path: /root/life/pkm
# What to sync
sources:
contacts:
path: references/contacts
entity_type: Person
extract:
- email_from_content
- company_from_property
- projects_from_links
clients:
path: references/clients
entity_type: Organization
extract:
- contract_value
- projects
- contacts
team:
path: references/team
entity_type: Person
role: team_member
extract:
- assignments
- response_patterns
- reports_to
daily_status:
path: daily-status
extract:
- response_times
- behavioral_patterns
- blockers
ontology:
storage_path: /root/life/pkm/memory/ontology
format: jsonl # or sqlite for scale
# Entity types to track
entities:
- Person
- Organization
- Project
- Event
- Task
# Relationships to extract
relationships:
- works_at
- assigned_to
- met_at
- for_client
- reports_to
- has_task
- blocks
feedback:
output_path: /root/life/pkm/ontology-sync/feedback
generate_reports: true
suggest_templates: true
highlight_missing: true
schedule:
# Run via cron every 3 hours
sync_interval: "0 */3 * * *"
analyze_daily: "0 9 * * *" # 9 AM daily
feedback_weekly: "0 10 * * MON" # Monday 10 AM
Scheduled Sync (Cron Integration)
Setup Automatic Sync
# Add to OpenClaw cron
python3 skills/obsidian-ontology-sync/scripts/setup-cron.pyOr manually via cron tool
cron add \
--schedule "0 */3 * * *" \
--task "python3 skills/obsidian-ontology-sync/scripts/sync.py extract" \
--label "Obsidian β Ontology Sync"
Cron Jobs Created:
1. Every 3 hours: Extract entities from Obsidian β Update ontology 2. Daily 9 AM: Run analytics and generate insights 3. Weekly Monday 10 AM: Generate feedback report + template suggestions
Queries (Using Ontology)
Once synced, you can query:
# All team members on high-value projects
python3 skills/ontology/scripts/ontology.py query \
--type Person \
--where '{"role":"team_member"}' \
--related assigned_to \
--filter '{"type":"Project","value__gt":400000}'Contacts from specific event not yet followed up
python3 skills/ontology/scripts/ontology.py query \
--type Person \
--where '{"met_at":"event_tech_conference_2026"}' \
--missing has_taskTeam response patterns
python3 skills/ontology/scripts/ontology.py query \
--type Person \
--where '{"role":"team_member"}' \
--aggregate response_patternProjects by client
python3 skills/ontology/scripts/ontology.py query \
--type Project \
--group-by for_client \
--count
Feedback Loop Examples
Example 1: Missing Email Detection
Ontology finds: Person entity with no email property
Feedback generated:
## Missing Contact InformationThe following team members are missing email addresses:
[ ] Bob (references/team/Bob.md)
[ ] Lucky (references/team/Lucky.md) Suggestion: Add email field to team member template:
\\\markdown
Email:
\\\
Example 2: Broken Project Links
Ontology finds: Person assigned_to Project that doesn't exist
Feedback generated:
## Broken Project ReferencesFound references to projects that don't have dedicated files:
[ ] "Project Epsilon" mentioned in team files but no projects/Project Epsilon.md
[ ] "Project Delta Tata DT" assigned but no project file Suggestion: Create project files with template
Example 3: Relationship Discovery
Ontology finds: Multiple people working at same company
Feedback generated:
## Suggested Company GroupingFound 3 contacts at "TechHub":
Jane Doe
[2 others from daily-status mentions] Suggestion: Create references/clients/TechHub.md and link contacts
Integration with Daily Workflow
Morning Routine (9 AM)
# Cron runs analysis
Generates daily-insights.md with:
Response rate from yesterday's status requests
Projects needing attention (blockers mentioned)
Contacts to follow up (met > 3 days ago, no task)
Weekly Review (Monday 10 AM)
# Cron generates weekly feedback
Creates suggestions for:
Missing information to fill in
Broken links to fix
New templates to adopt
Relationship insights
On-Demand Queries
# Before a meeting
"Show me all interactions with Client X"Resource planning
"Which team members are on <3 projects?"Sales pipeline
"Contacts met at conferences in last 30 days without follow-up"
Benefits
β For You
1. Zero Extra Work: Just keep writing normal Obsidian notes 2. Automatic Structure: Ontology extracted automatically 3. Powerful Queries: Find patterns across all your data 4. Quality Improvement: Feedback loop catches missing info 5. No Double Entry: Single source of truth (Obsidian)
β For Team Management
β For Sales/BD
β For Finance
File Structure After Sync
/root/life/pkm/
βββ references/
β βββ contacts/ # Source notes (you write these)
β βββ clients/ # Source notes
β βββ team/ # Source notes
βββ daily-status/ # Source notes
βββ projects/ # Source notes
β
βββ memory/ontology/ # Generated ontology
β βββ graph.jsonl # Entity/relation storage
β βββ schema.yaml # Type definitions
β
βββ ontology-sync/ # Sync outputs
βββ config.yaml # Your config
βββ feedback/
β βββ daily-insights.md
β βββ weekly-feedback.md
β βββ suggestions.md
βββ logs/
βββ sync-YYYY-MM-DD.log
Advanced: Bidirectional Sync
Future capability:
Update Obsidian notes FROM ontology insights:
# Automatically add missing fields
python3 skills/obsidian-ontology-sync/scripts/sync.py apply-feedbackWhat it does:
- Adds missing email field to contact notes
- Creates suggested project files
- Links related entities
- Updates frontmatter
Safety: Always creates backup before modifying files.
Comparison with Alternatives
| Approach | Pros | Cons | |----------|------|------| | Manual ontology | Full control | Too much work, falls behind | | Obsidian only | Simple | No structured queries | | Ontology only | Powerful queries | Not human-friendly | | This skill | Best of both | Initial setup needed |
Getting Started
1. Install Dependencies
# Already have ontology skill installed
clawhub install obsidian # If not already installed
2. Create Config
python3 skills/obsidian-ontology-sync/scripts/init.pyCreates:
- config.yaml with your vault path
- ontology directory structure
- cron jobs
3. Run First Sync
# Manual first sync to test
python3 skills/obsidian-ontology-sync/scripts/sync.py extract --dry-runSee what would be extracted
Review, then run for real:
python3 skills/obsidian-ontology-sync/scripts/sync.py extract
4. Enable Automatic Sync
python3 skills/obsidian-ontology-sync/scripts/setup-cron.pyConfirms cron jobs:
β Sync every 3 hours
β Daily analysis at 9 AM
β Weekly feedback Monday 10 AM
5. Query Your Data
# Try some queries
python3 skills/obsidian-ontology-sync/scripts/query.py "team members on high value projects"
Troubleshooting
Extraction Issues
# Dry run to see what would be extracted
python3 skills/obsidian-ontology-sync/scripts/sync.py extract --dry-run --verboseCheck specific file
python3 skills/obsidian-ontology-sync/scripts/debug.py \
--file references/contacts/Alice.md
Query Not Finding Data
# Check what's in ontology
python3 skills/ontology/scripts/ontology.py query --type PersonVerify sync ran
cat /root/life/pkm/ontology-sync/logs/sync-latest.log
Feedback Not Generated
# Manually run analysis
python3 skills/obsidian-ontology-sync/scripts/sync.py analyze
python3 skills/obsidian-ontology-sync/scripts/sync.py feedback
Version History
Author: Built for team management, contact tracking, and business intelligence at scale License: MIT Tags: obsidian, ontology, knowledge-graph, pkm, automation, sync
β‘ When to Use
π‘ Examples
1. Install Dependencies
# Already have ontology skill installed
clawhub install obsidian # If not already installed
2. Create Config
python3 skills/obsidian-ontology-sync/scripts/init.pyCreates:
- config.yaml with your vault path
- ontology directory structure
- cron jobs
3. Run First Sync
# Manual first sync to test
python3 skills/obsidian-ontology-sync/scripts/sync.py extract --dry-runSee what would be extracted
Review, then run for real:
python3 skills/obsidian-ontology-sync/scripts/sync.py extract
4. Enable Automatic Sync
python3 skills/obsidian-ontology-sync/scripts/setup-cron.pyConfirms cron jobs:
β Sync every 3 hours
β Daily analysis at 9 AM
β Weekly feedback Monday 10 AM
5. Query Your Data
# Try some queries
python3 skills/obsidian-ontology-sync/scripts/query.py "team members on high value projects"
βοΈ Configuration
config.yaml
# /root/life/pkm/ontology-sync/config.yamlobsidian:
vault_path: /root/life/pkm
# What to sync
sources:
contacts:
path: references/contacts
entity_type: Person
extract:
- email_from_content
- company_from_property
- projects_from_links
clients:
path: references/clients
entity_type: Organization
extract:
- contract_value
- projects
- contacts
team:
path: references/team
entity_type: Person
role: team_member
extract:
- assignments
- response_patterns
- reports_to
daily_status:
path: daily-status
extract:
- response_times
- behavioral_patterns
- blockers
ontology:
storage_path: /root/life/pkm/memory/ontology
format: jsonl # or sqlite for scale
# Entity types to track
entities:
- Person
- Organization
- Project
- Event
- Task
# Relationships to extract
relationships:
- works_at
- assigned_to
- met_at
- for_client
- reports_to
- has_task
- blocks
feedback:
output_path: /root/life/pkm/ontology-sync/feedback
generate_reports: true
suggest_templates: true
highlight_missing: true
schedule:
# Run via cron every 3 hours
sync_interval: "0 */3 * * *"
analyze_daily: "0 9 * * *" # 9 AM daily
feedback_weekly: "0 10 * * MON" # Monday 10 AM
π Tips & Best Practices
Great developer, responsive communication.
Becomes:
json
{
"entity": {
"id": "person_alice_johnson",
"type": "Person",
"properties": {
"name": "Alice Johnson",
"email": "alice@company.com",
"notes": "Great developer, responsive communication"
}
},
"relations": [
{"from": "person_alice_johnson", "rel": "works_at", "to": "org_acme"},
{"from": "person_alice_johnson", "rel": "met_at", "to": "event_tech_conference_2026"},
{"from": "person_alice_johnson", "rel": "assigned_to", "to": "project_alpha"}
]
}
``From Client Notes (
references/clients/*.md)Extracts:
Organization entity
has_contract_value β number
projects β Project entities
primary_contact β PersonFrom Team Notes (
references/team/*.md)Extracts:
Person entity
works_for β Organization
assigned_to β Project[]
reports_to β Person
response_pattern β (proactive, reactive, non-responsive)From Daily Status (
daily-status/YYYY-MM-DD/*.md)Extracts:
response_time property on Person
status_update β Event
blockers β Issue entities
behavioral_pattern trackingFrom Project Notes (
projects/*.md)Extracts:
Project entity
for_client β Organization
team β Person[]
status, value, deadline`