@ainote/mcp 1.1.0 → 1.1.1
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/lib/tools/dev-doc-tools.js +94 -5
- package/package.json +2 -2
|
@@ -1,12 +1,16 @@
|
|
|
1
1
|
import { toSuccessContent } from './internal/formatters.js';
|
|
2
|
+
import fs from 'fs';
|
|
3
|
+
import path from 'path';
|
|
2
4
|
|
|
3
5
|
function listDevDocsDefinition() {
|
|
4
6
|
return {
|
|
5
7
|
name: 'list_dev_docs',
|
|
6
|
-
description: `List
|
|
8
|
+
description: `List your synced dev documents stored in AI Note cloud.
|
|
7
9
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
+
Shows all documents under dev/ category including memory files, AI configs, and project docs.
|
|
11
|
+
Use this to see what's synced and which files have local_path set for multi-device sync.
|
|
12
|
+
|
|
13
|
+
Categories: memory, claude, cursor, windsurf, env, docs, or custom subcategories.`,
|
|
10
14
|
inputSchema: {
|
|
11
15
|
type: 'object',
|
|
12
16
|
properties: {
|
|
@@ -47,9 +51,15 @@ function getDevDocDefinition() {
|
|
|
47
51
|
function createDevDocDefinition() {
|
|
48
52
|
return {
|
|
49
53
|
name: 'create_dev_doc',
|
|
50
|
-
description: `
|
|
54
|
+
description: `Save a file to AI Note cloud for multi-device sync.
|
|
55
|
+
|
|
56
|
+
PRIMARY USE CASES:
|
|
57
|
+
- Memory files: ~/.claude/projects/.../memory/MEMORY.md
|
|
58
|
+
- AI configs: CLAUDE.md, .cursorrules, .windsurfrules (not in git)
|
|
59
|
+
- Project docs: architecture notes, planning docs
|
|
51
60
|
|
|
52
|
-
|
|
61
|
+
Set local_path to enable pull_dev_docs auto-sync on other devices.
|
|
62
|
+
Categories: memory | claude | cursor | env | docs`,
|
|
53
63
|
inputSchema: {
|
|
54
64
|
type: 'object',
|
|
55
65
|
properties: {
|
|
@@ -63,6 +73,10 @@ Use this to store CLAUDE.md content, cursor rules, windsurf rules, API specs, ar
|
|
|
63
73
|
type: 'string',
|
|
64
74
|
enum: ['markdown', 'json', 'yaml', 'text'],
|
|
65
75
|
description: 'Content type. Auto-detected from title extension if omitted.'
|
|
76
|
+
},
|
|
77
|
+
local_path: {
|
|
78
|
+
type: 'string',
|
|
79
|
+
description: 'Absolute local file path for multi-device sync (e.g., ~/.claude/projects/.../MEMORY.md)'
|
|
66
80
|
}
|
|
67
81
|
},
|
|
68
82
|
required: ['title', 'content']
|
|
@@ -85,6 +99,10 @@ function updateDevDocDefinition() {
|
|
|
85
99
|
type: 'string',
|
|
86
100
|
enum: ['replace', 'append', 'prepend'],
|
|
87
101
|
description: 'Update mode (default: replace)'
|
|
102
|
+
},
|
|
103
|
+
local_path: {
|
|
104
|
+
type: 'string',
|
|
105
|
+
description: 'Update the local file path for multi-device sync'
|
|
88
106
|
}
|
|
89
107
|
},
|
|
90
108
|
required: ['content']
|
|
@@ -107,6 +125,34 @@ function deleteDevDocDefinition() {
|
|
|
107
125
|
};
|
|
108
126
|
}
|
|
109
127
|
|
|
128
|
+
function pullDevDocsDefinition() {
|
|
129
|
+
return {
|
|
130
|
+
name: 'pull_dev_docs',
|
|
131
|
+
description: `Restore all synced files to THIS device. Writes files to their local paths on disk.
|
|
132
|
+
|
|
133
|
+
USE THIS WHEN:
|
|
134
|
+
- Setting up a new machine (desktop, laptop)
|
|
135
|
+
- Reinstalled macOS / fresh environment
|
|
136
|
+
- Want to sync latest versions of memory/config files from cloud
|
|
137
|
+
|
|
138
|
+
WHAT HAPPENS:
|
|
139
|
+
1. Fetches all dev docs with local_path set
|
|
140
|
+
2. Creates missing parent directories
|
|
141
|
+
3. Writes content to each local_path on this machine
|
|
142
|
+
|
|
143
|
+
Run once after installing ainote MCP on a new device to restore everything.`,
|
|
144
|
+
inputSchema: {
|
|
145
|
+
type: 'object',
|
|
146
|
+
properties: {
|
|
147
|
+
category: {
|
|
148
|
+
type: 'string',
|
|
149
|
+
description: 'Subcategory filter. Omit to pull all docs with local_path.'
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
|
|
110
156
|
function listDevCategoriesDefinition() {
|
|
111
157
|
return {
|
|
112
158
|
name: 'list_dev_categories',
|
|
@@ -155,6 +201,49 @@ export function getDevDocTools() {
|
|
|
155
201
|
return result;
|
|
156
202
|
}
|
|
157
203
|
},
|
|
204
|
+
{
|
|
205
|
+
definition: pullDevDocsDefinition(),
|
|
206
|
+
handler: async (args, { apiClient }) => {
|
|
207
|
+
const result = await apiClient.callTool('pull_dev_docs', args);
|
|
208
|
+
|
|
209
|
+
// Extract docs from resource data and write to local paths
|
|
210
|
+
let written = [];
|
|
211
|
+
let skipped = [];
|
|
212
|
+
let errors = [];
|
|
213
|
+
|
|
214
|
+
try {
|
|
215
|
+
const resourceText = result?.content?.find(c => c.type === 'resource')?.resource?.text;
|
|
216
|
+
if (resourceText) {
|
|
217
|
+
const data = JSON.parse(resourceText);
|
|
218
|
+
for (const doc of data.docs || []) {
|
|
219
|
+
if (!doc.local_path || !doc.content) {
|
|
220
|
+
skipped.push(doc.title);
|
|
221
|
+
continue;
|
|
222
|
+
}
|
|
223
|
+
const expandedPath = doc.local_path.replace(/^~/, process.env.HOME || '');
|
|
224
|
+
try {
|
|
225
|
+
const dir = path.dirname(expandedPath);
|
|
226
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
227
|
+
fs.writeFileSync(expandedPath, doc.content, 'utf8');
|
|
228
|
+
written.push(`✅ ${doc.title} → ${expandedPath}`);
|
|
229
|
+
} catch (e) {
|
|
230
|
+
errors.push(`❌ ${doc.title}: ${e.message}`);
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
} catch (e) {
|
|
235
|
+
errors.push(`Parse error: ${e.message}`);
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
const summary = [
|
|
239
|
+
written.length ? `Written (${written.length}):\n${written.join('\n')}` : null,
|
|
240
|
+
skipped.length ? `Skipped (no local_path): ${skipped.join(', ')}` : null,
|
|
241
|
+
errors.length ? `Errors:\n${errors.join('\n')}` : null,
|
|
242
|
+
].filter(Boolean).join('\n\n');
|
|
243
|
+
|
|
244
|
+
return [{ type: 'text', text: summary || 'No docs with local_path found.' }];
|
|
245
|
+
}
|
|
246
|
+
},
|
|
158
247
|
{
|
|
159
248
|
definition: listDevCategoriesDefinition(),
|
|
160
249
|
handler: async (_args, { apiClient }) => {
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ainote/mcp",
|
|
3
|
-
"version": "1.1.
|
|
4
|
-
"description": "MCP server for AI Note - Tasks
|
|
3
|
+
"version": "1.1.1",
|
|
4
|
+
"description": "MCP server for AI Note - Tasks, Dev Docs, and multi-device file sync (CLAUDE.md, memory files, Cursor rules, Windsurf rules)",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"bin": {
|