@khoinguyen2002/doc-mcp 1.0.2 → 1.0.3

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.
@@ -43,9 +43,11 @@ server.registerTool("read_drive_document", {
43
43
  description: "Read the content of a specific Google Drive document. The document will also be automatically ingested into vector memory for future semantic search.",
44
44
  inputSchema: {
45
45
  fileId: z.string().describe("The Google Drive file ID to read"),
46
+ offset: z.number().optional().describe("Starting character index (default: 0)"),
47
+ limit: z.number().optional().describe("Maximum number of characters to return (default: 10000)"),
46
48
  },
47
- }, async ({ fileId }) => {
48
- const res = await readDriveDocument(fileId);
49
+ }, async ({ fileId, offset, limit }) => {
50
+ const res = await readDriveDocument(fileId, offset, limit);
49
51
  if (!res.success) {
50
52
  return {
51
53
  content: [{ type: "text", text: `Error: ${res.error}` }],
@@ -53,7 +55,7 @@ server.registerTool("read_drive_document", {
53
55
  };
54
56
  }
55
57
  return {
56
- content: [{ type: "text", text: res.content || "No content found." }],
58
+ content: [{ type: "text", text: JSON.stringify(res.data, null, 2) }],
57
59
  };
58
60
  });
59
61
  server.registerTool("save_agent_note", {
@@ -16,14 +16,23 @@ export declare function syncSingleDocument(fileId: string, folderId: string): Pr
16
16
  driveModifiedTime: string;
17
17
  content?: undefined;
18
18
  }>;
19
- export declare function readDriveDocument(fileId: string): Promise<{
19
+ export declare function readDriveDocument(fileId: string, offset?: number, limit?: number): Promise<{
20
20
  success: boolean;
21
- content: string;
21
+ data: {
22
+ content: string;
23
+ metadata: {
24
+ totalSize: number;
25
+ offset: number;
26
+ limit: number;
27
+ isTruncated: boolean;
28
+ warning: string | undefined;
29
+ };
30
+ };
22
31
  error?: undefined;
23
32
  } | {
24
33
  success: boolean;
25
34
  error: any;
26
- content?: undefined;
35
+ data?: undefined;
27
36
  }>;
28
37
  export declare function syncFolderState(folderId: string): Promise<{
29
38
  success: boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"driveTools.d.ts","sourceRoot":"","sources":["../../src/tools/driveTools.ts"],"names":[],"mappings":"AAiCA,wBAAsB,cAAc,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,cAAc,CAAC,EAAE,MAAM;;;;;;;;GAoC7E;AAED,wBAAsB,kBAAkB,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM;;;;;;;;GA6CxE;AAED,wBAAsB,iBAAiB,CAAC,MAAM,EAAE,MAAM;;;;;;;;GAsCrD;AAED,wBAAsB,eAAe,CAAC,QAAQ,EAAE,MAAM;;;;;;GAqDrD"}
1
+ {"version":3,"file":"driveTools.d.ts","sourceRoot":"","sources":["../../src/tools/driveTools.ts"],"names":[],"mappings":"AAiCA,wBAAsB,cAAc,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,cAAc,CAAC,EAAE,MAAM;;;;;;;;GAoC7E;AAED,wBAAsB,kBAAkB,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM;;;;;;;;GA6CxE;AAED,wBAAsB,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,GAAE,MAAU,EAAE,KAAK,GAAE,MAAc;;;;;;;;;;;;;;;;;GAsDhG;AAED,wBAAsB,eAAe,CAAC,QAAQ,EAAE,MAAM;;;;;;GAqDrD"}
@@ -91,7 +91,7 @@ export async function syncSingleDocument(fileId, folderId) {
91
91
  }
92
92
  return { synced: false, driveModifiedTime };
93
93
  }
94
- export async function readDriveDocument(fileId) {
94
+ export async function readDriveDocument(fileId, offset = 0, limit = 10000) {
95
95
  const folderId = config.DOC_MCP_DRIVE_FOLDER_ID;
96
96
  if (!folderId) {
97
97
  return {
@@ -112,15 +112,28 @@ export async function readDriveDocument(fileId) {
112
112
  content = typeof res.data === "string" ? res.data : "";
113
113
  }
114
114
  let finalContent = content;
115
- const MAX_CHARS = 10000;
116
- if (finalContent && finalContent.length > MAX_CHARS) {
117
- finalContent =
118
- finalContent.substring(0, MAX_CHARS) +
119
- "\n\n... [Content truncated due to length. The full document has been automatically ingested into Vector Memory. Use search_knowledge to query specific details.]";
115
+ const totalSize = finalContent ? finalContent.length : 0;
116
+ if (finalContent) {
117
+ finalContent = finalContent.substring(offset, offset + limit);
118
+ }
119
+ const isTruncated = offset + (finalContent?.length || 0) < totalSize;
120
+ let warning = undefined;
121
+ if (isTruncated) {
122
+ warning = `[WARNING]: This is not the entire document. Content has been truncated from character ${offset} to ${offset + finalContent.length} out of ${totalSize} total characters. Please use 'offset' and 'limit' parameters to read the rest of the document, or use search_knowledge to query specific details.`;
123
+ finalContent += `\n\n${warning}`;
120
124
  }
121
125
  return {
122
126
  success: true,
123
- content: finalContent || "Empty file",
127
+ data: {
128
+ content: finalContent || "Empty file",
129
+ metadata: {
130
+ totalSize,
131
+ offset,
132
+ limit,
133
+ isTruncated,
134
+ warning,
135
+ },
136
+ },
124
137
  };
125
138
  }
126
139
  catch (err) {
@@ -1 +1 @@
1
- {"version":3,"file":"knowledgeTools.d.ts","sourceRoot":"","sources":["../../src/tools/knowledgeTools.ts"],"names":[],"mappings":"AAIA,wBAAsB,aAAa,CAAC,OAAO,EAAE,MAAM;;;;;;;;GAmBlD;AAED,wBAAsB,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,GAAE,MAAU;;;;;;;;GAoCpE"}
1
+ {"version":3,"file":"knowledgeTools.d.ts","sourceRoot":"","sources":["../../src/tools/knowledgeTools.ts"],"names":[],"mappings":"AAIA,wBAAsB,aAAa,CAAC,OAAO,EAAE,MAAM;;;;;;;;GAmBlD;AAED,wBAAsB,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,GAAE,MAAU;;;;;;;;GAqCpE"}
@@ -39,7 +39,8 @@ export async function searchKnowledge(query, topK = 3) {
39
39
  }
40
40
  return {
41
41
  success: true,
42
- results: results.map((r) => {
42
+ results: results
43
+ .map((r) => {
43
44
  let title = "Unknown Source";
44
45
  if (r.metadata) {
45
46
  try {
@@ -49,12 +50,12 @@ export async function searchKnowledge(query, topK = 3) {
49
50
  }
50
51
  catch (e) { }
51
52
  }
52
- return `[File: ${title} | File ID: ${r.file_id || 'N/A'}]\n${r.text}`;
53
- }).join("\n\n---\n\n"),
53
+ return `[File: ${title} | File ID: ${r.file_id || "N/A"}]\n${r.text}`;
54
+ })
55
+ .join("\n\n---\n\n"),
54
56
  };
55
57
  }
56
58
  catch (err) {
57
- console.error("searchKnowledge outer catch:", err.message);
58
59
  return { success: false, error: `Failed to search: ${err.message}` };
59
60
  }
60
61
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@khoinguyen2002/doc-mcp",
3
- "version": "1.0.2",
3
+ "version": "1.0.3",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "bin": {
package/src/mcp-server.ts CHANGED
@@ -60,10 +60,12 @@ server.registerTool(
60
60
  "Read the content of a specific Google Drive document. The document will also be automatically ingested into vector memory for future semantic search.",
61
61
  inputSchema: {
62
62
  fileId: z.string().describe("The Google Drive file ID to read"),
63
+ offset: z.number().optional().describe("Starting character index (default: 0)"),
64
+ limit: z.number().optional().describe("Maximum number of characters to return (default: 10000)"),
63
65
  },
64
66
  },
65
- async ({ fileId }) => {
66
- const res = await readDriveDocument(fileId);
67
+ async ({ fileId, offset, limit }) => {
68
+ const res = await readDriveDocument(fileId, offset, limit);
67
69
  if (!res.success) {
68
70
  return {
69
71
  content: [{ type: "text", text: `Error: ${res.error}` }],
@@ -71,7 +73,7 @@ server.registerTool(
71
73
  };
72
74
  }
73
75
  return {
74
- content: [{ type: "text", text: res.content || "No content found." }],
76
+ content: [{ type: "text", text: JSON.stringify(res.data, null, 2) }],
75
77
  };
76
78
  },
77
79
  );
@@ -116,7 +116,7 @@ export async function syncSingleDocument(fileId: string, folderId: string) {
116
116
  return { synced: false, driveModifiedTime };
117
117
  }
118
118
 
119
- export async function readDriveDocument(fileId: string) {
119
+ export async function readDriveDocument(fileId: string, offset: number = 0, limit: number = 10000) {
120
120
  const folderId = config.DOC_MCP_DRIVE_FOLDER_ID;
121
121
  if (!folderId) {
122
122
  return {
@@ -140,16 +140,32 @@ export async function readDriveDocument(fileId: string) {
140
140
  }
141
141
 
142
142
  let finalContent = content;
143
- const MAX_CHARS = 10000;
144
- if (finalContent && finalContent.length > MAX_CHARS) {
145
- finalContent =
146
- finalContent.substring(0, MAX_CHARS) +
147
- "\n\n... [Content truncated due to length. The full document has been automatically ingested into Vector Memory. Use search_knowledge to query specific details.]";
143
+ const totalSize = finalContent ? finalContent.length : 0;
144
+
145
+ if (finalContent) {
146
+ finalContent = finalContent.substring(offset, offset + limit);
147
+ }
148
+
149
+ const isTruncated = offset + (finalContent?.length || 0) < totalSize;
150
+ let warning = undefined;
151
+
152
+ if (isTruncated) {
153
+ warning = `[WARNING]: This is not the entire document. Content has been truncated from character ${offset} to ${offset + finalContent!.length} out of ${totalSize} total characters. Please use 'offset' and 'limit' parameters to read the rest of the document, or use search_knowledge to query specific details.`;
154
+ finalContent += `\n\n${warning}`;
148
155
  }
149
156
 
150
157
  return {
151
158
  success: true,
152
- content: finalContent || "Empty file",
159
+ data: {
160
+ content: finalContent || "Empty file",
161
+ metadata: {
162
+ totalSize,
163
+ offset,
164
+ limit,
165
+ isTruncated,
166
+ warning,
167
+ },
168
+ },
153
169
  };
154
170
  } catch (err: any) {
155
171
  return { success: false, error: err.message };