@intangle/mcp-server 2.5.5 → 2.5.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/.env.local CHANGED
@@ -1,2 +1,3 @@
1
1
  MCP_API_KEY=mcp_placeholder_key_will_be_replaced_by_user_specific_key
2
2
  NEXT_APP_URL=https://intangle.app
3
+ VERCEL_BYPASS_TOKEN=igXBygPO1T5dWLBaVyQiN9QB7IECZ50O
package/dist/index.js CHANGED
@@ -329,16 +329,39 @@ try {
329
329
  delete: args.delete,
330
330
  });
331
331
  }
332
+ async function handleUpdateFolders(args) {
333
+ if (!args.space_id) {
334
+ throw new Error("space_id is required. Use view_spaces to see available options.");
335
+ }
336
+ const hasOperation = !!args.list ||
337
+ (Array.isArray(args.create) && args.create.length > 0) ||
338
+ (Array.isArray(args.rename) && args.rename.length > 0) ||
339
+ (Array.isArray(args.move_items) && args.move_items.length > 0) ||
340
+ (Array.isArray(args.delete) && args.delete.length > 0);
341
+ if (!hasOperation) {
342
+ throw new Error("At least one operation is required: list, create, rename, move_items, or delete.");
343
+ }
344
+ return makeApiCall("update-folders", {
345
+ space_id: args.space_id,
346
+ list: args.list,
347
+ create: args.create,
348
+ rename: args.rename,
349
+ move_items: args.move_items,
350
+ delete: args.delete,
351
+ });
352
+ }
332
353
  async function handleMessage(args) {
333
354
  if (!args.space_id || !args.content) {
334
355
  throw new Error("space_id and content are required");
335
356
  }
357
+ // Keep one-turn MCP calls safely under common external tool-call deadlines
358
+ // while still allowing caller override for longer jobs.
336
359
  const timeoutMs = typeof args.timeout_ms === "number" && Number.isFinite(args.timeout_ms)
337
360
  ? Math.max(10_000, Math.min(300_000, Math.trunc(args.timeout_ms)))
338
- : undefined;
361
+ : 100_000;
339
362
  // Give backend a little extra headroom beyond requested assistant timeout.
340
- const requestTimeout = timeoutMs ? timeoutMs + 10_000 : undefined;
341
- return makeApiCall("message", args, requestTimeout);
363
+ const requestTimeout = timeoutMs + 10_000;
364
+ return makeApiCall("message", { ...args, timeout_ms: timeoutMs }, requestTimeout);
342
365
  }
343
366
  server.setRequestHandler(CallToolRequestSchema, async (request) => {
344
367
  const { name, arguments: args } = request.params;
@@ -374,6 +397,9 @@ try {
374
397
  case "update_space":
375
398
  result = await handleUpdateSpace(args);
376
399
  break;
400
+ case "update_folders":
401
+ result = await handleUpdateFolders(args);
402
+ break;
377
403
  case "message":
378
404
  result = await handleMessage(args);
379
405
  break;
@@ -1,9 +1,9 @@
1
1
  // Tools definition - matches the stdio server
2
- export const TOOLS = [
2
+ const TOOL_DEFINITIONS = [
3
3
  {
4
4
  name: "search",
5
5
  title: "Search Space",
6
- description: "Search for context, tasks, skills, and projects within a space. System automatically extracts quantity from natural language ('show 3 tasks' → 3 results, 'the last one' → 1 result) and intelligently formats results (1-3 items → summaries, 4+ items → IDs only). Use fetch tool to get full content for specific IDs when needed.",
6
+ description: "Search for context, tasks, skills, and projects within a space. System automatically extracts quantity from natural language ('show 3 tasks' → 3 results, 'the last one' → 1 result) and intelligently formats results (1-3 items → summaries, 4+ items → IDs only). Default to one search per question, then use fetch_items for full details instead of repeating paraphrased searches.",
7
7
  inputSchema: {
8
8
  type: "object",
9
9
  properties: {
@@ -90,7 +90,7 @@ export const TOOLS = [
90
90
  {
91
91
  name: "start",
92
92
  title: "Start Space Session",
93
- description: "Begin working in a space. Returns a dynamic briefing including: recent developments, current priorities, active tasks, user preferences for this space, and learned insights about how the user/org works. Use this context to personalize your assistance and anticipate needs.",
93
+ description: "Load a space fast for a new external caller. Returns assistant-curated current items, useful insights, skills, recent conversations, and assistant preferences so the caller can get oriented quickly and fetch deeper details only when needed.",
94
94
  inputSchema: {
95
95
  type: "object",
96
96
  properties: {
@@ -157,7 +157,7 @@ export const TOOLS = [
157
157
  {
158
158
  name: "update_memory",
159
159
  title: "Update Memory",
160
- description: "Add, update, or delete items in a space. Supports any combination of operations in a single call.\n\nTIPS FOR RICH MEMORY: The more context you provide, the smarter the system becomes:\n- Include WHY something matters, not just WHAT it is\n- Note user preferences, patterns, and approaches you observe\n- Describe repeatable workflows as skills (step-by-step procedures)\n- Link related items using parent_id or linkedItemIds\n- Use descriptive titles that capture the essence\n- Add context about decisions, reasoning, and outcomes\n\nThe system learns from patterns - sharing how the user works helps it anticipate their needs.",
160
+ description: "Add, update, or delete items in a space. Supports any combination of operations in a single call.\n\nIMPORTANT: Include at least one operation: add, update, or delete.\n\nTIPS FOR RICH MEMORY: The more context you provide, the smarter the system becomes:\n- Include WHY something matters, not just WHAT it is\n- Note user preferences, patterns, and approaches you observe\n- Describe repeatable workflows as skills (step-by-step procedures)\n- Link related items using parent_id or linkedItemIds\n- Use descriptive titles that capture the essence\n- Add context about decisions, reasoning, and outcomes\n\nThe system learns from patterns - sharing how the user works helps it anticipate their needs.",
161
161
  inputSchema: {
162
162
  type: "object",
163
163
  properties: {
@@ -185,8 +185,8 @@ export const TOOLS = [
185
185
  },
186
186
  type: {
187
187
  type: "string",
188
- enum: ["task", "context", "skill", "document"],
189
- description: "REQUIRED: Item type. 'task' for actionable items, 'context' for knowledge/facts, 'skill' for workflows, 'document' for long-form reference material. Omitting this triggers expensive auto-classification."
188
+ enum: ["task", "context", "skill", "document", "insight"],
189
+ description: "REQUIRED: Item type. 'task' for actionable items, 'context' for knowledge/facts, 'skill' for workflows, 'document' for long-form reference material, 'insight' for durable patterns/principles. Omitting this triggers expensive auto-classification."
190
190
  },
191
191
  subtasks: {
192
192
  type: "array",
@@ -306,7 +306,111 @@ export const TOOLS = [
306
306
  }
307
307
  }
308
308
  },
309
- required: ["space_id"]
309
+ required: ["space_id"],
310
+ anyOf: [{ required: ["add"] }, { required: ["update"] }, { required: ["delete"] }]
311
+ }
312
+ },
313
+ {
314
+ name: "update_folders",
315
+ title: "Update Folders",
316
+ description: "Unified folder management. Supports list, create, rename, move_items, and delete operations in one call so external MCP callers can organize memory the same way as the in-app assistant.",
317
+ inputSchema: {
318
+ type: "object",
319
+ properties: {
320
+ space_id: {
321
+ type: "string",
322
+ description: "REQUIRED: Space to operate in (use view_spaces to see available options)."
323
+ },
324
+ list: {
325
+ type: "object",
326
+ description: "Optional list operation. Use this first to discover existing folders and IDs.",
327
+ properties: {
328
+ section_type: {
329
+ type: "string",
330
+ enum: [
331
+ "projects",
332
+ "insights",
333
+ "insights_space",
334
+ "insights_user",
335
+ "agents",
336
+ "skills",
337
+ "conversations",
338
+ "dashboard"
339
+ ],
340
+ description: "Optional: filter folders by sidebar section."
341
+ }
342
+ }
343
+ },
344
+ create: {
345
+ type: "array",
346
+ description: "Optional create operations.",
347
+ items: {
348
+ type: "object",
349
+ properties: {
350
+ name: { type: "string", description: "Folder name." },
351
+ section_type: {
352
+ type: "string",
353
+ enum: [
354
+ "projects",
355
+ "insights",
356
+ "insights_space",
357
+ "insights_user",
358
+ "agents",
359
+ "skills",
360
+ "conversations",
361
+ "dashboard"
362
+ ],
363
+ description: "Sidebar section this folder belongs to."
364
+ },
365
+ parent_id: {
366
+ type: "string",
367
+ description: "Optional parent folder ID for nesting."
368
+ }
369
+ },
370
+ required: ["name", "section_type"]
371
+ }
372
+ },
373
+ rename: {
374
+ type: "array",
375
+ description: "Optional rename operations.",
376
+ items: {
377
+ type: "object",
378
+ properties: {
379
+ folder_id: { type: "string", description: "Folder ID to rename." },
380
+ new_name: { type: "string", description: "New folder name." }
381
+ },
382
+ required: ["folder_id", "new_name"]
383
+ }
384
+ },
385
+ move_items: {
386
+ type: "array",
387
+ description: "Optional item move operations. Set folder_id to null to move an item back to root.",
388
+ items: {
389
+ type: "object",
390
+ properties: {
391
+ item_id: { type: "string", description: "Item ID to move." },
392
+ folder_id: {
393
+ type: ["string", "null"],
394
+ description: "Target folder ID, or null to remove from folder."
395
+ }
396
+ },
397
+ required: ["item_id", "folder_id"]
398
+ }
399
+ },
400
+ delete: {
401
+ type: "array",
402
+ description: "Optional delete operations (folder IDs).",
403
+ items: { type: "string" }
404
+ }
405
+ },
406
+ required: ["space_id"],
407
+ anyOf: [
408
+ { required: ["list"] },
409
+ { required: ["create"] },
410
+ { required: ["rename"] },
411
+ { required: ["move_items"] },
412
+ { required: ["delete"] }
413
+ ]
310
414
  }
311
415
  },
312
416
  {
@@ -357,7 +461,7 @@ export const TOOLS = [
357
461
  }
358
462
  }
359
463
  // DISABLED: memory_action tool is broken and causing errors.
360
- // Pending OHM protocol fix. Use update_space, search, or fetch_items instead.
464
+ // Pending OHM protocol fix. Use update_memory, search, or fetch_items instead.
361
465
  // {
362
466
  // name: "memory_action",
363
467
  // title: "Memory Action (OHM Protocol)",
@@ -380,3 +484,31 @@ export const TOOLS = [
380
484
  // }
381
485
  // }
382
486
  ];
487
+ const READ_ONLY_TOOLS = new Set([
488
+ "search",
489
+ "fetch_items",
490
+ "start",
491
+ "view_spaces",
492
+ "view_space"
493
+ ]);
494
+ const DESTRUCTIVE_TOOLS = new Set([
495
+ "create_space",
496
+ "update_memory",
497
+ "update_folders"
498
+ ]);
499
+ const IDEMPOTENT_TOOLS = new Set([
500
+ "search",
501
+ "fetch_items",
502
+ "start",
503
+ "view_spaces",
504
+ "view_space"
505
+ ]);
506
+ export const TOOLS = TOOL_DEFINITIONS.map((tool) => ({
507
+ ...tool,
508
+ annotations: {
509
+ ...(READ_ONLY_TOOLS.has(tool.name) ? { readOnlyHint: true } : {}),
510
+ ...(DESTRUCTIVE_TOOLS.has(tool.name) ? { destructiveHint: true } : {}),
511
+ ...(IDEMPOTENT_TOOLS.has(tool.name) ? { idempotentHint: true } : {}),
512
+ openWorldHint: true
513
+ }
514
+ }));
package/index.ts CHANGED
@@ -448,20 +448,56 @@ try {
448
448
  })
449
449
  }
450
450
 
451
+ async function handleUpdateFolders(args: any) {
452
+ if (!args.space_id) {
453
+ throw new Error(
454
+ "space_id is required. Use view_spaces to see available options."
455
+ )
456
+ }
457
+
458
+ const hasOperation =
459
+ !!args.list ||
460
+ (Array.isArray(args.create) && args.create.length > 0) ||
461
+ (Array.isArray(args.rename) && args.rename.length > 0) ||
462
+ (Array.isArray(args.move_items) && args.move_items.length > 0) ||
463
+ (Array.isArray(args.delete) && args.delete.length > 0)
464
+
465
+ if (!hasOperation) {
466
+ throw new Error(
467
+ "At least one operation is required: list, create, rename, move_items, or delete."
468
+ )
469
+ }
470
+
471
+ return makeApiCall("update-folders", {
472
+ space_id: args.space_id,
473
+ list: args.list,
474
+ create: args.create,
475
+ rename: args.rename,
476
+ move_items: args.move_items,
477
+ delete: args.delete,
478
+ })
479
+ }
480
+
451
481
  async function handleMessage(args: any) {
452
482
  if (!args.space_id || !args.content) {
453
483
  throw new Error("space_id and content are required")
454
484
  }
455
485
 
486
+ // Keep one-turn MCP calls safely under common external tool-call deadlines
487
+ // while still allowing caller override for longer jobs.
456
488
  const timeoutMs =
457
489
  typeof args.timeout_ms === "number" && Number.isFinite(args.timeout_ms)
458
490
  ? Math.max(10_000, Math.min(300_000, Math.trunc(args.timeout_ms)))
459
- : undefined
491
+ : 100_000
460
492
 
461
493
  // Give backend a little extra headroom beyond requested assistant timeout.
462
- const requestTimeout = timeoutMs ? timeoutMs + 10_000 : undefined
494
+ const requestTimeout = timeoutMs + 10_000
463
495
 
464
- return makeApiCall("message", args, requestTimeout)
496
+ return makeApiCall(
497
+ "message",
498
+ { ...args, timeout_ms: timeoutMs },
499
+ requestTimeout
500
+ )
465
501
  }
466
502
 
467
503
  server.setRequestHandler(CallToolRequestSchema, async (request: any) => {
@@ -500,6 +536,9 @@ try {
500
536
  case "update_space":
501
537
  result = await handleUpdateSpace(args)
502
538
  break
539
+ case "update_folders":
540
+ result = await handleUpdateFolders(args)
541
+ break
503
542
  case "message":
504
543
  result = await handleMessage(args)
505
544
  break
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@intangle/mcp-server",
3
- "version": "2.5.5",
3
+ "version": "2.5.6",
4
4
  "description": "Model Context Protocol server for Intangle - AI context that persists across conversations",
5
5
  "main": "dist/index.js",
6
6
  "type": "module",
@@ -1,10 +1,10 @@
1
1
  // Tools definition - matches the stdio server
2
- export const TOOLS = [
2
+ const TOOL_DEFINITIONS = [
3
3
  {
4
4
  name: "search",
5
5
  title: "Search Space",
6
6
  description:
7
- "Search for context, tasks, skills, and projects within a space. System automatically extracts quantity from natural language ('show 3 tasks' → 3 results, 'the last one' → 1 result) and intelligently formats results (1-3 items → summaries, 4+ items → IDs only). Use fetch tool to get full content for specific IDs when needed.",
7
+ "Search for context, tasks, skills, and projects within a space. System automatically extracts quantity from natural language ('show 3 tasks' → 3 results, 'the last one' → 1 result) and intelligently formats results (1-3 items → summaries, 4+ items → IDs only). Default to one search per question, then use fetch_items for full details instead of repeating paraphrased searches.",
8
8
  inputSchema: {
9
9
  type: "object",
10
10
  properties: {
@@ -97,7 +97,7 @@ export const TOOLS = [
97
97
  name: "start",
98
98
  title: "Start Space Session",
99
99
  description:
100
- "Begin working in a space. Returns a dynamic briefing including: recent developments, current priorities, active tasks, user preferences for this space, and learned insights about how the user/org works. Use this context to personalize your assistance and anticipate needs.",
100
+ "Load a space fast for a new external caller. Returns assistant-curated current items, useful insights, skills, recent conversations, and assistant preferences so the caller can get oriented quickly and fetch deeper details only when needed.",
101
101
  inputSchema: {
102
102
  type: "object",
103
103
  properties: {
@@ -171,7 +171,7 @@ export const TOOLS = [
171
171
  name: "update_memory",
172
172
  title: "Update Memory",
173
173
  description:
174
- "Add, update, or delete items in a space. Supports any combination of operations in a single call.\n\nTIPS FOR RICH MEMORY: The more context you provide, the smarter the system becomes:\n- Include WHY something matters, not just WHAT it is\n- Note user preferences, patterns, and approaches you observe\n- Describe repeatable workflows as skills (step-by-step procedures)\n- Link related items using parent_id or linkedItemIds\n- Use descriptive titles that capture the essence\n- Add context about decisions, reasoning, and outcomes\n\nThe system learns from patterns - sharing how the user works helps it anticipate their needs.",
174
+ "Add, update, or delete items in a space. Supports any combination of operations in a single call.\n\nIMPORTANT: Include at least one operation: add, update, or delete.\n\nTIPS FOR RICH MEMORY: The more context you provide, the smarter the system becomes:\n- Include WHY something matters, not just WHAT it is\n- Note user preferences, patterns, and approaches you observe\n- Describe repeatable workflows as skills (step-by-step procedures)\n- Link related items using parent_id or linkedItemIds\n- Use descriptive titles that capture the essence\n- Add context about decisions, reasoning, and outcomes\n\nThe system learns from patterns - sharing how the user works helps it anticipate their needs.",
175
175
  inputSchema: {
176
176
  type: "object",
177
177
  properties: {
@@ -203,9 +203,9 @@ export const TOOLS = [
203
203
  },
204
204
  type: {
205
205
  type: "string",
206
- enum: ["task", "context", "skill", "document"],
206
+ enum: ["task", "context", "skill", "document", "insight"],
207
207
  description:
208
- "REQUIRED: Item type. 'task' for actionable items, 'context' for knowledge/facts, 'skill' for workflows, 'document' for long-form reference material. Omitting this triggers expensive auto-classification."
208
+ "REQUIRED: Item type. 'task' for actionable items, 'context' for knowledge/facts, 'skill' for workflows, 'document' for long-form reference material, 'insight' for durable patterns/principles. Omitting this triggers expensive auto-classification."
209
209
  },
210
210
  subtasks: {
211
211
  type: "array",
@@ -339,7 +339,115 @@ export const TOOLS = [
339
339
  }
340
340
  }
341
341
  },
342
- required: ["space_id"]
342
+ required: ["space_id"],
343
+ anyOf: [{ required: ["add"] }, { required: ["update"] }, { required: ["delete"] }]
344
+ }
345
+ },
346
+ {
347
+ name: "update_folders",
348
+ title: "Update Folders",
349
+ description:
350
+ "Unified folder management. Supports list, create, rename, move_items, and delete operations in one call so external MCP callers can organize memory the same way as the in-app assistant.",
351
+ inputSchema: {
352
+ type: "object",
353
+ properties: {
354
+ space_id: {
355
+ type: "string",
356
+ description:
357
+ "REQUIRED: Space to operate in (use view_spaces to see available options)."
358
+ },
359
+ list: {
360
+ type: "object",
361
+ description:
362
+ "Optional list operation. Use this first to discover existing folders and IDs.",
363
+ properties: {
364
+ section_type: {
365
+ type: "string",
366
+ enum: [
367
+ "projects",
368
+ "insights",
369
+ "insights_space",
370
+ "insights_user",
371
+ "agents",
372
+ "skills",
373
+ "conversations",
374
+ "dashboard"
375
+ ],
376
+ description: "Optional: filter folders by sidebar section."
377
+ }
378
+ }
379
+ },
380
+ create: {
381
+ type: "array",
382
+ description: "Optional create operations.",
383
+ items: {
384
+ type: "object",
385
+ properties: {
386
+ name: { type: "string", description: "Folder name." },
387
+ section_type: {
388
+ type: "string",
389
+ enum: [
390
+ "projects",
391
+ "insights",
392
+ "insights_space",
393
+ "insights_user",
394
+ "agents",
395
+ "skills",
396
+ "conversations",
397
+ "dashboard"
398
+ ],
399
+ description: "Sidebar section this folder belongs to."
400
+ },
401
+ parent_id: {
402
+ type: "string",
403
+ description: "Optional parent folder ID for nesting."
404
+ }
405
+ },
406
+ required: ["name", "section_type"]
407
+ }
408
+ },
409
+ rename: {
410
+ type: "array",
411
+ description: "Optional rename operations.",
412
+ items: {
413
+ type: "object",
414
+ properties: {
415
+ folder_id: { type: "string", description: "Folder ID to rename." },
416
+ new_name: { type: "string", description: "New folder name." }
417
+ },
418
+ required: ["folder_id", "new_name"]
419
+ }
420
+ },
421
+ move_items: {
422
+ type: "array",
423
+ description:
424
+ "Optional item move operations. Set folder_id to null to move an item back to root.",
425
+ items: {
426
+ type: "object",
427
+ properties: {
428
+ item_id: { type: "string", description: "Item ID to move." },
429
+ folder_id: {
430
+ type: ["string", "null"],
431
+ description: "Target folder ID, or null to remove from folder."
432
+ }
433
+ },
434
+ required: ["item_id", "folder_id"]
435
+ }
436
+ },
437
+ delete: {
438
+ type: "array",
439
+ description: "Optional delete operations (folder IDs).",
440
+ items: { type: "string" }
441
+ }
442
+ },
443
+ required: ["space_id"],
444
+ anyOf: [
445
+ { required: ["list"] },
446
+ { required: ["create"] },
447
+ { required: ["rename"] },
448
+ { required: ["move_items"] },
449
+ { required: ["delete"] }
450
+ ]
343
451
  }
344
452
  },
345
453
  {
@@ -396,7 +504,7 @@ export const TOOLS = [
396
504
  }
397
505
  }
398
506
  // DISABLED: memory_action tool is broken and causing errors.
399
- // Pending OHM protocol fix. Use update_space, search, or fetch_items instead.
507
+ // Pending OHM protocol fix. Use update_memory, search, or fetch_items instead.
400
508
  // {
401
509
  // name: "memory_action",
402
510
  // title: "Memory Action (OHM Protocol)",
@@ -419,3 +527,35 @@ export const TOOLS = [
419
527
  // }
420
528
  // }
421
529
  ]
530
+
531
+ const READ_ONLY_TOOLS = new Set([
532
+ "search",
533
+ "fetch_items",
534
+ "start",
535
+ "view_spaces",
536
+ "view_space"
537
+ ])
538
+
539
+ const DESTRUCTIVE_TOOLS = new Set([
540
+ "create_space",
541
+ "update_memory",
542
+ "update_folders"
543
+ ])
544
+
545
+ const IDEMPOTENT_TOOLS = new Set([
546
+ "search",
547
+ "fetch_items",
548
+ "start",
549
+ "view_spaces",
550
+ "view_space"
551
+ ])
552
+
553
+ export const TOOLS = TOOL_DEFINITIONS.map((tool) => ({
554
+ ...tool,
555
+ annotations: {
556
+ ...(READ_ONLY_TOOLS.has(tool.name) ? { readOnlyHint: true } : {}),
557
+ ...(DESTRUCTIVE_TOOLS.has(tool.name) ? { destructiveHint: true } : {}),
558
+ ...(IDEMPOTENT_TOOLS.has(tool.name) ? { idempotentHint: true } : {}),
559
+ openWorldHint: true
560
+ }
561
+ }))