@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.
Files changed (68) hide show
  1. package/README.md +219 -0
  2. package/dist/client.d.ts +24 -0
  3. package/dist/client.js +36 -0
  4. package/dist/client.js.map +1 -0
  5. package/dist/index.d.ts +2 -0
  6. package/dist/index.js +79 -0
  7. package/dist/index.js.map +1 -0
  8. package/dist/tools/analyze.d.ts +3 -0
  9. package/dist/tools/analyze.js +16 -0
  10. package/dist/tools/analyze.js.map +1 -0
  11. package/dist/tools/brand-styles.d.ts +3 -0
  12. package/dist/tools/brand-styles.js +108 -0
  13. package/dist/tools/brand-styles.js.map +1 -0
  14. package/dist/tools/bundle.d.ts +3 -0
  15. package/dist/tools/bundle.js +55 -0
  16. package/dist/tools/bundle.js.map +1 -0
  17. package/dist/tools/draft.d.ts +3 -0
  18. package/dist/tools/draft.js +41 -0
  19. package/dist/tools/draft.js.map +1 -0
  20. package/dist/tools/index.d.ts +3 -0
  21. package/dist/tools/index.js +46 -0
  22. package/dist/tools/index.js.map +1 -0
  23. package/dist/tools/post-approve.d.ts +3 -0
  24. package/dist/tools/post-approve.js +13 -0
  25. package/dist/tools/post-approve.js.map +1 -0
  26. package/dist/tools/post-carousel-companion.d.ts +3 -0
  27. package/dist/tools/post-carousel-companion.js +47 -0
  28. package/dist/tools/post-carousel-companion.js.map +1 -0
  29. package/dist/tools/post-carousel-schedule.d.ts +3 -0
  30. package/dist/tools/post-carousel-schedule.js +48 -0
  31. package/dist/tools/post-carousel-schedule.js.map +1 -0
  32. package/dist/tools/post-carousel-status.d.ts +3 -0
  33. package/dist/tools/post-carousel-status.js +12 -0
  34. package/dist/tools/post-carousel-status.js.map +1 -0
  35. package/dist/tools/post-carousel.d.ts +3 -0
  36. package/dist/tools/post-carousel.js +28 -0
  37. package/dist/tools/post-carousel.js.map +1 -0
  38. package/dist/tools/post-comment.d.ts +3 -0
  39. package/dist/tools/post-comment.js +68 -0
  40. package/dist/tools/post-comment.js.map +1 -0
  41. package/dist/tools/post-get.d.ts +3 -0
  42. package/dist/tools/post-get.js +12 -0
  43. package/dist/tools/post-get.js.map +1 -0
  44. package/dist/tools/post-image.d.ts +3 -0
  45. package/dist/tools/post-image.js +25 -0
  46. package/dist/tools/post-image.js.map +1 -0
  47. package/dist/tools/post-schedule.d.ts +3 -0
  48. package/dist/tools/post-schedule.js +20 -0
  49. package/dist/tools/post-schedule.js.map +1 -0
  50. package/dist/tools/post-update.d.ts +3 -0
  51. package/dist/tools/post-update.js +22 -0
  52. package/dist/tools/post-update.js.map +1 -0
  53. package/dist/tools/posts-list.d.ts +3 -0
  54. package/dist/tools/posts-list.js +45 -0
  55. package/dist/tools/posts-list.js.map +1 -0
  56. package/dist/tools/refine.d.ts +3 -0
  57. package/dist/tools/refine.js +34 -0
  58. package/dist/tools/refine.js.map +1 -0
  59. package/dist/tools/reshape.d.ts +3 -0
  60. package/dist/tools/reshape.js +42 -0
  61. package/dist/tools/reshape.js.map +1 -0
  62. package/dist/tools/split.d.ts +3 -0
  63. package/dist/tools/split.js +29 -0
  64. package/dist/tools/split.js.map +1 -0
  65. package/dist/tools/voice-profiles.d.ts +3 -0
  66. package/dist/tools/voice-profiles.js +63 -0
  67. package/dist/tools/voice-profiles.js.map +1 -0
  68. package/package.json +47 -0
@@ -0,0 +1,29 @@
1
+ import { z } from "zod";
2
+ export function register(server, client) {
3
+ server.tool("linwheel_split", "Split long content into a series of standalone LinkedIn posts. Each post works independently but together forms a coherent series. Good for long articles or transcripts.", {
4
+ text: z.string().describe("The long content to split into a series"),
5
+ maxPosts: z
6
+ .number()
7
+ .optional()
8
+ .describe("Maximum number of posts in the series (2-10, default: 5)"),
9
+ instructions: z
10
+ .string()
11
+ .optional()
12
+ .describe("Specific instructions for splitting"),
13
+ saveDrafts: z
14
+ .boolean()
15
+ .optional()
16
+ .describe("Save all posts as drafts in LinWheel dashboard (default: false)"),
17
+ }, async ({ text, maxPosts, instructions, saveDrafts }) => {
18
+ const result = await client.post("/api/agent/split", {
19
+ text,
20
+ maxPosts,
21
+ instructions,
22
+ saveDrafts,
23
+ });
24
+ return {
25
+ content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
26
+ };
27
+ });
28
+ }
29
+ //# sourceMappingURL=split.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"split.js","sourceRoot":"","sources":["../../src/tools/split.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,MAAM,UAAU,QAAQ,CAAC,MAAiB,EAAE,MAAsB;IAChE,MAAM,CAAC,IAAI,CACT,gBAAgB,EAChB,2KAA2K,EAC3K;QACE,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,yCAAyC,CAAC;QACpE,QAAQ,EAAE,CAAC;aACR,MAAM,EAAE;aACR,QAAQ,EAAE;aACV,QAAQ,CAAC,0DAA0D,CAAC;QACvE,YAAY,EAAE,CAAC;aACZ,MAAM,EAAE;aACR,QAAQ,EAAE;aACV,QAAQ,CAAC,qCAAqC,CAAC;QAClD,UAAU,EAAE,CAAC;aACV,OAAO,EAAE;aACT,QAAQ,EAAE;aACV,QAAQ,CAAC,iEAAiE,CAAC;KAC/E,EACD,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,YAAY,EAAE,UAAU,EAAE,EAAE,EAAE;QACrD,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,kBAAkB,EAAE;YACnD,IAAI;YACJ,QAAQ;YACR,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"}
@@ -0,0 +1,3 @@
1
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ import type { LinWheelClient } from "../client.js";
3
+ export declare function register(server: McpServer, client: LinWheelClient): void;
@@ -0,0 +1,63 @@
1
+ import { z } from "zod";
2
+ export function register(server, client) {
3
+ // List voice profiles
4
+ server.tool("linwheel_voice_profiles_list", "List all voice profiles. Shows which profile is currently active for style matching in content generation.", {}, async () => {
5
+ const result = await client.get("/api/agent/voice-profiles");
6
+ return {
7
+ content: [
8
+ { type: "text", text: JSON.stringify(result, null, 2) },
9
+ ],
10
+ };
11
+ });
12
+ // Create voice profile from writing samples
13
+ server.tool("linwheel_voice_profile_create", "Create a voice profile from writing samples. The active voice profile is injected into all content generation prompts for style matching. Provide 3+ writing samples for best results.", {
14
+ name: z.string().describe("Name for the voice profile"),
15
+ description: z
16
+ .string()
17
+ .optional()
18
+ .describe("Style notes (e.g. 'Technical, direct, slightly irreverent')"),
19
+ samples: z
20
+ .array(z.string())
21
+ .describe("Array of writing samples (articles, posts, etc.) for style matching. 3+ recommended."),
22
+ isActive: z
23
+ .boolean()
24
+ .optional()
25
+ .default(true)
26
+ .describe("Set as the active profile (default true). Only one profile can be active."),
27
+ }, async ({ name, description, samples, isActive }) => {
28
+ const result = await client.post("/api/agent/voice-profiles", {
29
+ name,
30
+ description,
31
+ samples,
32
+ isActive,
33
+ });
34
+ return {
35
+ content: [
36
+ { type: "text", text: JSON.stringify(result, null, 2) },
37
+ ],
38
+ };
39
+ });
40
+ // Delete voice profile
41
+ server.tool("linwheel_voice_profile_delete", "Delete a voice profile by ID.", {
42
+ profileId: z.string().describe("The voice profile ID to delete"),
43
+ }, async ({ profileId }) => {
44
+ const result = await client.delete(`/api/agent/voice-profiles/${profileId}`);
45
+ return {
46
+ content: [
47
+ { type: "text", text: JSON.stringify(result, null, 2) },
48
+ ],
49
+ };
50
+ });
51
+ // Activate voice profile
52
+ server.tool("linwheel_voice_profile_activate", "Set a voice profile as active. The active profile's writing samples are used for style matching in all content generation. Only one profile can be active at a time.", {
53
+ profileId: z.string().describe("The voice profile ID to activate"),
54
+ }, async ({ profileId }) => {
55
+ const result = await client.post(`/api/agent/voice-profiles/${profileId}/activate`, {});
56
+ return {
57
+ content: [
58
+ { type: "text", text: JSON.stringify(result, null, 2) },
59
+ ],
60
+ };
61
+ });
62
+ }
63
+ //# sourceMappingURL=voice-profiles.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"voice-profiles.js","sourceRoot":"","sources":["../../src/tools/voice-profiles.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,MAAM,UAAU,QAAQ,CAAC,MAAiB,EAAE,MAAsB;IAChE,sBAAsB;IACtB,MAAM,CAAC,IAAI,CACT,8BAA8B,EAC9B,4GAA4G,EAC5G,EAAE,EACF,KAAK,IAAI,EAAE;QACT,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,GAAG,CAAC,2BAA2B,CAAC,CAAC;QAC7D,OAAO;YACL,OAAO,EAAE;gBACP,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE;aACjE;SACF,CAAC;IACJ,CAAC,CACF,CAAC;IAEF,4CAA4C;IAC5C,MAAM,CAAC,IAAI,CACT,+BAA+B,EAC/B,wLAAwL,EACxL;QACE,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,4BAA4B,CAAC;QACvD,WAAW,EAAE,CAAC;aACX,MAAM,EAAE;aACR,QAAQ,EAAE;aACV,QAAQ,CAAC,6DAA6D,CAAC;QAC1E,OAAO,EAAE,CAAC;aACP,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;aACjB,QAAQ,CAAC,sFAAsF,CAAC;QACnG,QAAQ,EAAE,CAAC;aACR,OAAO,EAAE;aACT,QAAQ,EAAE;aACV,OAAO,CAAC,IAAI,CAAC;aACb,QAAQ,CAAC,2EAA2E,CAAC;KACzF,EACD,KAAK,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE;QACjD,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,2BAA2B,EAAE;YAC5D,IAAI;YACJ,WAAW;YACX,OAAO;YACP,QAAQ;SACT,CAAC,CAAC;QACH,OAAO;YACL,OAAO,EAAE;gBACP,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE;aACjE;SACF,CAAC;IACJ,CAAC,CACF,CAAC;IAEF,uBAAuB;IACvB,MAAM,CAAC,IAAI,CACT,+BAA+B,EAC/B,+BAA+B,EAC/B;QACE,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,gCAAgC,CAAC;KACjE,EACD,KAAK,EAAE,EAAE,SAAS,EAAE,EAAE,EAAE;QACtB,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,MAAM,CAChC,6BAA6B,SAAS,EAAE,CACzC,CAAC;QACF,OAAO;YACL,OAAO,EAAE;gBACP,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE;aACjE;SACF,CAAC;IACJ,CAAC,CACF,CAAC;IAEF,yBAAyB;IACzB,MAAM,CAAC,IAAI,CACT,iCAAiC,EACjC,sKAAsK,EACtK;QACE,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,kCAAkC,CAAC;KACnE,EACD,KAAK,EAAE,EAAE,SAAS,EAAE,EAAE,EAAE;QACtB,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,IAAI,CAC9B,6BAA6B,SAAS,WAAW,EACjD,EAAE,CACH,CAAC;QACF,OAAO;YACL,OAAO,EAAE;gBACP,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE;aACjE;SACF,CAAC;IACJ,CAAC,CACF,CAAC;AACJ,CAAC"}
package/package.json ADDED
@@ -0,0 +1,47 @@
1
+ {
2
+ "name": "@linwheel/mcp-server",
3
+ "version": "0.1.0",
4
+ "description": "MCP server for LinWheel — AI-powered LinkedIn content engine. Draft, schedule, and publish posts from Claude Code.",
5
+ "type": "module",
6
+ "bin": {
7
+ "linwheel-mcp": "./dist/index.js"
8
+ },
9
+ "files": [
10
+ "dist"
11
+ ],
12
+ "scripts": {
13
+ "build": "tsc",
14
+ "dev": "tsx src/index.ts",
15
+ "test": "vitest run",
16
+ "prepublishOnly": "npm run build"
17
+ },
18
+ "dependencies": {
19
+ "@linwheel/sdk": "^0.1.0",
20
+ "@modelcontextprotocol/sdk": "^1.26.0",
21
+ "zod": "^3.24.0"
22
+ },
23
+ "devDependencies": {
24
+ "tsx": "^4.19.0",
25
+ "typescript": "^5.9.3",
26
+ "vitest": "^3.2.1"
27
+ },
28
+ "license": "MIT",
29
+ "engines": {
30
+ "node": ">=20.0.0"
31
+ },
32
+ "homepage": "https://github.com/Peleke/linwheel/tree/main/mcp#readme",
33
+ "repository": {
34
+ "type": "git",
35
+ "url": "git+https://github.com/Peleke/linwheel.git",
36
+ "directory": "mcp"
37
+ },
38
+ "keywords": [
39
+ "linwheel",
40
+ "linkedin",
41
+ "mcp",
42
+ "model-context-protocol",
43
+ "claude",
44
+ "content-engine",
45
+ "agent"
46
+ ]
47
+ }