@tekmidian/devonthink-mcp 1.0.0 → 2.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/README.md +54 -9
- package/dist/index.d.ts +1 -1
- package/dist/index.js +19 -4
- package/dist/index.js.map +1 -1
- package/dist/server.d.ts +15 -9
- package/dist/server.js +177 -83
- package/dist/server.js.map +1 -1
- package/dist/tools/columnLayout.d.ts +83 -0
- package/dist/tools/columnLayout.js +321 -0
- package/dist/tools/columnLayout.js.map +1 -0
- package/dist/tools/listSmartGroups.d.ts +31 -0
- package/dist/tools/listSmartGroups.js +108 -0
- package/dist/tools/listSmartGroups.js.map +1 -0
- package/dist/tools/listSmartRules.d.ts +33 -0
- package/dist/tools/listSmartRules.js +113 -0
- package/dist/tools/listSmartRules.js.map +1 -0
- package/dist/tools/parseEmlHeaders.d.ts +40 -0
- package/dist/tools/parseEmlHeaders.js +183 -0
- package/dist/tools/parseEmlHeaders.js.map +1 -0
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
DEVONthink MCP server for Claude Code. Zero-config setup — one command and you're done.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
Extends [mcp-server-devonthink](https://github.com/dvcrn/mcp-server-devonthink) with additional tools for smart groups, smart rules, EML header parsing, and column layout management.
|
|
6
6
|
|
|
7
7
|
---
|
|
8
8
|
|
|
@@ -28,13 +28,17 @@ With this server running, Claude Code can:
|
|
|
28
28
|
- Cross-reference emails with archived documents
|
|
29
29
|
- Ask AI about documents (DEVONthink's built-in AI)
|
|
30
30
|
- List and navigate database groups
|
|
31
|
+
- **List smart groups** — enumerate all smart groups (not accessible via AppleScript)
|
|
32
|
+
- **List smart rules** — enumerate all smart rules (not accessible via AppleScript)
|
|
33
|
+
- **Parse EML headers** — extract Message-ID, In-Reply-To, References, Subject, etc.
|
|
34
|
+
- **Read/copy column layouts** — inspect and copy view column configurations
|
|
31
35
|
|
|
32
36
|
---
|
|
33
37
|
|
|
34
38
|
## Requirements
|
|
35
39
|
|
|
36
40
|
- macOS (DEVONthink is macOS-only)
|
|
37
|
-
- [DEVONthink 3](https://www.devontechnologies.com/apps/devonthink) installed and running
|
|
41
|
+
- [DEVONthink 3 or 4](https://www.devontechnologies.com/apps/devonthink) installed and running
|
|
38
42
|
- Node.js >= 18
|
|
39
43
|
- Claude Code
|
|
40
44
|
|
|
@@ -106,24 +110,62 @@ Example prompts:
|
|
|
106
110
|
- "Create a new markdown note in my Inbox with today's meeting notes"
|
|
107
111
|
- "List all documents tagged 'todo' in my Ablegen database"
|
|
108
112
|
- "Read the content of the PDF I imported yesterday"
|
|
113
|
+
- "List my smart groups"
|
|
114
|
+
- "Parse the headers from this .eml file to find its thread ID"
|
|
109
115
|
|
|
110
116
|
---
|
|
111
117
|
|
|
112
|
-
##
|
|
118
|
+
## Custom tools
|
|
119
|
+
|
|
120
|
+
### `list_smart_groups`
|
|
121
|
+
|
|
122
|
+
Parses `~/Library/Application Support/DEVONthink/SmartGroups.plist` and returns all smart groups with their name, UUID, target database UUID, and target group UUID.
|
|
123
|
+
|
|
124
|
+
Smart groups are NOT accessible via the standard AppleScript scripting dictionary. This tool is the only way to enumerate them. Use the returned `groupUuid` with the `search` tool's `groupUuid` parameter to query smart group contents.
|
|
125
|
+
|
|
126
|
+
### `list_smart_rules`
|
|
127
|
+
|
|
128
|
+
Same as above but for `SmartRules.plist`. Returns name, UUID, enabled state, trigger type, and optional group/database target for each rule.
|
|
129
|
+
|
|
130
|
+
### `parse_eml_headers`
|
|
131
|
+
|
|
132
|
+
Reads an RFC 2822 `.eml` file and extracts:
|
|
133
|
+
|
|
134
|
+
| Field | Description |
|
|
135
|
+
|-------|-------------|
|
|
136
|
+
| `messageId` | The `Message-ID` header |
|
|
137
|
+
| `inReplyTo` | The `In-Reply-To` header |
|
|
138
|
+
| `references` | Array of message IDs from the `References` header |
|
|
139
|
+
| `subject` | Decoded subject line |
|
|
140
|
+
| `from` | Sender |
|
|
141
|
+
| `to` | Recipients |
|
|
142
|
+
| `cc` | CC recipients |
|
|
143
|
+
| `date` | Date string |
|
|
113
144
|
|
|
114
|
-
|
|
145
|
+
Handles CRLF/LF line endings, folded headers, and RFC 2047 encoded words.
|
|
115
146
|
|
|
116
|
-
|
|
117
|
-
2. **A stable entry point** — `devonthink-mcp serve` resolves and starts the underlying server
|
|
147
|
+
### `get_column_layout`
|
|
118
148
|
|
|
119
|
-
|
|
149
|
+
Reads the column layout for a named smart group or smart rule from `~/Library/Preferences/com.devon-technologies.think.plist` using PlistBuddy. Returns the raw plist value so you can inspect column configuration.
|
|
150
|
+
|
|
151
|
+
### `copy_column_layout`
|
|
152
|
+
|
|
153
|
+
Copies the column layout from one smart group or smart rule to another. Automatically handles simple scalar values; for complex nested structures, returns the source value with guidance.
|
|
154
|
+
|
|
155
|
+
---
|
|
156
|
+
|
|
157
|
+
## How it works
|
|
158
|
+
|
|
159
|
+
`devonthink-mcp` runs as an in-process MCP server built on `@modelcontextprotocol/sdk`. It imports all upstream tool objects from `mcp-server-devonthink` and adds custom tools, then serves them through a single unified `ListTools` / `CallTool` handler.
|
|
160
|
+
|
|
161
|
+
The upstream tools communicate with DEVONthink via JXA (JavaScript for Automation) over the macOS Scripting Bridge.
|
|
120
162
|
|
|
121
163
|
---
|
|
122
164
|
|
|
123
165
|
## Troubleshooting
|
|
124
166
|
|
|
125
167
|
**"DEVONthink not found"**
|
|
126
|
-
Make sure DEVONthink 3 is installed in `/Applications` and running.
|
|
168
|
+
Make sure DEVONthink 3 or 4 is installed in `/Applications` and running.
|
|
127
169
|
|
|
128
170
|
**"No databases found"**
|
|
129
171
|
Open at least one DEVONthink database before using the MCP tools.
|
|
@@ -136,11 +178,14 @@ Open at least one DEVONthink database before using the MCP tools.
|
|
|
136
178
|
**AppleScript errors**
|
|
137
179
|
Grant Claude Code (or Terminal) Automation permissions in System Settings > Privacy & Security > Automation.
|
|
138
180
|
|
|
181
|
+
**`list_smart_groups` returns no results or error**
|
|
182
|
+
The plist format varies between DEVONthink versions. If the tool can't parse the structure, use `plutil -p ~/Library/Application\ Support/DEVONthink/SmartGroups.plist` to inspect the raw format and report an issue.
|
|
183
|
+
|
|
139
184
|
---
|
|
140
185
|
|
|
141
186
|
## Credits
|
|
142
187
|
|
|
143
|
-
The DEVONthink MCP implementation is by [dvcrn](https://github.com/dvcrn/mcp-server-devonthink). This package adds
|
|
188
|
+
The core DEVONthink MCP implementation is by [dvcrn](https://github.com/dvcrn/mcp-server-devonthink). This package adds setup tooling, packaging, and the custom extensions above.
|
|
144
189
|
|
|
145
190
|
---
|
|
146
191
|
|
package/dist/index.d.ts
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* Usage: devonthink-mcp <command>
|
|
6
6
|
*
|
|
7
7
|
* Commands:
|
|
8
|
-
* serve Start the MCP server (
|
|
8
|
+
* serve Start the in-process MCP server (default)
|
|
9
9
|
* setup Interactive first-time setup — configures ~/.claude.json
|
|
10
10
|
* version Print the version
|
|
11
11
|
*/
|
package/dist/index.js
CHANGED
|
@@ -5,12 +5,13 @@
|
|
|
5
5
|
* Usage: devonthink-mcp <command>
|
|
6
6
|
*
|
|
7
7
|
* Commands:
|
|
8
|
-
* serve Start the MCP server (
|
|
8
|
+
* serve Start the in-process MCP server (default)
|
|
9
9
|
* setup Interactive first-time setup — configures ~/.claude.json
|
|
10
10
|
* version Print the version
|
|
11
11
|
*/
|
|
12
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
12
13
|
import { runSetup } from "./setup.js";
|
|
13
|
-
import {
|
|
14
|
+
import { createExtendedServer } from "./server.js";
|
|
14
15
|
import { readFileSync } from "node:fs";
|
|
15
16
|
import { join, dirname } from "node:path";
|
|
16
17
|
import { fileURLToPath } from "node:url";
|
|
@@ -31,8 +32,22 @@ async function main() {
|
|
|
31
32
|
switch (command) {
|
|
32
33
|
case "serve":
|
|
33
34
|
case undefined: {
|
|
34
|
-
// Default: start the MCP server
|
|
35
|
-
|
|
35
|
+
// Default: start the in-process extended MCP server
|
|
36
|
+
const transport = new StdioServerTransport();
|
|
37
|
+
const { server, cleanup } = await createExtendedServer();
|
|
38
|
+
await server.connect(transport);
|
|
39
|
+
// Graceful shutdown
|
|
40
|
+
const shutdown = async () => {
|
|
41
|
+
await cleanup();
|
|
42
|
+
await server.close();
|
|
43
|
+
process.exit(0);
|
|
44
|
+
};
|
|
45
|
+
process.on("SIGINT", () => {
|
|
46
|
+
void shutdown();
|
|
47
|
+
});
|
|
48
|
+
process.on("SIGTERM", () => {
|
|
49
|
+
void shutdown();
|
|
50
|
+
});
|
|
36
51
|
break;
|
|
37
52
|
}
|
|
38
53
|
case "setup": {
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA;;;;;;;;;GASG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/server.d.ts
CHANGED
|
@@ -1,12 +1,18 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* server.ts —
|
|
2
|
+
* server.ts — In-process MCP server that merges upstream DEVONthink tools
|
|
3
|
+
* with custom extended tools.
|
|
3
4
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
*
|
|
10
|
-
*
|
|
5
|
+
* Replaces the previous thin pass-through (spawn pattern) with a real Server
|
|
6
|
+
* instance built from @modelcontextprotocol/sdk.
|
|
7
|
+
*
|
|
8
|
+
* Architecture:
|
|
9
|
+
* 1. Import all upstream tool objects from mcp-server-devonthink/dist/tools/
|
|
10
|
+
* 2. Import our custom tools from ./tools/
|
|
11
|
+
* 3. Register a unified ListTools + CallTool handler
|
|
12
|
+
* 4. Export createExtendedServer() which is called by index.ts
|
|
11
13
|
*/
|
|
12
|
-
|
|
14
|
+
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
|
15
|
+
export declare const createExtendedServer: () => Promise<{
|
|
16
|
+
server: Server;
|
|
17
|
+
cleanup: () => Promise<void>;
|
|
18
|
+
}>;
|
package/dist/server.js
CHANGED
|
@@ -1,89 +1,183 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* server.ts —
|
|
2
|
+
* server.ts — In-process MCP server that merges upstream DEVONthink tools
|
|
3
|
+
* with custom extended tools.
|
|
3
4
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
import { fileURLToPath } from "node:url";
|
|
13
|
-
/**
|
|
14
|
-
* Resolve the path to mcp-server-devonthink's dist/index.js.
|
|
15
|
-
* Tries the local node_modules first (when installed as dependency),
|
|
16
|
-
* then falls back to the globally installed package via npx resolution.
|
|
5
|
+
* Replaces the previous thin pass-through (spawn pattern) with a real Server
|
|
6
|
+
* instance built from @modelcontextprotocol/sdk.
|
|
7
|
+
*
|
|
8
|
+
* Architecture:
|
|
9
|
+
* 1. Import all upstream tool objects from mcp-server-devonthink/dist/tools/
|
|
10
|
+
* 2. Import our custom tools from ./tools/
|
|
11
|
+
* 3. Register a unified ListTools + CallTool handler
|
|
12
|
+
* 4. Export createExtendedServer() which is called by index.ts
|
|
17
13
|
*/
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
14
|
+
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
|
15
|
+
import { CallToolRequestSchema, ListToolsRequestSchema, ListResourcesRequestSchema, ListResourceTemplatesRequestSchema, ListPromptsRequestSchema, ErrorCode, McpError, } from "@modelcontextprotocol/sdk/types.js";
|
|
16
|
+
// ---------------------------------------------------------------------------
|
|
17
|
+
// Upstream tool imports — the dist/ files have no TypeScript declarations,
|
|
18
|
+
// so we use @ts-expect-error to suppress the "no type info" warnings.
|
|
19
|
+
// ---------------------------------------------------------------------------
|
|
20
|
+
// @ts-expect-error — no type declarations in upstream dist
|
|
21
|
+
import { isRunningTool } from "mcp-server-devonthink/dist/tools/isRunning.js";
|
|
22
|
+
// @ts-expect-error — no type declarations in upstream dist
|
|
23
|
+
import { createRecordTool } from "mcp-server-devonthink/dist/tools/createRecord.js";
|
|
24
|
+
// @ts-expect-error — no type declarations in upstream dist
|
|
25
|
+
import { deleteRecordTool } from "mcp-server-devonthink/dist/tools/deleteRecord.js";
|
|
26
|
+
// @ts-expect-error — no type declarations in upstream dist
|
|
27
|
+
import { moveRecordTool } from "mcp-server-devonthink/dist/tools/moveRecord.js";
|
|
28
|
+
// @ts-expect-error — no type declarations in upstream dist
|
|
29
|
+
import { getRecordPropertiesTool } from "mcp-server-devonthink/dist/tools/getRecordProperties.js";
|
|
30
|
+
// @ts-expect-error — no type declarations in upstream dist
|
|
31
|
+
import { getRecordByIdentifierTool } from "mcp-server-devonthink/dist/tools/getRecordByIdentifier.js";
|
|
32
|
+
// @ts-expect-error — no type declarations in upstream dist
|
|
33
|
+
import { searchTool } from "mcp-server-devonthink/dist/tools/search.js";
|
|
34
|
+
// @ts-expect-error — no type declarations in upstream dist
|
|
35
|
+
import { lookupRecordTool } from "mcp-server-devonthink/dist/tools/lookupRecord.js";
|
|
36
|
+
// @ts-expect-error — no type declarations in upstream dist
|
|
37
|
+
import { createFromUrlTool } from "mcp-server-devonthink/dist/tools/createFromUrl.js";
|
|
38
|
+
// @ts-expect-error — no type declarations in upstream dist
|
|
39
|
+
import { getOpenDatabasesTool } from "mcp-server-devonthink/dist/tools/getOpenDatabases.js";
|
|
40
|
+
// @ts-expect-error — no type declarations in upstream dist
|
|
41
|
+
import { currentDatabaseTool } from "mcp-server-devonthink/dist/tools/getCurrentDatabase.js";
|
|
42
|
+
// @ts-expect-error — no type declarations in upstream dist
|
|
43
|
+
import { selectedRecordsTool } from "mcp-server-devonthink/dist/tools/getSelectedRecords.js";
|
|
44
|
+
// @ts-expect-error — no type declarations in upstream dist
|
|
45
|
+
import { listGroupContentTool } from "mcp-server-devonthink/dist/tools/listGroupContent.js";
|
|
46
|
+
// @ts-expect-error — no type declarations in upstream dist
|
|
47
|
+
import { getRecordContentTool } from "mcp-server-devonthink/dist/tools/getRecordContent.js";
|
|
48
|
+
// @ts-expect-error — no type declarations in upstream dist
|
|
49
|
+
import { renameRecordTool } from "mcp-server-devonthink/dist/tools/renameRecord.js";
|
|
50
|
+
// @ts-expect-error — no type declarations in upstream dist
|
|
51
|
+
import { addTagsTool } from "mcp-server-devonthink/dist/tools/addTags.js";
|
|
52
|
+
// @ts-expect-error — no type declarations in upstream dist
|
|
53
|
+
import { removeTagsTool } from "mcp-server-devonthink/dist/tools/removeTags.js";
|
|
54
|
+
// @ts-expect-error — no type declarations in upstream dist
|
|
55
|
+
import { classifyTool } from "mcp-server-devonthink/dist/tools/classify.js";
|
|
56
|
+
// @ts-expect-error — no type declarations in upstream dist
|
|
57
|
+
import { compareTool } from "mcp-server-devonthink/dist/tools/compare.js";
|
|
58
|
+
// @ts-expect-error — no type declarations in upstream dist
|
|
59
|
+
import { replicateRecordTool } from "mcp-server-devonthink/dist/tools/replicateRecord.js";
|
|
60
|
+
// @ts-expect-error — no type declarations in upstream dist
|
|
61
|
+
import { duplicateRecordTool } from "mcp-server-devonthink/dist/tools/duplicateRecord.js";
|
|
62
|
+
// @ts-expect-error — no type declarations in upstream dist
|
|
63
|
+
import { convertRecordTool } from "mcp-server-devonthink/dist/tools/convertRecord.js";
|
|
64
|
+
// @ts-expect-error — no type declarations in upstream dist
|
|
65
|
+
import { updateRecordContentTool } from "mcp-server-devonthink/dist/tools/updateRecordContent.js";
|
|
66
|
+
// @ts-expect-error — no type declarations in upstream dist
|
|
67
|
+
import { setRecordPropertiesTool } from "mcp-server-devonthink/dist/tools/setRecordProperties.js";
|
|
68
|
+
// @ts-expect-error — no type declarations in upstream dist
|
|
69
|
+
import { askAiAboutDocumentsTool } from "mcp-server-devonthink/dist/tools/ai/askAiAboutDocuments.js";
|
|
70
|
+
// @ts-expect-error — no type declarations in upstream dist
|
|
71
|
+
import { checkAIHealthTool } from "mcp-server-devonthink/dist/tools/ai/checkAIHealth.js";
|
|
72
|
+
// @ts-expect-error — no type declarations in upstream dist
|
|
73
|
+
import { createSummaryDocumentTool } from "mcp-server-devonthink/dist/tools/ai/createSummaryDocument.js";
|
|
74
|
+
// @ts-expect-error — no type declarations in upstream dist
|
|
75
|
+
import { getToolDocumentationTool } from "mcp-server-devonthink/dist/tools/ai/getToolDocumentation.js";
|
|
76
|
+
// ---------------------------------------------------------------------------
|
|
77
|
+
// Custom tool imports
|
|
78
|
+
// ---------------------------------------------------------------------------
|
|
79
|
+
import { listSmartGroupsTool } from "./tools/listSmartGroups.js";
|
|
80
|
+
import { listSmartRulesTool } from "./tools/listSmartRules.js";
|
|
81
|
+
import { parseEmlHeadersTool } from "./tools/parseEmlHeaders.js";
|
|
82
|
+
import { getColumnLayoutTool, copyColumnLayoutTool } from "./tools/columnLayout.js";
|
|
83
|
+
// ---------------------------------------------------------------------------
|
|
84
|
+
// createExtendedServer
|
|
85
|
+
// ---------------------------------------------------------------------------
|
|
86
|
+
export const createExtendedServer = async () => {
|
|
87
|
+
const server = new Server({
|
|
88
|
+
name: "@tekmidian/devonthink-mcp",
|
|
89
|
+
version: "2.0.0",
|
|
90
|
+
}, {
|
|
91
|
+
capabilities: {
|
|
92
|
+
tools: {},
|
|
93
|
+
resources: {},
|
|
94
|
+
prompts: {},
|
|
95
|
+
},
|
|
96
|
+
});
|
|
97
|
+
// ---- Merge all tools: upstream first, then our custom extensions ----
|
|
98
|
+
const tools = [
|
|
99
|
+
// Upstream tools (all 28 from mcp-server-devonthink 1.7.1)
|
|
100
|
+
isRunningTool,
|
|
101
|
+
createRecordTool,
|
|
102
|
+
deleteRecordTool,
|
|
103
|
+
moveRecordTool,
|
|
104
|
+
getRecordPropertiesTool,
|
|
105
|
+
getRecordByIdentifierTool,
|
|
106
|
+
searchTool,
|
|
107
|
+
lookupRecordTool,
|
|
108
|
+
createFromUrlTool,
|
|
109
|
+
getOpenDatabasesTool,
|
|
110
|
+
currentDatabaseTool,
|
|
111
|
+
selectedRecordsTool,
|
|
112
|
+
listGroupContentTool,
|
|
113
|
+
getRecordContentTool,
|
|
114
|
+
renameRecordTool,
|
|
115
|
+
addTagsTool,
|
|
116
|
+
removeTagsTool,
|
|
117
|
+
classifyTool,
|
|
118
|
+
compareTool,
|
|
119
|
+
replicateRecordTool,
|
|
120
|
+
duplicateRecordTool,
|
|
121
|
+
convertRecordTool,
|
|
122
|
+
updateRecordContentTool,
|
|
123
|
+
setRecordPropertiesTool,
|
|
124
|
+
askAiAboutDocumentsTool,
|
|
125
|
+
checkAIHealthTool,
|
|
126
|
+
createSummaryDocumentTool,
|
|
127
|
+
getToolDocumentationTool,
|
|
128
|
+
// Custom extended tools
|
|
129
|
+
listSmartGroupsTool,
|
|
130
|
+
listSmartRulesTool,
|
|
131
|
+
parseEmlHeadersTool,
|
|
132
|
+
getColumnLayoutTool,
|
|
133
|
+
copyColumnLayoutTool,
|
|
37
134
|
];
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
135
|
+
// ---- ListTools handler ----
|
|
136
|
+
server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
137
|
+
return { tools };
|
|
138
|
+
});
|
|
139
|
+
// ---- Empty resource/prompt handlers (required by MCP spec) ----
|
|
140
|
+
server.setRequestHandler(ListResourcesRequestSchema, async () => {
|
|
141
|
+
return { resources: [] };
|
|
142
|
+
});
|
|
143
|
+
server.setRequestHandler(ListResourceTemplatesRequestSchema, async () => {
|
|
144
|
+
return { resources: [] };
|
|
145
|
+
});
|
|
146
|
+
server.setRequestHandler(ListPromptsRequestSchema, async () => {
|
|
147
|
+
return { prompts: [] };
|
|
148
|
+
});
|
|
149
|
+
// ---- CallTool handler ----
|
|
150
|
+
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
151
|
+
const { name, arguments: args = {} } = request.params;
|
|
152
|
+
const tool = tools.find((t) => t.name === name);
|
|
153
|
+
if (!tool) {
|
|
154
|
+
throw new McpError(ErrorCode.MethodNotFound, `Unknown tool: ${name}`);
|
|
41
155
|
}
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
else {
|
|
70
|
-
// Fallback: run via npx (works without local install)
|
|
71
|
-
process.stderr.write("[devonthink-mcp] mcp-server-devonthink not found locally — falling back to npx\n");
|
|
72
|
-
const child = spawn("npx", ["-y", "mcp-server-devonthink"], {
|
|
73
|
-
stdio: "inherit",
|
|
74
|
-
env: process.env,
|
|
75
|
-
});
|
|
76
|
-
await new Promise((resolve, reject) => {
|
|
77
|
-
child.on("exit", (code) => {
|
|
78
|
-
if (code === 0 || code === null) {
|
|
79
|
-
resolve();
|
|
80
|
-
}
|
|
81
|
-
else {
|
|
82
|
-
reject(new Error(`mcp-server-devonthink (npx) exited with code ${code}`));
|
|
83
|
-
}
|
|
84
|
-
});
|
|
85
|
-
child.on("error", reject);
|
|
86
|
-
});
|
|
87
|
-
}
|
|
88
|
-
}
|
|
156
|
+
if (typeof tool.run !== "function") {
|
|
157
|
+
throw new McpError(ErrorCode.InternalError, `Tool '${name}' has no run function.`);
|
|
158
|
+
}
|
|
159
|
+
try {
|
|
160
|
+
const result = await tool.run(args);
|
|
161
|
+
return {
|
|
162
|
+
content: [
|
|
163
|
+
{
|
|
164
|
+
type: "text",
|
|
165
|
+
text: JSON.stringify(result, null, 2),
|
|
166
|
+
},
|
|
167
|
+
],
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
catch (error) {
|
|
171
|
+
throw error instanceof McpError
|
|
172
|
+
? error
|
|
173
|
+
: new McpError(ErrorCode.InternalError, error instanceof Error ? error.message : String(error));
|
|
174
|
+
}
|
|
175
|
+
});
|
|
176
|
+
return {
|
|
177
|
+
server,
|
|
178
|
+
cleanup: async () => {
|
|
179
|
+
// No persistent resources to clean up
|
|
180
|
+
},
|
|
181
|
+
};
|
|
182
|
+
};
|
|
89
183
|
//# sourceMappingURL=server.js.map
|
package/dist/server.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* columnLayout.ts — Read and copy DEVONthink column layouts for smart groups/rules.
|
|
3
|
+
*
|
|
4
|
+
* Column layouts for list views are stored in
|
|
5
|
+
* ~/Library/Preferences/com.devon-technologies.think.plist under a "Columns" key.
|
|
6
|
+
* Each smart group or rule window remembers its column configuration keyed by
|
|
7
|
+
* the group/rule name or UUID.
|
|
8
|
+
*
|
|
9
|
+
* Tools exported:
|
|
10
|
+
* get_column_layout — Read columns for a named smart group or rule
|
|
11
|
+
* copy_column_layout — Copy column layout from one smart group/rule to another
|
|
12
|
+
*/
|
|
13
|
+
interface ColumnEntry {
|
|
14
|
+
identifier: string | null;
|
|
15
|
+
title: string | null;
|
|
16
|
+
width: number | null;
|
|
17
|
+
visible: boolean | null;
|
|
18
|
+
position: number | null;
|
|
19
|
+
}
|
|
20
|
+
interface GetColumnLayoutResult {
|
|
21
|
+
success: boolean;
|
|
22
|
+
name?: string;
|
|
23
|
+
plistKey?: string;
|
|
24
|
+
columns?: ColumnEntry[];
|
|
25
|
+
rawValue?: string;
|
|
26
|
+
error?: string;
|
|
27
|
+
}
|
|
28
|
+
export declare const getColumnLayoutTool: {
|
|
29
|
+
name: string;
|
|
30
|
+
description: string;
|
|
31
|
+
inputSchema: {
|
|
32
|
+
type: "object";
|
|
33
|
+
properties: {
|
|
34
|
+
name: {
|
|
35
|
+
type: string;
|
|
36
|
+
description: string;
|
|
37
|
+
};
|
|
38
|
+
plistKey: {
|
|
39
|
+
type: string;
|
|
40
|
+
description: string;
|
|
41
|
+
};
|
|
42
|
+
};
|
|
43
|
+
required: string[];
|
|
44
|
+
};
|
|
45
|
+
run: (args: Record<string, unknown>) => Promise<GetColumnLayoutResult>;
|
|
46
|
+
};
|
|
47
|
+
interface CopyColumnLayoutResult {
|
|
48
|
+
success: boolean;
|
|
49
|
+
sourceName?: string;
|
|
50
|
+
targetName?: string;
|
|
51
|
+
sourcePlistKey?: string;
|
|
52
|
+
targetPlistKey?: string;
|
|
53
|
+
message?: string;
|
|
54
|
+
error?: string;
|
|
55
|
+
}
|
|
56
|
+
export declare const copyColumnLayoutTool: {
|
|
57
|
+
name: string;
|
|
58
|
+
description: string;
|
|
59
|
+
inputSchema: {
|
|
60
|
+
type: "object";
|
|
61
|
+
properties: {
|
|
62
|
+
sourceName: {
|
|
63
|
+
type: string;
|
|
64
|
+
description: string;
|
|
65
|
+
};
|
|
66
|
+
targetName: {
|
|
67
|
+
type: string;
|
|
68
|
+
description: string;
|
|
69
|
+
};
|
|
70
|
+
sourcePlistKey: {
|
|
71
|
+
type: string;
|
|
72
|
+
description: string;
|
|
73
|
+
};
|
|
74
|
+
targetPlistKey: {
|
|
75
|
+
type: string;
|
|
76
|
+
description: string;
|
|
77
|
+
};
|
|
78
|
+
};
|
|
79
|
+
required: string[];
|
|
80
|
+
};
|
|
81
|
+
run: (args: Record<string, unknown>) => Promise<CopyColumnLayoutResult>;
|
|
82
|
+
};
|
|
83
|
+
export {};
|