@xreplyai/mcp 0.3.10 → 0.3.16
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 +11 -19
- package/dist/index.js +0 -0
- package/dist/server.js +2 -2
- package/dist/server.js.map +1 -1
- package/dist/tools/communities.d.ts.map +1 -1
- package/dist/tools/communities.js +1 -7
- package/dist/tools/communities.js.map +1 -1
- package/dist/tools/context.d.ts.map +1 -1
- package/dist/tools/context.js +117 -7
- package/dist/tools/context.js.map +1 -1
- package/dist/tools/helpers.d.ts +4 -0
- package/dist/tools/helpers.d.ts.map +1 -0
- package/dist/tools/helpers.js +8 -0
- package/dist/tools/helpers.js.map +1 -0
- package/dist/tools/media.d.ts +6 -0
- package/dist/tools/media.d.ts.map +1 -0
- package/dist/tools/media.js +195 -0
- package/dist/tools/media.js.map +1 -0
- package/dist/tools/posts.d.ts.map +1 -1
- package/dist/tools/posts.js +301 -50
- package/dist/tools/posts.js.map +1 -1
- package/dist/tools/publish.d.ts.map +1 -1
- package/dist/tools/publish.js +1 -7
- package/dist/tools/publish.js.map +1 -1
- package/dist/types.d.ts +22 -30
- package/dist/types.d.ts.map +1 -1
- package/package.json +2 -2
- package/dist/tools/viral-library.d.ts +0 -3
- package/dist/tools/viral-library.d.ts.map +0 -1
- package/dist/tools/viral-library.js +0 -92
- package/dist/tools/viral-library.js.map +0 -1
package/README.md
CHANGED
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
# @xreplyai/mcp
|
|
2
2
|
|
|
3
|
-
MCP server for [XreplyAI](https://xreplyai.com) — plan, generate, and schedule
|
|
3
|
+
MCP server for [XreplyAI](https://xreplyai.com) — plan, generate, and schedule posts in your voice. Manage your post queue and publish to X/Twitter from any AI agent.
|
|
4
4
|
|
|
5
5
|
## Features
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
12 tools covering the full posts workflow:
|
|
8
8
|
|
|
9
|
-
- **Discovery** — Browse the viral tweet library filtered by niche
|
|
10
9
|
- **Generation** — Generate single posts or batches in your voice
|
|
11
10
|
- **Post management** — Create, edit, delete posts
|
|
12
11
|
- **Publishing** — Publish immediately or schedule to X/Twitter
|
|
@@ -37,7 +36,7 @@ Add to your Claude Desktop config file:
|
|
|
37
36
|
"mcpServers": {
|
|
38
37
|
"xreply": {
|
|
39
38
|
"command": "npx",
|
|
40
|
-
"args": ["@xreplyai/mcp@0.3.
|
|
39
|
+
"args": ["@xreplyai/mcp@0.3.16"],
|
|
41
40
|
"env": {
|
|
42
41
|
"XREPLY_TOKEN": "your-jwt-token-here"
|
|
43
42
|
}
|
|
@@ -51,7 +50,7 @@ Add to your Claude Desktop config file:
|
|
|
51
50
|
Run this command:
|
|
52
51
|
|
|
53
52
|
```bash
|
|
54
|
-
claude mcp add xreply -e XREPLY_TOKEN=your-jwt-token-here -- npx @xreplyai/mcp@0.3.
|
|
53
|
+
claude mcp add xreply -e XREPLY_TOKEN=your-jwt-token-here -- npx @xreplyai/mcp@0.3.16
|
|
55
54
|
```
|
|
56
55
|
|
|
57
56
|
Then run `claude mcp list` to confirm it's registered.
|
|
@@ -63,7 +62,7 @@ Or add manually to `~/.claude/mcp.json`:
|
|
|
63
62
|
"mcpServers": {
|
|
64
63
|
"xreply": {
|
|
65
64
|
"command": "npx",
|
|
66
|
-
"args": ["@xreplyai/mcp@0.3.
|
|
65
|
+
"args": ["@xreplyai/mcp@0.3.16"],
|
|
67
66
|
"env": {
|
|
68
67
|
"XREPLY_TOKEN": "your-jwt-token-here"
|
|
69
68
|
}
|
|
@@ -85,7 +84,7 @@ Or add manually to `.cursor/mcp.json` in your project (or `~/.cursor/mcp.json` g
|
|
|
85
84
|
"mcpServers": {
|
|
86
85
|
"xreply": {
|
|
87
86
|
"command": "npx",
|
|
88
|
-
"args": ["@xreplyai/mcp@0.3.
|
|
87
|
+
"args": ["@xreplyai/mcp@0.3.16"],
|
|
89
88
|
"env": {
|
|
90
89
|
"XREPLY_TOKEN": "your-jwt-token-here"
|
|
91
90
|
}
|
|
@@ -103,7 +102,7 @@ Open Windsurf and go to **Plugins → Manage plugins → View raw config**, then
|
|
|
103
102
|
"mcpServers": {
|
|
104
103
|
"xreply": {
|
|
105
104
|
"command": "npx",
|
|
106
|
-
"args": ["@xreplyai/mcp@0.3.
|
|
105
|
+
"args": ["@xreplyai/mcp@0.3.16"],
|
|
107
106
|
"env": {
|
|
108
107
|
"XREPLY_TOKEN": "your-jwt-token-here"
|
|
109
108
|
}
|
|
@@ -144,7 +143,7 @@ cp -r mcp/openclaw/ ~/.openclaw/skills/xreply/
|
|
|
144
143
|
}
|
|
145
144
|
```
|
|
146
145
|
|
|
147
|
-
The skill uses `mcporter` to bridge OpenClaw to the
|
|
146
|
+
The skill uses `mcporter` to bridge OpenClaw to the XreplyAI MCP server. Install it with:
|
|
148
147
|
|
|
149
148
|
```bash
|
|
150
149
|
npm install -g mcporter
|
|
@@ -158,12 +157,6 @@ openclaw skills list --eligible
|
|
|
158
157
|
|
|
159
158
|
## Tools
|
|
160
159
|
|
|
161
|
-
### Discovery
|
|
162
|
-
|
|
163
|
-
| Tool | Description |
|
|
164
|
-
|------|-------------|
|
|
165
|
-
| `xreply_viral_library` | Browse viral tweets (100+ likes) filtered by niche and sort |
|
|
166
|
-
|
|
167
160
|
### Generation
|
|
168
161
|
|
|
169
162
|
| Tool | Description |
|
|
@@ -201,10 +194,9 @@ openclaw skills list --eligible
|
|
|
201
194
|
### Plan posts for the week
|
|
202
195
|
|
|
203
196
|
```
|
|
204
|
-
1.
|
|
205
|
-
2.
|
|
206
|
-
3.
|
|
207
|
-
4. xreply_posts_edit (id: X, scheduled_at: "2026-03-10T09:00:00Z") — schedule each
|
|
197
|
+
1. xreply_posts_generate_batch (category: "personalized", count: 7) — generate 7 posts
|
|
198
|
+
2. xreply_posts_list — review the queue
|
|
199
|
+
3. xreply_posts_edit (id: X, scheduled_at: "2026-03-10T09:00:00Z") — schedule each
|
|
208
200
|
```
|
|
209
201
|
|
|
210
202
|
### Quick post
|
package/dist/index.js
CHANGED
|
File without changes
|
package/dist/server.js
CHANGED
|
@@ -3,15 +3,15 @@ import { CallToolRequestSchema, ListToolsRequestSchema, } from "@modelcontextpro
|
|
|
3
3
|
import { getClient } from "./client.js";
|
|
4
4
|
import { postTools } from "./tools/posts.js";
|
|
5
5
|
import { publishTools } from "./tools/publish.js";
|
|
6
|
-
import { viralLibraryTools } from "./tools/viral-library.js";
|
|
7
6
|
import { contextTools } from "./tools/context.js";
|
|
8
7
|
import { communityTools } from "./tools/communities.js";
|
|
8
|
+
import { mediaTools } from "./tools/media.js";
|
|
9
9
|
const ALL_TOOLS = [
|
|
10
10
|
...postTools,
|
|
11
11
|
...publishTools,
|
|
12
|
-
...viralLibraryTools,
|
|
13
12
|
...contextTools,
|
|
14
13
|
...communityTools,
|
|
14
|
+
...mediaTools,
|
|
15
15
|
];
|
|
16
16
|
const TOOL_MAP = new Map(ALL_TOOLS.map((t) => [t.name, t]));
|
|
17
17
|
export function createServer() {
|
package/dist/server.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AACnE,OAAO,EACL,qBAAqB,EACrB,sBAAsB,GAEvB,MAAM,oCAAoC,CAAC;AAC5C,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AACnE,OAAO,EACL,qBAAqB,EACrB,sBAAsB,GAEvB,MAAM,oCAAoC,CAAC;AAC5C,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAG9C,MAAM,SAAS,GAAqB;IAClC,GAAG,SAAS;IACZ,GAAG,YAAY;IACf,GAAG,YAAY;IACf,GAAG,cAAc;IACjB,GAAG,UAAU;CACd,CAAC;AAEF,MAAM,QAAQ,GAAG,IAAI,GAAG,CACtB,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAClC,CAAC;AAEF,MAAM,UAAU,YAAY;IAC1B,MAAM,MAAM,GAAG,IAAI,MAAM,CACvB,EAAE,IAAI,EAAE,YAAY,EAAE,OAAO,EAAE,OAAO,EAAE,EACxC,EAAE,YAAY,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE,CAChC,CAAC;IAEF,MAAM,CAAC,iBAAiB,CAAC,sBAAsB,EAAE,KAAK,IAAI,EAAE,CAAC,CAAC;QAC5D,KAAK,EAAE,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YAC3B,IAAI,EAAE,CAAC,CAAC,IAAI;YACZ,WAAW,EAAE,CAAC,CAAC,WAAW;YAC1B,WAAW,EAAE,CAAC,CAAC,WAAW;SAC3B,CAAC,CAAC;KACJ,CAAC,CAAC,CAAC;IAEJ,MAAM,CAAC,iBAAiB,CAAC,qBAAqB,EAAE,KAAK,EAAE,OAAO,EAA2B,EAAE;QACzF,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC;QACjD,MAAM,IAAI,GAAG,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAEhC,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,OAAO;gBACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,iBAAiB,IAAI,EAAE,EAAE,CAAC;gBAC1D,OAAO,EAAE,IAAI;aACd,CAAC;QACJ,CAAC;QAED,MAAM,MAAM,GAAG,SAAS,EAAE,CAAC;QAC3B,OAAO,IAAI,CAAC,OAAO,CAAC,CAAC,IAAI,IAAI,EAAE,CAA4B,EAAE,MAAM,CAAC,CAAC;IACvE,CAAC,CAAC,CAAC;IAEH,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"communities.d.ts","sourceRoot":"","sources":["../../src/tools/communities.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAc,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"communities.d.ts","sourceRoot":"","sources":["../../src/tools/communities.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAc,MAAM,YAAY,CAAC;AAa7D,eAAO,MAAM,cAAc,EAAE,cAAc,EAmB1C,CAAC"}
|
|
@@ -1,10 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] };
|
|
3
|
-
}
|
|
4
|
-
function err(error) {
|
|
5
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
6
|
-
return { content: [{ type: "text", text: `Error: ${message}` }], isError: true };
|
|
7
|
-
}
|
|
1
|
+
import { ok, err } from "./helpers.js";
|
|
8
2
|
export const communityTools = [
|
|
9
3
|
{
|
|
10
4
|
name: "xreply_list_twitter_communities",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"communities.js","sourceRoot":"","sources":["../../src/tools/communities.ts"],"names":[],"mappings":"AAGA,
|
|
1
|
+
{"version":3,"file":"communities.js","sourceRoot":"","sources":["../../src/tools/communities.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,EAAE,EAAE,GAAG,EAAE,MAAM,cAAc,CAAC;AAWvC,MAAM,CAAC,MAAM,cAAc,GAAqB;IAC9C;QACE,IAAI,EAAE,iCAAiC;QACvC,WAAW,EACT,uNAAuN;QACzN,WAAW,EAAE;YACX,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE,EAAE;YACd,QAAQ,EAAE,EAAE;SACb;QACD,KAAK,CAAC,OAAO,CAAC,KAA8B,EAAE,MAAoB;YAChE,IAAI,CAAC;gBACH,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,GAAG,CAA6B,6BAA6B,CAAC,CAAC;gBAC3F,OAAO,EAAE,CAAC,MAAM,CAAC,CAAC;YACpB,CAAC;YAAC,OAAO,CAAC,EAAE,CAAC;gBACX,OAAO,GAAG,CAAC,CAAC,CAAC,CAAC;YAChB,CAAC;QACH,CAAC;KACF;CACF,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/tools/context.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/tools/context.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,cAAc,EAAc,MAAM,YAAY,CAAC;AA8B7D,eAAO,MAAM,YAAY,EAAE,cAAc,EAoOxC,CAAC"}
|
package/dist/tools/context.js
CHANGED
|
@@ -1,11 +1,17 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
2
|
+
import { ok, err } from "./helpers.js";
|
|
3
|
+
const PlatformStylesGetSchema = z.object({
|
|
4
|
+
platform: z.enum(["twitter", "linkedin", "threads", "instagram", "youtube", "bluesky", "facebook", "google_business"]).optional(),
|
|
5
|
+
});
|
|
6
|
+
const PlatformStylesSetSchema = z.object({
|
|
7
|
+
platform: z.enum(["twitter", "linkedin", "threads", "instagram", "youtube", "bluesky", "facebook", "google_business"]),
|
|
8
|
+
tone: z.enum(["auto", "casual", "professional", "witty", "empathetic"]).optional(),
|
|
9
|
+
target_length: z.number().int().positive().optional(),
|
|
10
|
+
hashtag_rules: z.enum(["none", "few", "moderate", "match_voice"]).optional(),
|
|
11
|
+
cta_rules: z.enum(["never", "soft_question", "link_in_comments", "direct"]).optional(),
|
|
12
|
+
banned_phrases: z.array(z.string()).optional(),
|
|
13
|
+
custom_instructions: z.string().max(500).optional(),
|
|
14
|
+
});
|
|
9
15
|
const PreferencesSetSchema = z.object({
|
|
10
16
|
tone: z
|
|
11
17
|
.enum(["auto", "casual", "professional", "witty", "empathetic"])
|
|
@@ -106,6 +112,110 @@ export const contextTools = [
|
|
|
106
112
|
}
|
|
107
113
|
},
|
|
108
114
|
},
|
|
115
|
+
{
|
|
116
|
+
name: "xreply_list_social_accounts",
|
|
117
|
+
description: "List all connected social accounts (X/Twitter, LinkedIn, YouTube, Threads, Instagram) with their IDs, platform, username, and primary status. Use this to find account_id values needed for xreply_posts_create and xreply_posts_publish.",
|
|
118
|
+
inputSchema: {
|
|
119
|
+
type: "object",
|
|
120
|
+
properties: {},
|
|
121
|
+
required: [],
|
|
122
|
+
},
|
|
123
|
+
async handler(_args, client) {
|
|
124
|
+
try {
|
|
125
|
+
const result = await client.get("/api/v1/social_accounts");
|
|
126
|
+
return ok(result);
|
|
127
|
+
}
|
|
128
|
+
catch (e) {
|
|
129
|
+
return err(e);
|
|
130
|
+
}
|
|
131
|
+
},
|
|
132
|
+
},
|
|
133
|
+
{
|
|
134
|
+
name: "xreply_platform_styles_get",
|
|
135
|
+
description: "Get the effective platform style profiles — system defaults merged with your per-platform overrides. Shows tone, structure, length targets, hashtag rules, CTA rules, and whether defaults are in use. Optionally filter to a single platform.",
|
|
136
|
+
inputSchema: {
|
|
137
|
+
type: "object",
|
|
138
|
+
properties: {
|
|
139
|
+
platform: {
|
|
140
|
+
type: "string",
|
|
141
|
+
enum: ["twitter", "linkedin", "threads", "instagram", "youtube", "bluesky", "facebook"],
|
|
142
|
+
description: "Optional — get a single platform's profile. Omit to get all platforms.",
|
|
143
|
+
},
|
|
144
|
+
},
|
|
145
|
+
required: [],
|
|
146
|
+
},
|
|
147
|
+
async handler(args, client) {
|
|
148
|
+
try {
|
|
149
|
+
const { platform } = PlatformStylesGetSchema.parse(args);
|
|
150
|
+
const result = await client.get("/api/v1/platform_styles");
|
|
151
|
+
if (platform) {
|
|
152
|
+
const profile = result.platform_styles[platform];
|
|
153
|
+
if (!profile) {
|
|
154
|
+
return err(`Unknown platform: ${platform}`);
|
|
155
|
+
}
|
|
156
|
+
return ok({ platform, platform_style: profile });
|
|
157
|
+
}
|
|
158
|
+
return ok(result);
|
|
159
|
+
}
|
|
160
|
+
catch (e) {
|
|
161
|
+
return err(e);
|
|
162
|
+
}
|
|
163
|
+
},
|
|
164
|
+
},
|
|
165
|
+
{
|
|
166
|
+
name: "xreply_platform_styles_set",
|
|
167
|
+
description: "Override style settings for a specific platform. Only the fields you provide are updated — other fields keep their defaults. Use this to customize tone, length, hashtag rules, CTA rules, banned phrases, or add custom instructions per platform.",
|
|
168
|
+
inputSchema: {
|
|
169
|
+
type: "object",
|
|
170
|
+
properties: {
|
|
171
|
+
platform: {
|
|
172
|
+
type: "string",
|
|
173
|
+
enum: ["twitter", "linkedin", "threads", "instagram", "youtube", "bluesky", "facebook"],
|
|
174
|
+
description: "Platform to update",
|
|
175
|
+
},
|
|
176
|
+
tone: {
|
|
177
|
+
type: "string",
|
|
178
|
+
enum: ["auto", "casual", "professional", "witty", "empathetic"],
|
|
179
|
+
description: "Tone override for this platform",
|
|
180
|
+
},
|
|
181
|
+
target_length: {
|
|
182
|
+
type: "integer",
|
|
183
|
+
description: "Target character length for generated posts on this platform",
|
|
184
|
+
},
|
|
185
|
+
hashtag_rules: {
|
|
186
|
+
type: "string",
|
|
187
|
+
enum: ["none", "few", "moderate", "match_voice"],
|
|
188
|
+
description: "Hashtag usage rule for this platform",
|
|
189
|
+
},
|
|
190
|
+
cta_rules: {
|
|
191
|
+
type: "string",
|
|
192
|
+
enum: ["never", "soft_question", "link_in_comments", "direct"],
|
|
193
|
+
description: "Call-to-action rule for this platform",
|
|
194
|
+
},
|
|
195
|
+
banned_phrases: {
|
|
196
|
+
type: "array",
|
|
197
|
+
items: { type: "string" },
|
|
198
|
+
description: "Phrases to never use in generated content for this platform",
|
|
199
|
+
},
|
|
200
|
+
custom_instructions: {
|
|
201
|
+
type: "string",
|
|
202
|
+
maxLength: 500,
|
|
203
|
+
description: "Free-text instructions applied when generating for this platform (max 500 chars)",
|
|
204
|
+
},
|
|
205
|
+
},
|
|
206
|
+
required: ["platform"],
|
|
207
|
+
},
|
|
208
|
+
async handler(args, client) {
|
|
209
|
+
try {
|
|
210
|
+
const { platform, ...overrides } = PlatformStylesSetSchema.parse(args);
|
|
211
|
+
const result = await client.patch(`/api/v1/platform_styles/${platform}`, { platform_style: overrides });
|
|
212
|
+
return ok(result);
|
|
213
|
+
}
|
|
214
|
+
catch (e) {
|
|
215
|
+
return err(e);
|
|
216
|
+
}
|
|
217
|
+
},
|
|
218
|
+
},
|
|
109
219
|
{
|
|
110
220
|
name: "xreply_rules_list",
|
|
111
221
|
description: "List custom writing rules that are applied during post generation — e.g., 'never use hashtags', 'always end with a question'. Requires Pro or BYOK subscription.",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"context.js","sourceRoot":"","sources":["../../src/tools/context.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;
|
|
1
|
+
{"version":3,"file":"context.js","sourceRoot":"","sources":["../../src/tools/context.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../src/tools/helpers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAE7C,wBAAgB,EAAE,CAAC,IAAI,EAAE,OAAO,GAAG,UAAU,CAE5C;AAED,wBAAgB,GAAG,CAAC,KAAK,EAAE,OAAO,GAAG,UAAU,CAG9C"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export function ok(data) {
|
|
2
|
+
return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] };
|
|
3
|
+
}
|
|
4
|
+
export function err(error) {
|
|
5
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
6
|
+
return { content: [{ type: "text", text: `Error: ${message}` }], isError: true };
|
|
7
|
+
}
|
|
8
|
+
//# sourceMappingURL=helpers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"helpers.js","sourceRoot":"","sources":["../../src/tools/helpers.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,EAAE,CAAC,IAAa;IAC9B,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC;AAC9E,CAAC;AAED,MAAM,UAAU,GAAG,CAAC,KAAc;IAChC,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACvE,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,OAAO,EAAE,EAAE,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;AACnF,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"media.d.ts","sourceRoot":"","sources":["../../src/tools/media.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAGjD,eAAO,MAAM,GAAG;qBAAsB,MAAM,KAAG,MAAM;CAAkC,CAAC;AA+BxF,eAAO,MAAM,UAAU,EAAE,cAAc,EA4LtC,CAAC"}
|
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { readFileSync } from "fs";
|
|
3
|
+
import { ok, err } from "./helpers.js";
|
|
4
|
+
export const _fs = { readFile: (path) => readFileSync(path) };
|
|
5
|
+
const ALLOWED_CONTENT_TYPES = ["image/jpeg", "image/png", "video/mp4", "video/quicktime"];
|
|
6
|
+
const TIKTOK_IMAGE_CONTENT_TYPES = ["image/jpeg", "image/png"];
|
|
7
|
+
const TIKTOK_VIDEO_CONTENT_TYPES = ["video/mp4", "video/quicktime"];
|
|
8
|
+
const LinkedInDocumentUploadSchema = z.object({
|
|
9
|
+
file_path: z.string().describe("Absolute path to the PDF file on disk"),
|
|
10
|
+
});
|
|
11
|
+
const InstagramMediaUploadSchema = z.object({
|
|
12
|
+
file_path: z.string().describe("Absolute path to the image or video file on disk"),
|
|
13
|
+
content_type: z
|
|
14
|
+
.enum(ALLOWED_CONTENT_TYPES)
|
|
15
|
+
.describe("MIME type of the file (image/jpeg, image/png, video/mp4, video/quicktime)"),
|
|
16
|
+
});
|
|
17
|
+
const TikTokImageUploadSchema = z.object({
|
|
18
|
+
file_path: z.string().describe("Absolute path to the image file on disk"),
|
|
19
|
+
content_type: z
|
|
20
|
+
.enum(TIKTOK_IMAGE_CONTENT_TYPES)
|
|
21
|
+
.describe("MIME type of the file (image/jpeg, image/png)"),
|
|
22
|
+
});
|
|
23
|
+
const TikTokVideoUploadSchema = z.object({
|
|
24
|
+
file_path: z.string().describe("Absolute path to the video file on disk"),
|
|
25
|
+
content_type: z
|
|
26
|
+
.enum(TIKTOK_VIDEO_CONTENT_TYPES)
|
|
27
|
+
.describe("MIME type of the file (video/mp4, video/quicktime)"),
|
|
28
|
+
});
|
|
29
|
+
export const mediaTools = [
|
|
30
|
+
{
|
|
31
|
+
name: "xreply_instagram_media_upload",
|
|
32
|
+
description: "Upload a local image or video file to R2 storage and get back a public URL to use in Instagram posts. " +
|
|
33
|
+
"Pass the returned url in post_contents[].metadata.image_url (single image), image_urls (carousel), or video_url (reel). " +
|
|
34
|
+
"Supports JPEG, PNG (images up to 8 MB) and MP4, MOV (videos up to 100 MB).",
|
|
35
|
+
inputSchema: {
|
|
36
|
+
type: "object",
|
|
37
|
+
properties: {
|
|
38
|
+
file_path: { type: "string", description: "Absolute path to the file on disk" },
|
|
39
|
+
content_type: {
|
|
40
|
+
type: "string",
|
|
41
|
+
enum: [...ALLOWED_CONTENT_TYPES],
|
|
42
|
+
description: "MIME type of the file",
|
|
43
|
+
},
|
|
44
|
+
},
|
|
45
|
+
required: ["file_path", "content_type"],
|
|
46
|
+
},
|
|
47
|
+
async handler(args, client) {
|
|
48
|
+
try {
|
|
49
|
+
const { file_path, content_type } = InstagramMediaUploadSchema.parse(args);
|
|
50
|
+
let fileData;
|
|
51
|
+
try {
|
|
52
|
+
fileData = _fs.readFile(file_path);
|
|
53
|
+
}
|
|
54
|
+
catch {
|
|
55
|
+
return err(`Could not read file at ${file_path}`);
|
|
56
|
+
}
|
|
57
|
+
const result = await client.post("/api/v1/instagram/media_uploads", { media: fileData.toString("base64"), content_type });
|
|
58
|
+
return ok({ url: result.url });
|
|
59
|
+
}
|
|
60
|
+
catch (e) {
|
|
61
|
+
return err(e);
|
|
62
|
+
}
|
|
63
|
+
},
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
name: "xreply_linkedin_document_upload",
|
|
67
|
+
description: "Upload a local PDF file to LinkedIn and get back a document_urn to use as a carousel post. " +
|
|
68
|
+
"Pass the returned document_urn in post_contents[].metadata.document_urn with content_type: 'document'. " +
|
|
69
|
+
"Supports PDF files up to 100 MB. LinkedIn renders the PDF as a swipeable carousel.",
|
|
70
|
+
inputSchema: {
|
|
71
|
+
type: "object",
|
|
72
|
+
properties: {
|
|
73
|
+
file_path: { type: "string", description: "Absolute path to the PDF file on disk" },
|
|
74
|
+
},
|
|
75
|
+
required: ["file_path"],
|
|
76
|
+
},
|
|
77
|
+
async handler(args, client) {
|
|
78
|
+
try {
|
|
79
|
+
const { file_path } = LinkedInDocumentUploadSchema.parse(args);
|
|
80
|
+
let fileData;
|
|
81
|
+
try {
|
|
82
|
+
fileData = _fs.readFile(file_path);
|
|
83
|
+
}
|
|
84
|
+
catch {
|
|
85
|
+
return err(`Could not read file at ${file_path}`);
|
|
86
|
+
}
|
|
87
|
+
if (!fileData.slice(0, 5).toString("ascii").startsWith("%PDF-")) {
|
|
88
|
+
return err("File does not appear to be a valid PDF");
|
|
89
|
+
}
|
|
90
|
+
const form = new FormData();
|
|
91
|
+
form.append("document", new Blob([fileData], { type: "application/pdf" }), file_path.split("/").pop() ?? "document.pdf");
|
|
92
|
+
const result = await client.postMultipart("/api/v1/linkedin/document_uploads", form);
|
|
93
|
+
return ok({ document_urn: result.document_urn });
|
|
94
|
+
}
|
|
95
|
+
catch (e) {
|
|
96
|
+
return err(e);
|
|
97
|
+
}
|
|
98
|
+
},
|
|
99
|
+
},
|
|
100
|
+
{
|
|
101
|
+
name: "xreply_tiktok_image_upload",
|
|
102
|
+
description: "Upload a local image file to R2 storage and get back a public URL to use in TikTok posts. " +
|
|
103
|
+
"Pass the returned url in post_contents[].metadata.image_url (single image) or image_urls[] (carousel). " +
|
|
104
|
+
"Supports JPEG and PNG images up to 8 MB.",
|
|
105
|
+
inputSchema: {
|
|
106
|
+
type: "object",
|
|
107
|
+
properties: {
|
|
108
|
+
file_path: { type: "string", description: "Absolute path to the image file on disk" },
|
|
109
|
+
content_type: {
|
|
110
|
+
type: "string",
|
|
111
|
+
enum: [...TIKTOK_IMAGE_CONTENT_TYPES],
|
|
112
|
+
description: "MIME type of the file (image/jpeg or image/png)",
|
|
113
|
+
},
|
|
114
|
+
},
|
|
115
|
+
required: ["file_path", "content_type"],
|
|
116
|
+
},
|
|
117
|
+
async handler(args, client) {
|
|
118
|
+
try {
|
|
119
|
+
const { file_path, content_type } = TikTokImageUploadSchema.parse(args);
|
|
120
|
+
let fileData;
|
|
121
|
+
try {
|
|
122
|
+
fileData = _fs.readFile(file_path);
|
|
123
|
+
}
|
|
124
|
+
catch {
|
|
125
|
+
return err(`Could not read file at ${file_path}`);
|
|
126
|
+
}
|
|
127
|
+
const result = await client.post("/api/v1/tiktok/media_uploads", { media: fileData.toString("base64"), content_type });
|
|
128
|
+
return ok({ url: result.url, r2_key: result.r2_key });
|
|
129
|
+
}
|
|
130
|
+
catch (e) {
|
|
131
|
+
return err(e);
|
|
132
|
+
}
|
|
133
|
+
},
|
|
134
|
+
},
|
|
135
|
+
{
|
|
136
|
+
name: "xreply_tiktok_video_upload",
|
|
137
|
+
description: "Upload a local video file to R2 storage for use in TikTok posts. " +
|
|
138
|
+
"Uses a presigned URL flow: fetches a presigned PUT URL from the backend, then uploads the video directly to R2. " +
|
|
139
|
+
"Pass the returned r2_key in post_contents[].metadata.r2_key. " +
|
|
140
|
+
"Supports MP4 and MOV (QuickTime) video formats.",
|
|
141
|
+
inputSchema: {
|
|
142
|
+
type: "object",
|
|
143
|
+
properties: {
|
|
144
|
+
file_path: { type: "string", description: "Absolute path to the video file on disk" },
|
|
145
|
+
content_type: {
|
|
146
|
+
type: "string",
|
|
147
|
+
enum: [...TIKTOK_VIDEO_CONTENT_TYPES],
|
|
148
|
+
description: "MIME type of the file (video/mp4 or video/quicktime)",
|
|
149
|
+
},
|
|
150
|
+
},
|
|
151
|
+
required: ["file_path", "content_type"],
|
|
152
|
+
},
|
|
153
|
+
async handler(args, client) {
|
|
154
|
+
try {
|
|
155
|
+
const { file_path, content_type } = TikTokVideoUploadSchema.parse(args);
|
|
156
|
+
let fileData;
|
|
157
|
+
try {
|
|
158
|
+
fileData = _fs.readFile(file_path);
|
|
159
|
+
}
|
|
160
|
+
catch {
|
|
161
|
+
return err(`Could not read file at ${file_path}`);
|
|
162
|
+
}
|
|
163
|
+
const presign = await client.get(`/api/v1/tiktok/uploads/presign?content_type=${encodeURIComponent(content_type)}`);
|
|
164
|
+
const uploadController = new AbortController();
|
|
165
|
+
const uploadTimer = setTimeout(() => uploadController.abort(), 300_000);
|
|
166
|
+
let uploadResponse;
|
|
167
|
+
try {
|
|
168
|
+
uploadResponse = await fetch(presign.upload_url, {
|
|
169
|
+
method: "PUT",
|
|
170
|
+
headers: { "Content-Type": content_type, "Content-Length": String(fileData.byteLength) },
|
|
171
|
+
body: fileData,
|
|
172
|
+
signal: uploadController.signal,
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
catch (e) {
|
|
176
|
+
clearTimeout(uploadTimer);
|
|
177
|
+
if (e instanceof Error && e.name === "AbortError") {
|
|
178
|
+
return err("Video upload timed out after 5 minutes. Try a smaller file or check your connection.");
|
|
179
|
+
}
|
|
180
|
+
return err(`Video upload failed: ${e instanceof Error ? e.message : String(e)}`);
|
|
181
|
+
}
|
|
182
|
+
clearTimeout(uploadTimer);
|
|
183
|
+
if (!uploadResponse.ok) {
|
|
184
|
+
const body = await uploadResponse.text().catch(() => "");
|
|
185
|
+
return err(`Video upload failed with HTTP ${uploadResponse.status}: ${body}`);
|
|
186
|
+
}
|
|
187
|
+
return ok({ r2_key: presign.r2_key });
|
|
188
|
+
}
|
|
189
|
+
catch (e) {
|
|
190
|
+
return err(e);
|
|
191
|
+
}
|
|
192
|
+
},
|
|
193
|
+
},
|
|
194
|
+
];
|
|
195
|
+
//# sourceMappingURL=media.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"media.js","sourceRoot":"","sources":["../../src/tools/media.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"posts.d.ts","sourceRoot":"","sources":["../../src/tools/posts.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAC;AACzE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAUjD,MAAM,MAAM,UAAU,GAAG,cAAc,CAAC;AAExC,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACrC,OAAO,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,EAAE,YAAY,KAAK,OAAO,CAAC,UAAU,CAAC,CAAC;CACvF;
|
|
1
|
+
{"version":3,"file":"posts.d.ts","sourceRoot":"","sources":["../../src/tools/posts.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAC;AACzE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAUjD,MAAM,MAAM,UAAU,GAAG,cAAc,CAAC;AAExC,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACrC,OAAO,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,EAAE,YAAY,KAAK,OAAO,CAAC,UAAU,CAAC,CAAC;CACvF;AAwHD,eAAO,MAAM,SAAS,EAAE,cAAc,EAgrBrC,CAAC"}
|