take-blip-mcp 0.1.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.
Files changed (87) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +424 -0
  3. package/dist/blip-client.d.ts +69 -0
  4. package/dist/blip-client.d.ts.map +1 -0
  5. package/dist/blip-client.js +187 -0
  6. package/dist/blip-client.js.map +1 -0
  7. package/dist/config.d.ts +37 -0
  8. package/dist/config.d.ts.map +1 -0
  9. package/dist/config.js +197 -0
  10. package/dist/config.js.map +1 -0
  11. package/dist/env-file.d.ts +16 -0
  12. package/dist/env-file.d.ts.map +1 -0
  13. package/dist/env-file.js +70 -0
  14. package/dist/env-file.js.map +1 -0
  15. package/dist/errors.d.ts +49 -0
  16. package/dist/errors.d.ts.map +1 -0
  17. package/dist/errors.js +74 -0
  18. package/dist/errors.js.map +1 -0
  19. package/dist/flow-map.d.ts +48 -0
  20. package/dist/flow-map.d.ts.map +1 -0
  21. package/dist/flow-map.js +209 -0
  22. package/dist/flow-map.js.map +1 -0
  23. package/dist/index.d.ts +3 -0
  24. package/dist/index.d.ts.map +1 -0
  25. package/dist/index.js +143 -0
  26. package/dist/index.js.map +1 -0
  27. package/dist/logger.d.ts +18 -0
  28. package/dist/logger.d.ts.map +1 -0
  29. package/dist/logger.js +42 -0
  30. package/dist/logger.js.map +1 -0
  31. package/dist/tools/ai.d.ts +3 -0
  32. package/dist/tools/ai.d.ts.map +1 -0
  33. package/dist/tools/ai.js +51 -0
  34. package/dist/tools/ai.js.map +1 -0
  35. package/dist/tools/broadcast.d.ts +3 -0
  36. package/dist/tools/broadcast.d.ts.map +1 -0
  37. package/dist/tools/broadcast.js +46 -0
  38. package/dist/tools/broadcast.js.map +1 -0
  39. package/dist/tools/buckets.d.ts +3 -0
  40. package/dist/tools/buckets.d.ts.map +1 -0
  41. package/dist/tools/buckets.js +49 -0
  42. package/dist/tools/buckets.js.map +1 -0
  43. package/dist/tools/command.d.ts +3 -0
  44. package/dist/tools/command.d.ts.map +1 -0
  45. package/dist/tools/command.js +41 -0
  46. package/dist/tools/command.js.map +1 -0
  47. package/dist/tools/contacts.d.ts +3 -0
  48. package/dist/tools/contacts.d.ts.map +1 -0
  49. package/dist/tools/contacts.js +119 -0
  50. package/dist/tools/contacts.js.map +1 -0
  51. package/dist/tools/context.d.ts +3 -0
  52. package/dist/tools/context.d.ts.map +1 -0
  53. package/dist/tools/context.js +50 -0
  54. package/dist/tools/context.js.map +1 -0
  55. package/dist/tools/events.d.ts +3 -0
  56. package/dist/tools/events.d.ts.map +1 -0
  57. package/dist/tools/events.js +48 -0
  58. package/dist/tools/events.js.map +1 -0
  59. package/dist/tools/flow-tools.d.ts +3 -0
  60. package/dist/tools/flow-tools.d.ts.map +1 -0
  61. package/dist/tools/flow-tools.js +77 -0
  62. package/dist/tools/flow-tools.js.map +1 -0
  63. package/dist/tools/flow.d.ts +3 -0
  64. package/dist/tools/flow.d.ts.map +1 -0
  65. package/dist/tools/flow.js +33 -0
  66. package/dist/tools/flow.js.map +1 -0
  67. package/dist/tools/index.d.ts +5 -0
  68. package/dist/tools/index.d.ts.map +1 -0
  69. package/dist/tools/index.js +32 -0
  70. package/dist/tools/index.js.map +1 -0
  71. package/dist/tools/messages.d.ts +3 -0
  72. package/dist/tools/messages.d.ts.map +1 -0
  73. package/dist/tools/messages.js +31 -0
  74. package/dist/tools/messages.js.map +1 -0
  75. package/dist/tools/schedules.d.ts +3 -0
  76. package/dist/tools/schedules.d.ts.map +1 -0
  77. package/dist/tools/schedules.js +25 -0
  78. package/dist/tools/schedules.js.map +1 -0
  79. package/dist/tools/shared.d.ts +55 -0
  80. package/dist/tools/shared.d.ts.map +1 -0
  81. package/dist/tools/shared.js +67 -0
  82. package/dist/tools/shared.js.map +1 -0
  83. package/dist/tools/threads.d.ts +3 -0
  84. package/dist/tools/threads.d.ts.map +1 -0
  85. package/dist/tools/threads.js +39 -0
  86. package/dist/tools/threads.js.map +1 -0
  87. package/package.json +60 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ai.js","sourceRoot":"","sources":["../../src/tools/ai.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,OAAO,EAAE,UAAU,EAAoB,MAAM,aAAa,CAAC;AAEpE,MAAM,EAAE,GAAG,0BAA0B,CAAC;AACtC,MAAM,qBAAqB,GAAG,+CAA+C,CAAC;AAE9E,MAAM,UAAU,eAAe,CAAC,GAAgB;IAC9C,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,GAAG,CAAC;IAE/B,MAAM,CAAC,YAAY,CACjB,aAAa,EACb;QACE,KAAK,EAAE,mDAAmD;QAC1D,WAAW,EACT,6EAA6E;YAC7E,yEAAyE;YACzE,6EAA6E;YAC7E,wCAAwC;QAC1C,WAAW,EAAE;YACX,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,mCAAmC,CAAC;YACrE,IAAI,EAAE,CAAC;iBACJ,IAAI,CAAC,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC;iBAC7B,OAAO,CAAC,WAAW,CAAC;iBACpB,QAAQ,CAAC,kEAAkE,CAAC;YAC/E,OAAO,EAAE,CAAC;iBACP,MAAM,EAAE;iBACR,QAAQ,EAAE;iBACV,QAAQ,CAAC,6DAA6D,CAAC;SAC3E;QACD,WAAW,EAAE,EAAE,YAAY,EAAE,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE;KACzD,EACD,KAAK,EAAE,IAAI,EAAE,EAAE,CACb,OAAO,CAAC,GAAG,EAAE,KAAK,IAAI,EAAE;QACtB,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,KAAK,WAAW,CAAC,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAAC,WAAW,CAAC;QAC1E,MAAM,QAAQ,GAA4B,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC;QAC9D,IAAI,IAAI,CAAC,OAAO;YAAE,QAAQ,CAAC,SAAS,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC;QACrD,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,WAAW,CAAC;YACnC,MAAM,EAAE,KAAK;YACb,EAAE,EAAE,EAAE;YACN,GAAG;YACH,IAAI,EAAE,qBAAqB;YAC3B,QAAQ;SACT,CAAC,CAAC;QACH,OAAO,UAAU,CAAC,GAAG,CAAC,QAAQ,IAAI,GAAG,CAAC,CAAC;IACzC,CAAC,CAAC,CACL,CAAC;AACJ,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { type ToolContext } from "./shared.js";
2
+ export declare function registerBroadcastTools(ctx: ToolContext): void;
3
+ //# sourceMappingURL=broadcast.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"broadcast.d.ts","sourceRoot":"","sources":["../../src/tools/broadcast.ts"],"names":[],"mappings":"AASA,OAAO,EAAuC,KAAK,WAAW,EAAE,MAAM,aAAa,CAAC;AAIpF,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,WAAW,GAAG,IAAI,CAkD7D"}
@@ -0,0 +1,46 @@
1
+ /**
2
+ * Broadcast / distribution-list tools (EXPERIMENTAL).
3
+ *
4
+ * Based on the Blip DistributionList extension. Postmaster and URIs are the
5
+ * commonly documented ones (postmaster@broadcast.msging.net, /lists,
6
+ * /lists/{id}/recipients) but were not fully verified against your account.
7
+ * If these fail, fall back to `blip_command`. Read-only here.
8
+ */
9
+ import { z } from "zod";
10
+ import { attempt, buildListQuery, jsonResult } from "./shared.js";
11
+ const BROADCAST = "postmaster@broadcast.msging.net";
12
+ export function registerBroadcastTools(ctx) {
13
+ const { server, client } = ctx;
14
+ server.registerTool("blip_list_broadcast_lists", {
15
+ title: "List broadcast lists (experimental)",
16
+ description: "EXPERIMENTAL. List broadcast/distribution lists. Read-only. " +
17
+ "If it fails for your account, use blip_command against the broadcast postmaster.",
18
+ inputSchema: {
19
+ skip: z.number().int().min(0).default(0).describe("Pagination offset."),
20
+ take: z.number().int().min(1).max(100).default(20).describe("Items to return (1-100)."),
21
+ },
22
+ annotations: { readOnlyHint: true, openWorldHint: true },
23
+ }, async (args) => attempt(ctx, async () => {
24
+ const uri = `/lists?${buildListQuery(args.skip, args.take)}`;
25
+ const res = await client.sendCommand({ method: "get", to: BROADCAST, uri });
26
+ return jsonResult(res.resource ?? res);
27
+ }));
28
+ server.registerTool("blip_list_recipients", {
29
+ title: "List broadcast list recipients (experimental)",
30
+ description: "EXPERIMENTAL. List the recipients of a broadcast/distribution list. Read-only.",
31
+ inputSchema: {
32
+ list: z
33
+ .string()
34
+ .min(1)
35
+ .describe("List identifier or name (e.g. my-list or my-list@broadcast.msging.net)."),
36
+ skip: z.number().int().min(0).default(0).describe("Pagination offset."),
37
+ take: z.number().int().min(1).max(100).default(20).describe("Items to return (1-100)."),
38
+ },
39
+ annotations: { readOnlyHint: true, openWorldHint: true },
40
+ }, async (args) => attempt(ctx, async () => {
41
+ const uri = `/lists/${encodeURIComponent(args.list)}/recipients?${buildListQuery(args.skip, args.take)}`;
42
+ const res = await client.sendCommand({ method: "get", to: BROADCAST, uri });
43
+ return jsonResult(res.resource ?? res);
44
+ }));
45
+ }
46
+ //# sourceMappingURL=broadcast.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"broadcast.js","sourceRoot":"","sources":["../../src/tools/broadcast.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,UAAU,EAAoB,MAAM,aAAa,CAAC;AAEpF,MAAM,SAAS,GAAG,iCAAiC,CAAC;AAEpD,MAAM,UAAU,sBAAsB,CAAC,GAAgB;IACrD,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,GAAG,CAAC;IAE/B,MAAM,CAAC,YAAY,CACjB,2BAA2B,EAC3B;QACE,KAAK,EAAE,qCAAqC;QAC5C,WAAW,EACT,8DAA8D;YAC9D,kFAAkF;QACpF,WAAW,EAAE;YACX,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,oBAAoB,CAAC;YACvE,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,0BAA0B,CAAC;SACxF;QACD,WAAW,EAAE,EAAE,YAAY,EAAE,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE;KACzD,EACD,KAAK,EAAE,IAAI,EAAE,EAAE,CACb,OAAO,CAAC,GAAG,EAAE,KAAK,IAAI,EAAE;QACtB,MAAM,GAAG,GAAG,UAAU,cAAc,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;QAC7D,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,WAAW,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,EAAE,SAAS,EAAE,GAAG,EAAE,CAAC,CAAC;QAC5E,OAAO,UAAU,CAAC,GAAG,CAAC,QAAQ,IAAI,GAAG,CAAC,CAAC;IACzC,CAAC,CAAC,CACL,CAAC;IAEF,MAAM,CAAC,YAAY,CACjB,sBAAsB,EACtB;QACE,KAAK,EAAE,+CAA+C;QACtD,WAAW,EACT,gFAAgF;QAClF,WAAW,EAAE;YACX,IAAI,EAAE,CAAC;iBACJ,MAAM,EAAE;iBACR,GAAG,CAAC,CAAC,CAAC;iBACN,QAAQ,CAAC,yEAAyE,CAAC;YACtF,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,oBAAoB,CAAC;YACvE,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,0BAA0B,CAAC;SACxF;QACD,WAAW,EAAE,EAAE,YAAY,EAAE,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE;KACzD,EACD,KAAK,EAAE,IAAI,EAAE,EAAE,CACb,OAAO,CAAC,GAAG,EAAE,KAAK,IAAI,EAAE;QACtB,MAAM,GAAG,GAAG,UAAU,kBAAkB,CAAC,IAAI,CAAC,IAAI,CAAC,eAAe,cAAc,CAC9E,IAAI,CAAC,IAAI,EACT,IAAI,CAAC,IAAI,CACV,EAAE,CAAC;QACJ,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,WAAW,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,EAAE,SAAS,EAAE,GAAG,EAAE,CAAC,CAAC;QAC5E,OAAO,UAAU,CAAC,GAAG,CAAC,QAAQ,IAAI,GAAG,CAAC,CAAC;IACzC,CAAC,CAAC,CACL,CAAC;AACJ,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { type ToolContext } from "./shared.js";
2
+ export declare function registerBucketTools(ctx: ToolContext): void;
3
+ //# sourceMappingURL=buckets.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"buckets.d.ts","sourceRoot":"","sources":["../../src/tools/buckets.ts"],"names":[],"mappings":"AASA,OAAO,EAAuD,KAAK,WAAW,EAAE,MAAM,aAAa,CAAC;AAEpG,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,WAAW,GAAG,IAAI,CAiD1D"}
@@ -0,0 +1,49 @@
1
+ /**
2
+ * Bucket (key/value storage) tools.
3
+ *
4
+ * Buckets live on your bot's OWN node, so these commands send NO `to` /
5
+ * postmaster (that is the correct Blip behavior). This differs from the
6
+ * initial spec note of `postmaster@msging.net`; use `blip_command` with an
7
+ * explicit `to` if your account is configured differently.
8
+ */
9
+ import { z } from "zod";
10
+ import { attempt, encodeBucketId, jsonResult, readOnlyNotice } from "./shared.js";
11
+ export function registerBucketTools(ctx) {
12
+ const { server, client, config } = ctx;
13
+ server.registerTool("blip_get_bucket", {
14
+ title: "Get a bucket value",
15
+ description: "Read a value from the bot's key/value storage by id. Read-only.",
16
+ inputSchema: {
17
+ id: z.string().min(1).describe("Bucket key/id, e.g. my_config or namespace:key."),
18
+ },
19
+ annotations: { readOnlyHint: true, openWorldHint: true },
20
+ }, async (args) => attempt(ctx, async () => {
21
+ const res = await client.sendCommand({ method: "get", uri: `/buckets/${encodeBucketId(args.id)}` });
22
+ return jsonResult(res.resource ?? res);
23
+ }));
24
+ server.registerTool("blip_set_bucket", {
25
+ title: "Set a bucket value",
26
+ description: "WRITE / SIDE EFFECT: store a value in the bot's key/value storage (method=set). " +
27
+ "Requires BLIP_ALLOW_WRITES=true.",
28
+ inputSchema: {
29
+ id: z.string().min(1).describe("Bucket key/id to write."),
30
+ value: z.unknown().describe("Value to store (any JSON)."),
31
+ type: z
32
+ .string()
33
+ .default("application/json")
34
+ .describe("Resource MIME type. Defaults to application/json."),
35
+ },
36
+ annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: true, openWorldHint: true },
37
+ }, async (args) => attempt(ctx, async () => {
38
+ if (!config.allowWrites)
39
+ return readOnlyNotice(`set bucket ${args.id}`);
40
+ const res = await client.sendCommand({
41
+ method: "set",
42
+ uri: `/buckets/${encodeBucketId(args.id)}`,
43
+ type: args.type,
44
+ resource: args.value,
45
+ });
46
+ return jsonResult(res);
47
+ }));
48
+ }
49
+ //# sourceMappingURL=buckets.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"buckets.js","sourceRoot":"","sources":["../../src/tools/buckets.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,UAAU,EAAE,cAAc,EAAoB,MAAM,aAAa,CAAC;AAEpG,MAAM,UAAU,mBAAmB,CAAC,GAAgB;IAClD,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,GAAG,CAAC;IAEvC,MAAM,CAAC,YAAY,CACjB,iBAAiB,EACjB;QACE,KAAK,EAAE,oBAAoB;QAC3B,WAAW,EAAE,iEAAiE;QAC9E,WAAW,EAAE;YACX,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,iDAAiD,CAAC;SAClF;QACD,WAAW,EAAE,EAAE,YAAY,EAAE,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE;KACzD,EACD,KAAK,EAAE,IAAI,EAAE,EAAE,CACb,OAAO,CAAC,GAAG,EAAE,KAAK,IAAI,EAAE;QACtB,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,WAAW,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,EAAE,YAAY,cAAc,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;QACpG,OAAO,UAAU,CAAC,GAAG,CAAC,QAAQ,IAAI,GAAG,CAAC,CAAC;IACzC,CAAC,CAAC,CACL,CAAC;IAEF,MAAM,CAAC,YAAY,CACjB,iBAAiB,EACjB;QACE,KAAK,EAAE,oBAAoB;QAC3B,WAAW,EACT,kFAAkF;YAClF,kCAAkC;QACpC,WAAW,EAAE;YACX,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,yBAAyB,CAAC;YACzD,KAAK,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,CAAC,4BAA4B,CAAC;YACzD,IAAI,EAAE,CAAC;iBACJ,MAAM,EAAE;iBACR,OAAO,CAAC,kBAAkB,CAAC;iBAC3B,QAAQ,CAAC,mDAAmD,CAAC;SACjE;QACD,WAAW,EAAE,EAAE,YAAY,EAAE,KAAK,EAAE,eAAe,EAAE,KAAK,EAAE,cAAc,EAAE,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE;KACxG,EACD,KAAK,EAAE,IAAI,EAAE,EAAE,CACb,OAAO,CAAC,GAAG,EAAE,KAAK,IAAI,EAAE;QACtB,IAAI,CAAC,MAAM,CAAC,WAAW;YAAE,OAAO,cAAc,CAAC,cAAc,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC;QACxE,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,WAAW,CAAC;YACnC,MAAM,EAAE,KAAK;YACb,GAAG,EAAE,YAAY,cAAc,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE;YAC1C,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,QAAQ,EAAE,IAAI,CAAC,KAAK;SACrB,CAAC,CAAC;QACH,OAAO,UAAU,CAAC,GAAG,CAAC,CAAC;IACzB,CAAC,CAAC,CACL,CAAC;AACJ,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { type ToolContext } from "./shared.js";
2
+ export declare function registerCommandTool(ctx: ToolContext): void;
3
+ //# sourceMappingURL=command.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"command.d.ts","sourceRoot":"","sources":["../../src/tools/command.ts"],"names":[],"mappings":"AAQA,OAAO,EAAuC,KAAK,WAAW,EAAE,MAAM,aAAa,CAAC;AAEpF,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,WAAW,GAAG,IAAI,CAqC1D"}
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Generic escape hatch: run ANY Blip command. This is what lets you reach
3
+ * resources that don't have a dedicated tool yet.
4
+ *
5
+ * Guardrail: when method != "get" and BLIP_ALLOW_WRITES is false, it refuses
6
+ * and returns a read-only notice instead of executing.
7
+ */
8
+ import { z } from "zod";
9
+ import { attempt, jsonResult, readOnlyNotice } from "./shared.js";
10
+ export function registerCommandTool(ctx) {
11
+ const { server, client, config } = ctx;
12
+ server.registerTool("blip_command", {
13
+ title: "Run a raw Blip command",
14
+ description: "Low-level access to the Blip Command API. Provide method, uri, optional to " +
15
+ "(postmaster) and resource. GET is always allowed; set/merge/delete require " +
16
+ "BLIP_ALLOW_WRITES=true. Examples of `to`: postmaster@crm.msging.net (contacts), " +
17
+ "postmaster@ai.msging.net (AI), postmaster@scheduler.msging.net (schedules). " +
18
+ "Omit `to` for resources on your own node (e.g. /buckets).",
19
+ inputSchema: {
20
+ method: z.enum(["get", "set", "merge", "delete"]).describe("Command method."),
21
+ uri: z.string().min(1).describe("Resource URI, e.g. /contacts?$take=1 or /buckets/my_key."),
22
+ to: z.string().optional().describe("Optional postmaster/recipient. Omit for your own node."),
23
+ type: z.string().optional().describe("Optional resource MIME type (for set/merge)."),
24
+ resource: z.unknown().describe("Optional resource body (for set/merge).").optional(),
25
+ },
26
+ annotations: { readOnlyHint: false, destructiveHint: true, openWorldHint: true },
27
+ }, async (args) => attempt(ctx, async () => {
28
+ if (args.method !== "get" && !config.allowWrites) {
29
+ return readOnlyNotice(`${args.method.toUpperCase()} ${args.uri}`);
30
+ }
31
+ const res = await client.sendCommand({
32
+ method: args.method,
33
+ uri: args.uri,
34
+ to: args.to,
35
+ type: args.type,
36
+ resource: args.resource,
37
+ });
38
+ return jsonResult(res);
39
+ }));
40
+ }
41
+ //# sourceMappingURL=command.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"command.js","sourceRoot":"","sources":["../../src/tools/command.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,cAAc,EAAoB,MAAM,aAAa,CAAC;AAEpF,MAAM,UAAU,mBAAmB,CAAC,GAAgB;IAClD,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,GAAG,CAAC;IAEvC,MAAM,CAAC,YAAY,CACjB,cAAc,EACd;QACE,KAAK,EAAE,wBAAwB;QAC/B,WAAW,EACT,6EAA6E;YAC7E,6EAA6E;YAC7E,kFAAkF;YAClF,8EAA8E;YAC9E,2DAA2D;QAC7D,WAAW,EAAE;YACX,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,iBAAiB,CAAC;YAC7E,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,0DAA0D,CAAC;YAC3F,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,wDAAwD,CAAC;YAC5F,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,8CAA8C,CAAC;YACpF,QAAQ,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,CAAC,yCAAyC,CAAC,CAAC,QAAQ,EAAE;SACrF;QACD,WAAW,EAAE,EAAE,YAAY,EAAE,KAAK,EAAE,eAAe,EAAE,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE;KACjF,EACD,KAAK,EAAE,IAAI,EAAE,EAAE,CACb,OAAO,CAAC,GAAG,EAAE,KAAK,IAAI,EAAE;QACtB,IAAI,IAAI,CAAC,MAAM,KAAK,KAAK,IAAI,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC;YACjD,OAAO,cAAc,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,WAAW,EAAE,IAAI,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;QACpE,CAAC;QACD,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,WAAW,CAAC;YACnC,MAAM,EAAE,IAAI,CAAC,MAAM;YACnB,GAAG,EAAE,IAAI,CAAC,GAAG;YACb,EAAE,EAAE,IAAI,CAAC,EAAE;YACX,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,QAAQ,EAAE,IAAI,CAAC,QAAQ;SACxB,CAAC,CAAC;QACH,OAAO,UAAU,CAAC,GAAG,CAAC,CAAC;IACzB,CAAC,CAAC,CACL,CAAC;AACJ,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { type ToolContext } from "./shared.js";
2
+ export declare function registerContactTools(ctx: ToolContext): void;
3
+ //# sourceMappingURL=contacts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contacts.d.ts","sourceRoot":"","sources":["../../src/tools/contacts.ts"],"names":[],"mappings":"AAEA,OAAO,EAML,KAAK,WAAW,EACjB,MAAM,aAAa,CAAC;AAKrB,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,WAAW,GAAG,IAAI,CAgJ3D"}
@@ -0,0 +1,119 @@
1
+ /** Contact (CRM) tools. Target postmaster: postmaster@crm.msging.net */
2
+ import { z } from "zod";
3
+ import { attempt, buildListQuery, jsonResult, phoneCandidates, readOnlyNotice, } from "./shared.js";
4
+ const CRM = "postmaster@crm.msging.net";
5
+ const CONTACT_MIME = "application/vnd.lime.contact+json";
6
+ export function registerContactTools(ctx) {
7
+ const { server, client, config } = ctx;
8
+ server.registerTool("blip_list_contacts", {
9
+ title: "List Blip contacts",
10
+ description: "List contacts stored in your bot's CRM, with pagination and an optional " +
11
+ "OData $filter. Read-only. Example filter: substringof('WhatsApp',source)",
12
+ inputSchema: {
13
+ skip: z.number().int().min(0).default(0).describe("Items to skip (pagination offset)."),
14
+ take: z.number().int().min(1).max(100).default(20).describe("Items to return (1-100)."),
15
+ filter: z
16
+ .string()
17
+ .optional()
18
+ .describe("Optional OData $filter expression. Value is URL-encoded for you."),
19
+ },
20
+ annotations: { readOnlyHint: true, openWorldHint: true },
21
+ }, async (args) => attempt(ctx, async () => {
22
+ const uri = `/contacts?${buildListQuery(args.skip, args.take, args.filter)}`;
23
+ const res = await client.sendCommand({ method: "get", to: CRM, uri });
24
+ return jsonResult(res.resource ?? res);
25
+ }));
26
+ server.registerTool("blip_get_contact", {
27
+ title: "Get a Blip contact",
28
+ description: "Fetch a single contact by its identity (e.g. 5511999999999@wa.gw.msging.net). Read-only.",
29
+ inputSchema: {
30
+ identity: z.string().min(1).describe("The contact identity to fetch."),
31
+ },
32
+ annotations: { readOnlyHint: true, openWorldHint: true },
33
+ }, async (args) => attempt(ctx, async () => {
34
+ const uri = `/contacts/${encodeURIComponent(args.identity)}`;
35
+ const res = await client.sendCommand({ method: "get", to: CRM, uri });
36
+ return jsonResult(res.resource ?? res);
37
+ }));
38
+ server.registerTool("blip_find_contact_by_phone", {
39
+ title: "Find a contact by phone number",
40
+ description: "Find a CRM contact by phone number. Tries common formats automatically " +
41
+ "(with/without country code 55, with/without +), since Blip stores them " +
42
+ "inconsistently. Read-only. Use `flow` to pick which bot's CRM to search.",
43
+ inputSchema: {
44
+ phone: z
45
+ .string()
46
+ .min(6)
47
+ .describe("Phone in any common format, e.g. 11997053906 or +5511997053906."),
48
+ flow: z
49
+ .string()
50
+ .optional()
51
+ .describe("Configured flow (bot) whose CRM to search. Defaults to the default flow."),
52
+ },
53
+ annotations: { readOnlyHint: true, openWorldHint: true },
54
+ }, async (args) => attempt(ctx, async () => {
55
+ const flowClient = ctx.getClient(args.flow);
56
+ const tried = [];
57
+ for (const candidate of phoneCandidates(args.phone)) {
58
+ tried.push(candidate);
59
+ const filter = `phoneNumber eq '${candidate}'`;
60
+ const uri = `/contacts?$take=5&$filter=${encodeURIComponent(filter)}`;
61
+ const res = await flowClient.sendCommand({ method: "get", to: CRM, uri });
62
+ const resource = res.resource;
63
+ const items = resource?.items ?? [];
64
+ if (items.length > 0) {
65
+ return jsonResult({
66
+ found: true,
67
+ matchedFormat: candidate,
68
+ total: resource?.total ?? items.length,
69
+ contacts: items,
70
+ });
71
+ }
72
+ }
73
+ return jsonResult({
74
+ found: false,
75
+ message: `No contact found. Tried phoneNumber formats: ${tried.join(", ")}`,
76
+ });
77
+ }));
78
+ server.registerTool("blip_set_contact", {
79
+ title: "Create or update a Blip contact",
80
+ description: "WRITE / SIDE EFFECT: create or update a contact in the CRM (method=merge). " +
81
+ "The `contact` object must include an `identity`. Requires BLIP_ALLOW_WRITES=true.",
82
+ inputSchema: {
83
+ contact: z
84
+ .record(z.string(), z.unknown())
85
+ .describe("Contact resource. Must contain `identity`; other fields are optional."),
86
+ },
87
+ annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: true, openWorldHint: true },
88
+ }, async (args) => attempt(ctx, async () => {
89
+ const identity = args.contact["identity"];
90
+ if (typeof identity !== "string" || identity.length === 0) {
91
+ return jsonResult({ error: "contact.identity is required and must be a non-empty string." });
92
+ }
93
+ if (!config.allowWrites)
94
+ return readOnlyNotice(`upsert contact ${identity}`);
95
+ const res = await client.sendCommand({
96
+ method: "merge",
97
+ to: CRM,
98
+ uri: "/contacts",
99
+ type: CONTACT_MIME,
100
+ resource: args.contact,
101
+ });
102
+ return jsonResult(res);
103
+ }));
104
+ server.registerTool("blip_delete_contact", {
105
+ title: "Delete a Blip contact",
106
+ description: "WRITE / DESTRUCTIVE: permanently remove a contact by identity. Requires BLIP_ALLOW_WRITES=true.",
107
+ inputSchema: {
108
+ identity: z.string().min(1).describe("The contact identity to delete."),
109
+ },
110
+ annotations: { readOnlyHint: false, destructiveHint: true, idempotentHint: true, openWorldHint: true },
111
+ }, async (args) => attempt(ctx, async () => {
112
+ if (!config.allowWrites)
113
+ return readOnlyNotice(`delete contact ${args.identity}`);
114
+ const uri = `/contacts/${encodeURIComponent(args.identity)}`;
115
+ const res = await client.sendCommand({ method: "delete", to: CRM, uri });
116
+ return jsonResult(res);
117
+ }));
118
+ }
119
+ //# sourceMappingURL=contacts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contacts.js","sourceRoot":"","sources":["../../src/tools/contacts.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import { type ToolContext } from "./shared.js";
2
+ export declare function registerContextTools(ctx: ToolContext): void;
3
+ //# sourceMappingURL=context.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/tools/context.ts"],"names":[],"mappings":"AAYA,OAAO,EAAuB,KAAK,WAAW,EAAE,MAAM,aAAa,CAAC;AAEpE,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,WAAW,GAAG,IAAI,CAiD3D"}
@@ -0,0 +1,50 @@
1
+ /**
2
+ * Context-variable tools (EXPERIMENTAL) — the heart of "why did this contact
3
+ * match this rule?".
4
+ *
5
+ * Flow conditions evaluate against a contact's CONTEXT variables. Reading them
6
+ * shows the actual values a rule saw. The special variable `stateid@{flowId}`
7
+ * holds where the contact currently is in a given flow.
8
+ *
9
+ * Sent to the bot's own node (no `to`). If your account keeps context behind a
10
+ * postmaster, use `blip_command` with the appropriate `to`.
11
+ */
12
+ import { z } from "zod";
13
+ import { attempt, jsonResult } from "./shared.js";
14
+ export function registerContextTools(ctx) {
15
+ const { server, client } = ctx;
16
+ server.registerTool("blip_get_context", {
17
+ title: "Get a contact's context variables (experimental)",
18
+ description: "EXPERIMENTAL. List the Builder context variables stored for a contact — the actual " +
19
+ "values that flow conditions/rules evaluate against. Read-only. Use this to debug why " +
20
+ "a contact took one path instead of another.",
21
+ inputSchema: {
22
+ identity: z.string().min(1).describe("Contact identity, e.g. 5511999999999@wa.gw.msging.net."),
23
+ skip: z.number().int().min(0).default(0).describe("Pagination offset."),
24
+ take: z.number().int().min(1).max(100).default(50).describe("Variables to return (1-100)."),
25
+ },
26
+ annotations: { readOnlyHint: true, openWorldHint: true },
27
+ }, async (args) => attempt(ctx, async () => {
28
+ const uri = `/contexts/${encodeURIComponent(args.identity)}?skip=${args.skip}&take=${args.take}`;
29
+ const res = await client.sendCommand({ method: "get", uri });
30
+ return jsonResult(res.resource ?? res);
31
+ }));
32
+ server.registerTool("blip_get_context_variable", {
33
+ title: "Get one context variable of a contact (experimental)",
34
+ description: "EXPERIMENTAL. Read a single context variable for a contact. Read-only. " +
35
+ "Tip: variable `stateid@{flowId}` returns where the contact currently is in that flow.",
36
+ inputSchema: {
37
+ identity: z.string().min(1).describe("Contact identity."),
38
+ variable: z
39
+ .string()
40
+ .min(1)
41
+ .describe("Variable name, e.g. cpf, plano, or stateid@1234 for flow state."),
42
+ },
43
+ annotations: { readOnlyHint: true, openWorldHint: true },
44
+ }, async (args) => attempt(ctx, async () => {
45
+ const uri = `/contexts/${encodeURIComponent(args.identity)}/${encodeURIComponent(args.variable)}`;
46
+ const res = await client.sendCommand({ method: "get", uri });
47
+ return jsonResult(res.resource ?? res);
48
+ }));
49
+ }
50
+ //# sourceMappingURL=context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.js","sourceRoot":"","sources":["../../src/tools/context.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,OAAO,EAAE,UAAU,EAAoB,MAAM,aAAa,CAAC;AAEpE,MAAM,UAAU,oBAAoB,CAAC,GAAgB;IACnD,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,GAAG,CAAC;IAE/B,MAAM,CAAC,YAAY,CACjB,kBAAkB,EAClB;QACE,KAAK,EAAE,kDAAkD;QACzD,WAAW,EACT,qFAAqF;YACrF,uFAAuF;YACvF,6CAA6C;QAC/C,WAAW,EAAE;YACX,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,wDAAwD,CAAC;YAC9F,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,oBAAoB,CAAC;YACvE,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,8BAA8B,CAAC;SAC5F;QACD,WAAW,EAAE,EAAE,YAAY,EAAE,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE;KACzD,EACD,KAAK,EAAE,IAAI,EAAE,EAAE,CACb,OAAO,CAAC,GAAG,EAAE,KAAK,IAAI,EAAE;QACtB,MAAM,GAAG,GAAG,aAAa,kBAAkB,CAAC,IAAI,CAAC,QAAQ,CAAC,SAAS,IAAI,CAAC,IAAI,SAAS,IAAI,CAAC,IAAI,EAAE,CAAC;QACjG,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,WAAW,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,CAAC;QAC7D,OAAO,UAAU,CAAC,GAAG,CAAC,QAAQ,IAAI,GAAG,CAAC,CAAC;IACzC,CAAC,CAAC,CACL,CAAC;IAEF,MAAM,CAAC,YAAY,CACjB,2BAA2B,EAC3B;QACE,KAAK,EAAE,sDAAsD;QAC7D,WAAW,EACT,yEAAyE;YACzE,uFAAuF;QACzF,WAAW,EAAE;YACX,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,mBAAmB,CAAC;YACzD,QAAQ,EAAE,CAAC;iBACR,MAAM,EAAE;iBACR,GAAG,CAAC,CAAC,CAAC;iBACN,QAAQ,CAAC,iEAAiE,CAAC;SAC/E;QACD,WAAW,EAAE,EAAE,YAAY,EAAE,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE;KACzD,EACD,KAAK,EAAE,IAAI,EAAE,EAAE,CACb,OAAO,CAAC,GAAG,EAAE,KAAK,IAAI,EAAE;QACtB,MAAM,GAAG,GAAG,aAAa,kBAAkB,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,kBAAkB,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;QAClG,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,WAAW,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,CAAC;QAC7D,OAAO,UAAU,CAAC,GAAG,CAAC,QAAQ,IAAI,GAAG,CAAC,CAAC;IACzC,CAAC,CAAC,CACL,CAAC;AACJ,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { type ToolContext } from "./shared.js";
2
+ export declare function registerEventTools(ctx: ToolContext): void;
3
+ //# sourceMappingURL=events.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"events.d.ts","sourceRoot":"","sources":["../../src/tools/events.ts"],"names":[],"mappings":"AAOA,OAAO,EAAuC,KAAK,WAAW,EAAE,MAAM,aAAa,CAAC;AAEpF,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,WAAW,GAAG,IAAI,CAiDzD"}
@@ -0,0 +1,48 @@
1
+ /**
2
+ * Event-tracking (analytics) tools (EXPERIMENTAL). Read-only.
3
+ *
4
+ * If a flow logs custom events at key points, these surface the marks/counters,
5
+ * helping reconstruct the journey. Sent to the bot's own node (no `to`).
6
+ */
7
+ import { z } from "zod";
8
+ import { attempt, buildListQuery, jsonResult } from "./shared.js";
9
+ export function registerEventTools(ctx) {
10
+ const { server, client } = ctx;
11
+ server.registerTool("blip_list_event_categories", {
12
+ title: "List tracked event categories (experimental)",
13
+ description: "EXPERIMENTAL. List the event categories tracked by your flows. Read-only.",
14
+ inputSchema: {
15
+ skip: z.number().int().min(0).default(0).describe("Pagination offset."),
16
+ take: z.number().int().min(1).max(100).default(20).describe("Categories to return (1-100)."),
17
+ },
18
+ annotations: { readOnlyHint: true, openWorldHint: true },
19
+ }, async (args) => attempt(ctx, async () => {
20
+ const res = await client.sendCommand({
21
+ method: "get",
22
+ uri: `/event-track?${buildListQuery(args.skip, args.take)}`,
23
+ });
24
+ return jsonResult(res.resource ?? res);
25
+ }));
26
+ server.registerTool("blip_get_event_track", {
27
+ title: "Get tracked events for a category (experimental)",
28
+ description: "EXPERIMENTAL. Get tracked events/actions for a category, optionally within a date range " +
29
+ "(ISO dates, e.g. 2026-06-01). Read-only.",
30
+ inputSchema: {
31
+ category: z.string().min(1).describe("Event category name."),
32
+ startDate: z.string().optional().describe("Optional ISO start date, e.g. 2026-06-01."),
33
+ endDate: z.string().optional().describe("Optional ISO end date, e.g. 2026-06-19."),
34
+ },
35
+ annotations: { readOnlyHint: true, openWorldHint: true },
36
+ }, async (args) => attempt(ctx, async () => {
37
+ const params = [];
38
+ if (args.startDate)
39
+ params.push(`startDate=${encodeURIComponent(args.startDate)}`);
40
+ if (args.endDate)
41
+ params.push(`endDate=${encodeURIComponent(args.endDate)}`);
42
+ const query = params.length > 0 ? `?${params.join("&")}` : "";
43
+ const uri = `/event-track/${encodeURIComponent(args.category)}${query}`;
44
+ const res = await client.sendCommand({ method: "get", uri });
45
+ return jsonResult(res.resource ?? res);
46
+ }));
47
+ }
48
+ //# sourceMappingURL=events.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"events.js","sourceRoot":"","sources":["../../src/tools/events.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import { type ToolContext } from "./shared.js";
2
+ export declare function registerFlowMapTools(ctx: ToolContext): void;
3
+ //# sourceMappingURL=flow-tools.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"flow-tools.d.ts","sourceRoot":"","sources":["../../src/tools/flow-tools.ts"],"names":[],"mappings":"AAaA,OAAO,EAAuC,KAAK,WAAW,EAAE,MAAM,aAAa,CAAC;AAIpF,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,WAAW,GAAG,IAAI,CA8E3D"}
@@ -0,0 +1,77 @@
1
+ /**
2
+ * Flow mapping tools.
3
+ *
4
+ * - blip_list_flows: list configured flows (names/hosts only, never secrets).
5
+ * - blip_map_flow: read a flow definition and write a COMPONENTIZED set of docs
6
+ * (index + one file per block) under <flowsDir>/<flowName>/. Reads from Blip,
7
+ * writes local files only (no Blip-side mutation).
8
+ */
9
+ import { mkdir, writeFile } from "node:fs/promises";
10
+ import { dirname, join, resolve } from "node:path";
11
+ import { z } from "zod";
12
+ import { resolveFlow } from "../config.js";
13
+ import { buildFlowMap, renderFlowFiles } from "../flow-map.js";
14
+ import { attempt, encodeBucketId, jsonResult } from "./shared.js";
15
+ const DEFAULT_FLOW_KEY = "blip_portal:builder_published_flow";
16
+ export function registerFlowMapTools(ctx) {
17
+ const { server } = ctx;
18
+ server.registerTool("blip_list_flows", {
19
+ title: "List configured flows",
20
+ description: "List the flows (Blip bots) configured via blip.env / environment. Names and hosts only — " +
21
+ "never shows credentials. Read-only.",
22
+ inputSchema: {},
23
+ annotations: { readOnlyHint: true },
24
+ }, async () => attempt(ctx, async () => jsonResult({
25
+ defaultFlow: ctx.config.defaultFlowName,
26
+ flowsDir: ctx.flowsDir,
27
+ flows: ctx.flows.map((f) => ({
28
+ name: f.name,
29
+ host: f.baseUrl,
30
+ credentialMode: f.credentialMode,
31
+ isDefault: f.name === ctx.config.defaultFlowName,
32
+ })),
33
+ })));
34
+ server.registerTool("blip_map_flow", {
35
+ title: "Map a flow into componentized docs",
36
+ description: "Read a Blip Builder flow definition and write a COMPONENTIZED set of docs under " +
37
+ "<flowsDir>/<flow>/ : an index.md (block graph + who-connects-to-whom), index.json, and one " +
38
+ "blocks/<block>.md per block (what it does + its routing rules). Reads from Blip, writes local " +
39
+ "files only. Use `flow` to pick which configured flow to map (see blip_list_flows).",
40
+ inputSchema: {
41
+ flow: z.string().optional().describe("Configured flow name to map. Defaults to the default flow."),
42
+ key: z
43
+ .string()
44
+ .default(DEFAULT_FLOW_KEY)
45
+ .describe(`Flow storage key. Defaults to ${DEFAULT_FLOW_KEY} (try blip_portal:builder_working_flow for the draft).`),
46
+ full: z.boolean().default(false).describe("Include full message texts instead of short snippets."),
47
+ outDir: z.string().optional().describe("Override the output base dir (defaults to BLIP_FLOWS_DIR / 'flows')."),
48
+ },
49
+ annotations: { readOnlyHint: true, openWorldHint: true },
50
+ }, async (args) => attempt(ctx, async () => {
51
+ const flow = resolveFlow(ctx.config, args.flow);
52
+ const client = ctx.getClient(flow.name);
53
+ const res = await client.sendCommand({ method: "get", uri: `/buckets/${encodeBucketId(args.key)}` });
54
+ const resource = res.resource ?? res;
55
+ const map = buildFlowMap(args.key, resource, { full: args.full });
56
+ const files = renderFlowFiles(map);
57
+ const safeName = flow.name.replace(/[^a-zA-Z0-9._-]/g, "_") || "flow";
58
+ const baseDir = resolve(args.outDir ?? ctx.flowsDir, safeName);
59
+ for (const [rel, content] of Object.entries(files)) {
60
+ const target = join(baseDir, rel);
61
+ await mkdir(dirname(target), { recursive: true });
62
+ await writeFile(target, content, "utf8");
63
+ }
64
+ ctx.logger.info(`mapped flow "${flow.name}" -> ${baseDir} (${map.blockCount} blocks)`);
65
+ return jsonResult({
66
+ flow: flow.name,
67
+ host: flow.baseUrl,
68
+ key: args.key,
69
+ outputDir: baseDir,
70
+ blocks: map.blockCount,
71
+ subflows: Object.keys(map.subflows).length,
72
+ filesWritten: Object.keys(files).length,
73
+ index: join(baseDir, "index.md"),
74
+ });
75
+ }));
76
+ }
77
+ //# sourceMappingURL=flow-tools.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"flow-tools.js","sourceRoot":"","sources":["../../src/tools/flow-tools.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import { type ToolContext } from "./shared.js";
2
+ export declare function registerFlowTools(ctx: ToolContext): void;
3
+ //# sourceMappingURL=flow.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"flow.d.ts","sourceRoot":"","sources":["../../src/tools/flow.ts"],"names":[],"mappings":"AAUA,OAAO,EAAuC,KAAK,WAAW,EAAE,MAAM,aAAa,CAAC;AAIpF,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,WAAW,GAAG,IAAI,CA0BxD"}
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Flow-definition tool (EXPERIMENTAL). Read-only.
3
+ *
4
+ * The Builder flow (blocks + their conditions/rules) is stored in a bucket.
5
+ * Reading it lets you see the exact rule that routes a contact to a flow, so
6
+ * you can cross-check it against the contact's context variables.
7
+ *
8
+ * Sent to the bot's own node (no `to`).
9
+ */
10
+ import { z } from "zod";
11
+ import { attempt, encodeBucketId, jsonResult } from "./shared.js";
12
+ const DEFAULT_FLOW_KEY = "blip_portal:builder_published_flow";
13
+ export function registerFlowTools(ctx) {
14
+ const { server, client } = ctx;
15
+ server.registerTool("blip_get_flow", {
16
+ title: "Get the bot flow definition (experimental)",
17
+ description: "EXPERIMENTAL. Read the published Builder flow definition (blocks, outputs and their " +
18
+ "conditions/rules) from storage. Read-only. Use it to see the exact rule that routes a " +
19
+ "contact, then compare with blip_get_context. Default key: " +
20
+ `${DEFAULT_FLOW_KEY}. Try blip_portal:builder_working_flow for the draft.`,
21
+ inputSchema: {
22
+ key: z
23
+ .string()
24
+ .default(DEFAULT_FLOW_KEY)
25
+ .describe("Storage key of the flow. Defaults to the published flow."),
26
+ },
27
+ annotations: { readOnlyHint: true, openWorldHint: true },
28
+ }, async (args) => attempt(ctx, async () => {
29
+ const res = await client.sendCommand({ method: "get", uri: `/buckets/${encodeBucketId(args.key)}` });
30
+ return jsonResult(res.resource ?? res);
31
+ }));
32
+ }
33
+ //# sourceMappingURL=flow.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"flow.js","sourceRoot":"","sources":["../../src/tools/flow.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,UAAU,EAAoB,MAAM,aAAa,CAAC;AAEpF,MAAM,gBAAgB,GAAG,oCAAoC,CAAC;AAE9D,MAAM,UAAU,iBAAiB,CAAC,GAAgB;IAChD,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,GAAG,CAAC;IAE/B,MAAM,CAAC,YAAY,CACjB,eAAe,EACf;QACE,KAAK,EAAE,4CAA4C;QACnD,WAAW,EACT,sFAAsF;YACtF,wFAAwF;YACxF,4DAA4D;YAC5D,GAAG,gBAAgB,uDAAuD;QAC5E,WAAW,EAAE;YACX,GAAG,EAAE,CAAC;iBACH,MAAM,EAAE;iBACR,OAAO,CAAC,gBAAgB,CAAC;iBACzB,QAAQ,CAAC,0DAA0D,CAAC;SACxE;QACD,WAAW,EAAE,EAAE,YAAY,EAAE,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE;KACzD,EACD,KAAK,EAAE,IAAI,EAAE,EAAE,CACb,OAAO,CAAC,GAAG,EAAE,KAAK,IAAI,EAAE;QACtB,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,WAAW,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,EAAE,YAAY,cAAc,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC;QACrG,OAAO,UAAU,CAAC,GAAG,CAAC,QAAQ,IAAI,GAAG,CAAC,CAAC;IACzC,CAAC,CAAC,CACL,CAAC;AACJ,CAAC"}
@@ -0,0 +1,5 @@
1
+ /** Registers every tool on the MCP server. */
2
+ import type { ToolContext } from "./shared.js";
3
+ export type { ToolContext } from "./shared.js";
4
+ export declare function registerAllTools(ctx: ToolContext): void;
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AAAA,8CAA8C;AAC9C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAc/C,YAAY,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE/C,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,WAAW,GAAG,IAAI,CAkBvD"}