@attrove/mcp 0.1.12 → 0.1.13

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.
@@ -30,7 +30,7 @@ Use this tool when the user asks questions like:
30
30
  integration_ids: {
31
31
  type: "array",
32
32
  items: { type: "string" },
33
- description: "Optional: Filter to specific integration IDs (UUIDs)",
33
+ description: "Optional: Filter to specific integration IDs (int_xxx)",
34
34
  },
35
35
  include_sources: {
36
36
  type: "boolean",
@@ -68,8 +68,21 @@ async function executeQueryTool(client, input) {
68
68
  result += `\n- ${source.title}: "${source.snippet}"`;
69
69
  }
70
70
  }
71
+ const contextParts = [];
71
72
  if (response.used_message_ids?.length) {
72
- result += `\n\n_Based on ${response.used_message_ids.length} messages._`;
73
+ const n = response.used_message_ids.length;
74
+ contextParts.push(`${n} ${n === 1 ? "message" : "messages"}`);
75
+ }
76
+ if (response.used_meeting_ids?.length) {
77
+ const n = response.used_meeting_ids.length;
78
+ contextParts.push(`${n} ${n === 1 ? "meeting" : "meetings"}`);
79
+ }
80
+ if (response.used_event_ids?.length) {
81
+ const n = response.used_event_ids.length;
82
+ contextParts.push(`${n} ${n === 1 ? "event" : "events"}`);
83
+ }
84
+ if (contextParts.length > 0) {
85
+ result += `\n\n_Based on ${contextParts.join(", ")}._`;
73
86
  }
74
87
  return result;
75
88
  }
@@ -11,61 +11,73 @@ const constants_js_1 = require("../constants.js");
11
11
  * Tool definition for attrove_search.
12
12
  */
13
13
  exports.searchToolDefinition = {
14
- name: "attrove_search",
15
- description: `Search for messages or conversations in the user's own connected accounts.
14
+ name: 'attrove_search',
15
+ description: `Search messages, meetings, and calendar events in the user's own connected accounts.
16
16
 
17
- This read-only tool performs semantic search across the authenticated user's connected services and returns matching messages grouped by conversation. Only the user's own authorized data is searched. Use this when you need:
18
- - Message data without AI summarization
19
- - To find specific conversations or threads
17
+ This read-only tool performs semantic search across the authenticated user's connected services and returns matching communication context. Only the user's own authorized data is searched. Use this when you need:
18
+ - Message, meeting, or event matches without AI summarization
19
+ - To find specific conversations, meetings, or calendar events
20
20
  - To explore what information is available about a topic
21
21
 
22
22
  Use this tool when the user asks things like:
23
23
  - "Find all emails about the product launch"
24
- - "Show me conversations with the marketing team"
25
- - "Search for messages mentioning the deadline"`,
24
+ - "Show me meetings with the marketing team"
25
+ - "Search for updates about the deadline"`,
26
26
  inputSchema: {
27
- type: "object",
27
+ type: 'object',
28
28
  properties: {
29
29
  query: {
30
- type: "string",
31
- description: "The search query (semantic, not keyword-based)",
30
+ type: 'string',
31
+ description: 'The search query (semantic, not keyword-based)',
32
32
  },
33
33
  after_date: {
34
- type: "string",
35
- description: "Optional: Only include messages after this date (YYYY-MM-DD format)",
34
+ type: 'string',
35
+ description: 'Optional: Only include results after this date (YYYY-MM-DD format)',
36
36
  },
37
37
  before_date: {
38
- type: "string",
39
- description: "Optional: Only include messages before this date (YYYY-MM-DD format)",
38
+ type: 'string',
39
+ description: 'Optional: Only include results before this date (YYYY-MM-DD format)',
40
40
  },
41
41
  sender_domains: {
42
- type: "array",
43
- items: { type: "string" },
42
+ type: 'array',
43
+ items: { type: 'string' },
44
44
  description: 'Optional: Filter by sender email domains (e.g., ["acme.com"])',
45
45
  },
46
46
  include_body_text: {
47
- type: "boolean",
47
+ type: 'boolean',
48
48
  // NOTE: The "200 characters" must match MAX_BODY_PREVIEW_LENGTH in constants.ts
49
- description: "Optional: Include message body text preview (truncated to 200 characters)",
49
+ description: 'Optional: Include message body text preview (truncated to 200 characters) for message results',
50
50
  default: true,
51
51
  },
52
52
  },
53
- required: ["query"],
53
+ required: ['query'],
54
54
  },
55
55
  annotations: {
56
- title: "Search Messages",
56
+ title: 'Search Messages, Meetings & Events',
57
57
  readOnlyHint: true,
58
58
  destructiveHint: false,
59
59
  idempotentHint: true,
60
60
  openWorldHint: true,
61
61
  },
62
62
  };
63
+ /** Safely format a date string, returning a fallback for missing/invalid values. */
64
+ function formatDateSafe(dateInput) {
65
+ if (!dateInput)
66
+ return 'Unknown date';
67
+ const d = new Date(dateInput);
68
+ return Number.isNaN(d.getTime()) ? 'Invalid date' : d.toLocaleDateString();
69
+ }
70
+ /** Format a count with singular/plural label. */
71
+ function pluralize(count, singular, plural) {
72
+ return `${count} ${count === 1 ? singular : plural}`;
73
+ }
63
74
  /**
64
- * Search user messages via the SDK and format results grouped by conversation.
75
+ * Search user communication context via the SDK and format results.
65
76
  */
66
77
  async function executeSearchTool(client, input) {
67
78
  const options = {
68
79
  includeBodyText: input.include_body_text !== false,
80
+ expand: ['short_summary'],
69
81
  };
70
82
  if (input.after_date) {
71
83
  options.afterDate = input.after_date;
@@ -76,23 +88,46 @@ async function executeSearchTool(client, input) {
76
88
  if (input.sender_domains?.length) {
77
89
  options.senderDomains = input.sender_domains;
78
90
  }
79
- const response = await client.search(input.query, options);
91
+ let response;
92
+ try {
93
+ response = await client.search(input.query, options);
94
+ }
95
+ catch (error) {
96
+ const message = error instanceof Error ? error.message : String(error);
97
+ return `Search failed: ${message}. Try again or use a different query.`;
98
+ }
80
99
  // Format the response for MCP
81
- const messageCount = response.key_messages?.length ?? 0;
82
- if (messageCount === 0) {
83
- return `No messages found matching "${input.query}".`;
100
+ const messageCount = response.key_messages.length;
101
+ const meetingCount = response.key_meetings.length;
102
+ const eventCount = response.key_events.length;
103
+ if (messageCount === 0 && meetingCount === 0 && eventCount === 0) {
104
+ return `No results found matching "${input.query}".`;
105
+ }
106
+ // Build summary line
107
+ const summaryParts = [];
108
+ if (messageCount > 0) {
109
+ const conversationCount = response.conversations && typeof response.conversations === 'object'
110
+ ? Object.keys(response.conversations).length
111
+ : 0;
112
+ summaryParts.push(`${pluralize(messageCount, 'message', 'messages')} across ${pluralize(conversationCount, 'conversation', 'conversations')}`);
113
+ }
114
+ if (meetingCount > 0) {
115
+ summaryParts.push(pluralize(meetingCount, 'meeting', 'meetings'));
84
116
  }
85
- // Defensive check for conversations structure
86
- if (!response.conversations || typeof response.conversations !== "object") {
87
- return `Found ${messageCount} messages, but conversation data is unavailable.`;
117
+ if (eventCount > 0) {
118
+ summaryParts.push(pluralize(eventCount, 'event', 'events'));
88
119
  }
89
- const conversationCount = Object.keys(response.conversations).length;
90
- let result = `Found ${messageCount} relevant messages across ${conversationCount} conversations:\n`;
120
+ let result = `Found ${summaryParts.join(', ')}:\n`;
91
121
  // Track skipped data for warnings
92
122
  let skippedConversations = 0;
93
123
  let skippedThreads = 0;
94
124
  let skippedMessages = 0;
95
- for (const [convId, conv] of Object.entries(response.conversations)) {
125
+ let skippedMeetings = 0;
126
+ let skippedEvents = 0;
127
+ const conversations = response.conversations && typeof response.conversations === 'object'
128
+ ? response.conversations
129
+ : {};
130
+ for (const [convId, conv] of Object.entries(conversations)) {
96
131
  // Skip malformed conversation entries - may occur with API version mismatches or partial responses
97
132
  if (!conv || !conv.threads) {
98
133
  skippedConversations++;
@@ -120,42 +155,82 @@ async function executeSearchTool(client, input) {
120
155
  console.error("[AttroveMCP]", JSON.stringify({ level: "warn", msg: "Search skipped null message", errorId: "MCP_SEARCH_NULL_MESSAGE", conversationId: convId, threadId }));
121
156
  continue;
122
157
  }
123
- // Defensive date formatting to handle invalid dates gracefully
124
- let dateStr = "Unknown date";
125
- if (msg.received_at) {
126
- const parsedDate = new Date(msg.received_at);
127
- dateStr = Number.isNaN(parsedDate.getTime())
128
- ? "Invalid date"
129
- : parsedDate.toLocaleDateString();
130
- }
131
- result += `- **${msg.sender_name || "Unknown"}** (${dateStr}): `;
158
+ const dateStr = formatDateSafe(msg.received_at);
159
+ result += `- **${msg.sender_name || 'Unknown'}** (${dateStr}): `;
132
160
  if (msg.body_text) {
133
161
  const preview = msg.body_text.length > constants_js_1.MAX_BODY_PREVIEW_LENGTH
134
- ? msg.body_text.substring(0, constants_js_1.MAX_BODY_PREVIEW_LENGTH) + "..."
162
+ ? msg.body_text.substring(0, constants_js_1.MAX_BODY_PREVIEW_LENGTH) + '...'
135
163
  : msg.body_text;
136
- result += preview.replace(/\n/g, " ");
164
+ result += preview.replace(/\n/g, ' ');
137
165
  }
138
166
  else {
139
- result += "[Message content not included]";
167
+ result += '[Message content not included]';
140
168
  }
141
- result += "\n";
169
+ result += '\n';
142
170
  }
143
171
  }
144
172
  }
173
+ // Format meeting results
174
+ if (response.key_meetings.length > 0) {
175
+ result += `\n## Meetings\n`;
176
+ for (const meeting of response.key_meetings) {
177
+ if (!meeting) {
178
+ skippedMeetings++;
179
+ continue;
180
+ }
181
+ result += `- **${meeting.title}** (${formatDateSafe(meeting.start_time)})`;
182
+ if (meeting.has_transcript) {
183
+ result += ' [transcript available]';
184
+ }
185
+ result += '\n';
186
+ if (meeting.short_summary) {
187
+ result += ` ${meeting.short_summary}\n`;
188
+ }
189
+ }
190
+ }
191
+ // Format event results
192
+ if (response.key_events.length > 0) {
193
+ result += `\n## Calendar Events\n`;
194
+ for (const event of response.key_events) {
195
+ if (!event) {
196
+ skippedEvents++;
197
+ continue;
198
+ }
199
+ result += `- **${event.title || 'Untitled Event'}** (${formatDateSafe(event.start_time)})`;
200
+ if (event.all_day) {
201
+ result += ' [all day]';
202
+ }
203
+ result += '\n';
204
+ }
205
+ }
206
+ // Surface API-level warnings (e.g., hydration failures)
207
+ if (response.warnings && response.warnings.length > 0) {
208
+ result += `\n---\n_Server note: ${response.warnings.join(' ')}_\n`;
209
+ }
145
210
  // Add warning if data was skipped due to malformed entries
146
- const totalSkipped = skippedConversations + skippedThreads + skippedMessages;
211
+ const totalSkipped = skippedConversations +
212
+ skippedThreads +
213
+ skippedMessages +
214
+ skippedMeetings +
215
+ skippedEvents;
147
216
  if (totalSkipped > 0) {
148
- const warnings = [];
217
+ const skippedWarnings = [];
149
218
  if (skippedConversations > 0) {
150
- warnings.push(`${skippedConversations} conversation(s)`);
219
+ skippedWarnings.push(`${skippedConversations} conversation(s)`);
151
220
  }
152
221
  if (skippedThreads > 0) {
153
- warnings.push(`${skippedThreads} thread(s)`);
222
+ skippedWarnings.push(`${skippedThreads} thread(s)`);
154
223
  }
155
224
  if (skippedMessages > 0) {
156
- warnings.push(`${skippedMessages} message(s)`);
225
+ skippedWarnings.push(`${skippedMessages} message(s)`);
226
+ }
227
+ if (skippedMeetings > 0) {
228
+ skippedWarnings.push(`${skippedMeetings} meeting(s)`);
229
+ }
230
+ if (skippedEvents > 0) {
231
+ skippedWarnings.push(`${skippedEvents} event(s)`);
157
232
  }
158
- result += `\n---\n_Note: ${warnings.join(", ")} skipped due to incomplete data._\n`;
233
+ result += `\n---\n_Note: ${skippedWarnings.join(', ')} skipped due to incomplete data._\n`;
159
234
  }
160
235
  return result;
161
236
  }
@@ -1 +1 @@
1
- {"version":3,"file":"query.d.ts","sourceRoot":"","sources":["../../../../../packages/mcp/src/tools/query.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,oCAAoC,CAAC;AAC1D,OAAO,EAAE,OAAO,EAA+B,MAAM,cAAc,CAAC;AAEpE;;GAEG;AACH,eAAO,MAAM,mBAAmB,EAAE,IAsCjC,CAAC;AAEF;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;IAC3B,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B;AAED;;GAEG;AACH,wBAAsB,gBAAgB,CACpC,MAAM,EAAE,OAAO,EACf,KAAK,EAAE,cAAc,GACpB,OAAO,CAAC,MAAM,CAAC,CA2BjB"}
1
+ {"version":3,"file":"query.d.ts","sourceRoot":"","sources":["../../../../../packages/mcp/src/tools/query.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,oCAAoC,CAAC;AAC1D,OAAO,EAAE,OAAO,EAA+B,MAAM,cAAc,CAAC;AAEpE;;GAEG;AACH,eAAO,MAAM,mBAAmB,EAAE,IAsCjC,CAAC;AAEF;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;IAC3B,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B;AAED;;GAEG;AACH,wBAAsB,gBAAgB,CACpC,MAAM,EAAE,OAAO,EACf,KAAK,EAAE,cAAc,GACpB,OAAO,CAAC,MAAM,CAAC,CAwCjB"}
@@ -27,7 +27,7 @@ Use this tool when the user asks questions like:
27
27
  integration_ids: {
28
28
  type: "array",
29
29
  items: { type: "string" },
30
- description: "Optional: Filter to specific integration IDs (UUIDs)",
30
+ description: "Optional: Filter to specific integration IDs (int_xxx)",
31
31
  },
32
32
  include_sources: {
33
33
  type: "boolean",
@@ -65,8 +65,21 @@ export async function executeQueryTool(client, input) {
65
65
  result += `\n- ${source.title}: "${source.snippet}"`;
66
66
  }
67
67
  }
68
+ const contextParts = [];
68
69
  if (response.used_message_ids?.length) {
69
- result += `\n\n_Based on ${response.used_message_ids.length} messages._`;
70
+ const n = response.used_message_ids.length;
71
+ contextParts.push(`${n} ${n === 1 ? "message" : "messages"}`);
72
+ }
73
+ if (response.used_meeting_ids?.length) {
74
+ const n = response.used_meeting_ids.length;
75
+ contextParts.push(`${n} ${n === 1 ? "meeting" : "meetings"}`);
76
+ }
77
+ if (response.used_event_ids?.length) {
78
+ const n = response.used_event_ids.length;
79
+ contextParts.push(`${n} ${n === 1 ? "event" : "events"}`);
80
+ }
81
+ if (contextParts.length > 0) {
82
+ result += `\n\n_Based on ${contextParts.join(", ")}._`;
70
83
  }
71
84
  return result;
72
85
  }
@@ -1 +1 @@
1
- {"version":3,"file":"query.js","sourceRoot":"","sources":["../../../../../packages/mcp/src/tools/query.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAKH;;GAEG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAS;IACvC,IAAI,EAAE,eAAe;IACrB,WAAW,EAAE;;;;;;;;+CAQgC;IAC7C,WAAW,EAAE;QACX,IAAI,EAAE,QAAQ;QACd,UAAU,EAAE;YACV,KAAK,EAAE;gBACL,IAAI,EAAE,QAAQ;gBACd,WAAW,EAAE,8CAA8C;aAC5D;YACD,eAAe,EAAE;gBACf,IAAI,EAAE,OAAO;gBACb,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;gBACzB,WAAW,EAAE,sDAAsD;aACpE;YACD,eAAe,EAAE;gBACf,IAAI,EAAE,SAAS;gBACf,WAAW,EAAE,mDAAmD;gBAChE,OAAO,EAAE,KAAK;aACf;SACF;QACD,QAAQ,EAAE,CAAC,OAAO,CAAC;KACpB;IACD,WAAW,EAAE;QACX,KAAK,EAAE,aAAa;QACpB,YAAY,EAAE,IAAI;QAClB,eAAe,EAAE,KAAK;QACtB,cAAc,EAAE,IAAI;QACpB,aAAa,EAAE,IAAI;KACpB;CACF,CAAC;AAWF;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,MAAe,EACf,KAAqB;IAErB,MAAM,OAAO,GAAiB,EAAE,CAAC;IAEjC,IAAI,KAAK,CAAC,eAAe,EAAE,MAAM,EAAE,CAAC;QAClC,OAAO,CAAC,cAAc,GAAG,KAAK,CAAC,eAAe,CAAC;IACjD,CAAC;IACD,IAAI,KAAK,CAAC,eAAe,EAAE,CAAC;QAC1B,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC;IAChC,CAAC;IAED,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;IAE1D,8BAA8B;IAC9B,IAAI,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC;IAE7B,IAAI,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,CAAC;QAC7B,MAAM,IAAI,kBAAkB,CAAC;QAC7B,KAAK,MAAM,MAAM,IAAI,QAAQ,CAAC,OAAO,EAAE,CAAC;YACtC,MAAM,IAAI,OAAO,MAAM,CAAC,KAAK,MAAM,MAAM,CAAC,OAAO,GAAG,CAAC;QACvD,CAAC;IACH,CAAC;IAED,IAAI,QAAQ,CAAC,gBAAgB,EAAE,MAAM,EAAE,CAAC;QACtC,MAAM,IAAI,iBAAiB,QAAQ,CAAC,gBAAgB,CAAC,MAAM,aAAa,CAAC;IAC3E,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC"}
1
+ {"version":3,"file":"query.js","sourceRoot":"","sources":["../../../../../packages/mcp/src/tools/query.ts"],"names":[],"mappings":"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"}
@@ -3,8 +3,8 @@
3
3
  *
4
4
  * MCP tool for semantic search across user context.
5
5
  */
6
- import { Tool } from "@modelcontextprotocol/sdk/types.js";
7
- import { Attrove } from "@attrove/sdk";
6
+ import { Tool } from '@modelcontextprotocol/sdk/types.js';
7
+ import { Attrove } from '@attrove/sdk';
8
8
  /**
9
9
  * Tool definition for attrove_search.
10
10
  */
@@ -20,7 +20,7 @@ export interface SearchToolInput {
20
20
  include_body_text?: boolean;
21
21
  }
22
22
  /**
23
- * Search user messages via the SDK and format results grouped by conversation.
23
+ * Search user communication context via the SDK and format results.
24
24
  */
25
25
  export declare function executeSearchTool(client: Attrove, input: SearchToolInput): Promise<string>;
26
26
  //# sourceMappingURL=search.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"search.d.ts","sourceRoot":"","sources":["../../../../../packages/mcp/src/tools/search.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,oCAAoC,CAAC;AAC1D,OAAO,EACL,OAAO,EAIR,MAAM,cAAc,CAAC;AAGtB;;GAEG;AACH,eAAO,MAAM,oBAAoB,EAAE,IAqDlC,CAAC;AAEF;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,iBAAiB,CAAC,EAAE,OAAO,CAAC;CAC7B;AAED;;GAEG;AACH,wBAAsB,iBAAiB,CACrC,MAAM,EAAE,OAAO,EACf,KAAK,EAAE,eAAe,GACrB,OAAO,CAAC,MAAM,CAAC,CAqHjB"}
1
+ {"version":3,"file":"search.d.ts","sourceRoot":"","sources":["../../../../../packages/mcp/src/tools/search.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,oCAAoC,CAAC;AAC1D,OAAO,EACL,OAAO,EAOR,MAAM,cAAc,CAAC;AAGtB;;GAEG;AACH,eAAO,MAAM,oBAAoB,EAAE,IAqDlC,CAAC;AAEF;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,iBAAiB,CAAC,EAAE,OAAO,CAAC;CAC7B;AAcD;;GAEG;AACH,wBAAsB,iBAAiB,CACrC,MAAM,EAAE,OAAO,EACf,KAAK,EAAE,eAAe,GACrB,OAAO,CAAC,MAAM,CAAC,CA4LjB"}
@@ -3,66 +3,78 @@
3
3
  *
4
4
  * MCP tool for semantic search across user context.
5
5
  */
6
- import { MAX_BODY_PREVIEW_LENGTH } from "../constants.js";
6
+ import { MAX_BODY_PREVIEW_LENGTH } from '../constants.js';
7
7
  /**
8
8
  * Tool definition for attrove_search.
9
9
  */
10
10
  export const searchToolDefinition = {
11
- name: "attrove_search",
12
- description: `Search for messages or conversations in the user's own connected accounts.
11
+ name: 'attrove_search',
12
+ description: `Search messages, meetings, and calendar events in the user's own connected accounts.
13
13
 
14
- This read-only tool performs semantic search across the authenticated user's connected services and returns matching messages grouped by conversation. Only the user's own authorized data is searched. Use this when you need:
15
- - Message data without AI summarization
16
- - To find specific conversations or threads
14
+ This read-only tool performs semantic search across the authenticated user's connected services and returns matching communication context. Only the user's own authorized data is searched. Use this when you need:
15
+ - Message, meeting, or event matches without AI summarization
16
+ - To find specific conversations, meetings, or calendar events
17
17
  - To explore what information is available about a topic
18
18
 
19
19
  Use this tool when the user asks things like:
20
20
  - "Find all emails about the product launch"
21
- - "Show me conversations with the marketing team"
22
- - "Search for messages mentioning the deadline"`,
21
+ - "Show me meetings with the marketing team"
22
+ - "Search for updates about the deadline"`,
23
23
  inputSchema: {
24
- type: "object",
24
+ type: 'object',
25
25
  properties: {
26
26
  query: {
27
- type: "string",
28
- description: "The search query (semantic, not keyword-based)",
27
+ type: 'string',
28
+ description: 'The search query (semantic, not keyword-based)',
29
29
  },
30
30
  after_date: {
31
- type: "string",
32
- description: "Optional: Only include messages after this date (YYYY-MM-DD format)",
31
+ type: 'string',
32
+ description: 'Optional: Only include results after this date (YYYY-MM-DD format)',
33
33
  },
34
34
  before_date: {
35
- type: "string",
36
- description: "Optional: Only include messages before this date (YYYY-MM-DD format)",
35
+ type: 'string',
36
+ description: 'Optional: Only include results before this date (YYYY-MM-DD format)',
37
37
  },
38
38
  sender_domains: {
39
- type: "array",
40
- items: { type: "string" },
39
+ type: 'array',
40
+ items: { type: 'string' },
41
41
  description: 'Optional: Filter by sender email domains (e.g., ["acme.com"])',
42
42
  },
43
43
  include_body_text: {
44
- type: "boolean",
44
+ type: 'boolean',
45
45
  // NOTE: The "200 characters" must match MAX_BODY_PREVIEW_LENGTH in constants.ts
46
- description: "Optional: Include message body text preview (truncated to 200 characters)",
46
+ description: 'Optional: Include message body text preview (truncated to 200 characters) for message results',
47
47
  default: true,
48
48
  },
49
49
  },
50
- required: ["query"],
50
+ required: ['query'],
51
51
  },
52
52
  annotations: {
53
- title: "Search Messages",
53
+ title: 'Search Messages, Meetings & Events',
54
54
  readOnlyHint: true,
55
55
  destructiveHint: false,
56
56
  idempotentHint: true,
57
57
  openWorldHint: true,
58
58
  },
59
59
  };
60
+ /** Safely format a date string, returning a fallback for missing/invalid values. */
61
+ function formatDateSafe(dateInput) {
62
+ if (!dateInput)
63
+ return 'Unknown date';
64
+ const d = new Date(dateInput);
65
+ return Number.isNaN(d.getTime()) ? 'Invalid date' : d.toLocaleDateString();
66
+ }
67
+ /** Format a count with singular/plural label. */
68
+ function pluralize(count, singular, plural) {
69
+ return `${count} ${count === 1 ? singular : plural}`;
70
+ }
60
71
  /**
61
- * Search user messages via the SDK and format results grouped by conversation.
72
+ * Search user communication context via the SDK and format results.
62
73
  */
63
74
  export async function executeSearchTool(client, input) {
64
75
  const options = {
65
76
  includeBodyText: input.include_body_text !== false,
77
+ expand: ['short_summary'],
66
78
  };
67
79
  if (input.after_date) {
68
80
  options.afterDate = input.after_date;
@@ -73,23 +85,46 @@ export async function executeSearchTool(client, input) {
73
85
  if (input.sender_domains?.length) {
74
86
  options.senderDomains = input.sender_domains;
75
87
  }
76
- const response = await client.search(input.query, options);
88
+ let response;
89
+ try {
90
+ response = await client.search(input.query, options);
91
+ }
92
+ catch (error) {
93
+ const message = error instanceof Error ? error.message : String(error);
94
+ return `Search failed: ${message}. Try again or use a different query.`;
95
+ }
77
96
  // Format the response for MCP
78
- const messageCount = response.key_messages?.length ?? 0;
79
- if (messageCount === 0) {
80
- return `No messages found matching "${input.query}".`;
97
+ const messageCount = response.key_messages.length;
98
+ const meetingCount = response.key_meetings.length;
99
+ const eventCount = response.key_events.length;
100
+ if (messageCount === 0 && meetingCount === 0 && eventCount === 0) {
101
+ return `No results found matching "${input.query}".`;
102
+ }
103
+ // Build summary line
104
+ const summaryParts = [];
105
+ if (messageCount > 0) {
106
+ const conversationCount = response.conversations && typeof response.conversations === 'object'
107
+ ? Object.keys(response.conversations).length
108
+ : 0;
109
+ summaryParts.push(`${pluralize(messageCount, 'message', 'messages')} across ${pluralize(conversationCount, 'conversation', 'conversations')}`);
110
+ }
111
+ if (meetingCount > 0) {
112
+ summaryParts.push(pluralize(meetingCount, 'meeting', 'meetings'));
81
113
  }
82
- // Defensive check for conversations structure
83
- if (!response.conversations || typeof response.conversations !== "object") {
84
- return `Found ${messageCount} messages, but conversation data is unavailable.`;
114
+ if (eventCount > 0) {
115
+ summaryParts.push(pluralize(eventCount, 'event', 'events'));
85
116
  }
86
- const conversationCount = Object.keys(response.conversations).length;
87
- let result = `Found ${messageCount} relevant messages across ${conversationCount} conversations:\n`;
117
+ let result = `Found ${summaryParts.join(', ')}:\n`;
88
118
  // Track skipped data for warnings
89
119
  let skippedConversations = 0;
90
120
  let skippedThreads = 0;
91
121
  let skippedMessages = 0;
92
- for (const [convId, conv] of Object.entries(response.conversations)) {
122
+ let skippedMeetings = 0;
123
+ let skippedEvents = 0;
124
+ const conversations = response.conversations && typeof response.conversations === 'object'
125
+ ? response.conversations
126
+ : {};
127
+ for (const [convId, conv] of Object.entries(conversations)) {
93
128
  // Skip malformed conversation entries - may occur with API version mismatches or partial responses
94
129
  if (!conv || !conv.threads) {
95
130
  skippedConversations++;
@@ -117,42 +152,82 @@ export async function executeSearchTool(client, input) {
117
152
  console.error("[AttroveMCP]", JSON.stringify({ level: "warn", msg: "Search skipped null message", errorId: "MCP_SEARCH_NULL_MESSAGE", conversationId: convId, threadId }));
118
153
  continue;
119
154
  }
120
- // Defensive date formatting to handle invalid dates gracefully
121
- let dateStr = "Unknown date";
122
- if (msg.received_at) {
123
- const parsedDate = new Date(msg.received_at);
124
- dateStr = Number.isNaN(parsedDate.getTime())
125
- ? "Invalid date"
126
- : parsedDate.toLocaleDateString();
127
- }
128
- result += `- **${msg.sender_name || "Unknown"}** (${dateStr}): `;
155
+ const dateStr = formatDateSafe(msg.received_at);
156
+ result += `- **${msg.sender_name || 'Unknown'}** (${dateStr}): `;
129
157
  if (msg.body_text) {
130
158
  const preview = msg.body_text.length > MAX_BODY_PREVIEW_LENGTH
131
- ? msg.body_text.substring(0, MAX_BODY_PREVIEW_LENGTH) + "..."
159
+ ? msg.body_text.substring(0, MAX_BODY_PREVIEW_LENGTH) + '...'
132
160
  : msg.body_text;
133
- result += preview.replace(/\n/g, " ");
161
+ result += preview.replace(/\n/g, ' ');
134
162
  }
135
163
  else {
136
- result += "[Message content not included]";
164
+ result += '[Message content not included]';
137
165
  }
138
- result += "\n";
166
+ result += '\n';
139
167
  }
140
168
  }
141
169
  }
170
+ // Format meeting results
171
+ if (response.key_meetings.length > 0) {
172
+ result += `\n## Meetings\n`;
173
+ for (const meeting of response.key_meetings) {
174
+ if (!meeting) {
175
+ skippedMeetings++;
176
+ continue;
177
+ }
178
+ result += `- **${meeting.title}** (${formatDateSafe(meeting.start_time)})`;
179
+ if (meeting.has_transcript) {
180
+ result += ' [transcript available]';
181
+ }
182
+ result += '\n';
183
+ if (meeting.short_summary) {
184
+ result += ` ${meeting.short_summary}\n`;
185
+ }
186
+ }
187
+ }
188
+ // Format event results
189
+ if (response.key_events.length > 0) {
190
+ result += `\n## Calendar Events\n`;
191
+ for (const event of response.key_events) {
192
+ if (!event) {
193
+ skippedEvents++;
194
+ continue;
195
+ }
196
+ result += `- **${event.title || 'Untitled Event'}** (${formatDateSafe(event.start_time)})`;
197
+ if (event.all_day) {
198
+ result += ' [all day]';
199
+ }
200
+ result += '\n';
201
+ }
202
+ }
203
+ // Surface API-level warnings (e.g., hydration failures)
204
+ if (response.warnings && response.warnings.length > 0) {
205
+ result += `\n---\n_Server note: ${response.warnings.join(' ')}_\n`;
206
+ }
142
207
  // Add warning if data was skipped due to malformed entries
143
- const totalSkipped = skippedConversations + skippedThreads + skippedMessages;
208
+ const totalSkipped = skippedConversations +
209
+ skippedThreads +
210
+ skippedMessages +
211
+ skippedMeetings +
212
+ skippedEvents;
144
213
  if (totalSkipped > 0) {
145
- const warnings = [];
214
+ const skippedWarnings = [];
146
215
  if (skippedConversations > 0) {
147
- warnings.push(`${skippedConversations} conversation(s)`);
216
+ skippedWarnings.push(`${skippedConversations} conversation(s)`);
148
217
  }
149
218
  if (skippedThreads > 0) {
150
- warnings.push(`${skippedThreads} thread(s)`);
219
+ skippedWarnings.push(`${skippedThreads} thread(s)`);
151
220
  }
152
221
  if (skippedMessages > 0) {
153
- warnings.push(`${skippedMessages} message(s)`);
222
+ skippedWarnings.push(`${skippedMessages} message(s)`);
223
+ }
224
+ if (skippedMeetings > 0) {
225
+ skippedWarnings.push(`${skippedMeetings} meeting(s)`);
226
+ }
227
+ if (skippedEvents > 0) {
228
+ skippedWarnings.push(`${skippedEvents} event(s)`);
154
229
  }
155
- result += `\n---\n_Note: ${warnings.join(", ")} skipped due to incomplete data._\n`;
230
+ result += `\n---\n_Note: ${skippedWarnings.join(', ')} skipped due to incomplete data._\n`;
156
231
  }
157
232
  return result;
158
233
  }
@@ -1 +1 @@
1
- {"version":3,"file":"search.js","sourceRoot":"","sources":["../../../../../packages/mcp/src/tools/search.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"search.js","sourceRoot":"","sources":["../../../../../packages/mcp/src/tools/search.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@attrove/mcp",
3
3
  "mcpName": "com.attrove/mcp",
4
4
  "_versionNote": "Downstream files (server.json, SKILL.md) synced automatically by scripts/sync-sdk-version.js",
5
- "version": "0.1.12",
5
+ "version": "0.1.13",
6
6
  "description": "MCP server for Attrove — AI-powered context retrieval from Gmail, Slack, Calendar for Claude, Cursor, and ChatGPT",
7
7
  "type": "module",
8
8
  "main": "./cjs/index.js",
@@ -73,7 +73,7 @@
73
73
  },
74
74
  "dependencies": {
75
75
  "@modelcontextprotocol/sdk": "^1.0.0",
76
- "@attrove/sdk": "0.1.12",
76
+ "@attrove/sdk": "0.1.13",
77
77
  "tslib": "^2.6.0"
78
78
  },
79
79
  "devDependencies": {