TAKESHI MORITA10k downloadsAI assistant with chat, workflow automation, and semantic search (RAG). Supports Gemini, OpenAI, Anthropic, OpenRouter, Grok, local LLMs, and CLI backends.
Free and open-source AI assistant for Obsidian with Chat, Workflow Automation, and Semantic Search (RAG). Supports multiple LLM providers — use whichever AI fits your needs.
Use any LLM provider: Gemini, OpenAI, Anthropic, OpenRouter, Grok, OpenCode Zen / Go, local LLMs (Ollama, LM Studio, vLLM, OpenCode), or CLI tools (Antigravity CLI, Claude Code, Codex CLI).
| Provider | Chat | Vault Tools | Web Search | Image Gen | RAG |
|---|---|---|---|---|---|
| Gemini (API) | ✅ Streaming | ✅ Function calling | ✅ Tavily / Brave Search | ✅ Gemini Image models | ✅ |
| OpenAI (API) | ✅ Streaming | ✅ Function calling | ✅ Native / Tavily / Brave Search | ✅ DALL-E | ✅ |
| Anthropic (API) | ✅ Streaming | ✅ Tool use | ✅ Native / Tavily / Brave Search | ❌ | ✅ |
| OpenRouter (API) | ✅ Streaming | ✅ Function calling | ✅ Tavily / Brave Search | ❌ | ✅ |
| Grok (API) | ✅ Streaming | ✅ Function calling | ✅ Native / Tavily / Brave Search | ❌ | ✅ |
| OpenCode Zen / Go (API) | ✅ Streaming | ✅ Function calling | ✅ Tavily / Brave Search | ❌ | ✅ |
| Local LLM (LM Studio, vLLM, AnythingLLM) | ✅ Streaming | ✅ Function calling (auto-fallback) | ❌ | ❌ | ✅ |
| Local LLM (Ollama, OpenCode) | ✅ Streaming | ❌ (marker mode) | ❌ | ❌ | ✅ |
| CLI (Antigravity, Claude, Codex) | ✅ Streaming | ❌ | ❌ | ❌ | ✅ |
Web search defaults to built-in search for supported official OpenAI, Anthropic, and Grok APIs. Select Tavily or Brave Search for external search, including compatible gateways. Gemini requires a configured external provider; otherwise Web search stays off. Enable Web search in the chat search menu to use it alongside RAG.
[!TIP] Multiple providers can be configured simultaneously. Switch models freely during chat — each provider has its own API key and settings.
[!TIP] CLI Options let you use flagship models with just an account - no API key needed!
- Antigravity CLI: Install Antigravity CLI, run
agyand authenticate- Claude CLI: Install Claude Code (
npm install -g @anthropic-ai/claude-code), runclaudeand authenticate- Codex CLI: Install Codex CLI (
npm install -g @openai/codex), runcodexand authenticate
note, note-read, etc., or {content} / {selection} variables). LM Studio / vLLM / AnythingLLM local LLMs DO support vault tools when the underlying model supports OpenAI-style function calling — incompatible models are auto-detected on first use and downgraded to marker-based skill mode.The AI Chat feature provides an interactive conversation interface with your chosen LLM provider, integrated with your Obsidian vault.

Opening Chat:
Chat Controls:
Read answers aloud — Turn on Read responses aloud in the Vault tool menu. While it is on, a chip above the input says so and its ✕ switches it off. Each assistant bubble also has a speaker button to read that answer on demand, or stop one mid-sentence. Reading speed is adjustable right under the switch, and in Settings → Chat (0.5x to 5x; how fast a voice actually goes varies by voice - Windows voices typically stop speeding up past about 4x). While reading is on, the system prompt asks the model for a short spoken answer instead of Markdown, headings, lists, code or URLs.
Send dictated text — Turn on Send dictated text automatically in Settings to submit when pasted or dictated text ends with the send phrase (send it in English, editable per language). It works with OS dictation, Aqua Voice and similar tools.
Voice conversation — Install speech-popup and a microphone button appears above the send button. It always just opens the popup, so a popup you closed is one click away. While a conversation runs:
⟦voice-chat⟧ (show --append), so the chat submits it as your message; an ordinary clipboard paste is left in the composer, and so is one that arrives while an answer is still being generated.I'm done speaking by default). speech-popup closes as it always does, the chat receives an empty turn and reads it as "I'm done", so nothing has to be clicked. Pressing Enter on an empty popup, the ✕ on the voice conversation chip, and opening another chat end it too.flatpak override --user --talk-name=org.freedesktop.Flatpak md.obsidian.Obsidian, then set the binary's full host path (for example /home/you/.local/bin/speech-popup) as the command above; the plugin sends its commands through flatpak-spawn --host. Snap has no equivalent portal - use the AppImage or the Flatpak.Watch the voice conversation demo on YouTube
In Settings → Web search, choose Built-in search (default), Tavily, or Brave Search. Existing Tavily/Brave selections are preserved; old empty settings default to built-in search. API keys are retained when switching and follow the credential storage preference. Built-in search uses the official OpenAI, Anthropic, or Grok API. Gemini never uses Google Search: without a selected external provider and its API key, the Web search toggle is disabled and shown as off. Chat, Workflow command nodes (ragSetting: __websearch__), Dashboard and Connect Hub use the same selection. External search uses the web_search function tool and never falls back to built-in search. Gemini image generation with external search first retrieves references using a text model (up to three searches), including its token usage in the total. Tavily uses basic search; both external providers return up to five results.
API references: Tavily, Brave Search.
Enable Web search in the search menu before sending a prompt. It can be combined with a RAG setting. The model decides when to call the tool. Source links are retained in chat history. External search fees are billed by Tavily or Brave Search and are separate from AI token-cost estimates.
Create reusable prompt templates triggered by /:
{selection} (selected text) and {content} (active note)/ to see available commandsDefault: /infographic - Converts content to HTML infographic

Reference files and variables by typing @:
{selection} - Selected text{content} - Active note content[[vault-relative/path]][!NOTE] How
{selection}and{content}work: When you switch from Markdown View to Chat View, the selection would normally be cleared due to focus change. To preserve your selection, the plugin captures it when switching views and highlights the selected area with a background color in the Markdown View. The{selection}option only appears in @ suggestions when text was selected.Both
{selection}and{content}are intentionally not expanded in the input area—since the chat input is compact, expanding long text would make typing difficult. The content is expanded when you send the message, which you can verify by checking your sent message in the chat.
[!NOTE] Selecting a file with
@inserts a visible wikilink. Sent chat messages retain the original references, including paths with spaces and multiple files. Only the model request adds type and byte size beside each tool-readable reference; file contents and reading instructions are not added to the displayed message. You can also type[[Note]],[[folder/Note.md]], or@folder/Note.md(full vault-relative path). On send, references are resolved to exact paths, with file type and byte size taken from vault metadata without reading the body. With Vault tools enabled, the model is instructed to fetch contents usingread_note; this requires tool calling support. Avoiding automatic full-file expansion prevents large files from consuming excessive tokens and keeps chat history readable instead of filling messages with long file contents. The model can read text by line range (startLine/endLine) or PDFs by page range (startPage/endPage). When Vault tools are disabled or a CLI mode restricts vault tools, the text is included directly instead. Explicit references outside the allowed vault tool folders are also inlined. References do not appear as attachment chips. Use the attachment button to supply content directly regardless of Vault tool settings.
read_note accepts inclusive, 1-based startLine / endLine ranges for text files, for example {"fileName":"Notes/Large Note.md","startLine":100,"endLine":150}. Results include the selected range and total line count so the model can request additional lines as needed. Omitting startLine starts at line 1; omitting endLine reads to the end. Omitting both preserves full-text reads subject to the configured note character limit. PDFs use startPage / endPage; line and page ranges cannot be combined.
Attach files directly: Images (PNG, JPEG, GIF, WebP), PDFs, Text files
The AI can interact with your vault using these tools:
| Tool | Description |
|---|---|
read_note |
Read note content |
create_note |
Create new notes |
propose_edit |
Edit with confirmation dialog |
propose_delete |
Delete with confirmation dialog |
bulk_propose_edit |
Bulk edit multiple files with selection dialog |
bulk_propose_delete |
Bulk delete multiple files with selection dialog |
search_notes |
Search vault by name or content |
list_notes |
List notes in folder |
rename_note |
Rename/move notes |
create_folder |
Create new folders |
list_folders |
List folders in vault |
get_active_note_info |
Get info about active note |
bulk_propose_rename |
Bulk rename multiple files with selection dialog |
When the AI handles notes in Chat, it uses Vault tools. Control which vault tools the AI can use via the Database icon (📦) below the attachment button:
| Mode | Description | Tools Available |
|---|---|---|
| Vault: All | Full vault access | All tools |
| Vault: No search | Exclude search tools | All except search_notes, list_notes |
| Vault: Read only | Search and read without file changes | read_note, read_timeline, search_notes, list_notes, list_folders, get_active_note_info |
| Vault: Off | No vault access | None |
The same Database icon menu also has Previous messages (0-99). This controls how many messages before the current prompt are sent to the model as conversation context. Set it to 0 to send only the current prompt, such as when processing unrelated files one at a time. The value is saved for the workspace.
When to use each mode:
Automatic mode selection:
| Condition | Default Mode | Changeable |
|---|---|---|
| CLI models (Antigravity/Claude/Codex CLI) | Vault: Off | No |
| Local LLM | Vault: Off | No |
| Gemma 4 + RAG/Web Search | Vault: Off | Yes (disabling RAG/Web Search re-enables tools) |
| Normal | Vault: All | Yes |
Why some modes are forced:
LLM vault tool folders:
In Settings → Workspace → LLM vault tool folders, you can limit which vault folders LLM-driven vault tools may access. This applies to API providers and tools-capable Local LLMs, including LLM-triggered skill workflows. Leave the list empty to allow the whole vault. CLI models are not restricted by this setting because they do not use these vault tools.
When AI uses propose_edit:
Changes are NOT written until you confirm.
Track and restore changes made to your notes:
Automatic tracking - All AI edits (chat, workflow) and manual changes are recorded
File menu access - Right-click on a markdown file to access:
Command palette - Also available via "Show edit history" command
Diff view - See exactly what changed with color-coded additions/deletions
Restore - Revert to any previous version with one click
Copy - Save a historical version as a new file (default name: {filename}_{datetime}.md)
Resizable modal - Drag to move, resize from corners
Diff display:
+ lines existed in the older version- lines were added in the newer versionHow it works:
Edit history uses a snapshot-based approach:
When history is recorded:
propose_edit tool)note node)Storage: Edit history is stored in memory and cleared on Obsidian restart. Obsidian's built-in file recovery covers persistent version tracking.

MCP (Model Context Protocol) servers provide additional tools that extend the AI's capabilities beyond vault operations.
Two transport modes are supported:
HTTP (Streamable HTTP):
Stdio (Local process):
npx -y @modelcontextprotocol/server-filesystem /path/to/dir)You can paste a full command line into Command; inline arguments are prepended to the Arguments field. Quote paths or arguments containing spaces, for example "C:\Program Files\nodejs\node.exe" "C:\my app\server.js". Backslashes in Windows paths are preserved. During Test connection, editing and saving are disabled. Failed checks keep the dialog open with the launch or connection error; timeout errors include recent stderr output. Failed handshakes stop the child process.
Note: Stdio transport launches a local process and is desktop-only. Test connection is required before saving.

Using MCP tools:
mcp node to call MCP server tools.Tool approval: By default, each call shows the server name, tool name, and arguments. Choose Allow once, Always allow this tool, or Deny; closing the dialog denies the call. In each server’s settings, enable Always approve to skip all confirmations, or remove a tool from the allowed list and save to require approval again. Unsaved servers only support one-time approval.
Workflow mcp and command nodes can set confirm: "false" to skip MCP approval for that node, including automatic execution. The node editor exposes this as Confirm MCP tool calls. Later interactive calls from MCP Apps still follow server approval settings. For command nodes, vaultTools: "readOnly" limits built-in Vault tools to search and reading; it does not control external MCP permissions.
Tool hints: After successful connection test, available tool names are saved and displayed in both settings and chat UI for easy reference.
Some MCP tools return interactive UI that allows you to interact with the tool results visually. This feature is based on the MCP Apps specification.
How it works:
ui:// resource URI in its response metadata, the plugin fetches and renders the HTML contentsandbox="allow-scripts allow-forms")In Chat:
In Workflows:
Security: All MCP App content runs in a sandboxed iframe with restricted permissions. The iframe cannot access the parent page's DOM, cookies, or local storage. Only
allow-scriptsandallow-formsare enabled.
Extend the AI with custom instructions, reference materials, and executable workflows. Skills follow the industry-standard agent skills pattern (e.g., OpenAI Codex .codex/skills/).
SKILL.md filesreferences/.sh, .py, .js, .ts, .rb) as function calling tools (desktop only)/folder-name to instantly invoke a skill and sendCreate skills the same way as workflows — select + New (AI), check "Create as agent skill", and describe what you want. The AI generates both the SKILL.md instructions and the workflow.
For setup instructions and examples, see Agent Skills
Connect your Obsidian vault's LLM to Discord as a chat bot. Users can chat with the AI, switch models, use RAG search, and activate slash commands — all from Discord.
| Setting | Description | Default |
|---|---|---|
| Enabled | Toggle Discord bot on/off | Off |
| Bot Token | Discord bot token from Developer Portal | — |
| Respond to DMs | Whether the bot responds to direct messages | On |
| Require @mention | In server channels, only respond when @mentioned (DMs always respond) | On |
| Allowed Channel IDs | Comma-separated channel IDs to restrict (empty = all channels) | empty |
| Allowed User IDs | Comma-separated user IDs to restrict (empty = all users) | empty |
| Model Override | Specify which model to use for Discord (empty = current selected model) | empty |
| System Prompt Override | Custom system prompt for Discord conversations | empty |
| Max Response Length | Maximum characters per message (1–2000, Discord's limit) | 2000 |
[!TIP] Finding Channel/User IDs: In Discord, enable Developer Mode (Settings → Advanced → Developer Mode). Then right-click a channel or user and select Copy ID.
Users can interact with the bot using these commands in Discord:
| Command | Description |
|---|---|
!model |
List available models |
!model <name> |
Switch to a specific model for this channel |
!rag |
List available RAG settings |
!rag <name> |
Switch to a specific RAG setting for this channel |
!rag off |
Disable RAG for this channel |
!skill |
List available slash commands |
!skill <name> |
Activate a slash command (may require follow-up message) |
!research <query> |
Run Gemini Deep Research (background, may take several minutes) |
!discuss <theme> |
Start AI Discussion with configured participants (background) |
!reset |
Clear conversation history for this channel |
!help |
Show help message |
!rag command!skill!research command. Runs in the background so you can continue chatting while it works. Results are posted to the channel when complete (requires Gemini API key)[!NOTE] Conversation history is kept in memory only and is cleared when the bot disconnects or Obsidian restarts.
Build automated multi-step workflows directly in Markdown files. No programming knowledge required - just describe what you want in natural language, and the AI will create the workflow for you.

You don't need to learn YAML syntax or node types. Simply describe your workflow in plain language:

Modify existing workflows the same way:
25 node types are available for building workflows:
| Category | Nodes |
|---|---|
| Variables | variable, set |
| Control | if, while |
| LLM | command |
| Data | http, json, script, shell |
| Notes | note, note-read, note-search, note-list, folder-list, open |
| Files | file-explorer, file-save |
| Prompts | prompt-file, prompt-selection, dialog |
| Composition | workflow |
| External | mcp, obsidian-command |
| RAG | rag-sync |
| Utility | sleep |
For detailed node specifications and examples, see Workflow Nodes
Assign keyboard shortcuts to run workflows instantly:
Ctrl+Shift+T)When triggered by hotkey:
prompt-file uses the active file automatically (no dialog)prompt-selection uses the current selection, or full file content if no selectionWorkflows can be automatically triggered by Obsidian events:

| Event | Description |
|---|---|
| Startup | Triggered once when the Obsidian workspace is ready |
| File Created | Triggered when a new file is created |
| File Modified | Triggered when a file is saved (debounced 5s) |
| File Deleted | Triggered when a file is deleted |
| File Renamed | Triggered when a file is renamed |
| File Opened | Triggered when a file is opened |
Event trigger setup:
File pattern examples:
**/*.md - All Markdown files in any folderjournal/*.md - Markdown files in journal folder only*.md - Markdown files in root folder only**/{daily,weekly}/*.md - Files in daily or weekly foldersprojects/[a-z]*.md - Files starting with lowercase letterEvent variables: When triggered by an event, these variables are set automatically:
| Variable | Description |
|---|---|
_eventType |
Event type: startup, create, modify, delete, rename, file-open |
_eventFilePath |
Path of the affected file |
_eventFile |
JSON with file info (path, basename, name, extension) |
_eventFileContent |
File content (for create/modify/file-open events) |
_eventOldPath |
Previous path (for rename events only) |
Note:
prompt-fileandprompt-selectionnodes automatically use the event file when triggered by events.prompt-selectionuses the entire file content as the selection.
Startup triggers have no event file, and their optional file pattern is ignored.
Use a rag-sync node with a Startup event trigger to refresh a Local RAG index automatically whenever the Obsidian workspace becomes ready. The node performs a full incremental sync using the target folders, exclusion patterns, and embedding configuration from the selected RAG setting.
rag-sync node and select the RAG setting to sync.


Discord integration has been separated from LLM Hub into the LLM Connect Hub Obsidian plugin. LLM Connect Hub connects to Discord and Kakeratta, using the models, RAG, skills, and Vault tools exposed by LLM Hub. Enable both plugins.
On first connection, LLM Connect Hub copies any legacy Discord and Kakeratta settings and credentials, saves them, then stops the old connections. Review the migrated values in LLM Connect Hub settings.
For Kakeratta, each persona ID can select an answer model, Vault folders to read, a RAG setting, and folder skills. Vault tools are limited to the selected folders and disabled when the list is empty. Scoped Vault research requires an API model. RAG searches the selected index independently of the Vault folder list. Skill scripts and workflows are disabled for Kakeratta. See the LLM Connect Hub setup guide.
Dashboard functionality is provided by the separate Dashboard Hub plugin. When both plugins are enabled, LLM Hub supplies Dashboard Hub with its configured AI models, Chat handoff, Base generation, text rewriting, and Workflow generation/execution. Dashboard Hub also contributes its dashboard Agent Skill to LLM Hub at runtime.
See the Dashboard Hub documentation for dashboard features, widgets, storage, and schema details.
AI Discussion is provided by the separate Discussion Hub plugin. When both plugins are enabled, LLM Hub supplies Discussion Hub with its configured API, CLI, and local text models. Models contributed by Gemini Helper and Local LLM Hub can participate in the same discussion.
See the Discussion Hub documentation for discussion features, configuration, and usage details.
| Model | Description |
|---|---|
| Gemini 3.1 Pro Preview | Latest flagship model, 1M context (recommended) |
| Gemini 3.1 Pro Preview (Custom Tools) | Optimized for agentic workflows with custom tools and bash |
| Gemini 3.8 Flash | Latest fast model, 1M context (recommended) |
| Gemini 3.5 Flash Lite | Latest fast, low-cost model with 1M context |
| Gemini 3 Pro (Image) | Pro image generation, 4K |
| Gemini 3.1 Flash (Image) | Fast, low-cost image generation |
| Gemma 4 | Free, function calling and RAG/Web Search are mutually exclusive |
Thinking mode: For supported OpenAI and Gemini API models, choose the reasoning effort beside the model picker.
defaultleaves the choice to the provider, whilenoneis available when the model can disable reasoning. Gemini models that cannot fully disable thinking expose their lowest supported effort instead. Prompts no longer change the effort automatically.
| Model | Description |
|---|---|
| GPT-6 Astra | Most capable model for complex end-to-end work |
| GPT-5.6 Sol | Highest-quality GPT-5.6 tier; web search live-tested |
| GPT-5.6 Terra | Balanced GPT-5.6 tier |
| GPT-5.6 Luna | Fast, economical GPT-5.6 tier |
| GPT-5.4 | Earlier flagship model |
| GPT-5.4-mini | Cost-effective mid-tier model |
| GPT-5.4-nano | Lightweight, fast model |
| O3 | Reasoning model |
| DALL-E 3 / DALL-E 2 | Image generation |
| Model | Description |
|---|---|
| Claude Opus 5 | Complex agentic coding and enterprise work; adaptive thinking |
| Claude Opus 4.8 | Advanced reasoning and agentic work; web search live-tested |
| Claude Sonnet 5 | Balanced frontier model; web search live-tested |
| Claude Fable 5 | Advanced model; web search live-tested |
| Claude Opus 4.6 | Most capable model, extended thinking |
| Claude Sonnet 4.6 | Balanced performance and cost |
| Claude Haiku 4.5 | Fast, lightweight model; web search live-tested |
Configure any OpenAI-compatible endpoint with custom base URL and models. OpenRouter provides access to hundreds of models from various providers.
OpenCode offers two hosted gateways from the same account, both selectable from the provider dropdown:
https://opencode.ai/zen) — pay-per-use, includes several free models (Big Pickle, MiniMax M2.5 Free, etc.) and a broad model catalog (Claude, GPT-5.x, and more). Exposes OpenAI-compatible /v1/models + /v1/chat/completions, so models are listed automatically.https://opencode.ai/zen/go) — $5/first month, $10/month subscription with curated coding models (Grok, GLM, Kimi, DeepSeek, MiMo, MiniMax, Qwen, and more). The plugin fetches its live /v1/models catalog during Verify, so newly added and retired models are reflected automatically.Connect to locally running models via Ollama, LM Studio, vLLM, AnythingLLM, or the OpenCode local server. Models are auto-detected from the running server.
main.js, manifest.json, styles.css from releasesllm-hub folder in .obsidian/plugins/git clone https://github.com/takeshy/obsidian-llm-hub
cd obsidian-llm-hub
npm install
npm run build
Add one or more API providers in plugin settings. Each provider has its own API key and model selection.
| Provider | Get API Key |
|---|---|
| Gemini | ai.google.dev |
| OpenAI | platform.openai.com |
| Anthropic | console.anthropic.com |
| OpenRouter | openrouter.ai |
| Grok | console.x.ai |
| OpenCode Zen | opencode.ai |
| OpenCode Go | opencode.ai |
You can also add custom OpenAI-compatible endpoints.

Route all API requests through an HTTP CONNECT proxy for corporate gateway environments. See Proxy Settings for details.
Connect to locally running LLM servers:
[!NOTE] LM Studio / vLLM / AnythingLLM local LLMs use OpenAI-style function calling for vault tools — enabled by default for tools-capable models. If a model rejects the first tools request it is auto-flagged and downgraded to marker-based skill mode for subsequent turns; clear the flag in Settings → Local LLM → Re-enable tools to retry.
These tools follow Settings → Workspace → LLM vault tool folders, the same folder limit used for API providers and LLM-triggered skill workflows.
Ollama and OpenCode (Local) still use marker mode only. Use workflows or RAG for note operations with those frameworks.
The OpenCode framework connects to a local opencode serve instance, which exposes its own HTTP API instead of the OpenAI-compatible /v1/chat/completions shape. Streaming uses the server's /global/event SSE endpoint.
curl -fsSL https://opencode.ai/install | bash
opencode serve
It listens on http://localhost:4096 by default.http://localhost:4096), and click Fetch models.<providerID>/<modelID> (e.g. google/gemini-flash-lite-latest). Pick one and save.OpenCode recommends WSL on Windows for file-system performance and tool compatibility. Since Obsidian runs on the Windows host, the server must be bound to a reachable interface and — because it becomes accessible from outside WSL — protected with a password.
Install WSL (Microsoft's official guide) and open a WSL terminal.
Inside WSL, install OpenCode:
curl -fsSL https://opencode.ai/install | bash
Start the server bound to all interfaces, with a password:
OPENCODE_SERVER_PASSWORD='your-password' opencode serve --hostname 0.0.0.0 --port 4096
WSL2 forwards localhost to the Windows host automatically, so from Obsidian the URL is http://localhost:4096. If that doesn't resolve, run hostname -I in WSL and use http://<wsl-ip>:4096 instead.
In plugin settings → Local LLM → OpenCode (Local):
http://localhost:4096 (or the WSL IP)opencode (default; override with OPENCODE_SERVER_USERNAME if you set one)OPENCODE_SERVER_PASSWORDClick Fetch models, pick a <providerID>/<modelID> model, and save.
Antigravity CLI:
agyClaude CLI:
npm install -g @anthropic-ai/claude-codeclaudeCodex CLI:
npm install -g @openai/codexcodexCLI Limitations: No vault tool support, no web search, desktop only
TTY terminal: Run “LLM Hub: Open CLI terminal” from the command palette to open an in-Obsidian CLI terminal view. In desktop environments where node-pty and @xterm/xterm are available, the view starts a full TTY session for Antigravity / Claude / Codex with the vault root as the working directory.
[!NOTE] CLI-only usage: You can use CLI mode without any API key. Just install and verify a CLI tool.
Custom CLI Path: If automatic CLI detection fails, click the gear icon (⚙️) next to the Verify button to manually specify the CLI path. The plugin searches common installation paths automatically, including version managers (nodenv, nvm, volta, fnm, asdf, mise).
Leave the CLI path empty and click Verify — the plugin looks for agy on PATH. Claude's standalone installer at %LOCALAPPDATA%\Programs\claude\claude.exe is also picked up automatically.
Only set a custom CLI path if auto-detection fails. Any of the following works, listed from safest to most permissive:
.exe executable — e.g. C:\Users\YourName\AppData\Local\Programs\Antigravity\agy.exe. Runs directly..cmd / .bat wrapper — e.g. an agy.cmd wrapper on PATH. Must go through cmd.exe, so prompts containing &, |, >, ^, or %VAR% may misbehave.Use Get-Command agy / Get-Command claude / Get-Command codex in PowerShell to find the wrapper path; then either enter it directly or navigate to the sibling .exe when available.
which agy
/home/user/.local/bin/agy) in the CLI path settingsFor Claude CLI, use which claude. For Codex CLI, use which codex.
If detection fails, specify the CLI executable path directly (e.g., ~/.local/bin/agy).
[!TIP] Claude CLI tip: Chat sessions from LLM Hub are stored locally. You can continue conversations outside of Obsidian by running
claude --resumein your vault directory to see and resume past sessions.
0 is unlimited
YYYYMMDD-HHmmss_Chat title.md and omit frontmatter and restoration metadataPassword-protect your chat history and workflow execution logs separately.
Setup:


Each setting can be enabled/disabled independently.
Features:
How it works:
[Setup - once when setting password]
Password → Generate key pair (RSA) → Encrypt private key → Store in settings
[Encryption - for each file]
File content → Encrypt with new AES key → Encrypt AES key with public key
→ Save to file: encrypted data + encrypted private key (from settings) + salt
[Decryption]
Password + salt → Restore private key → Decrypt AES key → Decrypt file content
#!/usr/bin/env python3
"""Decrypt LLM Hub encrypted files without the plugin."""
import base64, sys, re, getpass
from cryptography.hazmat.primitives import hashes, serialization
from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC
from cryptography.hazmat.primitives.ciphers.aead import AESGCM
from cryptography.hazmat.primitives.asymmetric import padding
def decrypt_file(filepath: str, password: str) -> str:
with open(filepath, 'r') as f:
content = f.read()
# Parse YAML frontmatter
match = re.match(r'^---\n([\s\S]*?)\n---\n([\s\S]*)$', content)
if not match:
raise ValueError("Invalid encrypted file format")
frontmatter, encrypted_data = match.groups()
key_match = re.search(r'key:\s*(.+)', frontmatter)
salt_match = re.search(r'salt:\s*(.+)', frontmatter)
if not key_match or not salt_match:
raise ValueError("Missing key or salt in frontmatter")
enc_private_key = base64.b64decode(key_match.group(1).strip())
salt = base64.b64decode(salt_match.group(1).strip())
data = base64.b64decode(encrypted_data.strip())
# Derive key from password
kdf = PBKDF2HMAC(algorithm=hashes.SHA256(), length=32, salt=salt, iterations=100000)
derived_key = kdf.derive(password.encode())
# Decrypt private key
iv, enc_priv = enc_private_key[:12], enc_private_key[12:]
private_key_pem = AESGCM(derived_key).decrypt(iv, enc_priv, None)
private_key = serialization.load_der_private_key(base64.b64decode(private_key_pem), None)
# Parse encrypted data: key_length(2) + enc_aes_key + iv(12) + enc_content
key_len = (data[0] << 8) | data[1]
enc_aes_key = data[2:2+key_len]
content_iv = data[2+key_len:2+key_len+12]
enc_content = data[2+key_len+12:]
# Decrypt AES key with RSA private key
aes_key = private_key.decrypt(enc_aes_key, padding.OAEP(
mgf=padding.MGF1(algorithm=hashes.SHA256()), algorithm=hashes.SHA256(), label=None))
# Decrypt content
return AESGCM(aes_key).decrypt(content_iv, enc_content, None).decode('utf-8')
if __name__ == "__main__":
if len(sys.argv) != 2:
print(f"Usage: {sys.argv[0]} <encrypted_file>")
sys.exit(1)
password = getpass.getpass("Password: ")
print(decrypt_file(sys.argv[1], password))
Requires: pip install cryptography
Warning: If you forget your password, encrypted files cannot be recovered. Keep your password safe.
Tip: To encrypt all files in a directory at once, use a workflow. See the "Encrypt all files in a directory" example in Workflow Nodes.

Security benefits:
read_note tool). This keeps sensitive data like API keys safe from accidental exposure during chat.note-read node. When accessed, a password dialog appears, and the password is cached for the session.Local vector-based search that injects relevant vault content into LLM conversations. No external RAG server required — embeddings are generated and stored locally.
Setup:
+)| Setting | Description | Default |
|---|---|---|
| Embedding Base URL | Custom embedding server URL (empty = Gemini API) | empty |
| Embedding API Key | API key for custom server (empty = Gemini key) | empty |
| Embedding Model | Model name for embedding generation | gemini-embedding-2-preview |
| Chunk Size | Characters per chunk | 500 |
| Chunk Overlap | Overlap between chunks | 100 |
| PDF Chunk Pages | Number of PDF pages per embedding chunk (1–6) | 6 |
| Top K | Max chunks to retrieve per query | 5 |
| Score Threshold | Minimum similarity score (0.0–1.0) to include in results | 0.5 |
| Target Folders | Limit indexing to specific folders (empty = all) | empty |
| Exclude Patterns | Regex patterns to exclude files from indexing | empty |
Multimodal indexing (images, PDFs, audio, video) is automatically enabled when using Gemini native embedding models (
gemini-embedding-*). No manual configuration needed.
Large vaults and multiple indexes:
For large vaults, create multiple RAG settings for separate folders, sync each one, then create another RAG setting and choose Combine internal. Select the synced source settings to search them together from one chat/search selector. Combined settings use the embedding server, API key, and model from the first selected source setting.
During sync, changed files are processed and saved in small file batches. This is separate from the RAG chunk size setting. If Obsidian crashes during a large first-time sync, the next sync can continue from the saved index state instead of starting from scratch.
If PDF text extraction fails, the failed PDF paths are listed after sync, their checksums are saved, and they appear in the indexed file list with 0 chunks. They will not be retried on later syncs unless the PDF file changes. To force re-import, rename the PDF, modify the file, or clear/rebuild the RAG index.
External Index:
Use a pre-built index instead of syncing from the vault:
index.json and vectors.binHow it works: When RAG is active, each chat message triggers a local vector search. Relevant chunks are injected into the system prompt as context. Sources are shown in the chat UI — click to open the referenced note.
Vector search returns semantically similar chunks, so its results can include text that shares related wording without actually matching the question. Configure shared credentials under Jev in Settings, then toggle Keep only matching RAG results separately for each RAG setting. For example, enable it for notes and disable it for PDFs. Jev filtering also applies when that RAG index is used from Chat, Workflows, or Discord. For a combined index, its own toggle applies to the combined results.
New RAG settings default to ON; existing settings retain the previous global ON/OFF value when upgrading. Filtering is inactive until Jev credentials are configured. In RAG Search, Top K is the number of candidates checked per round. With Jev active, enable Search until an answer is found to check Top K batches in similarity order until matching results are found or no candidates meet the score threshold. All matches from the first successful batch are returned. Leave it off to check Top K candidates once. Repeated checks can increase API usage and search time.
In Chat, select a RAG index and set RAG Top K next to the search selector. Chat uses this many candidate chunks per rag_search call, before Jev filtering, with at most three calls per turn. With Jev active, Search until an answer is found appears beside Top K. Both values are saved per RAG setting, remembered after restarting, and shared with RAG Search, Workflows, and Discord. Workflow command nodes also offer this checkbox when the selected index has Jev active; a node can override the saved preference with ragSearchUntilFound: true or false. Omit this property to follow the index preference.
You can also toggle Filter with Jev in the settings card opened with the settings icon in RAG Search. This saves the selected index's setting and applies from the next search.
For PDFs indexed with Gemini's native embeddings, Jev uses text extracted from the matched pages. If no text can be extracted, the matched pages are rendered as images for Jev to judge, including scanned PDFs without a text layer. This works with both OpenRouter and a direct Jev key. Each scanned chunk uses a separate image request. Results are retained without filtering if rendering fails or exceeds the limits (16 pages or 12 MiB of base64 image data per chunk).
Jev can be configured in either of these ways:
https://api.typesafe.ai/v1/systemone, as documented in the official API reference.
Without Jev, all five results from vector similarity search are displayed for this query.

With Jev enabled, only the two results judged to match the query remain.

The RAG Search tab provides a dedicated interface for searching, filtering, editing, and sending RAG results to Chat or Discussion.

For full details, see RAG Search Documentation
/
Data stored locally:
Data sent to LLM providers:
Data sent to third-party services:
http nodes can send data to any URL specified in the workflowCLI providers (optional):
Discord bot (optional):
MCP servers (optional):
mcp nodesSecurity notes:
http nodes can transmit vault data to external endpointsnote nodes show a confirmation dialog before writing files (default behavior)confirmEdits: false will auto-apply file edits without showing Apply/Discard buttonshttp headers, mcp settings, etc.). Instead, store them in encrypted files and use note-read node to retrieve them at runtime. Workflows can read encrypted files with password prompt.See each provider's terms of service for data retention policies.
MIT
If you find this plugin useful, consider buying me a coffee!
Web search usage: the selected external provider has a usage row in Settings → Web search. Tavily fetches plan, API-key and pay-as-you-go credits only when Show remaining credits is clicked. Brave displays the last observed request quota and timestamp from real searches, without sending an extra search. Values are kept in memory, isolated by API key; they are cleared on plugin reload. Brave quota is a request allowance, not a monetary balance.