| name | ari-obsidian-patterns |
| description | Obsidian vault integration patterns โ vault-analyzer.ts, /ari-vault-* commands, morning briefing snippet, PARA structure, read-only enforcement |
| triggers | ["obsidian","vault","vault-ideas","vault-trace","vault-connect","vault-gaps","daily notes","obsidian mcp","local rest api","ari-vault"] |
ARI Obsidian Integration Patterns
Core Principle
ARI reads, Pryce writes. The vault is Pryce's second brain, not ARI's workspace. Agent-generated content NEVER enters the vault โ preserving integrity so pattern analysis reflects Pryce's actual thinking, not ARI's output.
Architecture
Pryce writes โ Obsidian Vault (markdown + backlinks)
โ
Obsidian Local REST API Plugin (127.0.0.1:27123)
โ
Obsidian MCP Server (iansinnott or cyanheads daemon)
โ
ARI / DEX reads vault (read-only)
โ
Patterns โ Morning briefing, DEX digest, /vault-* commands
MCP Configuration
Interactive (Claude Code sessions)
iansinnott/obsidian-claude-code-mcp โ 70+ tools, auto-discovers vault
Install: Obsidian โ Community Plugins โ "Claude Code MCP" โ install
No .mcp.json entry needed โ registers automatically
Daemon (scheduled ARI tasks)
{
"obsidian-vault": {
"command": "npx",
"args": ["-y", "cyanheads/obsidian-mcp-server"],
"env": {
"OBSIDIAN_API_KEY": "<key-from-local-rest-api-plugin>",
"OBSIDIAN_BASE_URL": "http://127.0.0.1:27123"
}
}
}
Prerequisite: Local REST API Plugin
- Obsidian โ Community Plugins โ search "Local REST API" (by coddingtonbear)
- Install โ enable
- Settings โ copy API key
- Plugin runs at
http://127.0.0.1:27123
Key REST API Endpoints
GET /vault/{file-path} # Read any vault file
GET /daily-notes/{YYYY-MM-DD}/ # Read specific daily note
GET /search/simple/?query=term # Full-text search
GET /open/{file-path} # Get currently open note
POST /vault/{file-path} # Write (NOT USED by ARI โ read-only)
vault-analyzer.ts โ 5 Implementation Patterns
File location: src/ai/obsidian/vault-analyzer.ts
import { ObsidianClient } from './obsidian-client.js';
const obsidian = new ObsidianClient({
baseUrl: process.env.OBSIDIAN_BASE_URL ?? 'http://127.0.0.1:27123',
apiKey: process.env.OBSIDIAN_API_KEY ?? '',
});
export async function morningVaultDigest(): Promise<VaultDigest> {
const yesterday = await obsidian.getDaily(dateMinusDays(1));
if (!yesterday) return { themes: [], questions: [], relatedNotes: [] };
const themes = extractTopics(yesterday.content);
const questions = extractQuestions(yesterday.content);
const relatedNotes = await findBacklinks(themes);
return { themes, questions, relatedNotes };
}
export async function scan30DayIdeas(): Promise<IdeaCluster[]> {
const dailies = await loadDailyNotes(30);
const mentions = buildMentionFrequencyMap(dailies);
const clusters = detectCoOccurrence(mentions, dailies, { threshold: 3 });
return clusters
.filter(c => c.dayCount >= 3)
.sort((a, b) => b.strength - a.strength);
}
export async function traceIdeaEvolution(
topic: string,
): Promise<EvolutionTimeline> {
const mentions = await searchDailies(topic, 30);
return mentions
.sort((a, b) => new Date(a.date).getTime() - new Date(b.date).getTime())
.map(d => ({
date: d.date,
context: extractContext(d.content, topic),
linkedNotes: extractWikilinks(d.content),
sentiment: inferSentiment(d.content, topic),
}));
}
export async function connectDomains(
domain1: string,
domain2: string,
): Promise<BridgeReport> {
const [d1Notes, d2Notes] = await Promise.all([
searchByTag(domain1),
searchByTag(domain2),
]);
return {
domain1,
domain2,
sharedReferences: findSharedRefs(d1Notes, d2Notes),
bridgeCandidates: identifyBridges(d1Notes, d2Notes),
};
}
export async function findGaps(): Promise<VaultGaps> {
const allNotes = await listAllFiles();
const orphans = allNotes.filter(n => getBacklinks(n).total === 0);
const staleHubs = allNotes.filter(
n => getBacklinks(n).incoming > 5 && n.mtime < daysAgo(30),
);
const underTagged = allNotes.filter(n => !n.tags || n.tags.length === 0);
return { orphans, staleHubs, underTagged };
}
Slash Commands
| Command | Agent | What It Does |
|---|
/ari-vault-ideas | DEX | 30-day scan โ cross-domain patterns, orphan notes, emerging themes |
/ari-vault-trace [topic] | DEX | Trace how an idea evolved across all vault notes over time |
/ari-vault-connect [d1] [d2] | DEX | Bridge two knowledge neighborhoods |
/ari-vault-gaps | DEX | Orphan notes, dead-end links, underexplored areas |
Example Output: /ari-vault-ideas
๐ 30-DAY VAULT INTELLIGENCE โ 2026-02-25
๐ EMERGING PATTERNS (appeared 3+ days)
โข "PayThePryce merch" โ mentioned 7 days across 3 threads
Connected: [[Kai's college fund]], [[PayThePryce monetization]]
โข "morning routine" โ appeared in 5 daily notes
First seen: Feb 12 | Latest: Feb 23
๐ณ๏ธ ORPHAN NODES (no backlinks)
โข [[2025-12-15]] (daily note, never linked)
โข [[Indiana wholesalers]] (created Feb 3, no connections)
๐ก IDEA CANDIDATES
Based on co-occurrence patterns:
โ "Indiana B2B + Pokemon TCG" appear together 4 times
Possible idea: local card shop partnership for Pryceless?
Example Output: /ari-vault-trace "Pryceless pricing"
๐ IDEA EVOLUTION โ "Pryceless pricing" (30 days)
Feb 2: [[2026-02-02]] โ "maybe charge $500/mo flat for small biz sites?"
Links: [[revenue goals]], [[Pryceless]]
Feb 8: [[2026-02-08]] โ "talked to Eric about retainer model vs project"
Sentiment: questioning
Links: [[Eric Rodriguez]], [[Pryceless Solutions]]
Feb 14: [[2026-02-14]] โ "leaning toward $299 setup + $149/mo retainer"
Sentiment: decided
Links: [[Pryceless pricing model]]
โ Direction: flat rate โ retainer (12 days to decision)
โ Key influence: [[Eric Rodriguez]] conversation
Vault Structure (Recommended)
Pryce's vault (iCloud or local):
โโโ 000-PRYCE/
โ โโโ user-context.md # Mirror of USER.md (Pryce maintains)
โ โโโ goals.md # 30/90/365 goals in his own words
โ โโโ preferences.md # Communication preferences
โโโ 001-DAILY/ # YYYY-MM-DD.md files
โโโ 002-PROJECTS/
โ โโโ PayThePryce.md
โ โโโ Pryceless.md
โ โโโ ARI.md
โโโ 003-KNOWLEDGE/ # Research, learning, insights
โโโ 004-IDEAS/ # Raw ideas (not yet committed)
โโโ 005-PEOPLE/ # Notes on contacts
โโโ 006-REFERENCES/ # Saved articles, bookmarks
Backlinks are the superpower. [[PayThePryce merch idea]] in a daily note creates a traversable link ARI can follow across time.
Frontmatter Standard
---
title: Note Title
created: 2026-02-25T06:30:00Z
modified: 2026-02-25T10:15:00Z
tags: [paytheprice, strategy, pokemon-tcg]
type: daily|project|area|resource|archive
status: active|draft|archived
related: [[note1]], [[note2]]
---
Type categories (PARA):
project โ time-bound (PayThePryce video series, P2 Q1 targets)
area โ ongoing (Content, Business Dev, ARI)
resource โ reference (market data, tools, people notes)
archive โ completed/inactive
Morning Briefing Vault Section
When ARI_OBSIDIAN_ENABLED=true, ari-briefings includes:
๐ VAULT SNAPSHOT
Yesterday's themes: [[PayThePryce]], [[Kai's birthday]], [[Pryceless Q1]]
Open questions: "Should we do merch before 10K subs?"
Linked notes: [[monetization strategy]] (last edited Feb 18)
Data flow:
ari-briefings reads ~/.ari/workspace/OBSIDIAN-DAILY-DIGEST.md (DEX writes this)
- DEX runs
morningVaultDigest() daily at 05:00 ET via ari-scheduler
- DEX writes output to
~/.ari/workspace/OBSIDIAN-DAILY-DIGEST.md
- ARI includes it in 06:30 ET briefing
Auto-Generated Workspace Files (ARI writes, NOT vault)
~/.ari/workspace/OBSIDIAN-DAILY-DIGEST.md # Morning briefing vault section
~/.ari/workspace/OBSIDIAN-IDEAS-30DAY.md # Pattern detection results
~/.ari/workspace/OBSIDIAN-GAPS.md # Gap detection results
~/.ari/workspace/OBSIDIAN-TRACES/ # Per-topic evolution traces
โโโ {topic}-trace-{YYYY-MM-DD}.md
These files are in ~/.ari/workspace/ NOT in the Obsidian vault. ARI never writes to the vault.
Scheduler Integration
Environment Variables
ARI_OBSIDIAN_ENABLED # 'true' to enable vault integration
OBSIDIAN_API_KEY # From Local REST API plugin settings
OBSIDIAN_BASE_URL # Default: http://127.0.0.1:27123
ARI_OBSIDIAN_VAULT_PATH # Path to vault (for MCP filesystem access)