obsidian-native-mcp 0.2.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.
Files changed (54) hide show
  1. package/.github/workflows/ci.yml +69 -0
  2. package/.husky/pre-commit +1 -0
  3. package/.prettierignore +3 -0
  4. package/.prettierrc +7 -0
  5. package/.releaserc.json +24 -0
  6. package/DEVELOPER.md +158 -0
  7. package/LICENSE +21 -0
  8. package/README.md +179 -0
  9. package/dist/cli/index.js +22 -0
  10. package/dist/cli/index.js.map +1 -0
  11. package/dist/handlers/prompts.js +127 -0
  12. package/dist/handlers/prompts.js.map +1 -0
  13. package/dist/handlers/tools.js +113 -0
  14. package/dist/handlers/tools.js.map +1 -0
  15. package/dist/mcp/http-transport.js +124 -0
  16. package/dist/mcp/http-transport.js.map +1 -0
  17. package/dist/mcp/protocol.js +38 -0
  18. package/dist/mcp/protocol.js.map +1 -0
  19. package/dist/mcp/server.js +257 -0
  20. package/dist/mcp/server.js.map +1 -0
  21. package/dist/mcp/stdio-transport.js +41 -0
  22. package/dist/mcp/stdio-transport.js.map +1 -0
  23. package/dist/mcp/transport.js +3 -0
  24. package/dist/mcp/transport.js.map +1 -0
  25. package/dist/plugin/main.js +1201 -0
  26. package/dist/plugin/main.js.map +1 -0
  27. package/dist/plugin/manifest.json +10 -0
  28. package/dist/plugin/settings.js +63 -0
  29. package/dist/plugin/settings.js.map +1 -0
  30. package/dist/utils/fs-utils.js +268 -0
  31. package/dist/utils/fs-utils.js.map +1 -0
  32. package/dist/utils/search.js +62 -0
  33. package/dist/utils/search.js.map +1 -0
  34. package/dist/utils/vaults.js +165 -0
  35. package/dist/utils/vaults.js.map +1 -0
  36. package/eslint.config.mjs +16 -0
  37. package/manifest.json +10 -0
  38. package/package.json +48 -0
  39. package/scripts/build-plugin.mjs +35 -0
  40. package/scripts/sync-version.cjs +12 -0
  41. package/src/cli/index.ts +25 -0
  42. package/src/handlers/prompts.ts +148 -0
  43. package/src/handlers/tools.ts +146 -0
  44. package/src/mcp/http-transport.ts +138 -0
  45. package/src/mcp/protocol.ts +69 -0
  46. package/src/mcp/server.ts +272 -0
  47. package/src/mcp/stdio-transport.ts +43 -0
  48. package/src/mcp/transport.ts +8 -0
  49. package/src/plugin/main.ts +91 -0
  50. package/src/plugin/settings.ts +69 -0
  51. package/src/utils/fs-utils.ts +358 -0
  52. package/src/utils/search.ts +84 -0
  53. package/src/utils/vaults.ts +175 -0
  54. package/tsconfig.json +20 -0
@@ -0,0 +1,69 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+ branches: [main]
8
+
9
+ permissions:
10
+ contents: read
11
+
12
+ jobs:
13
+ lint:
14
+ name: Lint and Type Check
15
+ runs-on: ubuntu-latest
16
+ steps:
17
+ - uses: actions/checkout@v4
18
+ - uses: actions/setup-node@v4
19
+ with:
20
+ node-version: "22"
21
+ cache: npm
22
+ - run: npm ci
23
+ - run: npm run lint
24
+ - run: npm run format:check
25
+ - run: npm run check
26
+
27
+ build:
28
+ name: Build
29
+ needs: lint
30
+ runs-on: ubuntu-latest
31
+ steps:
32
+ - uses: actions/checkout@v4
33
+ - uses: actions/setup-node@v4
34
+ with:
35
+ node-version: "22"
36
+ cache: npm
37
+ - run: npm ci
38
+ - run: npm run build
39
+ - run: npm run build:plugin
40
+ - uses: actions/upload-artifact@v4
41
+ with:
42
+ name: dist
43
+ path: dist/
44
+
45
+ release:
46
+ name: Release
47
+ if: github.event_name == 'push' && github.ref == 'refs/heads/main'
48
+ needs: build
49
+ runs-on: ubuntu-latest
50
+ permissions:
51
+ contents: write
52
+ issues: write
53
+ pull-requests: write
54
+ steps:
55
+ - uses: actions/checkout@v4
56
+ with:
57
+ fetch-depth: 0
58
+ persist-credentials: false
59
+ - uses: actions/setup-node@v4
60
+ with:
61
+ node-version: "22"
62
+ cache: npm
63
+ - run: npm ci
64
+ - run: npm run build
65
+ - name: Semantic Release
66
+ env:
67
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
68
+ NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
69
+ run: npx semantic-release
@@ -0,0 +1 @@
1
+ npx lint-staged
@@ -0,0 +1,3 @@
1
+ dist/
2
+ node_modules/
3
+ bun.lock
package/.prettierrc ADDED
@@ -0,0 +1,7 @@
1
+ {
2
+ "semi": true,
3
+ "singleQuote": false,
4
+ "tabWidth": 2,
5
+ "trailingComma": "all",
6
+ "printWidth": 100
7
+ }
@@ -0,0 +1,24 @@
1
+ {
2
+ "branches": ["main"],
3
+ "plugins": [
4
+ "@semantic-release/commit-analyzer",
5
+ "@semantic-release/release-notes-generator",
6
+ "@semantic-release/changelog",
7
+ "@semantic-release/npm",
8
+ [
9
+ "@semantic-release/exec",
10
+ {
11
+ "prepareCmd": "node scripts/sync-version.cjs && npm run build:plugin"
12
+ }
13
+ ],
14
+ [
15
+ "@semantic-release/github",
16
+ {
17
+ "assets": [
18
+ { "path": "dist/plugin/main.js", "label": "plugin-main.js" },
19
+ { "path": "dist/plugin/manifest.json", "label": "plugin-manifest.json" }
20
+ ]
21
+ }
22
+ ]
23
+ ]
24
+ }
package/DEVELOPER.md ADDED
@@ -0,0 +1,158 @@
1
+ # Developer Guide
2
+
3
+ ## Architecture
4
+
5
+ ```
6
+ src/
7
+ cli/index.ts CLI entry — reads config, starts stdio transport
8
+ plugin/
9
+ main.ts Obsidian plugin entry (extends Plugin)
10
+ settings.ts Settings tab with vault picker + copy URL
11
+ mcp/
12
+ protocol.ts JSON-RPC 2.0 types + Content-Length framing
13
+ transport.ts Transport interface
14
+ stdio-transport.ts Stdio transport (for CLI)
15
+ http-transport.ts HTTP/SSE transport (for plugin)
16
+ server.ts Transport-agnostic server — creates handlers + routes requests
17
+ handlers/
18
+ tools.ts Tool implementations (9 tools)
19
+ prompts.ts Prompt directory reader + template parser
20
+ utils/
21
+ fs-utils.ts File I/O, frontmatter parsing, heading/block patching
22
+ search.ts Recursive text search across .md files
23
+ vaults.ts VaultRegistry — config from env, file, Obsidian auto-discovery
24
+ ```
25
+
26
+ ### Key Design Decisions
27
+
28
+ **Zero dependencies.** The MCP protocol (JSON-RPC 2.0 over stdio with Content-Length framing) is implemented from scratch. No npm packages needed at runtime — only Node.js stdlib.
29
+
30
+ **Node.js everywhere.** All I/O uses `fs` and `fs/promises` — runs on any platform Node.js supports. Obsidian plugin runs inside Obsidian's Electron. CLI runs standalone.
31
+
32
+ **Two transports, shared logic.** The `server.ts` exports a `createServer()` factory that returns tool definitions and a `handleRequest()` function. The stdio and HTTP/SSE transports both use the same factory — only the I/O layer differs.
33
+
34
+ **Direct filesystem access.** Unlike `obsidian-mcp-tools` which communicates via HTTP with the Local REST API plugin, this server reads/writes files directly.
35
+
36
+ **Multi-vault first.** The `VaultRegistry` supports env var, config file, and Obsidian auto-discovery.
37
+
38
+ ## Development Workflow
39
+
40
+ ```bash
41
+ # Install dependencies
42
+ npm install
43
+
44
+ # Run CLI in dev mode (watch + hot reload)
45
+ npm run dev
46
+
47
+ # Type-check
48
+ npm run check
49
+
50
+ # Lint + format
51
+ npm run lint
52
+ npm run format
53
+
54
+ # Build TS to dist/
55
+ npm run build
56
+
57
+ # Build plugin bundle for Obsidian
58
+ npm run build:plugin
59
+
60
+ # Run CLI from compiled JS
61
+ npm run start
62
+
63
+ # Test via env var
64
+ OBSIDIAN_VAULT_PATHS=/path/to/vault node dist/cli/index.js
65
+ ```
66
+
67
+ ### Testing the CLI
68
+
69
+ ```bash
70
+ OBSIDIAN_VAULT_PATHS=/path/to/vault node --input-type=module -e '
71
+ const msgs = [
72
+ {jsonrpc:"2.0",id:1,method:"initialize",params:{}},
73
+ {jsonrpc:"2.0",id:2,method:"tools/call",params:{name:"list_vaults",arguments:{}}},
74
+ {jsonrpc:"2.0",id:3,method:"tools/call",params:{name:"list_files",arguments:{vault:"default"}}},
75
+ ];
76
+ let input = "";
77
+ for(const m of msgs){ const s = JSON.stringify(m); input += "Content-Length: "+s.length+"\r\n\r\n"+s; }
78
+ const {spawn} = await import("child_process");
79
+ const child = spawn("node", ["dist/cli/index.js"], {stdio:["pipe","pipe","pipe"]});
80
+ let buf = "";
81
+ child.stdout.on("data", c => buf += c.toString());
82
+ child.on("close", () => {
83
+ let remaining = buf;
84
+ while(true){
85
+ const m = remaining.match(/^Content-Length: (\d+)\r\n\r\n/);
86
+ if(!m) break;
87
+ const len = parseInt(m[1]), start = m[0].length;
88
+ if(remaining.length < start + len) break;
89
+ console.log(JSON.parse(remaining.slice(start, start + len)));
90
+ remaining = remaining.slice(start + len);
91
+ }
92
+ });
93
+ child.stdin.write(input);
94
+ child.stdin.end();
95
+ setTimeout(() => process.exit(0), 2000);
96
+ '
97
+ ```
98
+
99
+ ### Testing the Plugin
100
+
101
+ 1. Build the plugin: `npm run build:plugin`
102
+ 2. Copy `dist/plugin/` to `<your-vault>/.obsidian/plugins/obsidian-native-mcp/`
103
+ 3. Reload Obsidian, enable the plugin in Community Plugins
104
+ 4. Open plugin settings to see discovered vaults
105
+
106
+ ## Adding a New Tool
107
+
108
+ 1. Define the tool schema in `src/mcp/server.ts` — add to the `toolDefinitions` array
109
+ 2. Implement the handler in `src/handlers/tools.ts` — add to `getHandlers()`
110
+ 3. Implement the core logic in `src/utils/fs-utils.ts`, `search.ts`, or a new util
111
+
112
+ ## Release Process
113
+
114
+ ```bash
115
+ # 1. Update version in package.json and manifest.json
116
+ # 2. Build
117
+ npm run build
118
+ npm run build:plugin
119
+
120
+ # 3. Publish to npm
121
+ npm publish
122
+
123
+ # 4. Create GitHub release
124
+ gh release create v0.2.0 --title "v0.2.0" --generate-notes
125
+
126
+ # 5. Submit plugin to Obsidian community plugin list
127
+ # https://github.com/obsidianmd/obsidian-releases
128
+ ```
129
+
130
+ ## Protocol Reference
131
+
132
+ The server speaks the standard MCP protocol over stdio (CLI) or HTTP/SSE (plugin):
133
+
134
+ ### Stdio
135
+
136
+ ```
137
+ Client → Server: Content-Length: <N>\r\n\r\n<JSON-RPC body>
138
+ Server → Client: Content-Length: <N>\r\n\r\n<JSON-RPC body>
139
+ ```
140
+
141
+ ### HTTP/SSE
142
+
143
+ ```
144
+ Client → Server: GET /sse → SSE stream with endpoint event
145
+ Client → Server: POST /message?session_id=<id> → JSON-RPC request
146
+ Server → Client: SSE event "message" with JSON-RPC response
147
+ ```
148
+
149
+ ### Supported Methods
150
+
151
+ | Method | Purpose |
152
+ | --------------------------- | ------------------------- |
153
+ | `initialize` | Protocol handshake |
154
+ | `tools/list` | List available tools |
155
+ | `tools/call` | Execute a tool |
156
+ | `prompts/list` | List available prompts |
157
+ | `prompts/get` | Get prompt content |
158
+ | `notifications/initialized` | Client-ready notification |
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Utkarsh Srivastava
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,179 @@
1
+ <div align="center">
2
+
3
+ # Obsidian Native MCP
4
+
5
+ **Zero-dependency MCP server for Obsidian vaults**
6
+ Direct filesystem access — no Obsidian process, no REST API plugin required.
7
+
8
+ [![Build](https://img.shields.io/github/actions/workflow/status/usrivastava92/obsidian-native-mcp/ci.yml?branch=main&label=CI&logo=github)](https://github.com/usrivastava92/obsidian-native-mcp/actions)
9
+ [![Release](https://img.shields.io/github/v/release/usrivastava92/obsidian-native-mcp?logo=semanticrelease)](https://github.com/usrivastava92/obsidian-native-mcp/releases)
10
+ [![npm](https://img.shields.io/npm/v/obsidian-native-mcp?logo=npm)](https://www.npmjs.com/package/obsidian-native-mcp)
11
+ [![npm downloads](https://img.shields.io/npm/dm/obsidian-native-mcp?logo=npm)](https://www.npmjs.com/package/obsidian-native-mcp)
12
+ [![License](https://img.shields.io/github/license/usrivastava92/obsidian-native-mcp)](LICENSE)
13
+ [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen)](CONTRIBUTING.md)
14
+
15
+ </div>
16
+
17
+ Obsidian Native MCP is a [Model Context Protocol](https://modelcontextprotocol.io) server that gives AI assistants (Claude Desktop, etc.) direct, safe access to your Obsidian vaults.
18
+
19
+ **Two ways to use it:**
20
+
21
+ - **Obsidian plugin** (recommended) — 1-click install, auto-discovers vaults, settings UI, runs inside Obsidian
22
+ - **CLI** — standalone, works without Obsidian running, configured via env var or config file
23
+
24
+ **Why Obsidian Native MCP over other solutions?**
25
+
26
+ | Feature | Obsidian Native MCP | obsidian-mcp-tools (archived) |
27
+ | ------------------ | -------------------------------------- | ----------------------------------------- |
28
+ | Obsidian required? | **Plugin: no. CLI: no.** | Yes — must be running with Local REST API |
29
+ | Dependencies | **Zero** — uses only Node.js stdlib | MCP SDK, arktype, zod, radash, turndown… |
30
+ | Distribution | Obsidian plugin + npm CLI | Bun-compiled binary |
31
+ | Multi-vault | **Built-in** — one server, many vaults | No |
32
+ | Cross-platform | **1 codebase, runs everywhere (WORA)** | Platform-specific binaries |
33
+ | File patching | Headings, blocks, frontmatter | Via REST API |
34
+ | Setup effort | Plugin: 1 click. CLI: one command. | Manual download + config |
35
+
36
+ ## Installation
37
+
38
+ ### Obsidian plugin (recommended)
39
+
40
+ 1. Open Obsidian → Settings → Community Plugins → Browse
41
+ 2. Search for "Obsidian Native MCP" and install
42
+ 3. Enable the plugin in Community Plugins list
43
+ 4. Go to plugin settings → toggle which vaults to expose → copy the MCP URL
44
+
45
+ ### CLI (standalone)
46
+
47
+ ```bash
48
+ npm install -g obsidian-native-mcp
49
+ ```
50
+
51
+ ### Build from source
52
+
53
+ ```bash
54
+ git clone https://github.com/usrivastava92/obsidian-native-mcp.git
55
+ cd obsidian-native-mcp
56
+ npm install
57
+ npm run build
58
+ ```
59
+
60
+ ## Configuration
61
+
62
+ ### Plugin
63
+
64
+ Plugin auto-discovers all your Obsidian vaults from Obsidian's own config. Open plugin settings to select which vaults to expose.
65
+
66
+ ### CLI
67
+
68
+ Configure vault(s) via environment variable or config file.
69
+
70
+ ```bash
71
+ # Single vault
72
+ export OBSIDIAN_VAULT_PATHS=/Users/me/my-obsidian-vault
73
+
74
+ # Multiple vaults (semicolons on all platforms)
75
+ export OBSIDIAN_VAULT_PATHS=/Users/me/personal;/Users/me/work
76
+
77
+ # Windows
78
+ set OBSIDIAN_VAULT_PATHS=C:\Users\me\personal;C:\Users\me\work
79
+ ```
80
+
81
+ Config file at `~/.config/obsidian-native-mcp/vaults.json`:
82
+
83
+ ```json
84
+ {
85
+ "vaults": {
86
+ "personal": "/Users/me/personal-notes",
87
+ "work": "/Users/me/work-vault"
88
+ }
89
+ }
90
+ ```
91
+
92
+ ## Usage
93
+
94
+ ### Obsidian plugin
95
+
96
+ After enabling the plugin, open its settings tab. You'll see a URL like `http://127.0.0.1:9789/sse`. Add it to your `claude_desktop_config.json`:
97
+
98
+ ```json
99
+ {
100
+ "mcpServers": {
101
+ "obsidian-native-mcp": {
102
+ "url": "http://127.0.0.1:9789/sse"
103
+ }
104
+ }
105
+ }
106
+ ```
107
+
108
+ ### CLI
109
+
110
+ ```json
111
+ {
112
+ "mcpServers": {
113
+ "obsidian-native-mcp": {
114
+ "command": "obsidian-native-mcp",
115
+ "env": {
116
+ "OBSIDIAN_VAULT_PATHS": "/Users/me/my-obsidian-vault"
117
+ }
118
+ }
119
+ }
120
+ }
121
+ ```
122
+
123
+ ## Tools
124
+
125
+ | Tool | Description |
126
+ | ---------------- | ------------------------------------------------------- |
127
+ | `list_vaults` | List all configured vaults with paths |
128
+ | `get_vault_info` | Stats per vault (file count, etc.) |
129
+ | `list_files` | List files/dirs in a vault directory |
130
+ | `get_file` | Read file content (markdown or json with frontmatter) |
131
+ | `create_file` | Create or overwrite a file |
132
+ | `append_to_file` | Append content to a file |
133
+ | `patch_file` | Patch by heading, block reference, or frontmatter field |
134
+ | `delete_file` | Delete a file |
135
+ | `search` | Full-text search across markdown files |
136
+
137
+ All file tools accept an optional `vault` parameter. When only one vault is configured, it's inferred automatically.
138
+
139
+ ### Prompts
140
+
141
+ Place markdown files in a `Prompts/` folder in any vault, tagged with `mcp-tools-prompt` in frontmatter:
142
+
143
+ ```markdown
144
+ ---
145
+ tags: [mcp-tools-prompt]
146
+ description: Summarize the daily note
147
+ ---
148
+
149
+ Summarize what happened on <% tp.mcpTools.prompt("date", "Date to summarize") %>.
150
+ ```
151
+
152
+ Prompts appear automatically in your MCP client's prompt selector.
153
+
154
+ ## Roadmap
155
+
156
+ - [x] Zero-dependency MCP protocol implementation
157
+ - [x] Full vault CRUD (list, read, create, append, patch, delete)
158
+ - [x] Full-text search across vault
159
+ - [x] Multi-vault support
160
+ - [x] Cross-platform (runs anywhere Node.js runs)
161
+ - [x] Prompt templates from vault's Prompts folder
162
+ - [x] Config file support (`~/.config/obsidian-native-mcp/vaults.json`)
163
+ - [x] Obsidian community plugin with settings UI
164
+ - [x] Vault auto-discovery from Obsidian config
165
+ - [x] HTTP/SSE transport for plugin
166
+ - [x] Two distribution methods (plugin + CLI)
167
+ - [ ] Smart Connections-like semantic search (local embeddings)
168
+ - [ ] Vault change watching (file system events)
169
+ - [ ] npm publish workflow
170
+
171
+ ## Security
172
+
173
+ obsidian-native-mcp runs locally on your machine. The plugin exposes vaults over localhost only. The CLI communicates over local stdio. No data is sent to external services. Only vaults you explicitly select/configure are accessible.
174
+
175
+ For security concerns, please open an issue or see [SECURITY.md](SECURITY.md).
176
+
177
+ ## License
178
+
179
+ [MIT](LICENSE)
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const server_1 = require("../mcp/server");
4
+ const stdio_transport_1 = require("../mcp/stdio-transport");
5
+ const vaults_1 = require("../utils/vaults");
6
+ async function main() {
7
+ const registry = new vaults_1.VaultRegistry();
8
+ if (process.argv.includes("--version") || process.argv.includes("-v")) {
9
+ console.log("0.2.0");
10
+ process.exit(0);
11
+ }
12
+ console.error("obsidian-native-mcp server starting");
13
+ const server = (0, server_1.createServer)(registry);
14
+ const transport = new stdio_transport_1.StdioTransport();
15
+ transport.onRequest(async (msg) => server.handleRequest(msg));
16
+ transport.start();
17
+ }
18
+ main().catch((err) => {
19
+ console.error("Fatal error:", err);
20
+ process.exit(1);
21
+ });
22
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":";;AAAA,0CAA6C;AAC7C,4DAAwD;AACxD,4CAAgD;AAEhD,KAAK,UAAU,IAAI;IACjB,MAAM,QAAQ,GAAG,IAAI,sBAAa,EAAE,CAAC;IAErC,IAAI,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QACtE,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QACrB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,OAAO,CAAC,KAAK,CAAC,qCAAqC,CAAC,CAAC;IAErD,MAAM,MAAM,GAAG,IAAA,qBAAY,EAAC,QAAQ,CAAC,CAAC;IACtC,MAAM,SAAS,GAAG,IAAI,gCAAc,EAAE,CAAC;IAEvC,SAAS,CAAC,SAAS,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE,CAAC,MAAM,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC;IAC9D,SAAS,CAAC,KAAK,EAAE,CAAC;AACpB,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;IACnB,OAAO,CAAC,KAAK,CAAC,cAAc,EAAE,GAAG,CAAC,CAAC;IACnC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
@@ -0,0 +1,127 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.PromptHandler = void 0;
4
+ const fs_1 = require("fs");
5
+ const promises_1 = require("fs/promises");
6
+ const path_1 = require("path");
7
+ function parseFrontmatter(content) {
8
+ if (!content.startsWith("---"))
9
+ return null;
10
+ const endIndex = content.indexOf("---", 3);
11
+ if (endIndex === -1)
12
+ return null;
13
+ const raw = content.slice(3, endIndex).trim();
14
+ const body = content.slice(endIndex + 3).trim();
15
+ const frontmatter = {};
16
+ for (const line of raw.split("\n")) {
17
+ const colonIndex = line.indexOf(":");
18
+ if (colonIndex === -1)
19
+ continue;
20
+ const key = line.slice(0, colonIndex).trim();
21
+ let value = line.slice(colonIndex + 1).trim();
22
+ if (value.startsWith('"') && value.endsWith('"'))
23
+ value = value.slice(1, -1);
24
+ else if (value.startsWith("[") && value.endsWith("]")) {
25
+ value = value
26
+ .slice(1, -1)
27
+ .split(",")
28
+ .map((s) => s.trim().replace(/^["']|["']$/g, ""))
29
+ .filter(Boolean);
30
+ }
31
+ frontmatter[key] = value;
32
+ }
33
+ return { frontmatter, body };
34
+ }
35
+ class PromptHandler {
36
+ registry;
37
+ promptDir = "Prompts";
38
+ constructor(registry) {
39
+ this.registry = registry;
40
+ }
41
+ async list(vaultName) {
42
+ const vaultPath = this.registry.resolve(vaultName);
43
+ const promptPath = (0, path_1.join)(vaultPath, this.promptDir);
44
+ let entries;
45
+ try {
46
+ entries = (0, fs_1.readdirSync)(promptPath);
47
+ }
48
+ catch {
49
+ return [];
50
+ }
51
+ const prompts = [];
52
+ for (const entry of entries) {
53
+ if (!entry.endsWith(".md"))
54
+ continue;
55
+ const fullPath = (0, path_1.join)(promptPath, entry);
56
+ const stat = (0, fs_1.statSync)(fullPath);
57
+ if (!stat.isFile())
58
+ continue;
59
+ try {
60
+ const content = await (0, promises_1.readFile)(fullPath, "utf-8");
61
+ const parsed = parseFrontmatter(content);
62
+ const tags = parsed?.frontmatter?.tags || [];
63
+ if (!tags.includes("mcp-tools-prompt"))
64
+ continue;
65
+ const promptArgs = parsePromptParameters(parsed?.body || content);
66
+ prompts.push({
67
+ name: entry,
68
+ description: parsed?.frontmatter?.description || entry.replace(".md", ""),
69
+ arguments: promptArgs,
70
+ });
71
+ }
72
+ catch {
73
+ continue;
74
+ }
75
+ }
76
+ return prompts;
77
+ }
78
+ async get(name, vaultName) {
79
+ const vaultPath = this.registry.resolve(vaultName);
80
+ const promptPath = (0, path_1.join)(vaultPath, this.promptDir, name);
81
+ let content;
82
+ try {
83
+ content = await (0, promises_1.readFile)(promptPath, "utf-8");
84
+ }
85
+ catch {
86
+ throw new Error(`Prompt not found: ${name}`);
87
+ }
88
+ const parsed = parseFrontmatter(content);
89
+ const body = parsed?.body || content;
90
+ const withoutFrontmatter = body.trim();
91
+ return {
92
+ messages: [
93
+ {
94
+ role: "user",
95
+ content: {
96
+ type: "text",
97
+ text: withoutFrontmatter,
98
+ },
99
+ },
100
+ ],
101
+ };
102
+ }
103
+ }
104
+ exports.PromptHandler = PromptHandler;
105
+ function parsePromptParameters(content) {
106
+ const regex = /<%[-_*]*\s*tp\.mcpTools\.prompt\(([^)]+)\)\s*[-_]*%>/g;
107
+ const params = [];
108
+ let match;
109
+ while ((match = regex.exec(content)) !== null) {
110
+ try {
111
+ const argsStr = match[1];
112
+ const args = argsStr.split(",").map((s) => s.trim().replace(/^["']|["']$/g, ""));
113
+ if (args.length >= 1) {
114
+ params.push({
115
+ name: args[0],
116
+ description: args[1],
117
+ required: true,
118
+ });
119
+ }
120
+ }
121
+ catch {
122
+ continue;
123
+ }
124
+ }
125
+ return params;
126
+ }
127
+ //# sourceMappingURL=prompts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prompts.js","sourceRoot":"","sources":["../../src/handlers/prompts.ts"],"names":[],"mappings":"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"}