@xreplyai/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.
- package/README.md +153 -0
- package/dist/client.d.ts +15 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +95 -0
- package/dist/client.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +14 -0
- package/dist/index.js.map +1 -0
- package/dist/server.d.ts +3 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +38 -0
- package/dist/server.js.map +1 -0
- package/dist/tools/context.d.ts +3 -0
- package/dist/tools/context.d.ts.map +1 -0
- package/dist/tools/context.js +128 -0
- package/dist/tools/context.js.map +1 -0
- package/dist/tools/posts.d.ts +11 -0
- package/dist/tools/posts.d.ts.map +1 -0
- package/dist/tools/posts.js +213 -0
- package/dist/tools/posts.js.map +1 -0
- package/dist/tools/publish.d.ts +3 -0
- package/dist/tools/publish.d.ts.map +1 -0
- package/dist/tools/publish.js +46 -0
- package/dist/tools/publish.js.map +1 -0
- package/dist/tools/viral-library.d.ts +3 -0
- package/dist/tools/viral-library.d.ts.map +1 -0
- package/dist/tools/viral-library.js +58 -0
- package/dist/tools/viral-library.js.map +1 -0
- package/dist/types.d.ts +108 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/package.json +67 -0
package/README.md
ADDED
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
# @xreplyai/mcp
|
|
2
|
+
|
|
3
|
+
MCP server for [XReply AI](https://xreply.ai) — voice-aware post generation, viral library discovery, and post management for AI agents.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
13 tools covering the full posts workflow:
|
|
8
|
+
|
|
9
|
+
- **Discovery** — Browse the viral tweet library filtered by niche
|
|
10
|
+
- **Generation** — Generate single posts or batches in your voice
|
|
11
|
+
- **Post management** — Create, edit, delete posts
|
|
12
|
+
- **Publishing** — Publish immediately or schedule to X/Twitter
|
|
13
|
+
- **Context** — Check billing, voice profile, preferences, and custom rules
|
|
14
|
+
|
|
15
|
+
## Requirements
|
|
16
|
+
|
|
17
|
+
- Node.js 20+
|
|
18
|
+
- An XReply account (get your JWT token from Settings)
|
|
19
|
+
|
|
20
|
+
## Setup
|
|
21
|
+
|
|
22
|
+
### Get your token
|
|
23
|
+
|
|
24
|
+
Sign in to [XReply](https://xreply.ai), go to **Settings**, and copy your API token.
|
|
25
|
+
|
|
26
|
+
### Claude Desktop
|
|
27
|
+
|
|
28
|
+
Add to `~/Library/Application Support/Claude/claude_desktop_config.json`:
|
|
29
|
+
|
|
30
|
+
```json
|
|
31
|
+
{
|
|
32
|
+
"mcpServers": {
|
|
33
|
+
"xreply": {
|
|
34
|
+
"command": "npx",
|
|
35
|
+
"args": ["@xreplyai/mcp"],
|
|
36
|
+
"env": {
|
|
37
|
+
"XREPLY_TOKEN": "your-jwt-token-here"
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
### Cursor
|
|
45
|
+
|
|
46
|
+
Add to `.cursor/mcp.json` in your project (or `~/.cursor/mcp.json` globally):
|
|
47
|
+
|
|
48
|
+
```json
|
|
49
|
+
{
|
|
50
|
+
"mcpServers": {
|
|
51
|
+
"xreply": {
|
|
52
|
+
"command": "npx",
|
|
53
|
+
"args": ["@xreplyai/mcp"],
|
|
54
|
+
"env": {
|
|
55
|
+
"XREPLY_TOKEN": "your-jwt-token-here"
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### Windsurf
|
|
63
|
+
|
|
64
|
+
Add to `~/.codeium/windsurf/mcp_config.json`:
|
|
65
|
+
|
|
66
|
+
```json
|
|
67
|
+
{
|
|
68
|
+
"mcpServers": {
|
|
69
|
+
"xreply": {
|
|
70
|
+
"command": "npx",
|
|
71
|
+
"args": ["@xreplyai/mcp"],
|
|
72
|
+
"env": {
|
|
73
|
+
"XREPLY_TOKEN": "your-jwt-token-here"
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## Tools
|
|
81
|
+
|
|
82
|
+
### Discovery
|
|
83
|
+
|
|
84
|
+
| Tool | Description |
|
|
85
|
+
|------|-------------|
|
|
86
|
+
| `xreply_viral_library` | Browse viral tweets (100+ likes) filtered by niche and sort |
|
|
87
|
+
|
|
88
|
+
### Generation
|
|
89
|
+
|
|
90
|
+
| Tool | Description |
|
|
91
|
+
|------|-------------|
|
|
92
|
+
| `xreply_posts_generate` | Generate a single post in your voice |
|
|
93
|
+
| `xreply_posts_generate_batch` | Generate 1-9 posts at once by category |
|
|
94
|
+
|
|
95
|
+
### Post Management
|
|
96
|
+
|
|
97
|
+
| Tool | Description |
|
|
98
|
+
|------|-------------|
|
|
99
|
+
| `xreply_posts_list` | List all posts in your queue |
|
|
100
|
+
| `xreply_posts_create` | Save a post draft |
|
|
101
|
+
| `xreply_posts_edit` | Edit body or scheduled time |
|
|
102
|
+
| `xreply_posts_delete` | Delete a post |
|
|
103
|
+
|
|
104
|
+
### Publishing
|
|
105
|
+
|
|
106
|
+
| Tool | Description |
|
|
107
|
+
|------|-------------|
|
|
108
|
+
| `xreply_posts_publish` | Publish now or schedule to X/Twitter |
|
|
109
|
+
|
|
110
|
+
### Context
|
|
111
|
+
|
|
112
|
+
| Tool | Description |
|
|
113
|
+
|------|-------------|
|
|
114
|
+
| `xreply_billing_status` | Check subscription tier and quota |
|
|
115
|
+
| `xreply_voice_status` | Check voice profile analysis status |
|
|
116
|
+
| `xreply_preferences_get` | Get generation preferences |
|
|
117
|
+
| `xreply_preferences_set` | Update tone, emoji, structure preferences |
|
|
118
|
+
| `xreply_rules_list` | List custom writing rules |
|
|
119
|
+
|
|
120
|
+
## Example workflows
|
|
121
|
+
|
|
122
|
+
### Plan posts for the week
|
|
123
|
+
|
|
124
|
+
```
|
|
125
|
+
1. xreply_viral_library (niche: "saas") — find inspiration
|
|
126
|
+
2. xreply_posts_generate_batch (category: "for_you", count: 7) — generate 7 posts
|
|
127
|
+
3. xreply_posts_create — save the ones you like
|
|
128
|
+
4. xreply_posts_edit (id: X, scheduled_at: "2026-03-10T09:00:00Z") — schedule each
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
### Quick post
|
|
132
|
+
|
|
133
|
+
```
|
|
134
|
+
1. xreply_posts_generate (topic: "my SaaS hit 1000 users", angle: "story_arc")
|
|
135
|
+
2. xreply_posts_create (body: "<generated text>")
|
|
136
|
+
3. xreply_posts_publish (id: X) — post immediately
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
## Environment variables
|
|
140
|
+
|
|
141
|
+
| Variable | Required | Default | Description |
|
|
142
|
+
|----------|----------|---------|-------------|
|
|
143
|
+
| `XREPLY_TOKEN` | Yes | — | Your XReply JWT token |
|
|
144
|
+
| `XREPLY_API_URL` | No | `https://x-reply-ai-backend.onrender.com` | Override API base URL |
|
|
145
|
+
|
|
146
|
+
## Development
|
|
147
|
+
|
|
148
|
+
```bash
|
|
149
|
+
npm install
|
|
150
|
+
npm run build
|
|
151
|
+
npm test
|
|
152
|
+
XREPLY_TOKEN=your-token npx tsx src/index.ts
|
|
153
|
+
```
|
package/dist/client.d.ts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export declare class XReplyClient {
|
|
2
|
+
private token;
|
|
3
|
+
private baseUrl;
|
|
4
|
+
constructor(token: string, baseUrl?: string);
|
|
5
|
+
private headers;
|
|
6
|
+
private timeoutMs;
|
|
7
|
+
private request;
|
|
8
|
+
get<T>(path: string): Promise<T>;
|
|
9
|
+
post<T>(path: string, body?: unknown): Promise<T>;
|
|
10
|
+
patch<T>(path: string, body?: unknown): Promise<T>;
|
|
11
|
+
delete(path: string): Promise<void>;
|
|
12
|
+
}
|
|
13
|
+
export declare function getClient(): XReplyClient;
|
|
14
|
+
export declare function createClient(token: string, baseUrl?: string): XReplyClient;
|
|
15
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAUA,qBAAa,YAAY;IACvB,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,OAAO,CAAS;gBAEZ,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM;IAQ3C,OAAO,CAAC,OAAO;IAQf,OAAO,CAAC,SAAS;YAIH,OAAO;IAwDrB,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC;IAIhC,IAAI,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,CAAC,CAAC;IAIjD,KAAK,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,CAAC,CAAC;IAIlD,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAGpC;AAID,wBAAgB,SAAS,IAAI,YAAY,CASxC;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,YAAY,CAE1E"}
|
package/dist/client.js
ADDED
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
const DEFAULT_BASE_URL = "https://x-reply-ai-backend.onrender.com";
|
|
2
|
+
const DEFAULT_TIMEOUT_MS = 30_000;
|
|
3
|
+
const GENERATION_TIMEOUT_MS = 60_000;
|
|
4
|
+
const GENERATION_PATHS = ["/generate", "/generate_batch"];
|
|
5
|
+
function isGenerationPath(path) {
|
|
6
|
+
return GENERATION_PATHS.some((p) => path.includes(p));
|
|
7
|
+
}
|
|
8
|
+
export class XReplyClient {
|
|
9
|
+
token;
|
|
10
|
+
baseUrl;
|
|
11
|
+
constructor(token, baseUrl) {
|
|
12
|
+
this.token = token;
|
|
13
|
+
this.baseUrl = (baseUrl ?? process.env.XREPLY_API_URL ?? DEFAULT_BASE_URL).replace(/\/$/, "");
|
|
14
|
+
}
|
|
15
|
+
headers() {
|
|
16
|
+
return {
|
|
17
|
+
Authorization: `Bearer ${this.token}`,
|
|
18
|
+
"Content-Type": "application/json",
|
|
19
|
+
Accept: "application/json",
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
timeoutMs(path) {
|
|
23
|
+
return isGenerationPath(path) ? GENERATION_TIMEOUT_MS : DEFAULT_TIMEOUT_MS;
|
|
24
|
+
}
|
|
25
|
+
async request(method, path, body) {
|
|
26
|
+
const url = `${this.baseUrl}${path}`;
|
|
27
|
+
const timeout = this.timeoutMs(path);
|
|
28
|
+
const controller = new AbortController();
|
|
29
|
+
const timer = setTimeout(() => controller.abort(), timeout);
|
|
30
|
+
let response;
|
|
31
|
+
try {
|
|
32
|
+
response = await fetch(url, {
|
|
33
|
+
method,
|
|
34
|
+
headers: this.headers(),
|
|
35
|
+
body: body !== undefined ? JSON.stringify(body) : undefined,
|
|
36
|
+
signal: controller.signal,
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
catch (err) {
|
|
40
|
+
clearTimeout(timer);
|
|
41
|
+
if (err instanceof Error && err.name === "AbortError") {
|
|
42
|
+
throw new Error(`Request timed out after ${timeout / 1000}s: ${method} ${path}`);
|
|
43
|
+
}
|
|
44
|
+
throw new Error(`Network error: ${err instanceof Error ? err.message : String(err)}`);
|
|
45
|
+
}
|
|
46
|
+
clearTimeout(timer);
|
|
47
|
+
if (response.status === 401) {
|
|
48
|
+
throw new Error("Authentication failed: your XREPLY_TOKEN is expired or invalid. Generate a new token from the XReply settings page.");
|
|
49
|
+
}
|
|
50
|
+
if (response.status === 204) {
|
|
51
|
+
return undefined;
|
|
52
|
+
}
|
|
53
|
+
let data;
|
|
54
|
+
const contentType = response.headers.get("content-type") ?? "";
|
|
55
|
+
if (contentType.includes("application/json")) {
|
|
56
|
+
data = await response.json();
|
|
57
|
+
}
|
|
58
|
+
else {
|
|
59
|
+
const text = await response.text();
|
|
60
|
+
throw new Error(`Unexpected response (${response.status}): ${text}`);
|
|
61
|
+
}
|
|
62
|
+
if (!response.ok) {
|
|
63
|
+
const err = data;
|
|
64
|
+
throw new Error(err.message ?? err.error ?? `Request failed with status ${response.status}`);
|
|
65
|
+
}
|
|
66
|
+
return data;
|
|
67
|
+
}
|
|
68
|
+
get(path) {
|
|
69
|
+
return this.request("GET", path);
|
|
70
|
+
}
|
|
71
|
+
post(path, body) {
|
|
72
|
+
return this.request("POST", path, body ?? {});
|
|
73
|
+
}
|
|
74
|
+
patch(path, body) {
|
|
75
|
+
return this.request("PATCH", path, body ?? {});
|
|
76
|
+
}
|
|
77
|
+
delete(path) {
|
|
78
|
+
return this.request("DELETE", path);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
let _client = null;
|
|
82
|
+
export function getClient() {
|
|
83
|
+
if (!_client) {
|
|
84
|
+
const token = process.env.XREPLY_TOKEN;
|
|
85
|
+
if (!token) {
|
|
86
|
+
throw new Error("XREPLY_TOKEN environment variable is not set");
|
|
87
|
+
}
|
|
88
|
+
_client = new XReplyClient(token);
|
|
89
|
+
}
|
|
90
|
+
return _client;
|
|
91
|
+
}
|
|
92
|
+
export function createClient(token, baseUrl) {
|
|
93
|
+
return new XReplyClient(token, baseUrl);
|
|
94
|
+
}
|
|
95
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
3
|
+
import { createServer } from "./server.js";
|
|
4
|
+
const token = process.env.XREPLY_TOKEN;
|
|
5
|
+
if (!token) {
|
|
6
|
+
console.error("Error: XREPLY_TOKEN environment variable is required.\n" +
|
|
7
|
+
"Get your token from XReply settings and add it to your MCP config:\n" +
|
|
8
|
+
' "env": { "XREPLY_TOKEN": "your-token-here" }');
|
|
9
|
+
process.exit(1);
|
|
10
|
+
}
|
|
11
|
+
const server = createServer();
|
|
12
|
+
const transport = new StdioServerTransport();
|
|
13
|
+
await server.connect(transport);
|
|
14
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC;AACvC,IAAI,CAAC,KAAK,EAAE,CAAC;IACX,OAAO,CAAC,KAAK,CACX,yDAAyD;QACvD,sEAAsE;QACtE,gDAAgD,CACnD,CAAC;IACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC;AAED,MAAM,MAAM,GAAG,YAAY,EAAE,CAAC;AAC9B,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;AAE7C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC"}
|
package/dist/server.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AAwBnE,wBAAgB,YAAY,IAAI,MAAM,CA8BrC"}
|
package/dist/server.js
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
|
2
|
+
import { CallToolRequestSchema, ListToolsRequestSchema, } from "@modelcontextprotocol/sdk/types.js";
|
|
3
|
+
import { getClient } from "./client.js";
|
|
4
|
+
import { postTools } from "./tools/posts.js";
|
|
5
|
+
import { publishTools } from "./tools/publish.js";
|
|
6
|
+
import { viralLibraryTools } from "./tools/viral-library.js";
|
|
7
|
+
import { contextTools } from "./tools/context.js";
|
|
8
|
+
const ALL_TOOLS = [
|
|
9
|
+
...postTools,
|
|
10
|
+
...publishTools,
|
|
11
|
+
...viralLibraryTools,
|
|
12
|
+
...contextTools,
|
|
13
|
+
];
|
|
14
|
+
const TOOL_MAP = new Map(ALL_TOOLS.map((t) => [t.name, t]));
|
|
15
|
+
export function createServer() {
|
|
16
|
+
const server = new Server({ name: "xreply-mcp", version: "0.1.0" }, { capabilities: { tools: {} } });
|
|
17
|
+
server.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
18
|
+
tools: ALL_TOOLS.map((t) => ({
|
|
19
|
+
name: t.name,
|
|
20
|
+
description: t.description,
|
|
21
|
+
inputSchema: t.inputSchema,
|
|
22
|
+
})),
|
|
23
|
+
}));
|
|
24
|
+
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
25
|
+
const { name, arguments: args } = request.params;
|
|
26
|
+
const tool = TOOL_MAP.get(name);
|
|
27
|
+
if (!tool) {
|
|
28
|
+
return {
|
|
29
|
+
content: [{ type: "text", text: `Unknown tool: ${name}` }],
|
|
30
|
+
isError: true,
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
const client = getClient();
|
|
34
|
+
return tool.handler((args ?? {}), client);
|
|
35
|
+
});
|
|
36
|
+
return server;
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=server.js.map
|
|
@@ -0,0 +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,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAGlD,MAAM,SAAS,GAAqB;IAClC,GAAG,SAAS;IACZ,GAAG,YAAY;IACf,GAAG,iBAAiB;IACpB,GAAG,YAAY;CAChB,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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/tools/context.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,cAAc,EAAc,MAAM,YAAY,CAAC;AAuB7D,eAAO,MAAM,YAAY,EAAE,cAAc,EAoHxC,CAAC"}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
function ok(data) {
|
|
3
|
+
return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] };
|
|
4
|
+
}
|
|
5
|
+
function err(error) {
|
|
6
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
7
|
+
return { content: [{ type: "text", text: `Error: ${message}` }], isError: true };
|
|
8
|
+
}
|
|
9
|
+
const PreferencesSetSchema = z.object({
|
|
10
|
+
tone: z
|
|
11
|
+
.enum(["auto", "casual", "professional", "witty", "empathetic"])
|
|
12
|
+
.optional()
|
|
13
|
+
.describe("Tone preference"),
|
|
14
|
+
include_emoji: z.boolean().nullable().optional().describe("Include emoji in generated posts"),
|
|
15
|
+
structure: z
|
|
16
|
+
.enum(["one_liner", "paragraph", "question", "list", "story_arc"])
|
|
17
|
+
.optional()
|
|
18
|
+
.describe("Default post structure"),
|
|
19
|
+
});
|
|
20
|
+
export const contextTools = [
|
|
21
|
+
{
|
|
22
|
+
name: "xreply_billing_status",
|
|
23
|
+
description: "Get the current billing and subscription status — tier (free/byok/pro), quota usage, daily limits, and subscription details.",
|
|
24
|
+
inputSchema: {
|
|
25
|
+
type: "object",
|
|
26
|
+
properties: {},
|
|
27
|
+
required: [],
|
|
28
|
+
},
|
|
29
|
+
async handler(_args, client) {
|
|
30
|
+
try {
|
|
31
|
+
const result = await client.get("/api/v1/billing/subscriptions/current");
|
|
32
|
+
return ok(result);
|
|
33
|
+
}
|
|
34
|
+
catch (e) {
|
|
35
|
+
return err(e);
|
|
36
|
+
}
|
|
37
|
+
},
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
name: "xreply_voice_status",
|
|
41
|
+
description: "Get the voice profile status — whether it has been analyzed, tweet count, AI provider configured, and writing style summary. The voice profile powers personalized post generation.",
|
|
42
|
+
inputSchema: {
|
|
43
|
+
type: "object",
|
|
44
|
+
properties: {},
|
|
45
|
+
required: [],
|
|
46
|
+
},
|
|
47
|
+
async handler(_args, client) {
|
|
48
|
+
try {
|
|
49
|
+
const result = await client.get("/api/v1/voice_profile");
|
|
50
|
+
return ok(result);
|
|
51
|
+
}
|
|
52
|
+
catch (e) {
|
|
53
|
+
return err(e);
|
|
54
|
+
}
|
|
55
|
+
},
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
name: "xreply_preferences_get",
|
|
59
|
+
description: "Get the current post generation preferences — tone, emoji usage, and default structure.",
|
|
60
|
+
inputSchema: {
|
|
61
|
+
type: "object",
|
|
62
|
+
properties: {},
|
|
63
|
+
required: [],
|
|
64
|
+
},
|
|
65
|
+
async handler(_args, client) {
|
|
66
|
+
try {
|
|
67
|
+
const result = await client.get("/api/v1/preferences");
|
|
68
|
+
return ok(result);
|
|
69
|
+
}
|
|
70
|
+
catch (e) {
|
|
71
|
+
return err(e);
|
|
72
|
+
}
|
|
73
|
+
},
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
name: "xreply_preferences_set",
|
|
77
|
+
description: "Update post generation preferences. Provide only the fields you want to change — tone (auto/casual/professional/witty/empathetic), include_emoji (true/false/null), or structure (one_liner/paragraph/question/list/story_arc).",
|
|
78
|
+
inputSchema: {
|
|
79
|
+
type: "object",
|
|
80
|
+
properties: {
|
|
81
|
+
tone: {
|
|
82
|
+
type: "string",
|
|
83
|
+
enum: ["auto", "casual", "professional", "witty", "empathetic"],
|
|
84
|
+
description: "Tone preference",
|
|
85
|
+
},
|
|
86
|
+
include_emoji: {
|
|
87
|
+
type: ["boolean", "null"],
|
|
88
|
+
description: "Whether to include emoji",
|
|
89
|
+
},
|
|
90
|
+
structure: {
|
|
91
|
+
type: "string",
|
|
92
|
+
enum: ["one_liner", "paragraph", "question", "list", "story_arc"],
|
|
93
|
+
description: "Default post structure",
|
|
94
|
+
},
|
|
95
|
+
},
|
|
96
|
+
required: [],
|
|
97
|
+
},
|
|
98
|
+
async handler(args, client) {
|
|
99
|
+
try {
|
|
100
|
+
const params = PreferencesSetSchema.parse(args);
|
|
101
|
+
const result = await client.patch("/api/v1/preferences", { preferences: params });
|
|
102
|
+
return ok(result);
|
|
103
|
+
}
|
|
104
|
+
catch (e) {
|
|
105
|
+
return err(e);
|
|
106
|
+
}
|
|
107
|
+
},
|
|
108
|
+
},
|
|
109
|
+
{
|
|
110
|
+
name: "xreply_rules_list",
|
|
111
|
+
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.",
|
|
112
|
+
inputSchema: {
|
|
113
|
+
type: "object",
|
|
114
|
+
properties: {},
|
|
115
|
+
required: [],
|
|
116
|
+
},
|
|
117
|
+
async handler(_args, client) {
|
|
118
|
+
try {
|
|
119
|
+
const result = await client.get("/api/v1/custom_rules");
|
|
120
|
+
return ok(result);
|
|
121
|
+
}
|
|
122
|
+
catch (e) {
|
|
123
|
+
return err(e);
|
|
124
|
+
}
|
|
125
|
+
},
|
|
126
|
+
},
|
|
127
|
+
];
|
|
128
|
+
//# sourceMappingURL=context.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context.js","sourceRoot":"","sources":["../../src/tools/context.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { CallToolResult } from "@modelcontextprotocol/sdk/types.js";
|
|
2
|
+
import type { XReplyClient } from "../client.js";
|
|
3
|
+
export type ToolResult = CallToolResult;
|
|
4
|
+
export interface ToolDefinition {
|
|
5
|
+
name: string;
|
|
6
|
+
description: string;
|
|
7
|
+
inputSchema: Record<string, unknown>;
|
|
8
|
+
handler: (args: Record<string, unknown>, client: XReplyClient) => Promise<ToolResult>;
|
|
9
|
+
}
|
|
10
|
+
export declare const postTools: ToolDefinition[];
|
|
11
|
+
//# sourceMappingURL=posts.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"posts.d.ts","sourceRoot":"","sources":["../../src/tools/posts.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAC;AACzE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AASjD,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;AAqDD,eAAO,MAAM,SAAS,EAAE,cAAc,EA2LrC,CAAC"}
|
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
function ok(data) {
|
|
3
|
+
return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] };
|
|
4
|
+
}
|
|
5
|
+
function err(error) {
|
|
6
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
7
|
+
return { content: [{ type: "text", text: `Error: ${message}` }], isError: true };
|
|
8
|
+
}
|
|
9
|
+
const CreatePostSchema = z.object({
|
|
10
|
+
body: z.string().min(1).max(280).describe("The post body text (max 280 chars)"),
|
|
11
|
+
});
|
|
12
|
+
const GeneratePostSchema = z.object({
|
|
13
|
+
topic: z
|
|
14
|
+
.string()
|
|
15
|
+
.max(280)
|
|
16
|
+
.optional()
|
|
17
|
+
.describe("Optional topic or prompt for the post (max 280 chars)"),
|
|
18
|
+
angle: z
|
|
19
|
+
.enum(["one_liner", "list", "question", "story_arc", "paragraph", "my_voice"])
|
|
20
|
+
.optional()
|
|
21
|
+
.describe("Writing angle for the post"),
|
|
22
|
+
});
|
|
23
|
+
const GenerateBatchSchema = z.object({
|
|
24
|
+
category: z
|
|
25
|
+
.enum(["personalized", "trending", "viral"])
|
|
26
|
+
.describe("Category of posts to generate"),
|
|
27
|
+
count: z
|
|
28
|
+
.number()
|
|
29
|
+
.int()
|
|
30
|
+
.min(1)
|
|
31
|
+
.max(9)
|
|
32
|
+
.describe("Number of posts to generate (1-9). Cannot exceed your remaining daily quota."),
|
|
33
|
+
});
|
|
34
|
+
const EditPostSchema = z.object({
|
|
35
|
+
id: z.number().int().positive().describe("Post ID"),
|
|
36
|
+
body: z.string().min(1).max(280).optional().describe("New post body text"),
|
|
37
|
+
scheduled_at: z
|
|
38
|
+
.string()
|
|
39
|
+
.nullable()
|
|
40
|
+
.optional()
|
|
41
|
+
.describe("ISO 8601 datetime to schedule, or null to unschedule"),
|
|
42
|
+
});
|
|
43
|
+
const DeletePostSchema = z.object({
|
|
44
|
+
id: z.number().int().positive().describe("Post ID to delete"),
|
|
45
|
+
});
|
|
46
|
+
export const postTools = [
|
|
47
|
+
{
|
|
48
|
+
name: "xreply_posts_list",
|
|
49
|
+
description: "List all posts in the queue (drafts, scheduled, and recent). Returns post IDs, body text, status, and scheduled times.",
|
|
50
|
+
inputSchema: {
|
|
51
|
+
type: "object",
|
|
52
|
+
properties: {},
|
|
53
|
+
required: [],
|
|
54
|
+
},
|
|
55
|
+
async handler(_args, client) {
|
|
56
|
+
try {
|
|
57
|
+
const result = await client.get("/api/v1/posts");
|
|
58
|
+
return ok(result);
|
|
59
|
+
}
|
|
60
|
+
catch (e) {
|
|
61
|
+
return err(e);
|
|
62
|
+
}
|
|
63
|
+
},
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
name: "xreply_posts_create",
|
|
67
|
+
description: "Create a new post draft. The post is saved but not published until you call xreply_posts_publish.",
|
|
68
|
+
inputSchema: {
|
|
69
|
+
type: "object",
|
|
70
|
+
properties: {
|
|
71
|
+
body: { type: "string", minLength: 1, maxLength: 280, description: "Post body text" },
|
|
72
|
+
},
|
|
73
|
+
required: ["body"],
|
|
74
|
+
},
|
|
75
|
+
async handler(args, client) {
|
|
76
|
+
try {
|
|
77
|
+
const { body } = CreatePostSchema.parse(args);
|
|
78
|
+
const result = await client.post("/api/v1/posts", { post: { body } });
|
|
79
|
+
return ok(result);
|
|
80
|
+
}
|
|
81
|
+
catch (e) {
|
|
82
|
+
return err(e);
|
|
83
|
+
}
|
|
84
|
+
},
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
name: "xreply_posts_generate",
|
|
88
|
+
description: "Generate a single AI post in the user's voice and auto-save it as a draft. Optionally provide a topic and writing angle. Returns the generated body and the saved post ID — edit or delete from the queue as needed. Counts as 1 generation against the daily quota (5/day free, 100/day pro).",
|
|
89
|
+
inputSchema: {
|
|
90
|
+
type: "object",
|
|
91
|
+
properties: {
|
|
92
|
+
topic: {
|
|
93
|
+
type: "string",
|
|
94
|
+
maxLength: 280,
|
|
95
|
+
description: "Optional topic or prompt for the post",
|
|
96
|
+
},
|
|
97
|
+
angle: {
|
|
98
|
+
type: "string",
|
|
99
|
+
enum: ["one_liner", "list", "question", "story_arc", "paragraph", "my_voice"],
|
|
100
|
+
description: "Writing angle",
|
|
101
|
+
},
|
|
102
|
+
},
|
|
103
|
+
required: [],
|
|
104
|
+
},
|
|
105
|
+
async handler(args, client) {
|
|
106
|
+
try {
|
|
107
|
+
const params = GeneratePostSchema.parse(args);
|
|
108
|
+
const generated = await client.post("/api/v1/posts/generate", params);
|
|
109
|
+
const saved = await client.post("/api/v1/posts", {
|
|
110
|
+
post: { body: generated.body },
|
|
111
|
+
});
|
|
112
|
+
return ok({ body: generated.body, post: saved.post });
|
|
113
|
+
}
|
|
114
|
+
catch (e) {
|
|
115
|
+
return err(e);
|
|
116
|
+
}
|
|
117
|
+
},
|
|
118
|
+
},
|
|
119
|
+
{
|
|
120
|
+
name: "xreply_posts_generate_batch",
|
|
121
|
+
description: "Generate multiple AI posts at once in the user's voice. Use 'personalized' for posts tailored to your voice profile, 'trending' for timely content, or 'viral' for posts inspired by viral formats. Returns an array of post body strings. Each post counts as 1 generation against the daily quota (5/day free, 100/day pro) — a single batch of 9 will exhaust a free account. Check xreply_billing_status first if quota is a concern.",
|
|
122
|
+
inputSchema: {
|
|
123
|
+
type: "object",
|
|
124
|
+
properties: {
|
|
125
|
+
category: {
|
|
126
|
+
type: "string",
|
|
127
|
+
enum: ["personalized", "trending", "viral"],
|
|
128
|
+
description: "Category of posts to generate",
|
|
129
|
+
},
|
|
130
|
+
count: {
|
|
131
|
+
type: "integer",
|
|
132
|
+
minimum: 1,
|
|
133
|
+
maximum: 9,
|
|
134
|
+
description: "Number of posts to generate (1-9). Cannot exceed your remaining daily quota.",
|
|
135
|
+
},
|
|
136
|
+
},
|
|
137
|
+
required: ["category", "count"],
|
|
138
|
+
},
|
|
139
|
+
async handler(args, client) {
|
|
140
|
+
try {
|
|
141
|
+
const { category, count } = GenerateBatchSchema.parse(args);
|
|
142
|
+
const billing = await client.get("/api/v1/billing/subscriptions/current");
|
|
143
|
+
const remaining = billing.quota.replies_remaining_today;
|
|
144
|
+
if (remaining !== undefined && remaining !== null && remaining <= 0) {
|
|
145
|
+
return err(`Daily generation quota exhausted (${billing.quota.daily_limit}/day on ${billing.tier} plan). Resets at midnight.`);
|
|
146
|
+
}
|
|
147
|
+
const safeCount = remaining !== undefined && remaining !== null
|
|
148
|
+
? Math.min(count, remaining)
|
|
149
|
+
: count;
|
|
150
|
+
const result = await client.post("/api/v1/posts/generate_batch", { category, count: safeCount });
|
|
151
|
+
const extra = safeCount < count
|
|
152
|
+
? {
|
|
153
|
+
quota_warning: `Only ${safeCount} of ${count} requested posts generated — daily quota limit reached (${billing.quota.daily_limit}/day on ${billing.tier} plan).`,
|
|
154
|
+
}
|
|
155
|
+
: {};
|
|
156
|
+
return ok({ ...result, ...extra });
|
|
157
|
+
}
|
|
158
|
+
catch (e) {
|
|
159
|
+
return err(e);
|
|
160
|
+
}
|
|
161
|
+
},
|
|
162
|
+
},
|
|
163
|
+
{
|
|
164
|
+
name: "xreply_posts_edit",
|
|
165
|
+
description: "Edit a post's body text or scheduled time. Set scheduled_at to an ISO 8601 datetime to schedule it, or null to move it back to draft. Cannot edit posts that are processing or already posted.",
|
|
166
|
+
inputSchema: {
|
|
167
|
+
type: "object",
|
|
168
|
+
properties: {
|
|
169
|
+
id: { type: "integer", description: "Post ID" },
|
|
170
|
+
body: { type: "string", minLength: 1, maxLength: 280, description: "New post body" },
|
|
171
|
+
scheduled_at: {
|
|
172
|
+
type: ["string", "null"],
|
|
173
|
+
description: "ISO 8601 datetime or null to unschedule",
|
|
174
|
+
},
|
|
175
|
+
},
|
|
176
|
+
required: ["id"],
|
|
177
|
+
},
|
|
178
|
+
async handler(args, client) {
|
|
179
|
+
try {
|
|
180
|
+
const { id, ...rest } = EditPostSchema.parse(args);
|
|
181
|
+
const result = await client.patch(`/api/v1/posts/${id}`, {
|
|
182
|
+
post: rest,
|
|
183
|
+
});
|
|
184
|
+
return ok(result);
|
|
185
|
+
}
|
|
186
|
+
catch (e) {
|
|
187
|
+
return err(e);
|
|
188
|
+
}
|
|
189
|
+
},
|
|
190
|
+
},
|
|
191
|
+
{
|
|
192
|
+
name: "xreply_posts_delete",
|
|
193
|
+
description: "Delete a post. Cannot delete posts that are currently processing or already published.",
|
|
194
|
+
inputSchema: {
|
|
195
|
+
type: "object",
|
|
196
|
+
properties: {
|
|
197
|
+
id: { type: "integer", description: "Post ID to delete" },
|
|
198
|
+
},
|
|
199
|
+
required: ["id"],
|
|
200
|
+
},
|
|
201
|
+
async handler(args, client) {
|
|
202
|
+
try {
|
|
203
|
+
const { id } = DeletePostSchema.parse(args);
|
|
204
|
+
await client.delete(`/api/v1/posts/${id}`);
|
|
205
|
+
return ok({ success: true, message: `Post ${id} deleted.` });
|
|
206
|
+
}
|
|
207
|
+
catch (e) {
|
|
208
|
+
return err(e);
|
|
209
|
+
}
|
|
210
|
+
},
|
|
211
|
+
},
|
|
212
|
+
];
|
|
213
|
+
//# sourceMappingURL=posts.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"posts.js","sourceRoot":"","sources":["../../src/tools/posts.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"publish.d.ts","sourceRoot":"","sources":["../../src/tools/publish.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAc,MAAM,YAAY,CAAC;AAmB7D,eAAO,MAAM,YAAY,EAAE,cAAc,EA4BxC,CAAC"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
function ok(data) {
|
|
3
|
+
return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] };
|
|
4
|
+
}
|
|
5
|
+
function err(error) {
|
|
6
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
7
|
+
return { content: [{ type: "text", text: `Error: ${message}` }], isError: true };
|
|
8
|
+
}
|
|
9
|
+
const PublishSchema = z.object({
|
|
10
|
+
id: z.number().int().positive().describe("Post ID to publish"),
|
|
11
|
+
scheduled_at: z
|
|
12
|
+
.string()
|
|
13
|
+
.optional()
|
|
14
|
+
.describe("ISO 8601 datetime to schedule the post (omit to post immediately)"),
|
|
15
|
+
});
|
|
16
|
+
export const publishTools = [
|
|
17
|
+
{
|
|
18
|
+
name: "xreply_posts_publish",
|
|
19
|
+
description: "Publish or schedule a post. If scheduled_at is provided (ISO 8601), the post will be queued for that time. If omitted, the post is published immediately to X/Twitter. Requires X account to be connected.",
|
|
20
|
+
inputSchema: {
|
|
21
|
+
type: "object",
|
|
22
|
+
properties: {
|
|
23
|
+
id: { type: "integer", description: "Post ID" },
|
|
24
|
+
scheduled_at: {
|
|
25
|
+
type: "string",
|
|
26
|
+
description: "ISO 8601 datetime to schedule (omit to post now)",
|
|
27
|
+
},
|
|
28
|
+
},
|
|
29
|
+
required: ["id"],
|
|
30
|
+
},
|
|
31
|
+
async handler(args, client) {
|
|
32
|
+
try {
|
|
33
|
+
const { id, scheduled_at } = PublishSchema.parse(args);
|
|
34
|
+
const body = {};
|
|
35
|
+
if (scheduled_at !== undefined)
|
|
36
|
+
body.scheduled_at = scheduled_at;
|
|
37
|
+
const result = await client.post(`/api/v1/posts/${id}/publishes`, body);
|
|
38
|
+
return ok(result);
|
|
39
|
+
}
|
|
40
|
+
catch (e) {
|
|
41
|
+
return err(e);
|
|
42
|
+
}
|
|
43
|
+
},
|
|
44
|
+
},
|
|
45
|
+
];
|
|
46
|
+
//# sourceMappingURL=publish.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"publish.js","sourceRoot":"","sources":["../../src/tools/publish.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,SAAS,EAAE,CAAC,IAAa;IACvB,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,SAAS,GAAG,CAAC,KAAc;IACzB,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;AAED,MAAM,aAAa,GAAG,CAAC,CAAC,MAAM,CAAC;IAC7B,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,oBAAoB,CAAC;IAC9D,YAAY,EAAE,CAAC;SACZ,MAAM,EAAE;SACR,QAAQ,EAAE;SACV,QAAQ,CAAC,mEAAmE,CAAC;CACjF,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,YAAY,GAAqB;IAC5C;QACE,IAAI,EAAE,sBAAsB;QAC5B,WAAW,EACT,4MAA4M;QAC9M,WAAW,EAAE;YACX,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE;gBACV,EAAE,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,WAAW,EAAE,SAAS,EAAE;gBAC/C,YAAY,EAAE;oBACZ,IAAI,EAAE,QAAQ;oBACd,WAAW,EAAE,kDAAkD;iBAChE;aACF;YACD,QAAQ,EAAE,CAAC,IAAI,CAAC;SACjB;QACD,KAAK,CAAC,OAAO,CAAC,IAA6B,EAAE,MAAoB;YAC/D,IAAI,CAAC;gBACH,MAAM,EAAE,EAAE,EAAE,YAAY,EAAE,GAAG,aAAa,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;gBACvD,MAAM,IAAI,GAA4B,EAAE,CAAC;gBACzC,IAAI,YAAY,KAAK,SAAS;oBAAE,IAAI,CAAC,YAAY,GAAG,YAAY,CAAC;gBACjE,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,iBAAiB,EAAE,YAAY,EAAE,IAAI,CAAC,CAAC;gBACxE,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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"viral-library.d.ts","sourceRoot":"","sources":["../../src/tools/viral-library.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAc,MAAM,YAAY,CAAC;AAsB7D,eAAO,MAAM,iBAAiB,EAAE,cAAc,EAoC7C,CAAC"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
function ok(data) {
|
|
3
|
+
return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] };
|
|
4
|
+
}
|
|
5
|
+
function err(error) {
|
|
6
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
7
|
+
return { content: [{ type: "text", text: `Error: ${message}` }], isError: true };
|
|
8
|
+
}
|
|
9
|
+
const ViralLibrarySchema = z.object({
|
|
10
|
+
niche: z
|
|
11
|
+
.enum(["ai", "saas", "marketing", "productivity", "startups", "growth"])
|
|
12
|
+
.optional()
|
|
13
|
+
.describe("Filter by niche"),
|
|
14
|
+
sort: z
|
|
15
|
+
.enum(["top_engaged", "recent"])
|
|
16
|
+
.optional()
|
|
17
|
+
.describe("Sort order (default: top_engaged)"),
|
|
18
|
+
});
|
|
19
|
+
export const viralLibraryTools = [
|
|
20
|
+
{
|
|
21
|
+
name: "xreply_viral_library",
|
|
22
|
+
description: "Browse the viral tweet library — high-performing tweets (100+ likes) that can inspire post ideas. Filter by niche (ai/saas/marketing/productivity/startups/growth) and sort by engagement or recency. Requires Pro or BYOK subscription.",
|
|
23
|
+
inputSchema: {
|
|
24
|
+
type: "object",
|
|
25
|
+
properties: {
|
|
26
|
+
niche: {
|
|
27
|
+
type: "string",
|
|
28
|
+
enum: ["ai", "saas", "marketing", "productivity", "startups", "growth"],
|
|
29
|
+
description: "Filter by niche",
|
|
30
|
+
},
|
|
31
|
+
sort: {
|
|
32
|
+
type: "string",
|
|
33
|
+
enum: ["top_engaged", "recent"],
|
|
34
|
+
description: "Sort order (default: top_engaged)",
|
|
35
|
+
},
|
|
36
|
+
},
|
|
37
|
+
required: [],
|
|
38
|
+
},
|
|
39
|
+
async handler(args, client) {
|
|
40
|
+
try {
|
|
41
|
+
const params = ViralLibrarySchema.parse(args);
|
|
42
|
+
const query = new URLSearchParams();
|
|
43
|
+
if (params.niche)
|
|
44
|
+
query.set("niche", params.niche);
|
|
45
|
+
if (params.sort)
|
|
46
|
+
query.set("sort", params.sort);
|
|
47
|
+
const qs = query.toString();
|
|
48
|
+
const path = `/api/v1/viral_library${qs ? `?${qs}` : ""}`;
|
|
49
|
+
const result = await client.get(path);
|
|
50
|
+
return ok(result);
|
|
51
|
+
}
|
|
52
|
+
catch (e) {
|
|
53
|
+
return err(e);
|
|
54
|
+
}
|
|
55
|
+
},
|
|
56
|
+
},
|
|
57
|
+
];
|
|
58
|
+
//# sourceMappingURL=viral-library.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"viral-library.js","sourceRoot":"","sources":["../../src/tools/viral-library.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAKxB,SAAS,EAAE,CAAC,IAAa;IACvB,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,SAAS,GAAG,CAAC,KAAc;IACzB,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;AAED,MAAM,kBAAkB,GAAG,CAAC,CAAC,MAAM,CAAC;IAClC,KAAK,EAAE,CAAC;SACL,IAAI,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,cAAc,EAAE,UAAU,EAAE,QAAQ,CAAC,CAAC;SACvE,QAAQ,EAAE;SACV,QAAQ,CAAC,iBAAiB,CAAC;IAC9B,IAAI,EAAE,CAAC;SACJ,IAAI,CAAC,CAAC,aAAa,EAAE,QAAQ,CAAC,CAAC;SAC/B,QAAQ,EAAE;SACV,QAAQ,CAAC,mCAAmC,CAAC;CACjD,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,iBAAiB,GAAqB;IACjD;QACE,IAAI,EAAE,sBAAsB;QAC5B,WAAW,EACT,0OAA0O;QAC5O,WAAW,EAAE;YACX,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE;gBACV,KAAK,EAAE;oBACL,IAAI,EAAE,QAAQ;oBACd,IAAI,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,cAAc,EAAE,UAAU,EAAE,QAAQ,CAAC;oBACvE,WAAW,EAAE,iBAAiB;iBAC/B;gBACD,IAAI,EAAE;oBACJ,IAAI,EAAE,QAAQ;oBACd,IAAI,EAAE,CAAC,aAAa,EAAE,QAAQ,CAAC;oBAC/B,WAAW,EAAE,mCAAmC;iBACjD;aACF;YACD,QAAQ,EAAE,EAAE;SACb;QACD,KAAK,CAAC,OAAO,CAAC,IAA6B,EAAE,MAAoB;YAC/D,IAAI,CAAC;gBACH,MAAM,MAAM,GAAG,kBAAkB,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;gBAC9C,MAAM,KAAK,GAAG,IAAI,eAAe,EAAE,CAAC;gBACpC,IAAI,MAAM,CAAC,KAAK;oBAAE,KAAK,CAAC,GAAG,CAAC,OAAO,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC;gBACnD,IAAI,MAAM,CAAC,IAAI;oBAAE,KAAK,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC;gBAChD,MAAM,EAAE,GAAG,KAAK,CAAC,QAAQ,EAAE,CAAC;gBAC5B,MAAM,IAAI,GAAG,wBAAwB,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;gBAC1D,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,GAAG,CAAuB,IAAI,CAAC,CAAC;gBAC5D,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"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
export type AIProvider = "gemini" | "chatgpt" | "claude";
|
|
2
|
+
export type TonePreference = "auto" | "casual" | "professional" | "witty" | "empathetic";
|
|
3
|
+
export type StructurePreference = "one_liner" | "paragraph" | "question" | "list" | "story_arc";
|
|
4
|
+
export type VoiceProfileStatus = "not_configured" | "analyzing" | "ready" | "error";
|
|
5
|
+
export type PostStatus = "draft" | "scheduled" | "processing" | "posted" | "failed";
|
|
6
|
+
export type PostAngle = "one_liner" | "list" | "question" | "story_arc" | "paragraph" | "my_voice";
|
|
7
|
+
export type BatchCategory = "for_you" | "trending" | "viral";
|
|
8
|
+
export type ViralLibraryNiche = "ai" | "saas" | "marketing" | "productivity" | "startups" | "growth";
|
|
9
|
+
export type ViralLibrarySort = "top_engaged" | "recent";
|
|
10
|
+
export interface UserPreferences {
|
|
11
|
+
tone?: TonePreference;
|
|
12
|
+
include_emoji?: boolean | null;
|
|
13
|
+
structure?: StructurePreference;
|
|
14
|
+
}
|
|
15
|
+
export interface CustomRule {
|
|
16
|
+
id: number;
|
|
17
|
+
title: string;
|
|
18
|
+
content: string;
|
|
19
|
+
active: boolean;
|
|
20
|
+
created_at: string;
|
|
21
|
+
updated_at: string;
|
|
22
|
+
}
|
|
23
|
+
export interface CustomRulesResponse {
|
|
24
|
+
custom_rules: CustomRule[];
|
|
25
|
+
}
|
|
26
|
+
export interface Post {
|
|
27
|
+
id: number;
|
|
28
|
+
body: string;
|
|
29
|
+
status: PostStatus;
|
|
30
|
+
scheduled_at: string | null;
|
|
31
|
+
published_at: string | null;
|
|
32
|
+
created_at: string;
|
|
33
|
+
updated_at: string;
|
|
34
|
+
}
|
|
35
|
+
export interface PostsResponse {
|
|
36
|
+
posts: Post[];
|
|
37
|
+
}
|
|
38
|
+
export interface PostResponse {
|
|
39
|
+
post: Post;
|
|
40
|
+
}
|
|
41
|
+
export interface PostGenerateResponse {
|
|
42
|
+
body: string;
|
|
43
|
+
}
|
|
44
|
+
export interface PostBatchGenerateResponse {
|
|
45
|
+
posts: string[];
|
|
46
|
+
}
|
|
47
|
+
export interface ViralLibraryTweet {
|
|
48
|
+
tweet_id: string;
|
|
49
|
+
author_handle: string;
|
|
50
|
+
author_name: string;
|
|
51
|
+
tweet_text: string;
|
|
52
|
+
like_count: number;
|
|
53
|
+
retweet_count: number;
|
|
54
|
+
reply_count: number;
|
|
55
|
+
impression_count: number;
|
|
56
|
+
niche: string;
|
|
57
|
+
tweeted_at: string;
|
|
58
|
+
}
|
|
59
|
+
export interface ViralLibraryResponse {
|
|
60
|
+
tweets: ViralLibraryTweet[];
|
|
61
|
+
}
|
|
62
|
+
export interface VoiceProfile {
|
|
63
|
+
id: string;
|
|
64
|
+
ai_provider: string | null;
|
|
65
|
+
api_key_configured: boolean;
|
|
66
|
+
platform_managed: boolean;
|
|
67
|
+
api_key_preview?: string;
|
|
68
|
+
model_version?: string;
|
|
69
|
+
voice_preset_id?: string | null;
|
|
70
|
+
voice_preset_name?: string | null;
|
|
71
|
+
analyzed_at: string;
|
|
72
|
+
tweet_count: number;
|
|
73
|
+
writing_style: Record<string, unknown>;
|
|
74
|
+
}
|
|
75
|
+
export interface VoiceProfileResponse {
|
|
76
|
+
voice_profile: VoiceProfile;
|
|
77
|
+
summary?: string;
|
|
78
|
+
}
|
|
79
|
+
export interface APIError {
|
|
80
|
+
message: string;
|
|
81
|
+
code: string;
|
|
82
|
+
details?: unknown;
|
|
83
|
+
}
|
|
84
|
+
export type SubscriptionTier = "free" | "byok" | "pro";
|
|
85
|
+
export interface QuotaInfo {
|
|
86
|
+
tier: SubscriptionTier | null;
|
|
87
|
+
daily_limit?: number | null;
|
|
88
|
+
replies_used_today?: number;
|
|
89
|
+
replies_remaining_today?: number;
|
|
90
|
+
resets_at?: string;
|
|
91
|
+
message?: string;
|
|
92
|
+
requires_subscription?: boolean;
|
|
93
|
+
}
|
|
94
|
+
export interface Subscription {
|
|
95
|
+
id: number;
|
|
96
|
+
status: string;
|
|
97
|
+
current_period_start: string;
|
|
98
|
+
current_period_end: string;
|
|
99
|
+
cancel_at_period_end: boolean;
|
|
100
|
+
canceled_at?: string;
|
|
101
|
+
days_until_renewal: number;
|
|
102
|
+
}
|
|
103
|
+
export interface SubscriptionStatus {
|
|
104
|
+
subscription: Subscription | null;
|
|
105
|
+
tier: SubscriptionTier;
|
|
106
|
+
quota: QuotaInfo;
|
|
107
|
+
}
|
|
108
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
|
package/package.json
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@xreplyai/mcp",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "MCP server for XReply AI — voice-aware post generation, viral library, and post management",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"xreplyai-mcp": "./dist/index.js"
|
|
8
|
+
},
|
|
9
|
+
"main": "./dist/index.js",
|
|
10
|
+
"files": [
|
|
11
|
+
"dist"
|
|
12
|
+
],
|
|
13
|
+
"scripts": {
|
|
14
|
+
"build": "tsc",
|
|
15
|
+
"dev": "tsx src/index.ts",
|
|
16
|
+
"test": "node --experimental-vm-modules node_modules/.bin/jest",
|
|
17
|
+
"prepublishOnly": "npm run build"
|
|
18
|
+
},
|
|
19
|
+
"dependencies": {
|
|
20
|
+
"@modelcontextprotocol/sdk": "^1.0.0",
|
|
21
|
+
"zod": "^3.23.8"
|
|
22
|
+
},
|
|
23
|
+
"devDependencies": {
|
|
24
|
+
"@types/jest": "^29.5.12",
|
|
25
|
+
"@types/node": "^20.14.0",
|
|
26
|
+
"jest": "^29.7.0",
|
|
27
|
+
"ts-jest": "^29.1.4",
|
|
28
|
+
"tsx": "^4.15.6",
|
|
29
|
+
"typescript": "^5.4.5"
|
|
30
|
+
},
|
|
31
|
+
"jest": {
|
|
32
|
+
"preset": "ts-jest/presets/default-esm",
|
|
33
|
+
"testEnvironment": "node",
|
|
34
|
+
"extensionsToTreatAsEsm": [
|
|
35
|
+
".ts"
|
|
36
|
+
],
|
|
37
|
+
"moduleNameMapper": {
|
|
38
|
+
"^(\\.{1,2}/.*)\\.js$": "$1"
|
|
39
|
+
},
|
|
40
|
+
"transform": {
|
|
41
|
+
"^.+\\.tsx?$": [
|
|
42
|
+
"ts-jest",
|
|
43
|
+
{
|
|
44
|
+
"useESM": true,
|
|
45
|
+
"tsconfig": {
|
|
46
|
+
"module": "ESNext",
|
|
47
|
+
"moduleResolution": "bundler"
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
]
|
|
51
|
+
},
|
|
52
|
+
"transformIgnorePatterns": [
|
|
53
|
+
"/node_modules/(?!(@modelcontextprotocol|zod)/)"
|
|
54
|
+
]
|
|
55
|
+
},
|
|
56
|
+
"engines": {
|
|
57
|
+
"node": ">=20"
|
|
58
|
+
},
|
|
59
|
+
"keywords": [
|
|
60
|
+
"mcp",
|
|
61
|
+
"xreply",
|
|
62
|
+
"ai",
|
|
63
|
+
"twitter",
|
|
64
|
+
"x"
|
|
65
|
+
],
|
|
66
|
+
"license": "MIT"
|
|
67
|
+
}
|