m365connector 0.3.5 → 0.3.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "m365connector",
3
- "version": "0.3.5",
3
+ "version": "0.3.6",
4
4
  "description": "MCP server for M365 Connector browser extension",
5
5
  "type": "module",
6
6
  "main": "src/index.js",
@@ -4,10 +4,13 @@ const WHOAMI_TIMEOUT_MS = 60000;
4
4
  const FIND_PEOPLE_TIMEOUT_MS = 90000;
5
5
  const COUNT_PEOPLE_TIMEOUT_MS = 120000;
6
6
 
7
+ const SEARCH_FILE_THRESHOLD = 8192;
8
+ const OPEN_FILE_THRESHOLD = 4096;
9
+
7
10
  const SEARCH_TOOL = {
8
11
  name: "search",
9
12
  description:
10
- "Search across Microsoft 365 data including emails, files, Teams chats, calendar events, and external connectors.",
13
+ "Search across Microsoft 365 data including emails, files, Teams chats, calendar events, and external connectors. Large result sets are saved to a local temp file — use the returned file_path with your file-reading tool to access the full results.",
11
14
  inputSchema: {
12
15
  type: "object",
13
16
  properties: {
@@ -271,7 +274,7 @@ export function registerTools(registry, context) {
271
274
  const readHandle = makeReadHandle(context.readHandleCache, readContext);
272
275
 
273
276
  // Only expose the opaque handle to agents; never return internal read context.
274
- return {
277
+ const entry = {
275
278
  index: Number.isInteger(publicRow.index) ? publicRow.index : index,
276
279
  type: publicRow.type || "",
277
280
  title: publicRow.title || "",
@@ -300,9 +303,18 @@ export function registerTools(registry, context) {
300
303
  email: publicRow.email,
301
304
  _readHandle: readHandle
302
305
  };
306
+
307
+ // Strip null/undefined fields to reduce payload size
308
+ for (const key of Object.keys(entry)) {
309
+ if (entry[key] == null) {
310
+ delete entry[key];
311
+ }
312
+ }
313
+
314
+ return entry;
303
315
  });
304
316
 
305
- return {
317
+ const response = {
306
318
  results: transformedResults,
307
319
  totalEstimatedMatches: Number(resultObject.totalEstimatedMatches || 0),
308
320
  moreAvailable: Boolean(resultObject.moreAvailable),
@@ -312,6 +324,24 @@ export function registerTools(registry, context) {
312
324
  : from + transformedResults.length,
313
325
  warnings: Array.isArray(resultObject.warnings) ? resultObject.warnings : []
314
326
  };
327
+
328
+ const responseJson = JSON.stringify(response);
329
+ const responseBytes = Buffer.byteLength(responseJson, "utf-8");
330
+
331
+ if (responseBytes > SEARCH_FILE_THRESHOLD) {
332
+ const filePath = context.tempFiles.write(responseJson);
333
+ return {
334
+ result_count: transformedResults.length,
335
+ file_path: filePath,
336
+ file_size_bytes: responseBytes,
337
+ totalEstimatedMatches: response.totalEstimatedMatches,
338
+ moreAvailable: response.moreAvailable,
339
+ nextFrom: response.nextFrom,
340
+ warnings: response.warnings
341
+ };
342
+ }
343
+
344
+ return response;
315
345
  });
316
346
 
317
347
  registry.addTool(OPEN_TOOL, async (args) => {
@@ -345,8 +375,7 @@ export function registerTools(registry, context) {
345
375
  : (result.content != null ? JSON.stringify(result.content, null, 2) : "");
346
376
  const contentBytes = Buffer.byteLength(content, "utf-8");
347
377
 
348
- const FILE_THRESHOLD = 4096;
349
- const useFile = contentBytes > FILE_THRESHOLD;
378
+ const useFile = contentBytes > OPEN_FILE_THRESHOLD;
350
379
 
351
380
  const summary = {
352
381
  type: readContext.type || result.type || "",