How to Set Up Obsidian MCP Server (2026)
Connect your Obsidian vault to AI assistants via MCP
Start Building with Hypereal
Access Kling, Flux, Sora, Veo & more through a single API. Free credits to start, scale to millions.
No credit card required • 100k+ developers • Enterprise ready
How to Set Up Obsidian MCP Server (2026)
Obsidian is one of the most popular knowledge management tools, with millions of users storing notes, research, and personal wikis in local Markdown files. With MCP (Model Context Protocol), you can connect your Obsidian vault directly to AI assistants like Claude, letting them read your notes, search across your vault, create new notes, and work with your knowledge base in context.
This guide shows you how to set up an Obsidian MCP server and connect it to Claude Desktop, Cursor, or any MCP-compatible client.
Why Connect Obsidian to AI via MCP?
Without MCP, using AI with your Obsidian notes means manually copying and pasting content into chat windows. With MCP, the AI can:
- Search your entire vault by keyword, tag, or content
- Read specific notes and understand their context, including wiki links and backlinks
- Create new notes based on conversations or research
- Update existing notes with new information
- Analyze connections between notes using your link graph
- Generate summaries from multiple related notes
The AI gets direct access to your knowledge base rather than working with disconnected snippets.
Prerequisites
| Requirement | Details |
|---|---|
| Obsidian | Any recent version (vault is just a folder of Markdown files) |
| Node.js | v18 or higher |
| MCP client | Claude Desktop, Cursor, VS Code, etc. |
| npm | For installing the MCP server |
Option 1: Use the Obsidian MCP Server Package
The community-maintained obsidian-mcp-server package provides a ready-to-use MCP server for Obsidian vaults.
Step 1: Install the Server
npm install -g obsidian-mcp-server
Step 2: Configure Claude Desktop
Add the server to your Claude Desktop configuration.
macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
Windows: %APPDATA%\Claude\claude_desktop_config.json
{
"mcpServers": {
"obsidian": {
"command": "npx",
"args": [
"obsidian-mcp-server",
"--vault",
"/Users/yourname/Documents/MyVault"
]
}
}
}
Replace the path with the actual path to your Obsidian vault folder.
Step 3: Restart Claude Desktop
Close and reopen Claude Desktop. You should see the Obsidian MCP server listed in the tools panel.
Step 4: Test the Connection
Ask Claude to interact with your vault:
Search my Obsidian vault for notes about "machine learning"
Read the note called "Project Ideas" from my vault
Create a new note in my vault called "Meeting Notes 2026-02-06"
with a summary of what we discussed
Option 2: Use the Filesystem MCP Server
If you want a simpler setup without a dedicated Obsidian package, the official filesystem MCP server works directly with Obsidian vaults since they are just folders of Markdown files.
Step 1: Configure the Filesystem Server
{
"mcpServers": {
"obsidian-vault": {
"command": "npx",
"args": [
"-y",
"@modelcontextprotocol/server-filesystem",
"/Users/yourname/Documents/MyVault"
]
}
}
}
Step 2: Use It
The filesystem server gives the AI read and write access to all files in the vault directory. It can:
- List all notes and folders
- Read any note's content
- Create new Markdown files
- Edit existing files
- Search file names
The tradeoff compared to a dedicated Obsidian MCP server is that the filesystem server does not understand Obsidian-specific features like wiki links ([[note]]), tags, frontmatter, or the backlink graph.
Option 3: Build a Custom Obsidian MCP Server
For maximum control, you can build your own MCP server tailored to your vault's structure. Here is a minimal implementation in TypeScript:
Step 1: Set Up the Project
mkdir obsidian-mcp
cd obsidian-mcp
npm init -y
npm install @modelcontextprotocol/sdk zod glob
npm install -D typescript @types/node tsx
Step 2: Write the Server
Create src/index.ts:
#!/usr/bin/env node
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { z } from "zod";
import * as fs from "fs/promises";
import * as path from "path";
import { glob } from "glob";
const VAULT_PATH = process.argv[2] || process.env.OBSIDIAN_VAULT_PATH;
if (!VAULT_PATH) {
console.error("Usage: obsidian-mcp <vault-path>");
process.exit(1);
}
const server = new McpServer({
name: "obsidian-vault",
version: "1.0.0",
});
// Tool: Search notes by content
server.tool(
"search_notes",
"Search Obsidian vault notes by content or title",
{
query: z.string().describe("Search query (searches titles and content)"),
limit: z.number().optional().default(10).describe("Max results to return"),
},
async ({ query, limit }) => {
const files = await glob("**/*.md", { cwd: VAULT_PATH });
const results: { file: string; matches: string[] }[] = [];
const queryLower = query.toLowerCase();
for (const file of files) {
const content = await fs.readFile(
path.join(VAULT_PATH, file),
"utf-8"
);
const titleMatch = file.toLowerCase().includes(queryLower);
const lines = content.split("\n");
const matchingLines = lines.filter((line) =>
line.toLowerCase().includes(queryLower)
);
if (titleMatch || matchingLines.length > 0) {
results.push({
file,
matches: matchingLines.slice(0, 3),
});
}
if (results.length >= limit) break;
}
const output = results
.map(
(r) =>
`**${r.file}**\n${r.matches.map((m) => ` > ${m.trim()}`).join("\n")}`
)
.join("\n\n");
return {
content: [
{
type: "text",
text: results.length > 0 ? output : "No notes found matching your query.",
},
],
};
}
);
// Tool: Read a specific note
server.tool(
"read_note",
"Read the full content of an Obsidian note",
{
notePath: z
.string()
.describe("Path to the note relative to vault root (e.g., 'Projects/my-project.md')"),
},
async ({ notePath }) => {
try {
const fullPath = path.join(VAULT_PATH, notePath);
const content = await fs.readFile(fullPath, "utf-8");
return {
content: [{ type: "text", text: content }],
};
} catch {
return {
content: [{ type: "text", text: `Note not found: ${notePath}` }],
isError: true,
};
}
}
);
// Tool: Create a new note
server.tool(
"create_note",
"Create a new note in the Obsidian vault",
{
notePath: z
.string()
.describe("Path for the new note (e.g., 'Daily/2026-02-06.md')"),
content: z.string().describe("Markdown content for the note"),
},
async ({ notePath, content }) => {
const fullPath = path.join(VAULT_PATH, notePath);
const dir = path.dirname(fullPath);
await fs.mkdir(dir, { recursive: true });
await fs.writeFile(fullPath, content, "utf-8");
return {
content: [{ type: "text", text: `Created note: ${notePath}` }],
};
}
);
// Tool: List notes in a folder
server.tool(
"list_notes",
"List all notes in a vault folder",
{
folder: z
.string()
.optional()
.default("")
.describe("Folder path relative to vault root (empty for root)"),
},
async ({ folder }) => {
const searchPath = path.join(VAULT_PATH, folder);
const files = await glob("**/*.md", { cwd: searchPath });
return {
content: [
{
type: "text",
text:
files.length > 0
? files.map((f) => `- ${f}`).join("\n")
: "No notes found in this folder.",
},
],
};
}
);
// Tool: Get tags from a note
server.tool(
"get_tags",
"Extract all tags from a note or the entire vault",
{
notePath: z
.string()
.optional()
.describe("Specific note to get tags from (omit for all vault tags)"),
},
async ({ notePath }) => {
const files = notePath
? [notePath]
: await glob("**/*.md", { cwd: VAULT_PATH });
const tagSet = new Set<string>();
for (const file of files) {
const content = await fs.readFile(
path.join(VAULT_PATH, file),
"utf-8"
);
const tags = content.match(/#[\w\-\/]+/g);
if (tags) {
tags.forEach((tag) => tagSet.add(tag));
}
}
const sorted = Array.from(tagSet).sort();
return {
content: [
{
type: "text",
text:
sorted.length > 0
? sorted.join("\n")
: "No tags found.",
},
],
};
}
);
// Start the server
async function main() {
const transport = new StdioServerTransport();
await server.connect(transport);
console.error(`Obsidian MCP server running for vault: ${VAULT_PATH}`);
}
main().catch((error) => {
console.error("Fatal error:", error);
process.exit(1);
});
Step 3: Build and Connect
# Add to package.json
# "type": "module"
# "scripts": { "build": "tsc", "dev": "tsx src/index.ts" }
npx tsc
# Test
echo '{"jsonrpc":"2.0","method":"initialize","params":{"protocolVersion":"2025-03-26","capabilities":{},"clientInfo":{"name":"test","version":"1.0"}},"id":1}' | node dist/index.js /path/to/your/vault
Add to Claude Desktop config:
{
"mcpServers": {
"obsidian": {
"command": "node",
"args": [
"/path/to/obsidian-mcp/dist/index.js",
"/Users/yourname/Documents/MyVault"
]
}
}
}
Practical Use Cases
Research Assistant
Search my vault for all notes about "transformer architecture"
and create a summary note that combines the key insights
from all matching notes.
Daily Note Creation
Create a new daily note for today (2026-02-06) in my Daily folder.
Include a section for tasks, a section for meeting notes,
and link it to yesterday's daily note.
Knowledge Gap Analysis
List all tags in my vault and identify topics that have
fewer than 3 notes. These are potential knowledge gaps
I should research.
Note Refactoring
Read my "Machine Learning" note and split it into
separate notes for each major topic. Create wiki links
between them.
Security Considerations
When connecting your Obsidian vault to an AI via MCP, keep these in mind:
- The AI can read all files in the configured vault path. Do not connect a vault that contains sensitive information (passwords, financial data, private journals) unless you trust the AI provider's data handling policies.
- Write access means the AI can modify your notes. Use git or Obsidian's built-in version history to maintain backups.
- Limit the scope. Instead of connecting your entire vault, connect only specific subfolders that you want the AI to access.
{
"mcpServers": {
"obsidian-work": {
"command": "npx",
"args": [
"obsidian-mcp-server",
"--vault",
"/Users/yourname/Documents/MyVault/Work"
]
}
}
}
Troubleshooting
"Server failed to start" Verify Node.js v18+ is installed. Test the server manually by running the command from your terminal.
"Note not found" errors Check that the vault path is correct and uses the absolute path. On Windows, use forward slashes or escaped backslashes.
Large vaults are slow If your vault has thousands of notes, the search tool may be slow. Add content indexing or limit searches to specific folders.
Obsidian locks files Obsidian does not lock files, so the MCP server can read and write freely. However, changes made by the MCP server may not appear in Obsidian immediately -- press Ctrl/Cmd+R in Obsidian to refresh the file list.
Wrapping Up
Connecting Obsidian to AI via MCP transforms your static note collection into a dynamic knowledge base that AI can query, analyze, and extend. The setup takes about 10 minutes whether you use the pre-built package or the filesystem server, and the custom server approach gives you full control over what the AI can access and do.
If your projects involve AI-generated media like images, video, or talking avatars alongside your knowledge management, check out Hypereal AI for a unified API that handles all of it.
Try Hypereal AI free -- 35 credits, no credit card required.
Related Articles
Start Building Today
Get 35 free credits on signup. No credit card required. Generate your first image in under 5 minutes.
