obsidian-mcp-pro 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +198 -0
- package/build/config.d.ts +4 -0
- package/build/config.d.ts.map +1 -0
- package/build/config.js +147 -0
- package/build/config.js.map +1 -0
- package/build/index.d.ts +3 -0
- package/build/index.d.ts.map +1 -0
- package/build/index.js +135 -0
- package/build/index.js.map +1 -0
- package/build/lib/markdown.d.ts +43 -0
- package/build/lib/markdown.d.ts.map +1 -0
- package/build/lib/markdown.js +206 -0
- package/build/lib/markdown.js.map +1 -0
- package/build/lib/vault.d.ts +22 -0
- package/build/lib/vault.d.ts.map +1 -0
- package/build/lib/vault.js +182 -0
- package/build/lib/vault.js.map +1 -0
- package/build/tools/canvas.d.ts +3 -0
- package/build/tools/canvas.d.ts.map +1 -0
- package/build/tools/canvas.js +172 -0
- package/build/tools/canvas.js.map +1 -0
- package/build/tools/links.d.ts +3 -0
- package/build/tools/links.d.ts.map +1 -0
- package/build/tools/links.js +550 -0
- package/build/tools/links.js.map +1 -0
- package/build/tools/read.d.ts +3 -0
- package/build/tools/read.d.ts.map +1 -0
- package/build/tools/read.js +302 -0
- package/build/tools/read.js.map +1 -0
- package/build/tools/tags.d.ts +3 -0
- package/build/tools/tags.d.ts.map +1 -0
- package/build/tools/tags.js +146 -0
- package/build/tools/tags.js.map +1 -0
- package/build/tools/write.d.ts +3 -0
- package/build/tools/write.d.ts.map +1 -0
- package/build/tools/write.js +241 -0
- package/build/tools/write.js.map +1 -0
- package/build/types.d.ts +84 -0
- package/build/types.d.ts.map +1 -0
- package/build/types.js +2 -0
- package/build/types.js.map +1 -0
- package/package.json +37 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 [Your Name Here]
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
# obsidian-mcp-pro
|
|
2
|
+
|
|
3
|
+
**The most feature-complete MCP server for Obsidian vaults.**
|
|
4
|
+
|
|
5
|
+
[](https://www.npmjs.com/package/obsidian-mcp-pro)
|
|
6
|
+
[](https://opensource.org/licenses/MIT)
|
|
7
|
+
[](https://nodejs.org/)
|
|
8
|
+
|
|
9
|
+
Give AI assistants deep, structured access to your Obsidian knowledge base. Read, write, search, tag, analyze links, traverse graphs, and manipulate canvases — all through the [Model Context Protocol](https://modelcontextprotocol.io/).
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## Features
|
|
14
|
+
|
|
15
|
+
### Read & Search
|
|
16
|
+
- Full-text search across all vault notes
|
|
17
|
+
- Read individual notes with frontmatter parsing
|
|
18
|
+
- List and filter notes by folder, date, or pattern
|
|
19
|
+
- Search by frontmatter fields and values
|
|
20
|
+
- Retrieve daily notes automatically
|
|
21
|
+
|
|
22
|
+
### Write & Modify
|
|
23
|
+
- Create new notes with frontmatter and content
|
|
24
|
+
- Append or prepend content to existing notes
|
|
25
|
+
- Update frontmatter properties programmatically
|
|
26
|
+
- Move and rename notes with automatic link updates
|
|
27
|
+
- Delete notes safely
|
|
28
|
+
|
|
29
|
+
### Tags
|
|
30
|
+
- Build and query a complete tag index
|
|
31
|
+
- Search notes by single or multiple tags
|
|
32
|
+
|
|
33
|
+
### Links & Graph
|
|
34
|
+
- Get backlinks (what links *to* a note)
|
|
35
|
+
- Get outlinks (what a note links *to*)
|
|
36
|
+
- Find orphan notes with no inbound or outbound links
|
|
37
|
+
- Detect broken links pointing to non-existent notes
|
|
38
|
+
- Traverse graph neighbors to a configurable depth
|
|
39
|
+
|
|
40
|
+
### Canvas
|
|
41
|
+
- Read `.canvas` files with full node and edge data
|
|
42
|
+
- Add new nodes (text, file, link, group) to canvases
|
|
43
|
+
- Add edges between canvas nodes
|
|
44
|
+
- List all canvases in the vault
|
|
45
|
+
|
|
46
|
+
### MCP Resources
|
|
47
|
+
- `obsidian://note/{path}` — read any note by its vault-relative path
|
|
48
|
+
- `obsidian://tags` — retrieve the full tag index as JSON
|
|
49
|
+
- `obsidian://daily` — get today's daily note content
|
|
50
|
+
|
|
51
|
+
---
|
|
52
|
+
|
|
53
|
+
## Quick Start
|
|
54
|
+
|
|
55
|
+
### Claude Desktop
|
|
56
|
+
|
|
57
|
+
Add this to your Claude Desktop configuration file (`claude_desktop_config.json`):
|
|
58
|
+
|
|
59
|
+
```json
|
|
60
|
+
{
|
|
61
|
+
"mcpServers": {
|
|
62
|
+
"obsidian": {
|
|
63
|
+
"command": "npx",
|
|
64
|
+
"args": ["-y", "obsidian-mcp-pro"]
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
If you have multiple vaults, specify which one:
|
|
71
|
+
|
|
72
|
+
```json
|
|
73
|
+
{
|
|
74
|
+
"mcpServers": {
|
|
75
|
+
"obsidian": {
|
|
76
|
+
"command": "npx",
|
|
77
|
+
"args": ["-y", "obsidian-mcp-pro"],
|
|
78
|
+
"env": {
|
|
79
|
+
"OBSIDIAN_VAULT_PATH": "/path/to/your/vault"
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
### Claude Code
|
|
87
|
+
|
|
88
|
+
```bash
|
|
89
|
+
claude mcp add obsidian-mcp-pro -- npx -y obsidian-mcp-pro
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
---
|
|
93
|
+
|
|
94
|
+
## Configuration
|
|
95
|
+
|
|
96
|
+
The server locates your vault using the following priority:
|
|
97
|
+
|
|
98
|
+
| Priority | Method | Description |
|
|
99
|
+
|----------|--------|-------------|
|
|
100
|
+
| 1 | `OBSIDIAN_VAULT_PATH` | Environment variable with the absolute path to your vault |
|
|
101
|
+
| 2 | `OBSIDIAN_VAULT_NAME` | Environment variable to select a vault by folder name when multiple vaults exist |
|
|
102
|
+
| 3 | Auto-detection | Reads Obsidian's global config (`obsidian.json`) and uses the first valid vault found |
|
|
103
|
+
|
|
104
|
+
Auto-detection works on **macOS**, **Windows**, and **Linux** by reading the platform-specific Obsidian configuration directory.
|
|
105
|
+
|
|
106
|
+
---
|
|
107
|
+
|
|
108
|
+
## Tool Reference
|
|
109
|
+
|
|
110
|
+
| Tool | Description | Key Parameters |
|
|
111
|
+
|------|-------------|----------------|
|
|
112
|
+
| `search_notes` | Full-text search across all notes | `query`, `caseSensitive`, `maxResults`, `folder` |
|
|
113
|
+
| `get_note` | Read a note's content and metadata | `path` |
|
|
114
|
+
| `list_notes` | List notes in the vault or a folder | `folder`, `pattern`, `recursive` |
|
|
115
|
+
| `get_daily_note` | Get today's (or a specific date's) daily note | `date` |
|
|
116
|
+
| `search_by_frontmatter` | Find notes by frontmatter field values | `field`, `value`, `operator` |
|
|
117
|
+
| `create_note` | Create a new note with content and frontmatter | `path`, `content`, `frontmatter` |
|
|
118
|
+
| `append_to_note` | Append content to an existing note | `path`, `content` |
|
|
119
|
+
| `prepend_to_note` | Prepend content after frontmatter | `path`, `content` |
|
|
120
|
+
| `update_frontmatter` | Update frontmatter fields on a note | `path`, `fields` |
|
|
121
|
+
| `create_daily_note` | Create today's daily note from template | `date`, `content` |
|
|
122
|
+
| `move_note` | Move or rename a note | `source`, `destination` |
|
|
123
|
+
| `delete_note` | Delete a note from the vault | `path`, `confirm` |
|
|
124
|
+
| `get_tags` | Get all tags and their usage counts | `sort` |
|
|
125
|
+
| `search_by_tag` | Find all notes with a specific tag | `tag`, `includeChildren` |
|
|
126
|
+
| `get_backlinks` | Get all notes that link to a given note | `path` |
|
|
127
|
+
| `get_outlinks` | Get all links from a given note | `path` |
|
|
128
|
+
| `find_orphans` | Find notes with no links in or out | `folder` |
|
|
129
|
+
| `find_broken_links` | Detect links pointing to non-existent notes | `folder` |
|
|
130
|
+
| `get_graph_neighbors` | Get notes connected within N link hops | `path`, `depth` |
|
|
131
|
+
| `read_canvas` | Read a `.canvas` file's nodes and edges | `path` |
|
|
132
|
+
| `add_canvas_node` | Add a node to a canvas | `canvasPath`, `type`, `x`, `y`, `width`, `height` |
|
|
133
|
+
| `list_canvases` | List all `.canvas` files in the vault | `folder` |
|
|
134
|
+
| `add_canvas_edge` | Add an edge between two canvas nodes | `canvasPath`, `fromNode`, `toNode` |
|
|
135
|
+
|
|
136
|
+
---
|
|
137
|
+
|
|
138
|
+
## MCP Resources
|
|
139
|
+
|
|
140
|
+
Resources provide a URI-based way to access vault data:
|
|
141
|
+
|
|
142
|
+
| Resource URI | Description |
|
|
143
|
+
|-------------|-------------|
|
|
144
|
+
| `obsidian://note/{path}` | Read any note by its vault-relative path |
|
|
145
|
+
| `obsidian://tags` | Full tag index with file lists (JSON) |
|
|
146
|
+
| `obsidian://daily` | Today's daily note content |
|
|
147
|
+
|
|
148
|
+
---
|
|
149
|
+
|
|
150
|
+
## Development
|
|
151
|
+
|
|
152
|
+
```bash
|
|
153
|
+
# Clone the repository
|
|
154
|
+
git clone https://github.com/your-username/obsidian-mcp-pro.git
|
|
155
|
+
cd obsidian-mcp-pro
|
|
156
|
+
|
|
157
|
+
# Install dependencies
|
|
158
|
+
npm install
|
|
159
|
+
|
|
160
|
+
# Build
|
|
161
|
+
npm run build
|
|
162
|
+
|
|
163
|
+
# Run in development (watch mode)
|
|
164
|
+
npm run dev
|
|
165
|
+
|
|
166
|
+
# Start the server locally
|
|
167
|
+
OBSIDIAN_VAULT_PATH=/path/to/vault npm start
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
### Project Structure
|
|
171
|
+
|
|
172
|
+
```
|
|
173
|
+
src/
|
|
174
|
+
index.ts # Server entry point and resource registration
|
|
175
|
+
config.ts # Vault detection and configuration
|
|
176
|
+
types.ts # Shared TypeScript interfaces
|
|
177
|
+
lib/
|
|
178
|
+
vault.ts # Core vault operations (read, search, list)
|
|
179
|
+
markdown.ts # Frontmatter parsing and tag extraction
|
|
180
|
+
tools/
|
|
181
|
+
read.ts # Search, get, list, daily note tools
|
|
182
|
+
write.ts # Create, append, prepend, update, move, delete tools
|
|
183
|
+
tags.ts # Tag index and tag search tools
|
|
184
|
+
links.ts # Backlinks, outlinks, orphans, broken links, graph tools
|
|
185
|
+
canvas.ts # Canvas read, node, edge, and list tools
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
---
|
|
189
|
+
|
|
190
|
+
## License
|
|
191
|
+
|
|
192
|
+
MIT
|
|
193
|
+
|
|
194
|
+
---
|
|
195
|
+
|
|
196
|
+
## Contributing
|
|
197
|
+
|
|
198
|
+
Contributions welcome! Please open an issue first to discuss what you'd like to change. Pull requests without a corresponding issue may be closed.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAgJ/D,wBAAgB,cAAc,IAAI,WAAW,CAsB5C;AAED,wBAAgB,kBAAkB,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,eAAe,CAiCtE"}
|
package/build/config.js
ADDED
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import * as fs from "fs";
|
|
2
|
+
import * as path from "path";
|
|
3
|
+
import * as os from "os";
|
|
4
|
+
function getObsidianConfigPath() {
|
|
5
|
+
const platform = os.platform();
|
|
6
|
+
if (platform === "win32") {
|
|
7
|
+
const appData = process.env.APPDATA;
|
|
8
|
+
if (!appData) {
|
|
9
|
+
throw new Error("APPDATA environment variable is not set");
|
|
10
|
+
}
|
|
11
|
+
return path.join(appData, "obsidian", "obsidian.json");
|
|
12
|
+
}
|
|
13
|
+
if (platform === "darwin") {
|
|
14
|
+
return path.join(os.homedir(), "Library", "Application Support", "obsidian", "obsidian.json");
|
|
15
|
+
}
|
|
16
|
+
// Linux and other Unix-like systems
|
|
17
|
+
return path.join(os.homedir(), ".config", "obsidian", "obsidian.json");
|
|
18
|
+
}
|
|
19
|
+
function isValidVaultPath(vaultPath) {
|
|
20
|
+
try {
|
|
21
|
+
const obsidianDir = path.join(vaultPath, ".obsidian");
|
|
22
|
+
return (fs.existsSync(vaultPath) &&
|
|
23
|
+
fs.statSync(vaultPath).isDirectory() &&
|
|
24
|
+
fs.existsSync(obsidianDir) &&
|
|
25
|
+
fs.statSync(obsidianDir).isDirectory());
|
|
26
|
+
}
|
|
27
|
+
catch {
|
|
28
|
+
return false;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
function resolveVaultFromEnv() {
|
|
32
|
+
const envPath = process.env.OBSIDIAN_VAULT_PATH;
|
|
33
|
+
if (!envPath) {
|
|
34
|
+
return null;
|
|
35
|
+
}
|
|
36
|
+
const resolved = path.resolve(envPath);
|
|
37
|
+
if (!isValidVaultPath(resolved)) {
|
|
38
|
+
console.error(`OBSIDIAN_VAULT_PATH is set to "${resolved}" but it does not contain a valid Obsidian vault (.obsidian directory missing)`);
|
|
39
|
+
return null;
|
|
40
|
+
}
|
|
41
|
+
return resolved;
|
|
42
|
+
}
|
|
43
|
+
function resolveVaultFromObsidianConfig() {
|
|
44
|
+
let configPath;
|
|
45
|
+
try {
|
|
46
|
+
configPath = getObsidianConfigPath();
|
|
47
|
+
}
|
|
48
|
+
catch (err) {
|
|
49
|
+
console.error(`Failed to determine Obsidian config path: ${err}`);
|
|
50
|
+
return null;
|
|
51
|
+
}
|
|
52
|
+
if (!fs.existsSync(configPath)) {
|
|
53
|
+
console.error(`Obsidian config not found at ${configPath}`);
|
|
54
|
+
return null;
|
|
55
|
+
}
|
|
56
|
+
let config;
|
|
57
|
+
try {
|
|
58
|
+
const raw = fs.readFileSync(configPath, "utf-8");
|
|
59
|
+
config = JSON.parse(raw);
|
|
60
|
+
}
|
|
61
|
+
catch (err) {
|
|
62
|
+
console.error(`Failed to parse Obsidian config at ${configPath}: ${err}`);
|
|
63
|
+
return null;
|
|
64
|
+
}
|
|
65
|
+
if (!config.vaults || typeof config.vaults !== "object") {
|
|
66
|
+
console.error("No vaults found in Obsidian config");
|
|
67
|
+
return null;
|
|
68
|
+
}
|
|
69
|
+
const vaultEntries = Object.values(config.vaults);
|
|
70
|
+
if (vaultEntries.length === 0) {
|
|
71
|
+
console.error("Obsidian config contains no vault entries");
|
|
72
|
+
return null;
|
|
73
|
+
}
|
|
74
|
+
const desiredName = process.env.OBSIDIAN_VAULT_NAME;
|
|
75
|
+
if (desiredName) {
|
|
76
|
+
const matched = vaultEntries.find((entry) => {
|
|
77
|
+
const vaultName = path.basename(entry.path);
|
|
78
|
+
return vaultName === desiredName;
|
|
79
|
+
});
|
|
80
|
+
if (matched) {
|
|
81
|
+
const resolved = path.resolve(matched.path);
|
|
82
|
+
if (isValidVaultPath(resolved)) {
|
|
83
|
+
return resolved;
|
|
84
|
+
}
|
|
85
|
+
console.error(`Vault "${desiredName}" found in config but path "${resolved}" is not a valid vault`);
|
|
86
|
+
return null;
|
|
87
|
+
}
|
|
88
|
+
console.error(`OBSIDIAN_VAULT_NAME is set to "${desiredName}" but no matching vault was found in Obsidian config`);
|
|
89
|
+
return null;
|
|
90
|
+
}
|
|
91
|
+
// No name specified — try the first valid vault
|
|
92
|
+
for (const entry of vaultEntries) {
|
|
93
|
+
const resolved = path.resolve(entry.path);
|
|
94
|
+
if (isValidVaultPath(resolved)) {
|
|
95
|
+
if (vaultEntries.length > 1) {
|
|
96
|
+
console.error(`Multiple vaults found. Using "${path.basename(resolved)}". Set OBSIDIAN_VAULT_NAME to select a specific vault.`);
|
|
97
|
+
}
|
|
98
|
+
return resolved;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
console.error("No valid vault paths found in Obsidian config");
|
|
102
|
+
return null;
|
|
103
|
+
}
|
|
104
|
+
export function getVaultConfig() {
|
|
105
|
+
// Priority 1: environment variable
|
|
106
|
+
const envVault = resolveVaultFromEnv();
|
|
107
|
+
if (envVault) {
|
|
108
|
+
return {
|
|
109
|
+
vaultPath: envVault,
|
|
110
|
+
configPath: path.join(envVault, ".obsidian"),
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
// Priority 2: auto-detect from Obsidian's global config
|
|
114
|
+
const detectedVault = resolveVaultFromObsidianConfig();
|
|
115
|
+
if (detectedVault) {
|
|
116
|
+
return {
|
|
117
|
+
vaultPath: detectedVault,
|
|
118
|
+
configPath: path.join(detectedVault, ".obsidian"),
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
throw new Error("Unable to find an Obsidian vault. Set OBSIDIAN_VAULT_PATH environment variable or ensure Obsidian is installed with at least one vault configured.");
|
|
122
|
+
}
|
|
123
|
+
export function getDailyNoteConfig(vaultPath) {
|
|
124
|
+
const defaults = {
|
|
125
|
+
folder: "",
|
|
126
|
+
format: "YYYY-MM-DD",
|
|
127
|
+
};
|
|
128
|
+
const resolvedVaultPath = vaultPath ?? getVaultConfig().vaultPath;
|
|
129
|
+
const dailyNotesConfigPath = path.join(resolvedVaultPath, ".obsidian", "daily-notes.json");
|
|
130
|
+
if (!fs.existsSync(dailyNotesConfigPath)) {
|
|
131
|
+
return defaults;
|
|
132
|
+
}
|
|
133
|
+
try {
|
|
134
|
+
const raw = fs.readFileSync(dailyNotesConfigPath, "utf-8");
|
|
135
|
+
const parsed = JSON.parse(raw);
|
|
136
|
+
return {
|
|
137
|
+
folder: typeof parsed.folder === "string" ? parsed.folder : defaults.folder,
|
|
138
|
+
format: typeof parsed.format === "string" ? parsed.format : defaults.format,
|
|
139
|
+
template: typeof parsed.template === "string" ? parsed.template : undefined,
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
catch (err) {
|
|
143
|
+
console.error(`Failed to parse daily notes config at ${dailyNotesConfigPath}: ${err}`);
|
|
144
|
+
return defaults;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
|
package/build/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
|
package/build/index.js
ADDED
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import * as fs from "fs";
|
|
3
|
+
import * as path from "path";
|
|
4
|
+
import { McpServer, ResourceTemplate } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
5
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
6
|
+
import { getVaultConfig, getDailyNoteConfig } from "./config.js";
|
|
7
|
+
import { registerReadTools } from "./tools/read.js";
|
|
8
|
+
import { registerWriteTools } from "./tools/write.js";
|
|
9
|
+
import { registerTagTools } from "./tools/tags.js";
|
|
10
|
+
import { registerLinkTools } from "./tools/links.js";
|
|
11
|
+
import { registerCanvasTools } from "./tools/canvas.js";
|
|
12
|
+
async function main() {
|
|
13
|
+
let vaultPath;
|
|
14
|
+
try {
|
|
15
|
+
const config = getVaultConfig();
|
|
16
|
+
vaultPath = config.vaultPath;
|
|
17
|
+
}
|
|
18
|
+
catch (err) {
|
|
19
|
+
console.error(`[obsidian-mcp-pro] Failed to detect vault: ${err}`);
|
|
20
|
+
process.exit(1);
|
|
21
|
+
}
|
|
22
|
+
const server = new McpServer({
|
|
23
|
+
name: "obsidian-mcp-pro",
|
|
24
|
+
version: "1.0.0",
|
|
25
|
+
});
|
|
26
|
+
// --- MCP Resources ---
|
|
27
|
+
server.resource("note", new ResourceTemplate("obsidian://note/{path}", { list: undefined }), async (uri, params) => {
|
|
28
|
+
const rawPath = params.path;
|
|
29
|
+
const notePath = Array.isArray(rawPath) ? rawPath[0] : (rawPath ?? "");
|
|
30
|
+
const fullPath = path.join(vaultPath, notePath);
|
|
31
|
+
if (!fs.existsSync(fullPath)) {
|
|
32
|
+
throw new Error(`Note not found: ${notePath}`);
|
|
33
|
+
}
|
|
34
|
+
const content = fs.readFileSync(fullPath, "utf-8");
|
|
35
|
+
return {
|
|
36
|
+
contents: [
|
|
37
|
+
{
|
|
38
|
+
uri: uri.href,
|
|
39
|
+
mimeType: "text/markdown",
|
|
40
|
+
text: content,
|
|
41
|
+
},
|
|
42
|
+
],
|
|
43
|
+
};
|
|
44
|
+
});
|
|
45
|
+
server.resource("tags", "obsidian://tags", async (uri) => {
|
|
46
|
+
const tagIndex = {};
|
|
47
|
+
const walkDir = (dir) => {
|
|
48
|
+
const entries = fs.readdirSync(dir, { withFileTypes: true });
|
|
49
|
+
for (const entry of entries) {
|
|
50
|
+
if (entry.name.startsWith("."))
|
|
51
|
+
continue;
|
|
52
|
+
const fullPath = path.join(dir, entry.name);
|
|
53
|
+
if (entry.isDirectory()) {
|
|
54
|
+
walkDir(fullPath);
|
|
55
|
+
}
|
|
56
|
+
else if (entry.name.endsWith(".md")) {
|
|
57
|
+
const content = fs.readFileSync(fullPath, "utf-8");
|
|
58
|
+
const relativePath = path.relative(vaultPath, fullPath);
|
|
59
|
+
const tags = content.match(/#[a-zA-Z][\w/-]*/g) ?? [];
|
|
60
|
+
for (const tag of tags) {
|
|
61
|
+
if (!tagIndex[tag]) {
|
|
62
|
+
tagIndex[tag] = [];
|
|
63
|
+
}
|
|
64
|
+
tagIndex[tag].push(relativePath);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
};
|
|
69
|
+
walkDir(vaultPath);
|
|
70
|
+
return {
|
|
71
|
+
contents: [
|
|
72
|
+
{
|
|
73
|
+
uri: uri.href,
|
|
74
|
+
mimeType: "application/json",
|
|
75
|
+
text: JSON.stringify(tagIndex, null, 2),
|
|
76
|
+
},
|
|
77
|
+
],
|
|
78
|
+
};
|
|
79
|
+
});
|
|
80
|
+
server.resource("daily", "obsidian://daily", async (uri) => {
|
|
81
|
+
const dailyConfig = getDailyNoteConfig(vaultPath);
|
|
82
|
+
const today = new Date();
|
|
83
|
+
const year = today.getFullYear();
|
|
84
|
+
const month = String(today.getMonth() + 1).padStart(2, "0");
|
|
85
|
+
const day = String(today.getDate()).padStart(2, "0");
|
|
86
|
+
// Build the filename from the configured format
|
|
87
|
+
let filename = dailyConfig.format
|
|
88
|
+
.replace("YYYY", String(year))
|
|
89
|
+
.replace("MM", month)
|
|
90
|
+
.replace("DD", day);
|
|
91
|
+
if (!filename.endsWith(".md")) {
|
|
92
|
+
filename += ".md";
|
|
93
|
+
}
|
|
94
|
+
const dailyNotePath = dailyConfig.folder
|
|
95
|
+
? path.join(vaultPath, dailyConfig.folder, filename)
|
|
96
|
+
: path.join(vaultPath, filename);
|
|
97
|
+
if (!fs.existsSync(dailyNotePath)) {
|
|
98
|
+
return {
|
|
99
|
+
contents: [
|
|
100
|
+
{
|
|
101
|
+
uri: uri.href,
|
|
102
|
+
mimeType: "text/markdown",
|
|
103
|
+
text: `No daily note found for today (expected at ${path.relative(vaultPath, dailyNotePath)})`,
|
|
104
|
+
},
|
|
105
|
+
],
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
const content = fs.readFileSync(dailyNotePath, "utf-8");
|
|
109
|
+
return {
|
|
110
|
+
contents: [
|
|
111
|
+
{
|
|
112
|
+
uri: uri.href,
|
|
113
|
+
mimeType: "text/markdown",
|
|
114
|
+
text: content,
|
|
115
|
+
},
|
|
116
|
+
],
|
|
117
|
+
};
|
|
118
|
+
});
|
|
119
|
+
// --- Register tool groups ---
|
|
120
|
+
registerReadTools(server, vaultPath);
|
|
121
|
+
registerWriteTools(server, vaultPath);
|
|
122
|
+
registerTagTools(server, vaultPath);
|
|
123
|
+
registerLinkTools(server, vaultPath);
|
|
124
|
+
registerCanvasTools(server, vaultPath);
|
|
125
|
+
// --- Connect transport ---
|
|
126
|
+
const transport = new StdioServerTransport();
|
|
127
|
+
await server.connect(transport);
|
|
128
|
+
console.error(`[obsidian-mcp-pro] Server started`);
|
|
129
|
+
console.error(`[obsidian-mcp-pro] Vault: ${vaultPath}`);
|
|
130
|
+
}
|
|
131
|
+
main().catch((err) => {
|
|
132
|
+
console.error(`[obsidian-mcp-pro] Fatal error: ${err}`);
|
|
133
|
+
process.exit(1);
|
|
134
|
+
});
|
|
135
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import type { NoteMetadata, LinkInfo } from "../types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Parse YAML frontmatter from markdown content.
|
|
4
|
+
*/
|
|
5
|
+
export declare function parseFrontmatter(content: string): {
|
|
6
|
+
data: Record<string, unknown>;
|
|
7
|
+
content: string;
|
|
8
|
+
};
|
|
9
|
+
/**
|
|
10
|
+
* Parse existing frontmatter, merge with updates, and return full content
|
|
11
|
+
* with updated frontmatter. Creates frontmatter if none exists.
|
|
12
|
+
*/
|
|
13
|
+
export declare function updateFrontmatter(content: string, updates: Record<string, unknown>): string;
|
|
14
|
+
/**
|
|
15
|
+
* Extract all wikilinks and embeds from markdown content.
|
|
16
|
+
* Ignores links inside code blocks and inline code.
|
|
17
|
+
*/
|
|
18
|
+
export declare function extractWikilinks(content: string): LinkInfo[];
|
|
19
|
+
/**
|
|
20
|
+
* Extract inline tags and frontmatter tags from markdown content.
|
|
21
|
+
* Returns deduplicated tags without the `#` prefix.
|
|
22
|
+
* Ignores tags inside code blocks and inline code.
|
|
23
|
+
*/
|
|
24
|
+
export declare function extractTags(content: string): string[];
|
|
25
|
+
/**
|
|
26
|
+
* Extract aliases from frontmatter `aliases` field.
|
|
27
|
+
*/
|
|
28
|
+
export declare function extractAliases(content: string): string[];
|
|
29
|
+
/**
|
|
30
|
+
* Build a complete NoteMetadata object from a note's content and file stats.
|
|
31
|
+
*/
|
|
32
|
+
export declare function buildNoteMetadata(vaultPath: string, relativePath: string, content: string, stats: {
|
|
33
|
+
size: number;
|
|
34
|
+
created: Date | null;
|
|
35
|
+
modified: Date | null;
|
|
36
|
+
}): NoteMetadata;
|
|
37
|
+
/**
|
|
38
|
+
* Resolve a wikilink target to an actual file path using Obsidian's
|
|
39
|
+
* shortest-path matching strategy.
|
|
40
|
+
* Returns null if no match is found.
|
|
41
|
+
*/
|
|
42
|
+
export declare function resolveWikilink(link: string, _currentNotePath: string, allNotePaths: string[]): string | null;
|
|
43
|
+
//# sourceMappingURL=markdown.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"markdown.d.ts","sourceRoot":"","sources":["../../src/lib/markdown.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAE1D;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG;IACjD,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC9B,OAAO,EAAE,MAAM,CAAC;CACjB,CAMA;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC/B,MAAM,CAIR;AA0BD;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,QAAQ,EAAE,CAqC5D;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,CAqCrD;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,CAgBxD;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAC/B,SAAS,EAAE,MAAM,EACjB,YAAY,EAAE,MAAM,EACpB,OAAO,EAAE,MAAM,EACf,KAAK,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,IAAI,GAAG,IAAI,CAAC;IAAC,QAAQ,EAAE,IAAI,GAAG,IAAI,CAAA;CAAE,GACnE,YAAY,CAsBd;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAC7B,IAAI,EAAE,MAAM,EACZ,gBAAgB,EAAE,MAAM,EACxB,YAAY,EAAE,MAAM,EAAE,GACrB,MAAM,GAAG,IAAI,CA6Cf"}
|