@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.
- package/cjs/tools/query.js +15 -2
- package/cjs/tools/search.js +125 -50
- package/esm/tools/query.d.ts.map +1 -1
- package/esm/tools/query.js +15 -2
- package/esm/tools/query.js.map +1 -1
- package/esm/tools/search.d.ts +3 -3
- package/esm/tools/search.d.ts.map +1 -1
- package/esm/tools/search.js +126 -51
- package/esm/tools/search.js.map +1 -1
- package/package.json +2 -2
package/cjs/tools/query.js
CHANGED
|
@@ -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 (
|
|
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
|
-
|
|
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
|
}
|
package/cjs/tools/search.js
CHANGED
|
@@ -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:
|
|
15
|
-
description: `Search
|
|
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
|
|
18
|
-
- Message
|
|
19
|
-
- To find specific conversations or
|
|
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
|
|
25
|
-
- "Search for
|
|
24
|
+
- "Show me meetings with the marketing team"
|
|
25
|
+
- "Search for updates about the deadline"`,
|
|
26
26
|
inputSchema: {
|
|
27
|
-
type:
|
|
27
|
+
type: 'object',
|
|
28
28
|
properties: {
|
|
29
29
|
query: {
|
|
30
|
-
type:
|
|
31
|
-
description:
|
|
30
|
+
type: 'string',
|
|
31
|
+
description: 'The search query (semantic, not keyword-based)',
|
|
32
32
|
},
|
|
33
33
|
after_date: {
|
|
34
|
-
type:
|
|
35
|
-
description:
|
|
34
|
+
type: 'string',
|
|
35
|
+
description: 'Optional: Only include results after this date (YYYY-MM-DD format)',
|
|
36
36
|
},
|
|
37
37
|
before_date: {
|
|
38
|
-
type:
|
|
39
|
-
description:
|
|
38
|
+
type: 'string',
|
|
39
|
+
description: 'Optional: Only include results before this date (YYYY-MM-DD format)',
|
|
40
40
|
},
|
|
41
41
|
sender_domains: {
|
|
42
|
-
type:
|
|
43
|
-
items: { type:
|
|
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:
|
|
47
|
+
type: 'boolean',
|
|
48
48
|
// NOTE: The "200 characters" must match MAX_BODY_PREVIEW_LENGTH in constants.ts
|
|
49
|
-
description:
|
|
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: [
|
|
53
|
+
required: ['query'],
|
|
54
54
|
},
|
|
55
55
|
annotations: {
|
|
56
|
-
title:
|
|
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
|
|
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
|
-
|
|
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
|
|
82
|
-
|
|
83
|
-
|
|
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
|
-
|
|
86
|
-
|
|
87
|
-
return `Found ${messageCount} messages, but conversation data is unavailable.`;
|
|
117
|
+
if (eventCount > 0) {
|
|
118
|
+
summaryParts.push(pluralize(eventCount, 'event', 'events'));
|
|
88
119
|
}
|
|
89
|
-
|
|
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
|
-
|
|
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
|
-
|
|
124
|
-
|
|
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 +=
|
|
167
|
+
result += '[Message content not included]';
|
|
140
168
|
}
|
|
141
|
-
result +=
|
|
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 +
|
|
211
|
+
const totalSkipped = skippedConversations +
|
|
212
|
+
skippedThreads +
|
|
213
|
+
skippedMessages +
|
|
214
|
+
skippedMeetings +
|
|
215
|
+
skippedEvents;
|
|
147
216
|
if (totalSkipped > 0) {
|
|
148
|
-
const
|
|
217
|
+
const skippedWarnings = [];
|
|
149
218
|
if (skippedConversations > 0) {
|
|
150
|
-
|
|
219
|
+
skippedWarnings.push(`${skippedConversations} conversation(s)`);
|
|
151
220
|
}
|
|
152
221
|
if (skippedThreads > 0) {
|
|
153
|
-
|
|
222
|
+
skippedWarnings.push(`${skippedThreads} thread(s)`);
|
|
154
223
|
}
|
|
155
224
|
if (skippedMessages > 0) {
|
|
156
|
-
|
|
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: ${
|
|
233
|
+
result += `\n---\n_Note: ${skippedWarnings.join(', ')} skipped due to incomplete data._\n`;
|
|
159
234
|
}
|
|
160
235
|
return result;
|
|
161
236
|
}
|
package/esm/tools/query.d.ts.map
CHANGED
|
@@ -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,
|
|
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"}
|
package/esm/tools/query.js
CHANGED
|
@@ -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 (
|
|
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
|
-
|
|
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
|
}
|
package/esm/tools/query.js.map
CHANGED
|
@@ -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,
|
|
1
|
+
{"version":3,"file":"query.js","sourceRoot":"","sources":["../../../../../packages/mcp/src/tools/query.ts"],"names":[],"mappings":"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"}
|
package/esm/tools/search.d.ts
CHANGED
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
*
|
|
4
4
|
* MCP tool for semantic search across user context.
|
|
5
5
|
*/
|
|
6
|
-
import { Tool } from
|
|
7
|
-
import { Attrove } from
|
|
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
|
|
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,
|
|
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"}
|
package/esm/tools/search.js
CHANGED
|
@@ -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
|
|
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:
|
|
12
|
-
description: `Search
|
|
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
|
|
15
|
-
- Message
|
|
16
|
-
- To find specific conversations or
|
|
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
|
|
22
|
-
- "Search for
|
|
21
|
+
- "Show me meetings with the marketing team"
|
|
22
|
+
- "Search for updates about the deadline"`,
|
|
23
23
|
inputSchema: {
|
|
24
|
-
type:
|
|
24
|
+
type: 'object',
|
|
25
25
|
properties: {
|
|
26
26
|
query: {
|
|
27
|
-
type:
|
|
28
|
-
description:
|
|
27
|
+
type: 'string',
|
|
28
|
+
description: 'The search query (semantic, not keyword-based)',
|
|
29
29
|
},
|
|
30
30
|
after_date: {
|
|
31
|
-
type:
|
|
32
|
-
description:
|
|
31
|
+
type: 'string',
|
|
32
|
+
description: 'Optional: Only include results after this date (YYYY-MM-DD format)',
|
|
33
33
|
},
|
|
34
34
|
before_date: {
|
|
35
|
-
type:
|
|
36
|
-
description:
|
|
35
|
+
type: 'string',
|
|
36
|
+
description: 'Optional: Only include results before this date (YYYY-MM-DD format)',
|
|
37
37
|
},
|
|
38
38
|
sender_domains: {
|
|
39
|
-
type:
|
|
40
|
-
items: { type:
|
|
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:
|
|
44
|
+
type: 'boolean',
|
|
45
45
|
// NOTE: The "200 characters" must match MAX_BODY_PREVIEW_LENGTH in constants.ts
|
|
46
|
-
description:
|
|
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: [
|
|
50
|
+
required: ['query'],
|
|
51
51
|
},
|
|
52
52
|
annotations: {
|
|
53
|
-
title:
|
|
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
|
|
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
|
-
|
|
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
|
|
79
|
-
|
|
80
|
-
|
|
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
|
-
|
|
83
|
-
|
|
84
|
-
return `Found ${messageCount} messages, but conversation data is unavailable.`;
|
|
114
|
+
if (eventCount > 0) {
|
|
115
|
+
summaryParts.push(pluralize(eventCount, 'event', 'events'));
|
|
85
116
|
}
|
|
86
|
-
|
|
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
|
-
|
|
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
|
-
|
|
121
|
-
|
|
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 +=
|
|
164
|
+
result += '[Message content not included]';
|
|
137
165
|
}
|
|
138
|
-
result +=
|
|
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 +
|
|
208
|
+
const totalSkipped = skippedConversations +
|
|
209
|
+
skippedThreads +
|
|
210
|
+
skippedMessages +
|
|
211
|
+
skippedMeetings +
|
|
212
|
+
skippedEvents;
|
|
144
213
|
if (totalSkipped > 0) {
|
|
145
|
-
const
|
|
214
|
+
const skippedWarnings = [];
|
|
146
215
|
if (skippedConversations > 0) {
|
|
147
|
-
|
|
216
|
+
skippedWarnings.push(`${skippedConversations} conversation(s)`);
|
|
148
217
|
}
|
|
149
218
|
if (skippedThreads > 0) {
|
|
150
|
-
|
|
219
|
+
skippedWarnings.push(`${skippedThreads} thread(s)`);
|
|
151
220
|
}
|
|
152
221
|
if (skippedMessages > 0) {
|
|
153
|
-
|
|
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: ${
|
|
230
|
+
result += `\n---\n_Note: ${skippedWarnings.join(', ')} skipped due to incomplete data._\n`;
|
|
156
231
|
}
|
|
157
232
|
return result;
|
|
158
233
|
}
|
package/esm/tools/search.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"search.js","sourceRoot":"","sources":["../../../../../packages/mcp/src/tools/search.ts"],"names":[],"mappings":"AAAA;;;;GAIG;
|
|
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.
|
|
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.
|
|
76
|
+
"@attrove/sdk": "0.1.13",
|
|
77
77
|
"tslib": "^2.6.0"
|
|
78
78
|
},
|
|
79
79
|
"devDependencies": {
|