sad-mcp 0.1.5 → 0.1.6
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/dist/index.js +1 -1
- package/dist/text-cache.d.ts +6 -0
- package/dist/text-cache.js +44 -0
- package/dist/tools.js +11 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -7,7 +7,7 @@ import { trackServerStart } from "./tracking.js";
|
|
|
7
7
|
async function main() {
|
|
8
8
|
// Connect to Claude Desktop IMMEDIATELY — no blocking auth here
|
|
9
9
|
// Auth happens lazily on first Drive API call
|
|
10
|
-
const server = new Server({ name: "sad-mcp", version: "0.1.
|
|
10
|
+
const server = new Server({ name: "sad-mcp", version: "0.1.6" }, {
|
|
11
11
|
capabilities: {
|
|
12
12
|
tools: {},
|
|
13
13
|
prompts: {},
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { readFileSync, writeFileSync, mkdirSync, existsSync } from "fs";
|
|
2
|
+
import { join } from "path";
|
|
3
|
+
import { homedir } from "os";
|
|
4
|
+
const TEXT_CACHE_DIR = join(homedir(), ".sad-mcp", "text-cache");
|
|
5
|
+
const TEXT_CACHE_INDEX = join(TEXT_CACHE_DIR, "index.json");
|
|
6
|
+
function ensureDir() {
|
|
7
|
+
if (!existsSync(TEXT_CACHE_DIR)) {
|
|
8
|
+
mkdirSync(TEXT_CACHE_DIR, { recursive: true });
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
function loadIndex() {
|
|
12
|
+
try {
|
|
13
|
+
return JSON.parse(readFileSync(TEXT_CACHE_INDEX, "utf-8"));
|
|
14
|
+
}
|
|
15
|
+
catch {
|
|
16
|
+
return {};
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
function saveIndex(index) {
|
|
20
|
+
ensureDir();
|
|
21
|
+
writeFileSync(TEXT_CACHE_INDEX, JSON.stringify(index, null, 2));
|
|
22
|
+
}
|
|
23
|
+
export function loadTextCache() {
|
|
24
|
+
const index = loadIndex();
|
|
25
|
+
const result = {};
|
|
26
|
+
for (const [fileId, entry] of Object.entries(index)) {
|
|
27
|
+
try {
|
|
28
|
+
const text = readFileSync(join(TEXT_CACHE_DIR, entry.textFile), "utf-8");
|
|
29
|
+
result[fileId] = { modifiedTime: entry.modifiedTime, text };
|
|
30
|
+
}
|
|
31
|
+
catch {
|
|
32
|
+
// Skip missing text files
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
return result;
|
|
36
|
+
}
|
|
37
|
+
export function saveTextEntry(fileId, entry) {
|
|
38
|
+
ensureDir();
|
|
39
|
+
const textFile = `${fileId}.txt`;
|
|
40
|
+
writeFileSync(join(TEXT_CACHE_DIR, textFile), entry.text, "utf-8");
|
|
41
|
+
const index = loadIndex();
|
|
42
|
+
index[fileId] = { modifiedTime: entry.modifiedTime, textFile };
|
|
43
|
+
saveIndex(index);
|
|
44
|
+
}
|
package/dist/tools.js
CHANGED
|
@@ -1,19 +1,29 @@
|
|
|
1
1
|
import { ListToolsRequestSchema, CallToolRequestSchema, } from "@modelcontextprotocol/sdk/types.js";
|
|
2
2
|
import { listAllFiles, downloadFile, categorizeFile } from "./drive.js";
|
|
3
3
|
import { extractText, isExtractable } from "./text-extract.js";
|
|
4
|
+
import { loadTextCache, saveTextEntry } from "./text-cache.js";
|
|
4
5
|
import { trackToolCall } from "./tracking.js";
|
|
5
|
-
// In-memory text cache for search (populated
|
|
6
|
+
// In-memory text cache for search (populated from disk cache + fresh extractions)
|
|
6
7
|
const textCache = new Map();
|
|
7
8
|
async function ensureTextCache() {
|
|
8
9
|
if (textCache.size > 0)
|
|
9
10
|
return;
|
|
10
11
|
const files = await listAllFiles();
|
|
11
12
|
const extractableFiles = files.filter(isExtractable);
|
|
13
|
+
const diskCache = loadTextCache();
|
|
12
14
|
for (const file of extractableFiles) {
|
|
13
15
|
try {
|
|
16
|
+
// Check disk cache — hit if file hasn't changed
|
|
17
|
+
const cached = diskCache[file.id];
|
|
18
|
+
if (cached && cached.modifiedTime === file.modifiedTime) {
|
|
19
|
+
textCache.set(file.id, { file, text: cached.text });
|
|
20
|
+
continue;
|
|
21
|
+
}
|
|
22
|
+
// Cache miss — download and extract
|
|
14
23
|
const buffer = await downloadFile(file);
|
|
15
24
|
const text = await extractText(file, buffer);
|
|
16
25
|
textCache.set(file.id, { file, text });
|
|
26
|
+
saveTextEntry(file.id, { modifiedTime: file.modifiedTime, text });
|
|
17
27
|
}
|
|
18
28
|
catch {
|
|
19
29
|
// Skip files that fail to download/extract
|