@codespar/mcp-take-blip 0.1.2 → 0.2.1
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/README.md +13 -3
- package/dist/index.js +194 -4
- package/package.json +2 -2
- package/server.json +2 -2
- package/src/index.ts +184 -4
package/README.md
CHANGED
|
@@ -51,10 +51,10 @@ Add to `.cursor/mcp.json` or `.vscode/mcp.json`:
|
|
|
51
51
|
}
|
|
52
52
|
```
|
|
53
53
|
|
|
54
|
-
## Tools
|
|
54
|
+
## Tools (18)
|
|
55
55
|
|
|
56
|
-
| Tool |
|
|
57
|
-
|
|
56
|
+
| Tool | Purpose |
|
|
57
|
+
|---|---|
|
|
58
58
|
| `send_message` | Send a message to a contact via Take Blip |
|
|
59
59
|
| `get_contacts` | List contacts in Take Blip |
|
|
60
60
|
| `create_contact` | Create a contact in Take Blip |
|
|
@@ -63,6 +63,16 @@ Add to `.cursor/mcp.json` or `.vscode/mcp.json`:
|
|
|
63
63
|
| `get_analytics` | Get chatbot analytics and metrics |
|
|
64
64
|
| `create_broadcast` | Create a broadcast distribution list and send messages |
|
|
65
65
|
| `get_chatbot_flow` | Get chatbot flow/builder configuration |
|
|
66
|
+
| `update_contact` | Merge/update fields on an existing contact |
|
|
67
|
+
| `delete_contact` | Delete a contact by identity |
|
|
68
|
+
| `get_contact` | Get a single contact by identity |
|
|
69
|
+
| `get_thread` | Get the message thread between the bot and a specific identity |
|
|
70
|
+
| `create_ticket` | Open a support ticket / human handoff for a contact |
|
|
71
|
+
| `close_ticket` | Close an open support ticket |
|
|
72
|
+
| `list_tickets` | List tickets, optionally filtering by status |
|
|
73
|
+
| `track_event` | Track a custom analytics event in the bot event tracker |
|
|
74
|
+
| `set_bot_resource` | Set a bot resource value (used as bot variables / state via /resources bucket) |
|
|
75
|
+
| `get_bot_resource` | Get a bot resource value by name (variable / state) |
|
|
66
76
|
|
|
67
77
|
## Authentication
|
|
68
78
|
|
package/dist/index.js
CHANGED
|
@@ -2,21 +2,31 @@
|
|
|
2
2
|
/**
|
|
3
3
|
* MCP Server for Take Blip — Brazilian chatbot and messaging platform.
|
|
4
4
|
*
|
|
5
|
-
* Tools:
|
|
5
|
+
* Tools (18):
|
|
6
6
|
* - send_message: Send a message to a contact
|
|
7
7
|
* - get_contacts: List contacts
|
|
8
8
|
* - create_contact: Create a contact
|
|
9
|
+
* - update_contact: Merge/update a contact
|
|
10
|
+
* - delete_contact: Delete a contact
|
|
11
|
+
* - get_contact: Get a single contact by identity
|
|
9
12
|
* - get_threads: Get message threads
|
|
13
|
+
* - get_thread: Get a thread between bot and an identity
|
|
10
14
|
* - send_notification: Send a notification/broadcast message
|
|
11
15
|
* - get_analytics: Get chatbot analytics
|
|
12
16
|
* - create_broadcast: Create a broadcast list and send
|
|
13
17
|
* - get_chatbot_flow: Get chatbot flow configuration
|
|
18
|
+
* - create_ticket: Open a support ticket / human handoff
|
|
19
|
+
* - close_ticket: Close an open ticket
|
|
20
|
+
* - list_tickets: List tickets in a queue
|
|
21
|
+
* - track_event: Track a custom analytics event
|
|
22
|
+
* - set_bot_resource: Set a bot resource (variable / bucket value)
|
|
23
|
+
* - get_bot_resource: Get a bot resource (variable / bucket value)
|
|
14
24
|
*
|
|
15
25
|
* Environment:
|
|
16
26
|
* TAKE_BLIP_BOT_ID — Bot identifier
|
|
17
27
|
* TAKE_BLIP_ACCESS_KEY — Bot access key
|
|
18
28
|
*
|
|
19
|
-
* Note: Take Blip uses a JSON-based messaging protocol.
|
|
29
|
+
* Note: Take Blip uses a JSON-based messaging protocol (LIME/BLiP HTTP API).
|
|
20
30
|
* Requests go as POST to /commands with type/method/uri in body.
|
|
21
31
|
*/
|
|
22
32
|
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
|
@@ -66,7 +76,7 @@ async function blipMessage(to, type, content) {
|
|
|
66
76
|
}
|
|
67
77
|
return res.json();
|
|
68
78
|
}
|
|
69
|
-
const server = new Server({ name: "mcp-take-blip", version: "0.1
|
|
79
|
+
const server = new Server({ name: "mcp-take-blip", version: "0.2.1" }, { capabilities: { tools: {} } });
|
|
70
80
|
server.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
71
81
|
tools: [
|
|
72
82
|
{
|
|
@@ -177,6 +187,129 @@ server.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
|
177
187
|
},
|
|
178
188
|
},
|
|
179
189
|
},
|
|
190
|
+
{
|
|
191
|
+
name: "update_contact",
|
|
192
|
+
description: "Merge/update fields on an existing contact",
|
|
193
|
+
inputSchema: {
|
|
194
|
+
type: "object",
|
|
195
|
+
properties: {
|
|
196
|
+
identity: { type: "string", description: "Contact identity (e.g., 5511999999999@wa.gw.msging.net)" },
|
|
197
|
+
name: { type: "string", description: "Contact name" },
|
|
198
|
+
email: { type: "string", description: "Contact email" },
|
|
199
|
+
phoneNumber: { type: "string", description: "Phone number" },
|
|
200
|
+
group: { type: "string", description: "Contact group" },
|
|
201
|
+
extras: { type: "object", description: "Custom extras key/value object" },
|
|
202
|
+
},
|
|
203
|
+
required: ["identity"],
|
|
204
|
+
},
|
|
205
|
+
},
|
|
206
|
+
{
|
|
207
|
+
name: "delete_contact",
|
|
208
|
+
description: "Delete a contact by identity",
|
|
209
|
+
inputSchema: {
|
|
210
|
+
type: "object",
|
|
211
|
+
properties: {
|
|
212
|
+
identity: { type: "string", description: "Contact identity" },
|
|
213
|
+
},
|
|
214
|
+
required: ["identity"],
|
|
215
|
+
},
|
|
216
|
+
},
|
|
217
|
+
{
|
|
218
|
+
name: "get_contact",
|
|
219
|
+
description: "Get a single contact by identity",
|
|
220
|
+
inputSchema: {
|
|
221
|
+
type: "object",
|
|
222
|
+
properties: {
|
|
223
|
+
identity: { type: "string", description: "Contact identity" },
|
|
224
|
+
},
|
|
225
|
+
required: ["identity"],
|
|
226
|
+
},
|
|
227
|
+
},
|
|
228
|
+
{
|
|
229
|
+
name: "get_thread",
|
|
230
|
+
description: "Get the message thread between the bot and a specific identity",
|
|
231
|
+
inputSchema: {
|
|
232
|
+
type: "object",
|
|
233
|
+
properties: {
|
|
234
|
+
identity: { type: "string", description: "Contact identity" },
|
|
235
|
+
take: { type: "number", description: "Number of messages to return (default 20)" },
|
|
236
|
+
},
|
|
237
|
+
required: ["identity"],
|
|
238
|
+
},
|
|
239
|
+
},
|
|
240
|
+
{
|
|
241
|
+
name: "create_ticket",
|
|
242
|
+
description: "Open a support ticket / human handoff for a contact",
|
|
243
|
+
inputSchema: {
|
|
244
|
+
type: "object",
|
|
245
|
+
properties: {
|
|
246
|
+
customerIdentity: { type: "string", description: "Contact identity to open ticket for" },
|
|
247
|
+
team: { type: "string", description: "Agent team / queue name" },
|
|
248
|
+
},
|
|
249
|
+
required: ["customerIdentity"],
|
|
250
|
+
},
|
|
251
|
+
},
|
|
252
|
+
{
|
|
253
|
+
name: "close_ticket",
|
|
254
|
+
description: "Close an open support ticket",
|
|
255
|
+
inputSchema: {
|
|
256
|
+
type: "object",
|
|
257
|
+
properties: {
|
|
258
|
+
ticketId: { type: "string", description: "Ticket id to close" },
|
|
259
|
+
},
|
|
260
|
+
required: ["ticketId"],
|
|
261
|
+
},
|
|
262
|
+
},
|
|
263
|
+
{
|
|
264
|
+
name: "list_tickets",
|
|
265
|
+
description: "List tickets, optionally filtering by status",
|
|
266
|
+
inputSchema: {
|
|
267
|
+
type: "object",
|
|
268
|
+
properties: {
|
|
269
|
+
status: { type: "string", description: "Ticket status filter (e.g., Open, Waiting, Closed)" },
|
|
270
|
+
skip: { type: "number", description: "Pagination skip" },
|
|
271
|
+
take: { type: "number", description: "Pagination take (default 20)" },
|
|
272
|
+
},
|
|
273
|
+
},
|
|
274
|
+
},
|
|
275
|
+
{
|
|
276
|
+
name: "track_event",
|
|
277
|
+
description: "Track a custom analytics event in the bot event tracker",
|
|
278
|
+
inputSchema: {
|
|
279
|
+
type: "object",
|
|
280
|
+
properties: {
|
|
281
|
+
category: { type: "string", description: "Event category" },
|
|
282
|
+
action: { type: "string", description: "Event action" },
|
|
283
|
+
extras: { type: "object", description: "Additional event metadata" },
|
|
284
|
+
contactIdentity: { type: "string", description: "Contact identity associated with the event" },
|
|
285
|
+
},
|
|
286
|
+
required: ["category", "action"],
|
|
287
|
+
},
|
|
288
|
+
},
|
|
289
|
+
{
|
|
290
|
+
name: "set_bot_resource",
|
|
291
|
+
description: "Set a bot resource value (used as bot variables / state via /resources bucket)",
|
|
292
|
+
inputSchema: {
|
|
293
|
+
type: "object",
|
|
294
|
+
properties: {
|
|
295
|
+
name: { type: "string", description: "Resource name (key)" },
|
|
296
|
+
value: { description: "Resource value (string, number, object)" },
|
|
297
|
+
type: { type: "string", description: "MIME type (default text/plain; use application/json for objects)" },
|
|
298
|
+
},
|
|
299
|
+
required: ["name", "value"],
|
|
300
|
+
},
|
|
301
|
+
},
|
|
302
|
+
{
|
|
303
|
+
name: "get_bot_resource",
|
|
304
|
+
description: "Get a bot resource value by name (variable / state)",
|
|
305
|
+
inputSchema: {
|
|
306
|
+
type: "object",
|
|
307
|
+
properties: {
|
|
308
|
+
name: { type: "string", description: "Resource name (key)" },
|
|
309
|
+
},
|
|
310
|
+
required: ["name"],
|
|
311
|
+
},
|
|
312
|
+
},
|
|
180
313
|
],
|
|
181
314
|
}));
|
|
182
315
|
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
@@ -239,6 +372,63 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
239
372
|
const uri = args?.flowId ? `/buckets/blip_portal:builder_working_flow_${args.flowId}` : "/buckets/blip_portal:builder_working_flow";
|
|
240
373
|
return { content: [{ type: "text", text: JSON.stringify(await blipCommand(crypto.randomUUID(), "get", uri), null, 2) }] };
|
|
241
374
|
}
|
|
375
|
+
case "update_contact": {
|
|
376
|
+
const resource = { identity: args?.identity };
|
|
377
|
+
if (args?.name)
|
|
378
|
+
resource.name = args.name;
|
|
379
|
+
if (args?.email)
|
|
380
|
+
resource.email = args.email;
|
|
381
|
+
if (args?.phoneNumber)
|
|
382
|
+
resource.phoneNumber = args.phoneNumber;
|
|
383
|
+
if (args?.group)
|
|
384
|
+
resource.group = args.group;
|
|
385
|
+
if (args?.extras)
|
|
386
|
+
resource.extras = args.extras;
|
|
387
|
+
return { content: [{ type: "text", text: JSON.stringify(await blipCommand(crypto.randomUUID(), "merge", "/contacts", "application/vnd.lime.contact+json", resource), null, 2) }] };
|
|
388
|
+
}
|
|
389
|
+
case "delete_contact": {
|
|
390
|
+
return { content: [{ type: "text", text: JSON.stringify(await blipCommand(crypto.randomUUID(), "delete", `/contacts/${encodeURIComponent(String(args?.identity))}`), null, 2) }] };
|
|
391
|
+
}
|
|
392
|
+
case "get_contact": {
|
|
393
|
+
return { content: [{ type: "text", text: JSON.stringify(await blipCommand(crypto.randomUUID(), "get", `/contacts/${encodeURIComponent(String(args?.identity))}`), null, 2) }] };
|
|
394
|
+
}
|
|
395
|
+
case "get_thread": {
|
|
396
|
+
const take = args?.take ? `$take=${args.take}` : "$take=20";
|
|
397
|
+
return { content: [{ type: "text", text: JSON.stringify(await blipCommand(crypto.randomUUID(), "get", `/threads/${encodeURIComponent(String(args?.identity))}?${take}`), null, 2) }] };
|
|
398
|
+
}
|
|
399
|
+
case "create_ticket": {
|
|
400
|
+
const resource = { customerIdentity: args?.customerIdentity };
|
|
401
|
+
if (args?.team)
|
|
402
|
+
resource.team = args.team;
|
|
403
|
+
return { content: [{ type: "text", text: JSON.stringify(await blipCommand(crypto.randomUUID(), "set", "/tickets", "application/vnd.iris.ticket+json", resource), null, 2) }] };
|
|
404
|
+
}
|
|
405
|
+
case "close_ticket": {
|
|
406
|
+
return { content: [{ type: "text", text: JSON.stringify(await blipCommand(crypto.randomUUID(), "set", `/tickets/${encodeURIComponent(String(args?.ticketId))}/change-status`, "application/vnd.iris.ticket+json", { status: "ClosedAttendant" }), null, 2) }] };
|
|
407
|
+
}
|
|
408
|
+
case "list_tickets": {
|
|
409
|
+
const filters = [];
|
|
410
|
+
if (args?.status)
|
|
411
|
+
filters.push(`$filter=${encodeURIComponent(`status eq '${args.status}'`)}`);
|
|
412
|
+
if (args?.skip)
|
|
413
|
+
filters.push(`$skip=${args.skip}`);
|
|
414
|
+
filters.push(args?.take ? `$take=${args.take}` : "$take=20");
|
|
415
|
+
return { content: [{ type: "text", text: JSON.stringify(await blipCommand(crypto.randomUUID(), "get", `/tickets?${filters.join("&")}`), null, 2) }] };
|
|
416
|
+
}
|
|
417
|
+
case "track_event": {
|
|
418
|
+
const resource = { category: args?.category, action: args?.action };
|
|
419
|
+
if (args?.extras)
|
|
420
|
+
resource.extras = args.extras;
|
|
421
|
+
if (args?.contactIdentity)
|
|
422
|
+
resource.contactIdentity = args.contactIdentity;
|
|
423
|
+
return { content: [{ type: "text", text: JSON.stringify(await blipCommand(crypto.randomUUID(), "set", "/event-track", "application/vnd.iris.eventTrack+json", resource), null, 2) }] };
|
|
424
|
+
}
|
|
425
|
+
case "set_bot_resource": {
|
|
426
|
+
const type = String(args?.type || (typeof args?.value === "object" ? "application/json" : "text/plain"));
|
|
427
|
+
return { content: [{ type: "text", text: JSON.stringify(await blipCommand(crypto.randomUUID(), "set", `/resources/${encodeURIComponent(String(args?.name))}`, type, args?.value), null, 2) }] };
|
|
428
|
+
}
|
|
429
|
+
case "get_bot_resource": {
|
|
430
|
+
return { content: [{ type: "text", text: JSON.stringify(await blipCommand(crypto.randomUUID(), "get", `/resources/${encodeURIComponent(String(args?.name))}`), null, 2) }] };
|
|
431
|
+
}
|
|
242
432
|
default:
|
|
243
433
|
return { content: [{ type: "text", text: `Unknown tool: ${name}` }], isError: true };
|
|
244
434
|
}
|
|
@@ -265,7 +455,7 @@ async function main() {
|
|
|
265
455
|
const t = new StreamableHTTPServerTransport({ sessionIdGenerator: () => randomUUID(), onsessioninitialized: (id) => { transports.set(id, t); } });
|
|
266
456
|
t.onclose = () => { if (t.sessionId)
|
|
267
457
|
transports.delete(t.sessionId); };
|
|
268
|
-
const s = new Server({ name: "mcp-take-blip", version: "0.1
|
|
458
|
+
const s = new Server({ name: "mcp-take-blip", version: "0.2.1" }, { capabilities: { tools: {} } });
|
|
269
459
|
server._requestHandlers.forEach((v, k) => s._requestHandlers.set(k, v));
|
|
270
460
|
server._notificationHandlers?.forEach((v, k) => s._notificationHandlers.set(k, v));
|
|
271
461
|
await s.connect(t);
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@codespar/mcp-take-blip",
|
|
3
|
-
"version": "0.1
|
|
4
|
-
"description": "MCP server for Take Blip
|
|
3
|
+
"version": "0.2.1",
|
|
4
|
+
"description": "MCP server for Take Blip \u2014 chatbots, messaging, contacts, broadcasts",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
7
7
|
"bin": {
|
package/server.json
CHANGED
|
@@ -7,12 +7,12 @@
|
|
|
7
7
|
"source": "github",
|
|
8
8
|
"subfolder": "packages/communication/take-blip"
|
|
9
9
|
},
|
|
10
|
-
"version": "0.1
|
|
10
|
+
"version": "0.2.1",
|
|
11
11
|
"packages": [
|
|
12
12
|
{
|
|
13
13
|
"registryType": "npm",
|
|
14
14
|
"identifier": "@codespar/mcp-take-blip",
|
|
15
|
-
"version": "0.1
|
|
15
|
+
"version": "0.2.1",
|
|
16
16
|
"transport": {
|
|
17
17
|
"type": "stdio"
|
|
18
18
|
},
|
package/src/index.ts
CHANGED
|
@@ -3,21 +3,31 @@
|
|
|
3
3
|
/**
|
|
4
4
|
* MCP Server for Take Blip — Brazilian chatbot and messaging platform.
|
|
5
5
|
*
|
|
6
|
-
* Tools:
|
|
6
|
+
* Tools (18):
|
|
7
7
|
* - send_message: Send a message to a contact
|
|
8
8
|
* - get_contacts: List contacts
|
|
9
9
|
* - create_contact: Create a contact
|
|
10
|
+
* - update_contact: Merge/update a contact
|
|
11
|
+
* - delete_contact: Delete a contact
|
|
12
|
+
* - get_contact: Get a single contact by identity
|
|
10
13
|
* - get_threads: Get message threads
|
|
14
|
+
* - get_thread: Get a thread between bot and an identity
|
|
11
15
|
* - send_notification: Send a notification/broadcast message
|
|
12
16
|
* - get_analytics: Get chatbot analytics
|
|
13
17
|
* - create_broadcast: Create a broadcast list and send
|
|
14
18
|
* - get_chatbot_flow: Get chatbot flow configuration
|
|
19
|
+
* - create_ticket: Open a support ticket / human handoff
|
|
20
|
+
* - close_ticket: Close an open ticket
|
|
21
|
+
* - list_tickets: List tickets in a queue
|
|
22
|
+
* - track_event: Track a custom analytics event
|
|
23
|
+
* - set_bot_resource: Set a bot resource (variable / bucket value)
|
|
24
|
+
* - get_bot_resource: Get a bot resource (variable / bucket value)
|
|
15
25
|
*
|
|
16
26
|
* Environment:
|
|
17
27
|
* TAKE_BLIP_BOT_ID — Bot identifier
|
|
18
28
|
* TAKE_BLIP_ACCESS_KEY — Bot access key
|
|
19
29
|
*
|
|
20
|
-
* Note: Take Blip uses a JSON-based messaging protocol.
|
|
30
|
+
* Note: Take Blip uses a JSON-based messaging protocol (LIME/BLiP HTTP API).
|
|
21
31
|
* Requests go as POST to /commands with type/method/uri in body.
|
|
22
32
|
*/
|
|
23
33
|
|
|
@@ -76,7 +86,7 @@ async function blipMessage(to: string, type: string, content: unknown): Promise<
|
|
|
76
86
|
}
|
|
77
87
|
|
|
78
88
|
const server = new Server(
|
|
79
|
-
{ name: "mcp-take-blip", version: "0.1
|
|
89
|
+
{ name: "mcp-take-blip", version: "0.2.1" },
|
|
80
90
|
{ capabilities: { tools: {} } }
|
|
81
91
|
);
|
|
82
92
|
|
|
@@ -190,6 +200,129 @@ server.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
|
190
200
|
},
|
|
191
201
|
},
|
|
192
202
|
},
|
|
203
|
+
{
|
|
204
|
+
name: "update_contact",
|
|
205
|
+
description: "Merge/update fields on an existing contact",
|
|
206
|
+
inputSchema: {
|
|
207
|
+
type: "object",
|
|
208
|
+
properties: {
|
|
209
|
+
identity: { type: "string", description: "Contact identity (e.g., 5511999999999@wa.gw.msging.net)" },
|
|
210
|
+
name: { type: "string", description: "Contact name" },
|
|
211
|
+
email: { type: "string", description: "Contact email" },
|
|
212
|
+
phoneNumber: { type: "string", description: "Phone number" },
|
|
213
|
+
group: { type: "string", description: "Contact group" },
|
|
214
|
+
extras: { type: "object", description: "Custom extras key/value object" },
|
|
215
|
+
},
|
|
216
|
+
required: ["identity"],
|
|
217
|
+
},
|
|
218
|
+
},
|
|
219
|
+
{
|
|
220
|
+
name: "delete_contact",
|
|
221
|
+
description: "Delete a contact by identity",
|
|
222
|
+
inputSchema: {
|
|
223
|
+
type: "object",
|
|
224
|
+
properties: {
|
|
225
|
+
identity: { type: "string", description: "Contact identity" },
|
|
226
|
+
},
|
|
227
|
+
required: ["identity"],
|
|
228
|
+
},
|
|
229
|
+
},
|
|
230
|
+
{
|
|
231
|
+
name: "get_contact",
|
|
232
|
+
description: "Get a single contact by identity",
|
|
233
|
+
inputSchema: {
|
|
234
|
+
type: "object",
|
|
235
|
+
properties: {
|
|
236
|
+
identity: { type: "string", description: "Contact identity" },
|
|
237
|
+
},
|
|
238
|
+
required: ["identity"],
|
|
239
|
+
},
|
|
240
|
+
},
|
|
241
|
+
{
|
|
242
|
+
name: "get_thread",
|
|
243
|
+
description: "Get the message thread between the bot and a specific identity",
|
|
244
|
+
inputSchema: {
|
|
245
|
+
type: "object",
|
|
246
|
+
properties: {
|
|
247
|
+
identity: { type: "string", description: "Contact identity" },
|
|
248
|
+
take: { type: "number", description: "Number of messages to return (default 20)" },
|
|
249
|
+
},
|
|
250
|
+
required: ["identity"],
|
|
251
|
+
},
|
|
252
|
+
},
|
|
253
|
+
{
|
|
254
|
+
name: "create_ticket",
|
|
255
|
+
description: "Open a support ticket / human handoff for a contact",
|
|
256
|
+
inputSchema: {
|
|
257
|
+
type: "object",
|
|
258
|
+
properties: {
|
|
259
|
+
customerIdentity: { type: "string", description: "Contact identity to open ticket for" },
|
|
260
|
+
team: { type: "string", description: "Agent team / queue name" },
|
|
261
|
+
},
|
|
262
|
+
required: ["customerIdentity"],
|
|
263
|
+
},
|
|
264
|
+
},
|
|
265
|
+
{
|
|
266
|
+
name: "close_ticket",
|
|
267
|
+
description: "Close an open support ticket",
|
|
268
|
+
inputSchema: {
|
|
269
|
+
type: "object",
|
|
270
|
+
properties: {
|
|
271
|
+
ticketId: { type: "string", description: "Ticket id to close" },
|
|
272
|
+
},
|
|
273
|
+
required: ["ticketId"],
|
|
274
|
+
},
|
|
275
|
+
},
|
|
276
|
+
{
|
|
277
|
+
name: "list_tickets",
|
|
278
|
+
description: "List tickets, optionally filtering by status",
|
|
279
|
+
inputSchema: {
|
|
280
|
+
type: "object",
|
|
281
|
+
properties: {
|
|
282
|
+
status: { type: "string", description: "Ticket status filter (e.g., Open, Waiting, Closed)" },
|
|
283
|
+
skip: { type: "number", description: "Pagination skip" },
|
|
284
|
+
take: { type: "number", description: "Pagination take (default 20)" },
|
|
285
|
+
},
|
|
286
|
+
},
|
|
287
|
+
},
|
|
288
|
+
{
|
|
289
|
+
name: "track_event",
|
|
290
|
+
description: "Track a custom analytics event in the bot event tracker",
|
|
291
|
+
inputSchema: {
|
|
292
|
+
type: "object",
|
|
293
|
+
properties: {
|
|
294
|
+
category: { type: "string", description: "Event category" },
|
|
295
|
+
action: { type: "string", description: "Event action" },
|
|
296
|
+
extras: { type: "object", description: "Additional event metadata" },
|
|
297
|
+
contactIdentity: { type: "string", description: "Contact identity associated with the event" },
|
|
298
|
+
},
|
|
299
|
+
required: ["category", "action"],
|
|
300
|
+
},
|
|
301
|
+
},
|
|
302
|
+
{
|
|
303
|
+
name: "set_bot_resource",
|
|
304
|
+
description: "Set a bot resource value (used as bot variables / state via /resources bucket)",
|
|
305
|
+
inputSchema: {
|
|
306
|
+
type: "object",
|
|
307
|
+
properties: {
|
|
308
|
+
name: { type: "string", description: "Resource name (key)" },
|
|
309
|
+
value: { description: "Resource value (string, number, object)" },
|
|
310
|
+
type: { type: "string", description: "MIME type (default text/plain; use application/json for objects)" },
|
|
311
|
+
},
|
|
312
|
+
required: ["name", "value"],
|
|
313
|
+
},
|
|
314
|
+
},
|
|
315
|
+
{
|
|
316
|
+
name: "get_bot_resource",
|
|
317
|
+
description: "Get a bot resource value by name (variable / state)",
|
|
318
|
+
inputSchema: {
|
|
319
|
+
type: "object",
|
|
320
|
+
properties: {
|
|
321
|
+
name: { type: "string", description: "Resource name (key)" },
|
|
322
|
+
},
|
|
323
|
+
required: ["name"],
|
|
324
|
+
},
|
|
325
|
+
},
|
|
193
326
|
],
|
|
194
327
|
}));
|
|
195
328
|
|
|
@@ -254,6 +387,53 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
254
387
|
const uri = args?.flowId ? `/buckets/blip_portal:builder_working_flow_${args.flowId}` : "/buckets/blip_portal:builder_working_flow";
|
|
255
388
|
return { content: [{ type: "text", text: JSON.stringify(await blipCommand(crypto.randomUUID(), "get", uri), null, 2) }] };
|
|
256
389
|
}
|
|
390
|
+
case "update_contact": {
|
|
391
|
+
const resource: Record<string, unknown> = { identity: args?.identity };
|
|
392
|
+
if (args?.name) resource.name = args.name;
|
|
393
|
+
if (args?.email) resource.email = args.email;
|
|
394
|
+
if (args?.phoneNumber) resource.phoneNumber = args.phoneNumber;
|
|
395
|
+
if (args?.group) resource.group = args.group;
|
|
396
|
+
if (args?.extras) resource.extras = args.extras;
|
|
397
|
+
return { content: [{ type: "text", text: JSON.stringify(await blipCommand(crypto.randomUUID(), "merge", "/contacts", "application/vnd.lime.contact+json", resource), null, 2) }] };
|
|
398
|
+
}
|
|
399
|
+
case "delete_contact": {
|
|
400
|
+
return { content: [{ type: "text", text: JSON.stringify(await blipCommand(crypto.randomUUID(), "delete", `/contacts/${encodeURIComponent(String(args?.identity))}`), null, 2) }] };
|
|
401
|
+
}
|
|
402
|
+
case "get_contact": {
|
|
403
|
+
return { content: [{ type: "text", text: JSON.stringify(await blipCommand(crypto.randomUUID(), "get", `/contacts/${encodeURIComponent(String(args?.identity))}`), null, 2) }] };
|
|
404
|
+
}
|
|
405
|
+
case "get_thread": {
|
|
406
|
+
const take = args?.take ? `$take=${args.take}` : "$take=20";
|
|
407
|
+
return { content: [{ type: "text", text: JSON.stringify(await blipCommand(crypto.randomUUID(), "get", `/threads/${encodeURIComponent(String(args?.identity))}?${take}`), null, 2) }] };
|
|
408
|
+
}
|
|
409
|
+
case "create_ticket": {
|
|
410
|
+
const resource: Record<string, unknown> = { customerIdentity: args?.customerIdentity };
|
|
411
|
+
if (args?.team) resource.team = args.team;
|
|
412
|
+
return { content: [{ type: "text", text: JSON.stringify(await blipCommand(crypto.randomUUID(), "set", "/tickets", "application/vnd.iris.ticket+json", resource), null, 2) }] };
|
|
413
|
+
}
|
|
414
|
+
case "close_ticket": {
|
|
415
|
+
return { content: [{ type: "text", text: JSON.stringify(await blipCommand(crypto.randomUUID(), "set", `/tickets/${encodeURIComponent(String(args?.ticketId))}/change-status`, "application/vnd.iris.ticket+json", { status: "ClosedAttendant" }), null, 2) }] };
|
|
416
|
+
}
|
|
417
|
+
case "list_tickets": {
|
|
418
|
+
const filters: string[] = [];
|
|
419
|
+
if (args?.status) filters.push(`$filter=${encodeURIComponent(`status eq '${args.status}'`)}`);
|
|
420
|
+
if (args?.skip) filters.push(`$skip=${args.skip}`);
|
|
421
|
+
filters.push(args?.take ? `$take=${args.take}` : "$take=20");
|
|
422
|
+
return { content: [{ type: "text", text: JSON.stringify(await blipCommand(crypto.randomUUID(), "get", `/tickets?${filters.join("&")}`), null, 2) }] };
|
|
423
|
+
}
|
|
424
|
+
case "track_event": {
|
|
425
|
+
const resource: Record<string, unknown> = { category: args?.category, action: args?.action };
|
|
426
|
+
if (args?.extras) resource.extras = args.extras;
|
|
427
|
+
if (args?.contactIdentity) resource.contactIdentity = args.contactIdentity;
|
|
428
|
+
return { content: [{ type: "text", text: JSON.stringify(await blipCommand(crypto.randomUUID(), "set", "/event-track", "application/vnd.iris.eventTrack+json", resource), null, 2) }] };
|
|
429
|
+
}
|
|
430
|
+
case "set_bot_resource": {
|
|
431
|
+
const type = String(args?.type || (typeof args?.value === "object" ? "application/json" : "text/plain"));
|
|
432
|
+
return { content: [{ type: "text", text: JSON.stringify(await blipCommand(crypto.randomUUID(), "set", `/resources/${encodeURIComponent(String(args?.name))}`, type, args?.value), null, 2) }] };
|
|
433
|
+
}
|
|
434
|
+
case "get_bot_resource": {
|
|
435
|
+
return { content: [{ type: "text", text: JSON.stringify(await blipCommand(crypto.randomUUID(), "get", `/resources/${encodeURIComponent(String(args?.name))}`), null, 2) }] };
|
|
436
|
+
}
|
|
257
437
|
default:
|
|
258
438
|
return { content: [{ type: "text", text: `Unknown tool: ${name}` }], isError: true };
|
|
259
439
|
}
|
|
@@ -276,7 +456,7 @@ async function main() {
|
|
|
276
456
|
if (!sid && isInitializeRequest(req.body)) {
|
|
277
457
|
const t = new StreamableHTTPServerTransport({ sessionIdGenerator: () => randomUUID(), onsessioninitialized: (id) => { transports.set(id, t); } });
|
|
278
458
|
t.onclose = () => { if (t.sessionId) transports.delete(t.sessionId); };
|
|
279
|
-
const s = new Server({ name: "mcp-take-blip", version: "0.1
|
|
459
|
+
const s = new Server({ name: "mcp-take-blip", version: "0.2.1" }, { capabilities: { tools: {} } }); (server as any)._requestHandlers.forEach((v: any, k: any) => (s as any)._requestHandlers.set(k, v)); (server as any)._notificationHandlers?.forEach((v: any, k: any) => (s as any)._notificationHandlers.set(k, v)); await s.connect(t);
|
|
280
460
|
await t.handleRequest(req, res, req.body); return;
|
|
281
461
|
}
|
|
282
462
|
res.status(400).json({ jsonrpc: "2.0", error: { code: -32000, message: "Bad Request" }, id: null });
|