salesflare-mcp-server 1.0.0
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/API.md +691 -0
- package/CHANGELOG.md +49 -0
- package/CLAUDE.md +117 -0
- package/CONTRIBUTING.md +399 -0
- package/FIX_PLAN.md +70 -0
- package/INSPECTOR.md +191 -0
- package/LICENSE +21 -0
- package/PUBLISH.md +73 -0
- package/README.md +383 -0
- package/dist/auth/api-key-auth.d.ts +75 -0
- package/dist/auth/api-key-auth.d.ts.map +1 -0
- package/dist/auth/api-key-auth.js +103 -0
- package/dist/auth/oauth-auth.d.ts +81 -0
- package/dist/auth/oauth-auth.d.ts.map +1 -0
- package/dist/auth/oauth-auth.js +123 -0
- package/dist/auth/token-manager.d.ts +105 -0
- package/dist/auth/token-manager.d.ts.map +1 -0
- package/dist/auth/token-manager.js +87 -0
- package/dist/client/salesflare-client.d.ts +219 -0
- package/dist/client/salesflare-client.d.ts.map +1 -0
- package/dist/client/salesflare-client.js +484 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +82 -0
- package/dist/server.d.ts +39 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +140 -0
- package/dist/tools/companies.d.ts +45 -0
- package/dist/tools/companies.d.ts.map +1 -0
- package/dist/tools/companies.js +392 -0
- package/dist/tools/contacts.d.ts +45 -0
- package/dist/tools/contacts.d.ts.map +1 -0
- package/dist/tools/contacts.js +290 -0
- package/dist/tools/deals.d.ts +46 -0
- package/dist/tools/deals.d.ts.map +1 -0
- package/dist/tools/deals.js +442 -0
- package/dist/tools/pipeline.d.ts +43 -0
- package/dist/tools/pipeline.d.ts.map +1 -0
- package/dist/tools/pipeline.js +328 -0
- package/dist/tools/tasks.d.ts +44 -0
- package/dist/tools/tasks.d.ts.map +1 -0
- package/dist/tools/tasks.js +406 -0
- package/dist/transport/http-transport.d.ts +36 -0
- package/dist/transport/http-transport.d.ts.map +1 -0
- package/dist/transport/http-transport.js +173 -0
- package/dist/transport/stdio-transport.d.ts +37 -0
- package/dist/transport/stdio-transport.d.ts.map +1 -0
- package/dist/transport/stdio-transport.js +129 -0
- package/dist/types/company.d.ts +223 -0
- package/dist/types/company.d.ts.map +1 -0
- package/dist/types/company.js +8 -0
- package/dist/types/contact.d.ts +166 -0
- package/dist/types/contact.d.ts.map +1 -0
- package/dist/types/contact.js +8 -0
- package/dist/types/deal.d.ts +203 -0
- package/dist/types/deal.d.ts.map +1 -0
- package/dist/types/deal.js +8 -0
- package/dist/types/pipeline.d.ts +116 -0
- package/dist/types/pipeline.d.ts.map +1 -0
- package/dist/types/pipeline.js +8 -0
- package/dist/types/task.d.ts +154 -0
- package/dist/types/task.d.ts.map +1 -0
- package/dist/types/task.js +8 -0
- package/dist/utils/errors.d.ts +128 -0
- package/dist/utils/errors.d.ts.map +1 -0
- package/dist/utils/errors.js +205 -0
- package/dist/utils/validation.d.ts +354 -0
- package/dist/utils/validation.d.ts.map +1 -0
- package/dist/utils/validation.js +716 -0
- package/package.json +49 -0
- package/test-tasks-debug.js +21 -0
- package/test-tasks-params.js +52 -0
- package/test-tools.js +171 -0
|
@@ -0,0 +1,392 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Company tools for Salesflare MCP Server
|
|
3
|
+
*
|
|
4
|
+
* Implements CRUD operations for companies:
|
|
5
|
+
* - salesflare_companies_list: List companies with filtering and pagination
|
|
6
|
+
* - salesflare_companies_create: Create new companies
|
|
7
|
+
* - salesflare_companies_update: Update existing companies
|
|
8
|
+
* - salesflare_companies_delete: Delete companies
|
|
9
|
+
*
|
|
10
|
+
* @module tools/companies
|
|
11
|
+
*/
|
|
12
|
+
import { SalesflareError, ErrorCode } from '../utils/errors.js';
|
|
13
|
+
/**
|
|
14
|
+
* Company tool definitions with JSON schemas
|
|
15
|
+
*/
|
|
16
|
+
const companyTools = [
|
|
17
|
+
{
|
|
18
|
+
name: 'salesflare_companies_list',
|
|
19
|
+
description: 'List companies from Salesflare CRM with optional filtering and pagination. ' +
|
|
20
|
+
'Supports filtering by name (partial match), industry (exact match), tags (AND logic), owner, and search. ' +
|
|
21
|
+
'Returns paginated results with total count and has_more indicator.',
|
|
22
|
+
inputSchema: {
|
|
23
|
+
type: 'object',
|
|
24
|
+
properties: {
|
|
25
|
+
name: { type: 'string', description: 'Filter by name (partial match, case-insensitive)' },
|
|
26
|
+
industry: { type: 'string', description: 'Filter by industry (exact match)' },
|
|
27
|
+
tags: { type: 'array', items: { type: 'string' }, description: 'Filter by tags (companies must have all specified tags)' },
|
|
28
|
+
owner: { type: 'string', description: 'Filter by owner ID or name' },
|
|
29
|
+
search: { type: 'string', description: 'Free-text search across company fields' },
|
|
30
|
+
page: { type: 'number', description: 'Page number (default: 1)' },
|
|
31
|
+
limit: { type: 'number', description: 'Items per page (default: 20, max: 100)' },
|
|
32
|
+
},
|
|
33
|
+
},
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
name: 'salesflare_companies_create',
|
|
37
|
+
description: 'Create a new company in Salesflare CRM. ' +
|
|
38
|
+
'Name is required. Optional fields include website, industry, phone, description, address, social_media, tags, and owner_id.',
|
|
39
|
+
inputSchema: {
|
|
40
|
+
type: 'object',
|
|
41
|
+
properties: {
|
|
42
|
+
name: { type: 'string', description: 'Company name (required)' },
|
|
43
|
+
website: { type: 'string', description: 'Company website URL' },
|
|
44
|
+
industry: { type: 'string', description: 'Industry category' },
|
|
45
|
+
phone: { type: 'string', description: 'Phone number' },
|
|
46
|
+
description: { type: 'string', description: 'Company description' },
|
|
47
|
+
address: {
|
|
48
|
+
type: 'object',
|
|
49
|
+
description: 'Address information',
|
|
50
|
+
properties: {
|
|
51
|
+
street: { type: 'string', description: 'Street address' },
|
|
52
|
+
city: { type: 'string', description: 'City' },
|
|
53
|
+
state: { type: 'string', description: 'State or province' },
|
|
54
|
+
zip: { type: 'string', description: 'ZIP or postal code' },
|
|
55
|
+
country: { type: 'string', description: 'Country' },
|
|
56
|
+
},
|
|
57
|
+
},
|
|
58
|
+
social_media: {
|
|
59
|
+
type: 'object',
|
|
60
|
+
description: 'Social media profiles',
|
|
61
|
+
properties: {
|
|
62
|
+
linkedin: { type: 'string', description: 'LinkedIn profile URL' },
|
|
63
|
+
twitter: { type: 'string', description: 'Twitter/X handle or URL' },
|
|
64
|
+
facebook: { type: 'string', description: 'Facebook page URL' },
|
|
65
|
+
},
|
|
66
|
+
},
|
|
67
|
+
tags: { type: 'array', items: { type: 'string' }, description: 'Tags to assign' },
|
|
68
|
+
owner_id: { type: 'string', description: 'Owner/user ID to assign (UUID)' },
|
|
69
|
+
},
|
|
70
|
+
required: ['name'],
|
|
71
|
+
},
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
name: 'salesflare_companies_update',
|
|
75
|
+
description: 'Update an existing company in Salesflare CRM. ' +
|
|
76
|
+
'Requires company_id. All other fields are optional - only provided fields will be updated.',
|
|
77
|
+
inputSchema: {
|
|
78
|
+
type: 'object',
|
|
79
|
+
properties: {
|
|
80
|
+
company_id: { type: 'string', description: 'Company UUID to update' },
|
|
81
|
+
name: { type: 'string', description: 'Company name' },
|
|
82
|
+
website: { type: 'string', description: 'Company website URL' },
|
|
83
|
+
industry: { type: 'string', description: 'Industry category' },
|
|
84
|
+
phone: { type: 'string', description: 'Phone number' },
|
|
85
|
+
description: { type: 'string', description: 'Company description' },
|
|
86
|
+
address: {
|
|
87
|
+
type: 'object',
|
|
88
|
+
description: 'Address information',
|
|
89
|
+
properties: {
|
|
90
|
+
street: { type: 'string', description: 'Street address' },
|
|
91
|
+
city: { type: 'string', description: 'City' },
|
|
92
|
+
state: { type: 'string', description: 'State or province' },
|
|
93
|
+
zip: { type: 'string', description: 'ZIP or postal code' },
|
|
94
|
+
country: { type: 'string', description: 'Country' },
|
|
95
|
+
},
|
|
96
|
+
},
|
|
97
|
+
social_media: {
|
|
98
|
+
type: 'object',
|
|
99
|
+
description: 'Social media profiles',
|
|
100
|
+
properties: {
|
|
101
|
+
linkedin: { type: 'string', description: 'LinkedIn profile URL' },
|
|
102
|
+
twitter: { type: 'string', description: 'Twitter/X handle or URL' },
|
|
103
|
+
facebook: { type: 'string', description: 'Facebook page URL' },
|
|
104
|
+
},
|
|
105
|
+
},
|
|
106
|
+
tags: { type: 'array', items: { type: 'string' }, description: 'Tags to assign' },
|
|
107
|
+
owner_id: { type: 'string', description: 'Owner/user ID to assign (UUID)' },
|
|
108
|
+
},
|
|
109
|
+
required: ['company_id'],
|
|
110
|
+
},
|
|
111
|
+
},
|
|
112
|
+
{
|
|
113
|
+
name: 'salesflare_companies_delete',
|
|
114
|
+
description: 'Delete a company from Salesflare CRM. ' +
|
|
115
|
+
'Requires company_id. Associated contacts will be unlinked before deletion. ' +
|
|
116
|
+
'This action cannot be undone.',
|
|
117
|
+
inputSchema: {
|
|
118
|
+
type: 'object',
|
|
119
|
+
properties: {
|
|
120
|
+
company_id: { type: 'string', description: 'Company UUID to delete' },
|
|
121
|
+
},
|
|
122
|
+
required: ['company_id'],
|
|
123
|
+
},
|
|
124
|
+
},
|
|
125
|
+
];
|
|
126
|
+
/**
|
|
127
|
+
* Exported company tools array for unified registration
|
|
128
|
+
*/
|
|
129
|
+
export { companyTools };
|
|
130
|
+
/**
|
|
131
|
+
* Handle company tool calls
|
|
132
|
+
*
|
|
133
|
+
* @param client - Salesflare API client
|
|
134
|
+
* @param name - Tool name
|
|
135
|
+
* @param args - Tool arguments
|
|
136
|
+
* @returns Tool response
|
|
137
|
+
*/
|
|
138
|
+
export async function handleCompaniesTool(client, name, args) {
|
|
139
|
+
switch (name) {
|
|
140
|
+
case 'salesflare_companies_list':
|
|
141
|
+
return await handleListCompanies(client, args);
|
|
142
|
+
case 'salesflare_companies_create':
|
|
143
|
+
return await handleCreateCompany(client, args);
|
|
144
|
+
case 'salesflare_companies_update':
|
|
145
|
+
return await handleUpdateCompany(client, args);
|
|
146
|
+
case 'salesflare_companies_delete':
|
|
147
|
+
return await handleDeleteCompany(client, args);
|
|
148
|
+
default:
|
|
149
|
+
throw new SalesflareError({
|
|
150
|
+
code: ErrorCode.INVALID_INPUT,
|
|
151
|
+
message: `Unknown company tool: ${name}`,
|
|
152
|
+
retryable: false,
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* Register company-related tools with the MCP server
|
|
158
|
+
*
|
|
159
|
+
* @deprecated Use handleCompaniesTool instead for unified registration
|
|
160
|
+
* @param server - MCP Server instance
|
|
161
|
+
* @param client - Salesflare API client
|
|
162
|
+
*/
|
|
163
|
+
export function registerCompaniesTools(server, client) {
|
|
164
|
+
// This function is deprecated - use unified tool registration in server.ts
|
|
165
|
+
// Kept for backward compatibility
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Handle salesflare_companies_list tool call
|
|
169
|
+
* Implements filters per D-12 to D-16
|
|
170
|
+
*/
|
|
171
|
+
async function handleListCompanies(client, params) {
|
|
172
|
+
// Build query parameters from filters
|
|
173
|
+
const queryParams = {};
|
|
174
|
+
if (params.name)
|
|
175
|
+
queryParams.name = params.name;
|
|
176
|
+
if (params.industry)
|
|
177
|
+
queryParams.industry = params.industry;
|
|
178
|
+
if (params.tags && params.tags.length > 0)
|
|
179
|
+
queryParams.tags = params.tags.join(',');
|
|
180
|
+
if (params.owner)
|
|
181
|
+
queryParams.owner = params.owner;
|
|
182
|
+
if (params.search)
|
|
183
|
+
queryParams.search = params.search;
|
|
184
|
+
// Pagination
|
|
185
|
+
queryParams.page = Number(params.page) || 1;
|
|
186
|
+
queryParams.limit = Number(params.limit) || 20;
|
|
187
|
+
// Call Salesflare API (companies endpoint is /accounts)
|
|
188
|
+
const response = await client.get('/accounts', { params: queryParams });
|
|
189
|
+
// Handle different response formats
|
|
190
|
+
const items = response.items || (Array.isArray(response) ? response : []);
|
|
191
|
+
const total = response.total ?? items.length;
|
|
192
|
+
const page = (response.page ?? Number(params.page)) || 1;
|
|
193
|
+
const limit = (response.limit ?? Number(params.limit)) || 20;
|
|
194
|
+
// Transform to curated response format (D-08)
|
|
195
|
+
const companies = items.map((item) => ({
|
|
196
|
+
id: item.id,
|
|
197
|
+
name: item.name,
|
|
198
|
+
website: item.website,
|
|
199
|
+
industry: item.industry,
|
|
200
|
+
phone: item.phone,
|
|
201
|
+
description: item.description,
|
|
202
|
+
address: item.address ? {
|
|
203
|
+
street: item.address.street,
|
|
204
|
+
city: item.address.city,
|
|
205
|
+
state: item.address.state,
|
|
206
|
+
zip: item.address.zip,
|
|
207
|
+
country: item.address.country,
|
|
208
|
+
} : undefined,
|
|
209
|
+
social_media: item.social_media ? {
|
|
210
|
+
linkedin: item.social_media.linkedin,
|
|
211
|
+
twitter: item.social_media.twitter,
|
|
212
|
+
facebook: item.social_media.facebook,
|
|
213
|
+
} : undefined,
|
|
214
|
+
tags: item.tags,
|
|
215
|
+
owner: item.owner ? {
|
|
216
|
+
id: item.owner.id,
|
|
217
|
+
name: item.owner.name,
|
|
218
|
+
} : undefined,
|
|
219
|
+
created_at: item.created_at,
|
|
220
|
+
updated_at: item.updated_at,
|
|
221
|
+
}));
|
|
222
|
+
const listResponse = {
|
|
223
|
+
companies,
|
|
224
|
+
total,
|
|
225
|
+
page,
|
|
226
|
+
limit,
|
|
227
|
+
has_more: page * limit < total,
|
|
228
|
+
};
|
|
229
|
+
// Generate human-readable summary (D-09)
|
|
230
|
+
const summaryText = listResponse.companies.length === 0
|
|
231
|
+
? 'No companies found matching the criteria.'
|
|
232
|
+
: `Found ${listResponse.total} company(ies). Showing page ${listResponse.page} with ${listResponse.companies.length} result(s).` +
|
|
233
|
+
(listResponse.has_more ? ` More pages available.` : '');
|
|
234
|
+
return {
|
|
235
|
+
content: [
|
|
236
|
+
{ type: 'text', text: summaryText },
|
|
237
|
+
{ type: 'text', text: JSON.stringify(listResponse, null, 2) },
|
|
238
|
+
],
|
|
239
|
+
};
|
|
240
|
+
}
|
|
241
|
+
/**
|
|
242
|
+
* Handle salesflare_companies_create tool call
|
|
243
|
+
* Name is required per D-01, other fields optional per D-02
|
|
244
|
+
*/
|
|
245
|
+
async function handleCreateCompany(client, params) {
|
|
246
|
+
// Call Salesflare API to create company (endpoint is /accounts)
|
|
247
|
+
const response = await client.post('/accounts', {
|
|
248
|
+
name: params.name,
|
|
249
|
+
website: params.website,
|
|
250
|
+
industry: params.industry,
|
|
251
|
+
phone: params.phone,
|
|
252
|
+
description: params.description,
|
|
253
|
+
address: params.address,
|
|
254
|
+
social_media: params.social_media,
|
|
255
|
+
tags: params.tags,
|
|
256
|
+
owner_id: params.owner_id,
|
|
257
|
+
});
|
|
258
|
+
// Transform to curated response format (D-08)
|
|
259
|
+
const company = {
|
|
260
|
+
id: response.id,
|
|
261
|
+
name: response.name,
|
|
262
|
+
website: response.website,
|
|
263
|
+
industry: response.industry,
|
|
264
|
+
phone: response.phone,
|
|
265
|
+
description: response.description,
|
|
266
|
+
address: response.address ? {
|
|
267
|
+
street: response.address.street,
|
|
268
|
+
city: response.address.city,
|
|
269
|
+
state: response.address.state,
|
|
270
|
+
zip: response.address.zip,
|
|
271
|
+
country: response.address.country,
|
|
272
|
+
} : undefined,
|
|
273
|
+
social_media: response.social_media ? {
|
|
274
|
+
linkedin: response.social_media.linkedin,
|
|
275
|
+
twitter: response.social_media.twitter,
|
|
276
|
+
facebook: response.social_media.facebook,
|
|
277
|
+
} : undefined,
|
|
278
|
+
tags: response.tags,
|
|
279
|
+
owner: response.owner ? {
|
|
280
|
+
id: response.owner.id,
|
|
281
|
+
name: response.owner.name,
|
|
282
|
+
} : undefined,
|
|
283
|
+
created_at: response.created_at,
|
|
284
|
+
updated_at: response.updated_at,
|
|
285
|
+
};
|
|
286
|
+
return {
|
|
287
|
+
content: [
|
|
288
|
+
{ type: 'text', text: `Company created: ${company.name}` },
|
|
289
|
+
{ type: 'text', text: JSON.stringify(company, null, 2) },
|
|
290
|
+
],
|
|
291
|
+
};
|
|
292
|
+
}
|
|
293
|
+
/**
|
|
294
|
+
* Handle salesflare_companies_update tool call
|
|
295
|
+
*/
|
|
296
|
+
async function handleUpdateCompany(client, params) {
|
|
297
|
+
const { company_id, ...updateData } = params;
|
|
298
|
+
// Check if at least one field is provided for update
|
|
299
|
+
const hasUpdateFields = Object.keys(updateData).length > 0;
|
|
300
|
+
if (!hasUpdateFields) {
|
|
301
|
+
return {
|
|
302
|
+
content: [
|
|
303
|
+
{ type: 'text', text: 'Error [INVALID_INPUT]: At least one field must be provided for update.' },
|
|
304
|
+
{ type: 'text', text: '{}' },
|
|
305
|
+
],
|
|
306
|
+
};
|
|
307
|
+
}
|
|
308
|
+
// Call Salesflare API to update company (endpoint is /accounts)
|
|
309
|
+
const response = await client.patch(`/accounts/${company_id}`, updateData);
|
|
310
|
+
// Transform to curated response format (D-08)
|
|
311
|
+
const company = {
|
|
312
|
+
id: response.id,
|
|
313
|
+
name: response.name,
|
|
314
|
+
website: response.website,
|
|
315
|
+
industry: response.industry,
|
|
316
|
+
phone: response.phone,
|
|
317
|
+
description: response.description,
|
|
318
|
+
address: response.address ? {
|
|
319
|
+
street: response.address.street,
|
|
320
|
+
city: response.address.city,
|
|
321
|
+
state: response.address.state,
|
|
322
|
+
zip: response.address.zip,
|
|
323
|
+
country: response.address.country,
|
|
324
|
+
} : undefined,
|
|
325
|
+
social_media: response.social_media ? {
|
|
326
|
+
linkedin: response.social_media.linkedin,
|
|
327
|
+
twitter: response.social_media.twitter,
|
|
328
|
+
facebook: response.social_media.facebook,
|
|
329
|
+
} : undefined,
|
|
330
|
+
tags: response.tags,
|
|
331
|
+
owner: response.owner ? {
|
|
332
|
+
id: response.owner.id,
|
|
333
|
+
name: response.owner.name,
|
|
334
|
+
} : undefined,
|
|
335
|
+
created_at: response.created_at,
|
|
336
|
+
updated_at: response.updated_at,
|
|
337
|
+
};
|
|
338
|
+
return {
|
|
339
|
+
content: [
|
|
340
|
+
{ type: 'text', text: `Company updated: ${company.name}` },
|
|
341
|
+
{ type: 'text', text: JSON.stringify(company, null, 2) },
|
|
342
|
+
],
|
|
343
|
+
};
|
|
344
|
+
}
|
|
345
|
+
/**
|
|
346
|
+
* Handle salesflare_companies_delete tool call
|
|
347
|
+
* Implements D-07: Unlink all associated contacts before deletion
|
|
348
|
+
*/
|
|
349
|
+
async function handleDeleteCompany(client, params) {
|
|
350
|
+
let unlinkedCount = 0;
|
|
351
|
+
try {
|
|
352
|
+
// Step 1: Find associated contacts with this company_id
|
|
353
|
+
const contactsResponse = await client.get('/contacts', {
|
|
354
|
+
params: { company_id: params.company_id, limit: 100 },
|
|
355
|
+
});
|
|
356
|
+
const associatedContacts = contactsResponse.items || [];
|
|
357
|
+
// Step 2: Unlink all associated contacts (best effort)
|
|
358
|
+
// Set company_id to null to preserve contacts while allowing company deletion
|
|
359
|
+
for (const contact of associatedContacts) {
|
|
360
|
+
try {
|
|
361
|
+
await client.patch(`/contacts/${contact.id}`, { company_id: null });
|
|
362
|
+
unlinkedCount++;
|
|
363
|
+
}
|
|
364
|
+
catch (unlinkError) {
|
|
365
|
+
// Log but don't fail - continue with other contacts and company deletion
|
|
366
|
+
console.warn(`Failed to unlink contact ${contact.id} from company ${params.company_id}:`, unlinkError);
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
// Step 3: Delete the company
|
|
370
|
+
await client.delete(`/accounts/${params.company_id}`);
|
|
371
|
+
// Step 4: Return appropriate success message (D-10)
|
|
372
|
+
const message = unlinkedCount > 0
|
|
373
|
+
? `Company deleted. ${unlinkedCount} associated contact(s) unlinked.`
|
|
374
|
+
: 'Company deleted successfully.';
|
|
375
|
+
return {
|
|
376
|
+
content: [{ type: 'text', text: message }],
|
|
377
|
+
};
|
|
378
|
+
}
|
|
379
|
+
catch (error) {
|
|
380
|
+
// Handle specific error cases
|
|
381
|
+
if (error instanceof SalesflareError) {
|
|
382
|
+
// If company not found, we still report success if we tried to unlink contacts
|
|
383
|
+
if (error.code === ErrorCode.NOT_FOUND && unlinkedCount > 0) {
|
|
384
|
+
return {
|
|
385
|
+
content: [{ type: 'text', text: `Company not found (may have been already deleted). ${unlinkedCount} associated contact(s) were unlinked.` }],
|
|
386
|
+
};
|
|
387
|
+
}
|
|
388
|
+
throw error;
|
|
389
|
+
}
|
|
390
|
+
throw error;
|
|
391
|
+
}
|
|
392
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Contact tools for Salesflare MCP Server
|
|
3
|
+
*
|
|
4
|
+
* Implements CRUD operations for contacts:
|
|
5
|
+
* - salesflare_contacts_list: List contacts with filtering and pagination
|
|
6
|
+
* - salesflare_contacts_create: Create new contacts
|
|
7
|
+
* - salesflare_contacts_update: Update existing contacts
|
|
8
|
+
* - salesflare_contacts_delete: Delete contacts
|
|
9
|
+
*
|
|
10
|
+
* @module tools/contacts
|
|
11
|
+
*/
|
|
12
|
+
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
|
|
13
|
+
import { Tool } from '@modelcontextprotocol/sdk/types.js';
|
|
14
|
+
import { SalesflareClient } from '../client/salesflare-client.js';
|
|
15
|
+
/**
|
|
16
|
+
* Contact tool definitions with Zod schemas
|
|
17
|
+
*/
|
|
18
|
+
declare const contactTools: Tool[];
|
|
19
|
+
/**
|
|
20
|
+
* Exported contact tools array for unified registration
|
|
21
|
+
*/
|
|
22
|
+
export { contactTools };
|
|
23
|
+
/**
|
|
24
|
+
* Handle contact tool calls
|
|
25
|
+
*
|
|
26
|
+
* @param client - Salesflare API client
|
|
27
|
+
* @param name - Tool name
|
|
28
|
+
* @param args - Tool arguments
|
|
29
|
+
* @returns Tool response
|
|
30
|
+
*/
|
|
31
|
+
export declare function handleContactsTool(client: SalesflareClient, name: string, args: unknown): Promise<{
|
|
32
|
+
content: Array<{
|
|
33
|
+
type: string;
|
|
34
|
+
text: string;
|
|
35
|
+
}>;
|
|
36
|
+
}>;
|
|
37
|
+
/**
|
|
38
|
+
* Register contact-related tools with the MCP server
|
|
39
|
+
*
|
|
40
|
+
* @deprecated Use handleContactsTool instead for unified registration
|
|
41
|
+
* @param server - MCP Server instance
|
|
42
|
+
* @param client - Salesflare API client
|
|
43
|
+
*/
|
|
44
|
+
export declare function registerContactsTools(server: Server, client: SalesflareClient): void;
|
|
45
|
+
//# sourceMappingURL=contacts.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"contacts.d.ts","sourceRoot":"","sources":["../../src/tools/contacts.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AACnE,OAAO,EAGL,IAAI,EACL,MAAM,oCAAoC,CAAC;AAC5C,OAAO,EAAE,gBAAgB,EAAE,MAAM,gCAAgC,CAAC;AAkBlE;;GAEG;AACH,QAAA,MAAM,YAAY,EAAE,IAAI,EAsEvB,CAAC;AAEF;;GAEG;AACH,OAAO,EAAE,YAAY,EAAE,CAAC;AAExB;;;;;;;GAOG;AACH,wBAAsB,kBAAkB,CACtC,MAAM,EAAE,gBAAgB,EACxB,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,OAAO,GACZ,OAAO,CAAC;IAAE,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;CAAE,CAAC,CAqB7D;AAED;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,gBAAgB,GAAG,IAAI,CAGpF"}
|