@linwheel/mcp-server 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.
- package/README.md +219 -0
- package/dist/client.d.ts +24 -0
- package/dist/client.js +36 -0
- package/dist/client.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +79 -0
- package/dist/index.js.map +1 -0
- package/dist/tools/analyze.d.ts +3 -0
- package/dist/tools/analyze.js +16 -0
- package/dist/tools/analyze.js.map +1 -0
- package/dist/tools/brand-styles.d.ts +3 -0
- package/dist/tools/brand-styles.js +108 -0
- package/dist/tools/brand-styles.js.map +1 -0
- package/dist/tools/bundle.d.ts +3 -0
- package/dist/tools/bundle.js +55 -0
- package/dist/tools/bundle.js.map +1 -0
- package/dist/tools/draft.d.ts +3 -0
- package/dist/tools/draft.js +41 -0
- package/dist/tools/draft.js.map +1 -0
- package/dist/tools/index.d.ts +3 -0
- package/dist/tools/index.js +46 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/post-approve.d.ts +3 -0
- package/dist/tools/post-approve.js +13 -0
- package/dist/tools/post-approve.js.map +1 -0
- package/dist/tools/post-carousel-companion.d.ts +3 -0
- package/dist/tools/post-carousel-companion.js +47 -0
- package/dist/tools/post-carousel-companion.js.map +1 -0
- package/dist/tools/post-carousel-schedule.d.ts +3 -0
- package/dist/tools/post-carousel-schedule.js +48 -0
- package/dist/tools/post-carousel-schedule.js.map +1 -0
- package/dist/tools/post-carousel-status.d.ts +3 -0
- package/dist/tools/post-carousel-status.js +12 -0
- package/dist/tools/post-carousel-status.js.map +1 -0
- package/dist/tools/post-carousel.d.ts +3 -0
- package/dist/tools/post-carousel.js +28 -0
- package/dist/tools/post-carousel.js.map +1 -0
- package/dist/tools/post-comment.d.ts +3 -0
- package/dist/tools/post-comment.js +68 -0
- package/dist/tools/post-comment.js.map +1 -0
- package/dist/tools/post-get.d.ts +3 -0
- package/dist/tools/post-get.js +12 -0
- package/dist/tools/post-get.js.map +1 -0
- package/dist/tools/post-image.d.ts +3 -0
- package/dist/tools/post-image.js +25 -0
- package/dist/tools/post-image.js.map +1 -0
- package/dist/tools/post-schedule.d.ts +3 -0
- package/dist/tools/post-schedule.js +20 -0
- package/dist/tools/post-schedule.js.map +1 -0
- package/dist/tools/post-update.d.ts +3 -0
- package/dist/tools/post-update.js +22 -0
- package/dist/tools/post-update.js.map +1 -0
- package/dist/tools/posts-list.d.ts +3 -0
- package/dist/tools/posts-list.js +45 -0
- package/dist/tools/posts-list.js.map +1 -0
- package/dist/tools/refine.d.ts +3 -0
- package/dist/tools/refine.js +34 -0
- package/dist/tools/refine.js.map +1 -0
- package/dist/tools/reshape.d.ts +3 -0
- package/dist/tools/reshape.js +42 -0
- package/dist/tools/reshape.js.map +1 -0
- package/dist/tools/split.d.ts +3 -0
- package/dist/tools/split.js +29 -0
- package/dist/tools/split.js.map +1 -0
- package/dist/tools/voice-profiles.d.ts +3 -0
- package/dist/tools/voice-profiles.js +63 -0
- package/dist/tools/voice-profiles.js.map +1 -0
- package/package.json +47 -0
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import * as analyze from "./analyze.js";
|
|
2
|
+
import * as reshape from "./reshape.js";
|
|
3
|
+
import * as refine from "./refine.js";
|
|
4
|
+
import * as split from "./split.js";
|
|
5
|
+
import * as draft from "./draft.js";
|
|
6
|
+
import * as bundle from "./bundle.js";
|
|
7
|
+
import * as postsList from "./posts-list.js";
|
|
8
|
+
import * as postGet from "./post-get.js";
|
|
9
|
+
import * as postUpdate from "./post-update.js";
|
|
10
|
+
import * as postApprove from "./post-approve.js";
|
|
11
|
+
import * as postSchedule from "./post-schedule.js";
|
|
12
|
+
import * as postImage from "./post-image.js";
|
|
13
|
+
import * as postCarousel from "./post-carousel.js";
|
|
14
|
+
import * as postCarouselCompanion from "./post-carousel-companion.js";
|
|
15
|
+
import * as postCarouselStatus from "./post-carousel-status.js";
|
|
16
|
+
import * as postCarouselSchedule from "./post-carousel-schedule.js";
|
|
17
|
+
import * as postComment from "./post-comment.js";
|
|
18
|
+
import * as voiceProfiles from "./voice-profiles.js";
|
|
19
|
+
import * as brandStyles from "./brand-styles.js";
|
|
20
|
+
const ALL_TOOLS = [
|
|
21
|
+
analyze,
|
|
22
|
+
reshape,
|
|
23
|
+
refine,
|
|
24
|
+
split,
|
|
25
|
+
draft,
|
|
26
|
+
bundle,
|
|
27
|
+
postsList,
|
|
28
|
+
postGet,
|
|
29
|
+
postUpdate,
|
|
30
|
+
postApprove,
|
|
31
|
+
postSchedule,
|
|
32
|
+
postImage,
|
|
33
|
+
postCarousel,
|
|
34
|
+
postCarouselCompanion,
|
|
35
|
+
postCarouselStatus,
|
|
36
|
+
postCarouselSchedule,
|
|
37
|
+
postComment,
|
|
38
|
+
voiceProfiles,
|
|
39
|
+
brandStyles,
|
|
40
|
+
];
|
|
41
|
+
export function registerAllTools(server, client) {
|
|
42
|
+
for (const tool of ALL_TOOLS) {
|
|
43
|
+
tool.register(server, client);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,OAAO,MAAM,cAAc,CAAC;AACxC,OAAO,KAAK,OAAO,MAAM,cAAc,CAAC;AACxC,OAAO,KAAK,MAAM,MAAM,aAAa,CAAC;AACtC,OAAO,KAAK,KAAK,MAAM,YAAY,CAAC;AACpC,OAAO,KAAK,KAAK,MAAM,YAAY,CAAC;AACpC,OAAO,KAAK,MAAM,MAAM,aAAa,CAAC;AACtC,OAAO,KAAK,SAAS,MAAM,iBAAiB,CAAC;AAC7C,OAAO,KAAK,OAAO,MAAM,eAAe,CAAC;AACzC,OAAO,KAAK,UAAU,MAAM,kBAAkB,CAAC;AAC/C,OAAO,KAAK,WAAW,MAAM,mBAAmB,CAAC;AACjD,OAAO,KAAK,YAAY,MAAM,oBAAoB,CAAC;AACnD,OAAO,KAAK,SAAS,MAAM,iBAAiB,CAAC;AAC7C,OAAO,KAAK,YAAY,MAAM,oBAAoB,CAAC;AACnD,OAAO,KAAK,qBAAqB,MAAM,8BAA8B,CAAC;AACtE,OAAO,KAAK,kBAAkB,MAAM,2BAA2B,CAAC;AAChE,OAAO,KAAK,oBAAoB,MAAM,6BAA6B,CAAC;AACpE,OAAO,KAAK,WAAW,MAAM,mBAAmB,CAAC;AACjD,OAAO,KAAK,aAAa,MAAM,qBAAqB,CAAC;AACrD,OAAO,KAAK,WAAW,MAAM,mBAAmB,CAAC;AAEjD,MAAM,SAAS,GAAG;IAChB,OAAO;IACP,OAAO;IACP,MAAM;IACN,KAAK;IACL,KAAK;IACL,MAAM;IACN,SAAS;IACT,OAAO;IACP,UAAU;IACV,WAAW;IACX,YAAY;IACZ,SAAS;IACT,YAAY;IACZ,qBAAqB;IACrB,kBAAkB;IAClB,oBAAoB;IACpB,WAAW;IACX,aAAa;IACb,WAAW;CACZ,CAAC;AAEF,MAAM,UAAU,gBAAgB,CAAC,MAAiB,EAAE,MAAsB;IACxE,KAAK,MAAM,IAAI,IAAI,SAAS,EAAE,CAAC;QAC7B,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export function register(server, client) {
|
|
3
|
+
server.tool("linwheel_post_approve", "Approve or unapprove a LinkedIn post. Approved posts with autoPublish=true will be published automatically at their scheduled time by LinWheel's cron job.", {
|
|
4
|
+
postId: z.string().describe("The post ID"),
|
|
5
|
+
approved: z.boolean().describe("true to approve, false to unapprove"),
|
|
6
|
+
}, async ({ postId, approved }) => {
|
|
7
|
+
const result = await client.post(`/api/agent/posts/${postId}/approve`, { approved });
|
|
8
|
+
return {
|
|
9
|
+
content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
|
|
10
|
+
};
|
|
11
|
+
});
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=post-approve.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"post-approve.js","sourceRoot":"","sources":["../../src/tools/post-approve.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,MAAM,UAAU,QAAQ,CAAC,MAAiB,EAAE,MAAsB;IAChE,MAAM,CAAC,IAAI,CACT,uBAAuB,EACvB,4JAA4J,EAC5J;QACE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,aAAa,CAAC;QAC1C,QAAQ,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,CAAC,qCAAqC,CAAC;KACtE,EACD,KAAK,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,EAAE,EAAE;QAC7B,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,IAAI,CAC9B,oBAAoB,MAAM,UAAU,EACpC,EAAE,QAAQ,EAAE,CACb,CAAC;QACF,OAAO;YACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC;SAC5E,CAAC;IACJ,CAAC,CACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export function register(server, client) {
|
|
3
|
+
server.tool("linwheel_post_carousel_companion", "Auto-generate a carousel by extracting key points from a post's text via LLM. Call after a post is approved and you want a staggered carousel version (default: 2 days later). Replaces any existing carousel. Returns carouselId, carouselUrl (PDF), caption, slide details, and schedule state. ~10-20s (LLM + render). Optionally set offsetDays or scheduledAt to auto-schedule for publishing.", {
|
|
4
|
+
postId: z.string().describe("The post ID to generate a companion carousel for"),
|
|
5
|
+
slideCount: z
|
|
6
|
+
.number()
|
|
7
|
+
.int()
|
|
8
|
+
.min(3)
|
|
9
|
+
.max(10)
|
|
10
|
+
.optional()
|
|
11
|
+
.describe("Number of slides (3-10, default 5)"),
|
|
12
|
+
instructions: z
|
|
13
|
+
.string()
|
|
14
|
+
.optional()
|
|
15
|
+
.describe("Optional guidance for the LLM when analyzing the post (e.g. 'Focus on the regulatory angle')"),
|
|
16
|
+
offsetDays: z
|
|
17
|
+
.number()
|
|
18
|
+
.int()
|
|
19
|
+
.optional()
|
|
20
|
+
.describe("Days after the post's scheduledAt to schedule the carousel (default 2). Ignored if scheduledAt is provided."),
|
|
21
|
+
scheduledAt: z
|
|
22
|
+
.string()
|
|
23
|
+
.optional()
|
|
24
|
+
.describe("Explicit ISO 8601 datetime to schedule the carousel. Takes precedence over offsetDays."),
|
|
25
|
+
autoPublish: z
|
|
26
|
+
.boolean()
|
|
27
|
+
.optional()
|
|
28
|
+
.describe("Auto-publish carousel when scheduled time arrives (default true)"),
|
|
29
|
+
}, async ({ postId, slideCount, instructions, offsetDays, scheduledAt, autoPublish }) => {
|
|
30
|
+
const body = {};
|
|
31
|
+
if (slideCount !== undefined)
|
|
32
|
+
body.slideCount = slideCount;
|
|
33
|
+
if (instructions !== undefined)
|
|
34
|
+
body.instructions = instructions;
|
|
35
|
+
if (offsetDays !== undefined)
|
|
36
|
+
body.offsetDays = offsetDays;
|
|
37
|
+
if (scheduledAt !== undefined)
|
|
38
|
+
body.scheduledAt = scheduledAt;
|
|
39
|
+
if (autoPublish !== undefined)
|
|
40
|
+
body.autoPublish = autoPublish;
|
|
41
|
+
const result = await client.post(`/api/agent/posts/${postId}/carousel-companion`, body);
|
|
42
|
+
return {
|
|
43
|
+
content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
|
|
44
|
+
};
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=post-carousel-companion.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"post-carousel-companion.js","sourceRoot":"","sources":["../../src/tools/post-carousel-companion.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,MAAM,UAAU,QAAQ,CAAC,MAAiB,EAAE,MAAsB;IAChE,MAAM,CAAC,IAAI,CACT,kCAAkC,EAClC,qYAAqY,EACrY;QACE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,kDAAkD,CAAC;QAC/E,UAAU,EAAE,CAAC;aACV,MAAM,EAAE;aACR,GAAG,EAAE;aACL,GAAG,CAAC,CAAC,CAAC;aACN,GAAG,CAAC,EAAE,CAAC;aACP,QAAQ,EAAE;aACV,QAAQ,CAAC,oCAAoC,CAAC;QACjD,YAAY,EAAE,CAAC;aACZ,MAAM,EAAE;aACR,QAAQ,EAAE;aACV,QAAQ,CACP,8FAA8F,CAC/F;QACH,UAAU,EAAE,CAAC;aACV,MAAM,EAAE;aACR,GAAG,EAAE;aACL,QAAQ,EAAE;aACV,QAAQ,CACP,6GAA6G,CAC9G;QACH,WAAW,EAAE,CAAC;aACX,MAAM,EAAE;aACR,QAAQ,EAAE;aACV,QAAQ,CACP,wFAAwF,CACzF;QACH,WAAW,EAAE,CAAC;aACX,OAAO,EAAE;aACT,QAAQ,EAAE;aACV,QAAQ,CAAC,kEAAkE,CAAC;KAChF,EACD,KAAK,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,YAAY,EAAE,UAAU,EAAE,WAAW,EAAE,WAAW,EAAE,EAAE,EAAE;QACnF,MAAM,IAAI,GAA4B,EAAE,CAAC;QACzC,IAAI,UAAU,KAAK,SAAS;YAAE,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;QAC3D,IAAI,YAAY,KAAK,SAAS;YAAE,IAAI,CAAC,YAAY,GAAG,YAAY,CAAC;QACjE,IAAI,UAAU,KAAK,SAAS;YAAE,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;QAC3D,IAAI,WAAW,KAAK,SAAS;YAAE,IAAI,CAAC,WAAW,GAAG,WAAW,CAAC;QAC9D,IAAI,WAAW,KAAK,SAAS;YAAE,IAAI,CAAC,WAAW,GAAG,WAAW,CAAC;QAE9D,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,IAAI,CAC9B,oBAAoB,MAAM,qBAAqB,EAC/C,IAAI,CACL,CAAC;QACF,OAAO;YACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC;SACnE,CAAC;IACJ,CAAC,CACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export function register(server, client) {
|
|
3
|
+
server.tool("linwheel_post_carousel_schedule", "Set when a carousel auto-publishes to LinkedIn. Call after generating a carousel to schedule it — either at an explicit datetime, N days after the parent post (offsetDays), or simultaneous with the post (sharedSchedule). Set unschedule=true to cancel. Returns action taken, carouselId, status, scheduledAt, and autoPublish flag. ~200 tokens.", {
|
|
4
|
+
postId: z.string().describe("The post ID whose carousel to schedule"),
|
|
5
|
+
scheduledAt: z
|
|
6
|
+
.string()
|
|
7
|
+
.optional()
|
|
8
|
+
.describe("ISO 8601 datetime to schedule the carousel. Set to null (via unschedule param) to unschedule."),
|
|
9
|
+
offsetDays: z
|
|
10
|
+
.number()
|
|
11
|
+
.int()
|
|
12
|
+
.min(0)
|
|
13
|
+
.optional()
|
|
14
|
+
.describe("Days after the parent post's scheduledAt to publish the carousel (e.g. 2 for staggered publishing)"),
|
|
15
|
+
sharedSchedule: z
|
|
16
|
+
.boolean()
|
|
17
|
+
.optional()
|
|
18
|
+
.describe("Use the same schedule as the parent post (true)"),
|
|
19
|
+
autoPublish: z
|
|
20
|
+
.boolean()
|
|
21
|
+
.optional()
|
|
22
|
+
.describe("Auto-publish when scheduled time arrives (default true)"),
|
|
23
|
+
unschedule: z
|
|
24
|
+
.boolean()
|
|
25
|
+
.optional()
|
|
26
|
+
.describe("Set to true to unschedule the carousel"),
|
|
27
|
+
}, async ({ postId, scheduledAt, offsetDays, sharedSchedule, autoPublish, unschedule }) => {
|
|
28
|
+
const body = {};
|
|
29
|
+
if (unschedule) {
|
|
30
|
+
body.scheduledAt = null;
|
|
31
|
+
}
|
|
32
|
+
else {
|
|
33
|
+
if (scheduledAt !== undefined)
|
|
34
|
+
body.scheduledAt = scheduledAt;
|
|
35
|
+
if (offsetDays !== undefined)
|
|
36
|
+
body.offsetDays = offsetDays;
|
|
37
|
+
if (sharedSchedule !== undefined)
|
|
38
|
+
body.sharedSchedule = sharedSchedule;
|
|
39
|
+
if (autoPublish !== undefined)
|
|
40
|
+
body.autoPublish = autoPublish;
|
|
41
|
+
}
|
|
42
|
+
const result = await client.post(`/api/agent/posts/${postId}/carousel-status`, body);
|
|
43
|
+
return {
|
|
44
|
+
content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
|
|
45
|
+
};
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=post-carousel-schedule.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"post-carousel-schedule.js","sourceRoot":"","sources":["../../src/tools/post-carousel-schedule.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,MAAM,UAAU,QAAQ,CAAC,MAAiB,EAAE,MAAsB;IAChE,MAAM,CAAC,IAAI,CACT,iCAAiC,EACjC,uVAAuV,EACvV;QACE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,wCAAwC,CAAC;QACrE,WAAW,EAAE,CAAC;aACX,MAAM,EAAE;aACR,QAAQ,EAAE;aACV,QAAQ,CACP,+FAA+F,CAChG;QACH,UAAU,EAAE,CAAC;aACV,MAAM,EAAE;aACR,GAAG,EAAE;aACL,GAAG,CAAC,CAAC,CAAC;aACN,QAAQ,EAAE;aACV,QAAQ,CACP,oGAAoG,CACrG;QACH,cAAc,EAAE,CAAC;aACd,OAAO,EAAE;aACT,QAAQ,EAAE;aACV,QAAQ,CAAC,iDAAiD,CAAC;QAC9D,WAAW,EAAE,CAAC;aACX,OAAO,EAAE;aACT,QAAQ,EAAE;aACV,QAAQ,CAAC,yDAAyD,CAAC;QACtE,UAAU,EAAE,CAAC;aACV,OAAO,EAAE;aACT,QAAQ,EAAE;aACV,QAAQ,CAAC,wCAAwC,CAAC;KACtD,EACD,KAAK,EAAE,EAAE,MAAM,EAAE,WAAW,EAAE,UAAU,EAAE,cAAc,EAAE,WAAW,EAAE,UAAU,EAAE,EAAE,EAAE;QACrF,MAAM,IAAI,GAA4B,EAAE,CAAC;QACzC,IAAI,UAAU,EAAE,CAAC;YACf,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;QAC1B,CAAC;aAAM,CAAC;YACN,IAAI,WAAW,KAAK,SAAS;gBAAE,IAAI,CAAC,WAAW,GAAG,WAAW,CAAC;YAC9D,IAAI,UAAU,KAAK,SAAS;gBAAE,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;YAC3D,IAAI,cAAc,KAAK,SAAS;gBAAE,IAAI,CAAC,cAAc,GAAG,cAAc,CAAC;YACvE,IAAI,WAAW,KAAK,SAAS;gBAAE,IAAI,CAAC,WAAW,GAAG,WAAW,CAAC;QAChE,CAAC;QAED,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,IAAI,CAC9B,oBAAoB,MAAM,kBAAkB,EAC5C,IAAI,CACL,CAAC;QACF,OAAO;YACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC;SACnE,CAAC;IACJ,CAAC,CACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export function register(server, client) {
|
|
3
|
+
server.tool("linwheel_post_carousel_status", "Check whether a post has a carousel and its current state. Returns exists flag, status (pending/ready/scheduled/published/failed), autoPublish, scheduledAt, carouselUrl, publishError, and pageCount. ~200 tokens. Call before scheduling to verify the carousel exists and has a PDF, or after a failed publish to read the error.", {
|
|
4
|
+
postId: z.string().describe("The post ID to check carousel status for"),
|
|
5
|
+
}, async ({ postId }) => {
|
|
6
|
+
const result = await client.get(`/api/agent/posts/${postId}/carousel-status`);
|
|
7
|
+
return {
|
|
8
|
+
content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
|
|
9
|
+
};
|
|
10
|
+
});
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=post-carousel-status.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"post-carousel-status.js","sourceRoot":"","sources":["../../src/tools/post-carousel-status.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,MAAM,UAAU,QAAQ,CAAC,MAAiB,EAAE,MAAsB;IAChE,MAAM,CAAC,IAAI,CACT,+BAA+B,EAC/B,sUAAsU,EACtU;QACE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,0CAA0C,CAAC;KACxE,EACD,KAAK,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE;QACnB,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,GAAG,CAAC,oBAAoB,MAAM,kBAAkB,CAAC,CAAC;QAC9E,OAAO;YACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC;SACnE,CAAC;IACJ,CAAC,CACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export function register(server, client) {
|
|
3
|
+
server.tool("linwheel_post_carousel", "Generate a text carousel (1-10 slides) for a post. First slide becomes the title, last slide becomes the CTA, middle slides are content. Published as a PDF document to LinkedIn.", {
|
|
4
|
+
postId: z.string().describe("The post ID to attach the carousel to"),
|
|
5
|
+
slides: z
|
|
6
|
+
.array(z.object({
|
|
7
|
+
headlineText: z.string().describe("Slide headline"),
|
|
8
|
+
caption: z.string().optional().describe("Optional slide caption"),
|
|
9
|
+
}))
|
|
10
|
+
.describe("Carousel slides (1-10)"),
|
|
11
|
+
stylePreset: z
|
|
12
|
+
.enum([
|
|
13
|
+
"typographic_minimal",
|
|
14
|
+
"gradient_text",
|
|
15
|
+
"dark_mode",
|
|
16
|
+
"accent_bar",
|
|
17
|
+
"abstract_shapes",
|
|
18
|
+
])
|
|
19
|
+
.optional()
|
|
20
|
+
.describe("Visual style (default: typographic_minimal)"),
|
|
21
|
+
}, async ({ postId, slides, stylePreset }) => {
|
|
22
|
+
const result = await client.post(`/api/agent/posts/${postId}/carousel`, { slides, stylePreset });
|
|
23
|
+
return {
|
|
24
|
+
content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
|
|
25
|
+
};
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=post-carousel.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"post-carousel.js","sourceRoot":"","sources":["../../src/tools/post-carousel.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,MAAM,UAAU,QAAQ,CAAC,MAAiB,EAAE,MAAsB;IAChE,MAAM,CAAC,IAAI,CACT,wBAAwB,EACxB,mLAAmL,EACnL;QACE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,uCAAuC,CAAC;QACpE,MAAM,EAAE,CAAC;aACN,KAAK,CACJ,CAAC,CAAC,MAAM,CAAC;YACP,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,gBAAgB,CAAC;YACnD,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,wBAAwB,CAAC;SAClE,CAAC,CACH;aACA,QAAQ,CAAC,wBAAwB,CAAC;QACrC,WAAW,EAAE,CAAC;aACX,IAAI,CAAC;YACJ,qBAAqB;YACrB,eAAe;YACf,WAAW;YACX,YAAY;YACZ,iBAAiB;SAClB,CAAC;aACD,QAAQ,EAAE;aACV,QAAQ,CAAC,6CAA6C,CAAC;KAC3D,EACD,KAAK,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,EAAE,EAAE;QACxC,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,IAAI,CAC9B,oBAAoB,MAAM,WAAW,EACrC,EAAE,MAAM,EAAE,WAAW,EAAE,CACxB,CAAC;QACF,OAAO;YACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC;SAC5E,CAAC;IACJ,CAAC,CACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export function register(server, client) {
|
|
3
|
+
server.tool("linwheel_post_comment", "Attach a scheduled follow-up comment to a post. The comment auto-publishes as a reply on LinkedIn after the post goes live, delayed by delayMinutes (default 30, range 1-1440). Use this to boost engagement — e.g. add a question, link, or CTA as the first comment. Returns the comment ID, status (pending until post publishes, then scheduled), and scheduledAt. ~200 tokens.", {
|
|
4
|
+
post_id: z.string().describe("The post ID to attach the comment to"),
|
|
5
|
+
comment_text: z
|
|
6
|
+
.string()
|
|
7
|
+
.describe("The comment text to post as a follow-up reply"),
|
|
8
|
+
delay_minutes: z
|
|
9
|
+
.number()
|
|
10
|
+
.int()
|
|
11
|
+
.min(1)
|
|
12
|
+
.max(1440)
|
|
13
|
+
.optional()
|
|
14
|
+
.default(30)
|
|
15
|
+
.describe("Minutes after post publishes to post the comment (1-1440, default 30)"),
|
|
16
|
+
}, async ({ post_id, comment_text, delay_minutes }) => {
|
|
17
|
+
const result = await client.post(`/api/agent/posts/${post_id}/comments`, {
|
|
18
|
+
commentText: comment_text,
|
|
19
|
+
delayMinutes: delay_minutes,
|
|
20
|
+
});
|
|
21
|
+
return {
|
|
22
|
+
content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
|
|
23
|
+
};
|
|
24
|
+
});
|
|
25
|
+
server.tool("linwheel_post_comments_list", "List all scheduled follow-up comments for a post. Returns an array of comments with their IDs, text, delay, status (pending/scheduled/published/failed), and scheduledAt. Use this to check what comments are queued before adding more. ~300 tokens.", {
|
|
26
|
+
post_id: z.string().describe("The post ID to list comments for"),
|
|
27
|
+
}, async ({ post_id }) => {
|
|
28
|
+
const result = await client.get(`/api/agent/posts/${post_id}/comments`);
|
|
29
|
+
return {
|
|
30
|
+
content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
|
|
31
|
+
};
|
|
32
|
+
});
|
|
33
|
+
server.tool("linwheel_post_comment_update", "Edit a scheduled comment's text or delay before it publishes. Call after linwheel_post_comments_list shows a comment that needs rewording or a different delay. Only works while status is pending or scheduled. Returns success confirmation. ~100 tokens.", {
|
|
34
|
+
post_id: z.string().describe("The post ID the comment belongs to"),
|
|
35
|
+
comment_id: z.string().describe("The comment ID to update"),
|
|
36
|
+
comment_text: z
|
|
37
|
+
.string()
|
|
38
|
+
.optional()
|
|
39
|
+
.describe("New comment text (omit to keep current)"),
|
|
40
|
+
delay_minutes: z
|
|
41
|
+
.number()
|
|
42
|
+
.int()
|
|
43
|
+
.min(1)
|
|
44
|
+
.max(1440)
|
|
45
|
+
.optional()
|
|
46
|
+
.describe("New delay in minutes (1-1440, omit to keep current)"),
|
|
47
|
+
}, async ({ post_id, comment_id, comment_text, delay_minutes }) => {
|
|
48
|
+
const body = {};
|
|
49
|
+
if (comment_text !== undefined)
|
|
50
|
+
body.commentText = comment_text;
|
|
51
|
+
if (delay_minutes !== undefined)
|
|
52
|
+
body.delayMinutes = delay_minutes;
|
|
53
|
+
const result = await client.patch(`/api/agent/posts/${post_id}/comments/${comment_id}`, body);
|
|
54
|
+
return {
|
|
55
|
+
content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
|
|
56
|
+
};
|
|
57
|
+
});
|
|
58
|
+
server.tool("linwheel_post_comment_delete", "Remove a scheduled comment that is no longer needed. Call after linwheel_post_comments_list shows a stale or duplicate comment. Only works while status is pending, scheduled, or failed. Returns success confirmation. ~100 tokens.", {
|
|
59
|
+
post_id: z.string().describe("The post ID the comment belongs to"),
|
|
60
|
+
comment_id: z.string().describe("The comment ID to delete"),
|
|
61
|
+
}, async ({ post_id, comment_id }) => {
|
|
62
|
+
const result = await client.delete(`/api/agent/posts/${post_id}/comments/${comment_id}`);
|
|
63
|
+
return {
|
|
64
|
+
content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
|
|
65
|
+
};
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
//# sourceMappingURL=post-comment.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"post-comment.js","sourceRoot":"","sources":["../../src/tools/post-comment.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export function register(server, client) {
|
|
3
|
+
server.tool("linwheel_post_get", "Get full details of a single LinkedIn post draft including text, hook, approval status, schedule, and attached image intent.", {
|
|
4
|
+
postId: z.string().describe("The post ID to retrieve"),
|
|
5
|
+
}, async ({ postId }) => {
|
|
6
|
+
const result = await client.get(`/api/agent/posts/${postId}`);
|
|
7
|
+
return {
|
|
8
|
+
content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
|
|
9
|
+
};
|
|
10
|
+
});
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=post-get.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"post-get.js","sourceRoot":"","sources":["../../src/tools/post-get.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,MAAM,UAAU,QAAQ,CAAC,MAAiB,EAAE,MAAsB;IAChE,MAAM,CAAC,IAAI,CACT,mBAAmB,EACnB,8HAA8H,EAC9H;QACE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,yBAAyB,CAAC;KACvD,EACD,KAAK,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE;QACnB,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,GAAG,CAAC,oBAAoB,MAAM,EAAE,CAAC,CAAC;QAC9D,OAAO;YACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC;SAC5E,CAAC;IACJ,CAAC,CACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export function register(server, client) {
|
|
3
|
+
server.tool("linwheel_post_image", "Generate a typographic hero image for a post. The image renders headline text on a styled gradient background. Replaces any existing image for this post.", {
|
|
4
|
+
postId: z.string().describe("The post ID to attach the image to"),
|
|
5
|
+
headlineText: z
|
|
6
|
+
.string()
|
|
7
|
+
.describe("Text to render on the image (max 200 chars)"),
|
|
8
|
+
stylePreset: z
|
|
9
|
+
.enum([
|
|
10
|
+
"typographic_minimal",
|
|
11
|
+
"gradient_text",
|
|
12
|
+
"dark_mode",
|
|
13
|
+
"accent_bar",
|
|
14
|
+
"abstract_shapes",
|
|
15
|
+
])
|
|
16
|
+
.optional()
|
|
17
|
+
.describe("Visual style (default: typographic_minimal)"),
|
|
18
|
+
}, async ({ postId, headlineText, stylePreset }) => {
|
|
19
|
+
const result = await client.post(`/api/agent/posts/${postId}/image`, { headlineText, stylePreset });
|
|
20
|
+
return {
|
|
21
|
+
content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
|
|
22
|
+
};
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=post-image.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"post-image.js","sourceRoot":"","sources":["../../src/tools/post-image.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,MAAM,UAAU,QAAQ,CAAC,MAAiB,EAAE,MAAsB;IAChE,MAAM,CAAC,IAAI,CACT,qBAAqB,EACrB,2JAA2J,EAC3J;QACE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,oCAAoC,CAAC;QACjE,YAAY,EAAE,CAAC;aACZ,MAAM,EAAE;aACR,QAAQ,CAAC,6CAA6C,CAAC;QAC1D,WAAW,EAAE,CAAC;aACX,IAAI,CAAC;YACJ,qBAAqB;YACrB,eAAe;YACf,WAAW;YACX,YAAY;YACZ,iBAAiB;SAClB,CAAC;aACD,QAAQ,EAAE;aACV,QAAQ,CAAC,6CAA6C,CAAC;KAC3D,EACD,KAAK,EAAE,EAAE,MAAM,EAAE,YAAY,EAAE,WAAW,EAAE,EAAE,EAAE;QAC9C,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,IAAI,CAC9B,oBAAoB,MAAM,QAAQ,EAClC,EAAE,YAAY,EAAE,WAAW,EAAE,CAC9B,CAAC;QACF,OAAO;YACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC;SAC5E,CAAC;IACJ,CAAC,CACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export function register(server, client) {
|
|
3
|
+
server.tool("linwheel_post_schedule", "Set or clear the scheduled publish time for a post. Pass scheduledAt as ISO 8601 datetime to schedule, or null to unschedule. Combined with approved=true and autoPublish=true, the post will auto-publish at the scheduled time.", {
|
|
4
|
+
postId: z.string().describe("The post ID"),
|
|
5
|
+
scheduledAt: z
|
|
6
|
+
.string()
|
|
7
|
+
.nullable()
|
|
8
|
+
.describe("ISO 8601 datetime to schedule, or null to unschedule"),
|
|
9
|
+
autoPublish: z
|
|
10
|
+
.boolean()
|
|
11
|
+
.optional()
|
|
12
|
+
.describe("Toggle auto-publish (default: keeps current setting)"),
|
|
13
|
+
}, async ({ postId, scheduledAt, autoPublish }) => {
|
|
14
|
+
const result = await client.patch(`/api/agent/posts/${postId}/schedule`, { scheduledAt, autoPublish });
|
|
15
|
+
return {
|
|
16
|
+
content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
|
|
17
|
+
};
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=post-schedule.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"post-schedule.js","sourceRoot":"","sources":["../../src/tools/post-schedule.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,MAAM,UAAU,QAAQ,CAAC,MAAiB,EAAE,MAAsB;IAChE,MAAM,CAAC,IAAI,CACT,wBAAwB,EACxB,mOAAmO,EACnO;QACE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,aAAa,CAAC;QAC1C,WAAW,EAAE,CAAC;aACX,MAAM,EAAE;aACR,QAAQ,EAAE;aACV,QAAQ,CAAC,sDAAsD,CAAC;QACnE,WAAW,EAAE,CAAC;aACX,OAAO,EAAE;aACT,QAAQ,EAAE;aACV,QAAQ,CAAC,sDAAsD,CAAC;KACpE,EACD,KAAK,EAAE,EAAE,MAAM,EAAE,WAAW,EAAE,WAAW,EAAE,EAAE,EAAE;QAC7C,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,KAAK,CAC/B,oBAAoB,MAAM,WAAW,EACrC,EAAE,WAAW,EAAE,WAAW,EAAE,CAC7B,CAAC;QACF,OAAO;YACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC;SAC5E,CAAC;IACJ,CAAC,CACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export function register(server, client) {
|
|
3
|
+
server.tool("linwheel_post_update", "Update a post's text, hook, or autoPublish setting. Cannot edit posts already published to LinkedIn.", {
|
|
4
|
+
postId: z.string().describe("The post ID to update"),
|
|
5
|
+
fullText: z.string().optional().describe("New post text"),
|
|
6
|
+
hook: z.string().optional().describe("New hook line"),
|
|
7
|
+
autoPublish: z
|
|
8
|
+
.boolean()
|
|
9
|
+
.optional()
|
|
10
|
+
.describe("Toggle auto-publish behavior"),
|
|
11
|
+
}, async ({ postId, fullText, hook, autoPublish }) => {
|
|
12
|
+
const result = await client.patch(`/api/agent/posts/${postId}`, {
|
|
13
|
+
fullText,
|
|
14
|
+
hook,
|
|
15
|
+
autoPublish,
|
|
16
|
+
});
|
|
17
|
+
return {
|
|
18
|
+
content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
|
|
19
|
+
};
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=post-update.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"post-update.js","sourceRoot":"","sources":["../../src/tools/post-update.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,MAAM,UAAU,QAAQ,CAAC,MAAiB,EAAE,MAAsB;IAChE,MAAM,CAAC,IAAI,CACT,sBAAsB,EACtB,sGAAsG,EACtG;QACE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,uBAAuB,CAAC;QACpD,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,eAAe,CAAC;QACzD,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,eAAe,CAAC;QACrD,WAAW,EAAE,CAAC;aACX,OAAO,EAAE;aACT,QAAQ,EAAE;aACV,QAAQ,CAAC,8BAA8B,CAAC;KAC5C,EACD,KAAK,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,EAAE,EAAE;QAChD,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,KAAK,CAAC,oBAAoB,MAAM,EAAE,EAAE;YAC9D,QAAQ;YACR,IAAI;YACJ,WAAW;SACZ,CAAC,CAAC;QACH,OAAO;YACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC;SAC5E,CAAC;IACJ,CAAC,CACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export function register(server, client) {
|
|
3
|
+
server.tool("linwheel_posts_list", "List LinkedIn post drafts with optional filters. Returns posts with their IDs, text previews, approval status, and schedule info. Use this to check what's been drafted or find posts to approve/schedule.", {
|
|
4
|
+
approved: z
|
|
5
|
+
.enum(["true", "false"])
|
|
6
|
+
.optional()
|
|
7
|
+
.describe("Filter by approval status"),
|
|
8
|
+
scheduled: z
|
|
9
|
+
.enum(["true", "false"])
|
|
10
|
+
.optional()
|
|
11
|
+
.describe("Filter by has scheduled time"),
|
|
12
|
+
published: z
|
|
13
|
+
.enum(["true", "false"])
|
|
14
|
+
.optional()
|
|
15
|
+
.describe("Filter by already published to LinkedIn"),
|
|
16
|
+
type: z
|
|
17
|
+
.string()
|
|
18
|
+
.optional()
|
|
19
|
+
.describe("Filter by post angle (e.g. field_note, contrarian)"),
|
|
20
|
+
limit: z
|
|
21
|
+
.number()
|
|
22
|
+
.optional()
|
|
23
|
+
.describe("Max results (default 50, max 100)"),
|
|
24
|
+
offset: z.number().optional().describe("Pagination offset"),
|
|
25
|
+
}, async ({ approved, scheduled, published, type, limit, offset }) => {
|
|
26
|
+
const query = {};
|
|
27
|
+
if (approved)
|
|
28
|
+
query.approved = approved;
|
|
29
|
+
if (scheduled)
|
|
30
|
+
query.scheduled = scheduled;
|
|
31
|
+
if (published)
|
|
32
|
+
query.published = published;
|
|
33
|
+
if (type)
|
|
34
|
+
query.type = type;
|
|
35
|
+
if (limit !== undefined)
|
|
36
|
+
query.limit = String(limit);
|
|
37
|
+
if (offset !== undefined)
|
|
38
|
+
query.offset = String(offset);
|
|
39
|
+
const result = await client.get("/api/agent/posts", query);
|
|
40
|
+
return {
|
|
41
|
+
content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
|
|
42
|
+
};
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=posts-list.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"posts-list.js","sourceRoot":"","sources":["../../src/tools/posts-list.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,MAAM,UAAU,QAAQ,CAAC,MAAiB,EAAE,MAAsB;IAChE,MAAM,CAAC,IAAI,CACT,qBAAqB,EACrB,4MAA4M,EAC5M;QACE,QAAQ,EAAE,CAAC;aACR,IAAI,CAAC,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;aACvB,QAAQ,EAAE;aACV,QAAQ,CAAC,2BAA2B,CAAC;QACxC,SAAS,EAAE,CAAC;aACT,IAAI,CAAC,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;aACvB,QAAQ,EAAE;aACV,QAAQ,CAAC,8BAA8B,CAAC;QAC3C,SAAS,EAAE,CAAC;aACT,IAAI,CAAC,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;aACvB,QAAQ,EAAE;aACV,QAAQ,CAAC,yCAAyC,CAAC;QACtD,IAAI,EAAE,CAAC;aACJ,MAAM,EAAE;aACR,QAAQ,EAAE;aACV,QAAQ,CAAC,oDAAoD,CAAC;QACjE,KAAK,EAAE,CAAC;aACL,MAAM,EAAE;aACR,QAAQ,EAAE;aACV,QAAQ,CAAC,mCAAmC,CAAC;QAChD,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,mBAAmB,CAAC;KAC5D,EACD,KAAK,EAAE,EAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE;QAChE,MAAM,KAAK,GAA2B,EAAE,CAAC;QACzC,IAAI,QAAQ;YAAE,KAAK,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACxC,IAAI,SAAS;YAAE,KAAK,CAAC,SAAS,GAAG,SAAS,CAAC;QAC3C,IAAI,SAAS;YAAE,KAAK,CAAC,SAAS,GAAG,SAAS,CAAC;QAC3C,IAAI,IAAI;YAAE,KAAK,CAAC,IAAI,GAAG,IAAI,CAAC;QAC5B,IAAI,KAAK,KAAK,SAAS;YAAE,KAAK,CAAC,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;QACrD,IAAI,MAAM,KAAK,SAAS;YAAE,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC;QAExD,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,GAAG,CAAC,kBAAkB,EAAE,KAAK,CAAC,CAAC;QAC3D,OAAO;YACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC;SAC5E,CAAC;IACJ,CAAC,CACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export function register(server, client) {
|
|
3
|
+
server.tool("linwheel_refine", "Run an LLM editing pass on text. Light = grammar only. Medium = grammar + LinkedIn formatting (short lines, whitespace, hook). Heavy = full rewrite with new structure. Optionally saves the result as a draft.", {
|
|
4
|
+
text: z.string().describe("The text to refine"),
|
|
5
|
+
intensity: z
|
|
6
|
+
.enum(["light", "medium", "heavy"])
|
|
7
|
+
.optional()
|
|
8
|
+
.describe("Editing intensity (default: medium)"),
|
|
9
|
+
instructions: z
|
|
10
|
+
.string()
|
|
11
|
+
.optional()
|
|
12
|
+
.describe("Custom editing instructions"),
|
|
13
|
+
postType: z
|
|
14
|
+
.string()
|
|
15
|
+
.optional()
|
|
16
|
+
.describe("Target angle for tone guidance"),
|
|
17
|
+
saveDraft: z
|
|
18
|
+
.boolean()
|
|
19
|
+
.optional()
|
|
20
|
+
.describe("Save the refined text as a new draft (default: false)"),
|
|
21
|
+
}, async ({ text, intensity, instructions, postType, saveDraft }) => {
|
|
22
|
+
const result = await client.post("/api/agent/refine", {
|
|
23
|
+
text,
|
|
24
|
+
intensity,
|
|
25
|
+
instructions,
|
|
26
|
+
postType,
|
|
27
|
+
saveDraft,
|
|
28
|
+
});
|
|
29
|
+
return {
|
|
30
|
+
content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
|
|
31
|
+
};
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=refine.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"refine.js","sourceRoot":"","sources":["../../src/tools/refine.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,MAAM,UAAU,QAAQ,CAAC,MAAiB,EAAE,MAAsB;IAChE,MAAM,CAAC,IAAI,CACT,iBAAiB,EACjB,iNAAiN,EACjN;QACE,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,oBAAoB,CAAC;QAC/C,SAAS,EAAE,CAAC;aACT,IAAI,CAAC,CAAC,OAAO,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;aAClC,QAAQ,EAAE;aACV,QAAQ,CAAC,qCAAqC,CAAC;QAClD,YAAY,EAAE,CAAC;aACZ,MAAM,EAAE;aACR,QAAQ,EAAE;aACV,QAAQ,CAAC,6BAA6B,CAAC;QAC1C,QAAQ,EAAE,CAAC;aACR,MAAM,EAAE;aACR,QAAQ,EAAE;aACV,QAAQ,CAAC,gCAAgC,CAAC;QAC7C,SAAS,EAAE,CAAC;aACT,OAAO,EAAE;aACT,QAAQ,EAAE;aACV,QAAQ,CAAC,uDAAuD,CAAC;KACrE,EACD,KAAK,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,YAAY,EAAE,QAAQ,EAAE,SAAS,EAAE,EAAE,EAAE;QAC/D,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,mBAAmB,EAAE;YACpD,IAAI;YACJ,SAAS;YACT,YAAY;YACZ,QAAQ;YACR,SAAS;SACV,CAAC,CAAC;QACH,OAAO;YACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC;SAC5E,CAAC;IACJ,CAAC,CACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
const POST_ANGLES = [
|
|
3
|
+
"contrarian",
|
|
4
|
+
"field_note",
|
|
5
|
+
"demystification",
|
|
6
|
+
"identity_validation",
|
|
7
|
+
"provocateur",
|
|
8
|
+
"synthesizer",
|
|
9
|
+
"curious_cat",
|
|
10
|
+
];
|
|
11
|
+
export function register(server, client) {
|
|
12
|
+
server.tool("linwheel_reshape", "Decompose source content into multiple angle-specific LinkedIn posts. Each angle produces a distinct post with the author's voice preserved. Set saveDrafts=true to save all generated posts to LinWheel's dashboard for review. This is the primary tool for turning articles/notes into social content.", {
|
|
13
|
+
text: z.string().describe("The source content to reshape into LinkedIn posts"),
|
|
14
|
+
angles: z
|
|
15
|
+
.array(z.enum(POST_ANGLES))
|
|
16
|
+
.describe("Which angles to reshape into. Options: contrarian, field_note, demystification, identity_validation, provocateur, synthesizer, curious_cat"),
|
|
17
|
+
preEdit: z
|
|
18
|
+
.boolean()
|
|
19
|
+
.optional()
|
|
20
|
+
.describe("Light-edit the input text before reshaping (default: false)"),
|
|
21
|
+
instructions: z
|
|
22
|
+
.string()
|
|
23
|
+
.optional()
|
|
24
|
+
.describe("Specific instructions for the reshape, e.g. tone or audience notes"),
|
|
25
|
+
saveDrafts: z
|
|
26
|
+
.boolean()
|
|
27
|
+
.optional()
|
|
28
|
+
.describe("Save all generated posts as drafts in LinWheel dashboard (default: false). Set true for the normal workflow."),
|
|
29
|
+
}, async ({ text, angles, preEdit, instructions, saveDrafts }) => {
|
|
30
|
+
const result = await client.post("/api/agent/reshape", {
|
|
31
|
+
text,
|
|
32
|
+
angles,
|
|
33
|
+
preEdit,
|
|
34
|
+
instructions,
|
|
35
|
+
saveDrafts,
|
|
36
|
+
});
|
|
37
|
+
return {
|
|
38
|
+
content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
|
|
39
|
+
};
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=reshape.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reshape.js","sourceRoot":"","sources":["../../src/tools/reshape.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,MAAM,WAAW,GAAG;IAClB,YAAY;IACZ,YAAY;IACZ,iBAAiB;IACjB,qBAAqB;IACrB,aAAa;IACb,aAAa;IACb,aAAa;CACL,CAAC;AAEX,MAAM,UAAU,QAAQ,CAAC,MAAiB,EAAE,MAAsB;IAChE,MAAM,CAAC,IAAI,CACT,kBAAkB,EAClB,2SAA2S,EAC3S;QACE,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,mDAAmD,CAAC;QAC9E,MAAM,EAAE,CAAC;aACN,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;aAC1B,QAAQ,CACP,4IAA4I,CAC7I;QACH,OAAO,EAAE,CAAC;aACP,OAAO,EAAE;aACT,QAAQ,EAAE;aACV,QAAQ,CAAC,6DAA6D,CAAC;QAC1E,YAAY,EAAE,CAAC;aACZ,MAAM,EAAE;aACR,QAAQ,EAAE;aACV,QAAQ,CAAC,oEAAoE,CAAC;QACjF,UAAU,EAAE,CAAC;aACV,OAAO,EAAE;aACT,QAAQ,EAAE;aACV,QAAQ,CACP,8GAA8G,CAC/G;KACJ,EACD,KAAK,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,EAAE,EAAE;QAC5D,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,oBAAoB,EAAE;YACrD,IAAI;YACJ,MAAM;YACN,OAAO;YACP,YAAY;YACZ,UAAU;SACX,CAAC,CAAC;QACH,OAAO;YACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC;SAC5E,CAAC;IACJ,CAAC,CACF,CAAC;AACJ,CAAC"}
|