@opentweet/mcp-server 1.0.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 +99 -0
- package/dist/api-client.d.ts +102 -0
- package/dist/api-client.d.ts.map +1 -0
- package/dist/api-client.js +125 -0
- package/dist/api-client.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +44 -0
- package/dist/index.js.map +1 -0
- package/dist/prompts/index.d.ts +3 -0
- package/dist/prompts/index.d.ts.map +1 -0
- package/dist/prompts/index.js +93 -0
- package/dist/prompts/index.js.map +1 -0
- package/dist/resources/index.d.ts +4 -0
- package/dist/resources/index.d.ts.map +1 -0
- package/dist/resources/index.js +55 -0
- package/dist/resources/index.js.map +1 -0
- package/dist/tools/account.d.ts +4 -0
- package/dist/tools/account.d.ts.map +1 -0
- package/dist/tools/account.js +38 -0
- package/dist/tools/account.js.map +1 -0
- package/dist/tools/analytics.d.ts +4 -0
- package/dist/tools/analytics.d.ts.map +1 -0
- package/dist/tools/analytics.js +100 -0
- package/dist/tools/analytics.js.map +1 -0
- package/dist/tools/media.d.ts +4 -0
- package/dist/tools/media.d.ts.map +1 -0
- package/dist/tools/media.js +47 -0
- package/dist/tools/media.js.map +1 -0
- package/dist/tools/posts.d.ts +4 -0
- package/dist/tools/posts.d.ts.map +1 -0
- package/dist/tools/posts.js +194 -0
- package/dist/tools/posts.js.map +1 -0
- package/dist/tools/scheduling.d.ts +4 -0
- package/dist/tools/scheduling.d.ts.map +1 -0
- package/dist/tools/scheduling.js +52 -0
- package/dist/tools/scheduling.js.map +1 -0
- package/dist/types.d.ts +104 -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 +52 -0
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
export function registerAnalyticsTools(server, client) {
|
|
3
|
+
server.tool('opentweet_get_analytics', 'Get your posting analytics including stats, streaks, trends, category breakdown, and recent activity. Use type parameter to get specific analytics.', {
|
|
4
|
+
type: z.enum(['overview', 'tweets', 'best_times', 'growth']).optional()
|
|
5
|
+
.describe('Type of analytics: "overview" (default, posting stats + streaks + trends), "tweets" (per-tweet engagement, requires Advanced plan), "best_times" (optimal posting hours/days), "growth" (follower growth predictions)'),
|
|
6
|
+
period: z.string().optional().describe('Time period for tweet analytics (e.g. "7d", "30d", "90d"). Only for type="tweets".'),
|
|
7
|
+
sort_by: z.string().optional().describe('Sort tweet analytics by metric (e.g. "impressions", "engagement_rate"). Only for type="tweets".'),
|
|
8
|
+
}, async ({ type = 'overview', period, sort_by }) => {
|
|
9
|
+
try {
|
|
10
|
+
if (type === 'overview') {
|
|
11
|
+
const data = await client.getAnalyticsOverview();
|
|
12
|
+
const { stats: s, streaks: st, trends: t, categories } = data;
|
|
13
|
+
let text = `📊 Posting Analytics Overview\n\n`;
|
|
14
|
+
text += `Stats:\n`;
|
|
15
|
+
text += ` Posts created: ${s.total_posts_created}\n`;
|
|
16
|
+
text += ` Posts published: ${s.total_posts_published}\n`;
|
|
17
|
+
text += ` Posts scheduled: ${s.total_posts_scheduled}\n`;
|
|
18
|
+
text += ` Publishing rate: ${s.publishing_rate}%\n`;
|
|
19
|
+
text += ` Active days: ${s.total_active_days}\n`;
|
|
20
|
+
text += ` Avg posts/week: ${s.avg_posts_per_week}\n`;
|
|
21
|
+
text += ` Most active day: ${s.most_active_day}\n`;
|
|
22
|
+
text += ` Most active hour: ${s.most_active_hour}:00\n`;
|
|
23
|
+
text += ` Threads created: ${s.total_threads_created}\n`;
|
|
24
|
+
text += ` Media posts: ${s.total_media_posts}\n\n`;
|
|
25
|
+
text += `Streaks:\n`;
|
|
26
|
+
text += ` Current streak: ${st.current} days\n`;
|
|
27
|
+
text += ` Longest streak: ${st.longest} days\n`;
|
|
28
|
+
text += ` Last posted: ${st.last_posted_date || 'Never'}\n\n`;
|
|
29
|
+
text += `Trends:\n`;
|
|
30
|
+
text += ` This week: ${t.this_week} posts (last week: ${t.last_week})\n`;
|
|
31
|
+
text += ` This month: ${t.this_month} posts (last month: ${t.last_month})\n`;
|
|
32
|
+
if (t.best_month)
|
|
33
|
+
text += ` Best month: ${t.best_month.month} (${t.best_month.count} posts)\n`;
|
|
34
|
+
text += `\nTop categories:\n`;
|
|
35
|
+
categories.slice(0, 5).forEach(c => {
|
|
36
|
+
text += ` ${c.name}: ${c.count} posts (${c.percentage}%)\n`;
|
|
37
|
+
});
|
|
38
|
+
text += `\nLast 7 days activity: [${data.recent_activity.last_7_days.join(', ')}]`;
|
|
39
|
+
return { content: [{ type: 'text', text }] };
|
|
40
|
+
}
|
|
41
|
+
if (type === 'tweets') {
|
|
42
|
+
const data = await client.getTweetAnalytics({ period, sort_by });
|
|
43
|
+
return {
|
|
44
|
+
content: [{
|
|
45
|
+
type: 'text',
|
|
46
|
+
text: `Tweet Engagement Analytics:\n\n${JSON.stringify(data, null, 2)}`,
|
|
47
|
+
}],
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
if (type === 'best_times') {
|
|
51
|
+
const data = await client.getBestTimes();
|
|
52
|
+
return {
|
|
53
|
+
content: [{
|
|
54
|
+
type: 'text',
|
|
55
|
+
text: `Best Posting Times:\n\n${JSON.stringify(data, null, 2)}`,
|
|
56
|
+
}],
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
if (type === 'growth') {
|
|
60
|
+
const data = await client.getGrowthSummary();
|
|
61
|
+
return {
|
|
62
|
+
content: [{
|
|
63
|
+
type: 'text',
|
|
64
|
+
text: `Growth Summary:\n\n${JSON.stringify(data, null, 2)}`,
|
|
65
|
+
}],
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
return {
|
|
69
|
+
content: [{ type: 'text', text: 'Unknown analytics type.' }],
|
|
70
|
+
isError: true,
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
catch (error) {
|
|
74
|
+
return {
|
|
75
|
+
content: [{ type: 'text', text: `Error: ${error.message}` }],
|
|
76
|
+
isError: true,
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
});
|
|
80
|
+
server.tool('opentweet_get_followers', 'Get follower growth data over time. Shows follower count snapshots and growth trends.', {
|
|
81
|
+
days: z.number().int().min(1).max(365).optional().describe('Number of days of history to retrieve (default 30, max 365)'),
|
|
82
|
+
}, async ({ days }) => {
|
|
83
|
+
try {
|
|
84
|
+
const data = await client.getFollowerGrowth({ days });
|
|
85
|
+
return {
|
|
86
|
+
content: [{
|
|
87
|
+
type: 'text',
|
|
88
|
+
text: `Follower Growth (${days || 30} days):\n\n${JSON.stringify(data, null, 2)}`,
|
|
89
|
+
}],
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
catch (error) {
|
|
93
|
+
return {
|
|
94
|
+
content: [{ type: 'text', text: `Error: ${error.message}` }],
|
|
95
|
+
isError: true,
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
//# sourceMappingURL=analytics.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"analytics.js","sourceRoot":"","sources":["../../src/tools/analytics.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"media.d.ts","sourceRoot":"","sources":["../../src/tools/media.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEpE,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAcnD,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,eAAe,QAuC5E"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { readFileSync } from 'fs';
|
|
3
|
+
import { basename, extname } from 'path';
|
|
4
|
+
const MIME_MAP = {
|
|
5
|
+
'.jpg': 'image/jpeg',
|
|
6
|
+
'.jpeg': 'image/jpeg',
|
|
7
|
+
'.png': 'image/png',
|
|
8
|
+
'.gif': 'image/gif',
|
|
9
|
+
'.webp': 'image/webp',
|
|
10
|
+
'.mp4': 'video/mp4',
|
|
11
|
+
'.mov': 'video/quicktime',
|
|
12
|
+
};
|
|
13
|
+
export function registerMediaTools(server, client) {
|
|
14
|
+
server.tool('opentweet_upload_media', 'Upload an image or video file to use in tweets. Returns a URL that can be passed to create_tweet or update_tweet in the media_urls field. Supported formats: JPG, PNG, GIF, WebP (max 5MB), MP4, MOV (max 20MB).', {
|
|
15
|
+
file_path: z.string().describe('Absolute path to the image or video file on disk'),
|
|
16
|
+
}, async ({ file_path }) => {
|
|
17
|
+
try {
|
|
18
|
+
const ext = extname(file_path).toLowerCase();
|
|
19
|
+
const mimeType = MIME_MAP[ext];
|
|
20
|
+
if (!mimeType) {
|
|
21
|
+
return {
|
|
22
|
+
content: [{
|
|
23
|
+
type: 'text',
|
|
24
|
+
text: `Error: Unsupported file type "${ext}". Supported: ${Object.keys(MIME_MAP).join(', ')}`,
|
|
25
|
+
}],
|
|
26
|
+
isError: true,
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
const buffer = readFileSync(file_path);
|
|
30
|
+
const fileName = basename(file_path);
|
|
31
|
+
const result = await client.uploadMedia(buffer, fileName, mimeType);
|
|
32
|
+
return {
|
|
33
|
+
content: [{
|
|
34
|
+
type: 'text',
|
|
35
|
+
text: `Media uploaded successfully.\n\nURL: ${result.url}\n\nUse this URL in the media_urls field when creating or updating a tweet.`,
|
|
36
|
+
}],
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
catch (error) {
|
|
40
|
+
return {
|
|
41
|
+
content: [{ type: 'text', text: `Error: ${error.message}` }],
|
|
42
|
+
isError: true,
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=media.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"media.js","sourceRoot":"","sources":["../../src/tools/media.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,YAAY,EAAE,MAAM,IAAI,CAAC;AAClC,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAEzC,MAAM,QAAQ,GAA2B;IACvC,MAAM,EAAE,YAAY;IACpB,OAAO,EAAE,YAAY;IACrB,MAAM,EAAE,WAAW;IACnB,MAAM,EAAE,WAAW;IACnB,OAAO,EAAE,YAAY;IACrB,MAAM,EAAE,WAAW;IACnB,MAAM,EAAE,iBAAiB;CAC1B,CAAC;AAEF,MAAM,UAAU,kBAAkB,CAAC,MAAiB,EAAE,MAAuB;IAC3E,MAAM,CAAC,IAAI,CACT,wBAAwB,EACxB,kNAAkN,EAClN;QACE,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,kDAAkD,CAAC;KACnF,EACD,KAAK,EAAE,EAAE,SAAS,EAAE,EAAE,EAAE;QACtB,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC,WAAW,EAAE,CAAC;YAC7C,MAAM,QAAQ,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC;YAC/B,IAAI,CAAC,QAAQ,EAAE,CAAC;gBACd,OAAO;oBACL,OAAO,EAAE,CAAC;4BACR,IAAI,EAAE,MAAe;4BACrB,IAAI,EAAE,iCAAiC,GAAG,iBAAiB,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;yBAC9F,CAAC;oBACF,OAAO,EAAE,IAAI;iBACd,CAAC;YACJ,CAAC;YAED,MAAM,MAAM,GAAG,YAAY,CAAC,SAAS,CAAC,CAAC;YACvC,MAAM,QAAQ,GAAG,QAAQ,CAAC,SAAS,CAAC,CAAC;YACrC,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,WAAW,CAAC,MAAM,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC;YAEpE,OAAO;gBACL,OAAO,EAAE,CAAC;wBACR,IAAI,EAAE,MAAe;wBACrB,IAAI,EAAE,wCAAwC,MAAM,CAAC,GAAG,6EAA6E;qBACtI,CAAC;aACH,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO;gBACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,UAAW,KAAe,CAAC,OAAO,EAAE,EAAE,CAAC;gBAChF,OAAO,EAAE,IAAI;aACd,CAAC;QACJ,CAAC;IACH,CAAC,CACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"posts.d.ts","sourceRoot":"","sources":["../../src/tools/posts.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEpE,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAEnD,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,eAAe,QA8N3E"}
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
export function registerPostTools(server, client) {
|
|
3
|
+
server.tool('opentweet_create_tweet', 'Create a tweet. Can save as draft, schedule for a specific time, or publish immediately to X.', {
|
|
4
|
+
text: z.string().max(280).describe('Tweet text content (max 280 characters)'),
|
|
5
|
+
category: z.string().optional().describe('Category/topic tag (e.g. "Tech", "Marketing"). Defaults to "General"'),
|
|
6
|
+
scheduled_date: z.string().optional().describe('ISO 8601 date-time to schedule the tweet (e.g. "2026-03-15T09:00:00Z"). Omit to save as draft.'),
|
|
7
|
+
publish_now: z.boolean().optional().describe('Set to true to publish immediately to X instead of saving as draft'),
|
|
8
|
+
media_urls: z.array(z.string()).optional().describe('Array of media URLs (upload first with opentweet_upload_media)'),
|
|
9
|
+
}, async ({ text, category, scheduled_date, publish_now, media_urls }) => {
|
|
10
|
+
try {
|
|
11
|
+
const result = await client.createPost({
|
|
12
|
+
text,
|
|
13
|
+
category,
|
|
14
|
+
scheduled_date,
|
|
15
|
+
publish_now,
|
|
16
|
+
media_urls,
|
|
17
|
+
});
|
|
18
|
+
const post = result.posts[0];
|
|
19
|
+
const status = publish_now
|
|
20
|
+
? `Published to X (x.com/i/status/${post.x_post_id})`
|
|
21
|
+
: scheduled_date
|
|
22
|
+
? `Scheduled for ${scheduled_date}`
|
|
23
|
+
: 'Saved as draft';
|
|
24
|
+
return {
|
|
25
|
+
content: [{
|
|
26
|
+
type: 'text',
|
|
27
|
+
text: `Tweet created successfully.\n\nStatus: ${status}\nID: ${post.id}\nText: ${post.text}\nCategory: ${post.category}`,
|
|
28
|
+
}],
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
catch (error) {
|
|
32
|
+
return {
|
|
33
|
+
content: [{ type: 'text', text: `Error: ${error.message}` }],
|
|
34
|
+
isError: true,
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
server.tool('opentweet_create_thread', 'Create a Twitter/X thread (multiple connected tweets posted as a chain).', {
|
|
39
|
+
tweets: z.array(z.string().max(280)).min(2).max(25).describe('Array of tweet texts in order (each max 280 chars, 2-25 tweets)'),
|
|
40
|
+
category: z.string().optional().describe('Category/topic tag'),
|
|
41
|
+
scheduled_date: z.string().optional().describe('ISO 8601 date-time to schedule. Omit to save as draft.'),
|
|
42
|
+
publish_now: z.boolean().optional().describe('Set to true to publish immediately'),
|
|
43
|
+
}, async ({ tweets, category, scheduled_date, publish_now }) => {
|
|
44
|
+
try {
|
|
45
|
+
const result = await client.createPost({
|
|
46
|
+
text: tweets[0],
|
|
47
|
+
is_thread: true,
|
|
48
|
+
thread_tweets: tweets.slice(1),
|
|
49
|
+
category,
|
|
50
|
+
scheduled_date,
|
|
51
|
+
publish_now,
|
|
52
|
+
});
|
|
53
|
+
const post = result.posts[0];
|
|
54
|
+
const status = publish_now
|
|
55
|
+
? 'Published to X'
|
|
56
|
+
: scheduled_date
|
|
57
|
+
? `Scheduled for ${scheduled_date}`
|
|
58
|
+
: 'Saved as draft';
|
|
59
|
+
return {
|
|
60
|
+
content: [{
|
|
61
|
+
type: 'text',
|
|
62
|
+
text: `Thread created (${tweets.length} tweets).\n\nStatus: ${status}\nID: ${post.id}\nFirst tweet: ${tweets[0]}`,
|
|
63
|
+
}],
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
catch (error) {
|
|
67
|
+
return {
|
|
68
|
+
content: [{ type: 'text', text: `Error: ${error.message}` }],
|
|
69
|
+
isError: true,
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
server.tool('opentweet_list_tweets', 'List your tweets with optional filtering by status. Returns paginated results.', {
|
|
74
|
+
status: z.enum(['scheduled', 'posted', 'draft', 'failed']).optional().describe('Filter by status: "scheduled" (upcoming), "posted" (published), "draft" (unscheduled), "failed" (errors)'),
|
|
75
|
+
page: z.number().int().min(1).optional().describe('Page number (default 1)'),
|
|
76
|
+
limit: z.number().int().min(1).max(100).optional().describe('Results per page (default 20, max 100)'),
|
|
77
|
+
}, async ({ status, page, limit }) => {
|
|
78
|
+
try {
|
|
79
|
+
const result = await client.listPosts({ status, page, limit });
|
|
80
|
+
if (result.posts.length === 0) {
|
|
81
|
+
return {
|
|
82
|
+
content: [{
|
|
83
|
+
type: 'text',
|
|
84
|
+
text: status
|
|
85
|
+
? `No ${status} tweets found.`
|
|
86
|
+
: 'No tweets found.',
|
|
87
|
+
}],
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
const lines = result.posts.map((p, i) => {
|
|
91
|
+
const num = ((result.pagination.page - 1) * result.pagination.limit) + i + 1;
|
|
92
|
+
const statusLabel = p.posted
|
|
93
|
+
? 'POSTED'
|
|
94
|
+
: p.failed
|
|
95
|
+
? 'FAILED'
|
|
96
|
+
: p.scheduled_date
|
|
97
|
+
? `SCHEDULED ${p.scheduled_date}`
|
|
98
|
+
: 'DRAFT';
|
|
99
|
+
const preview = p.text.length > 100 ? p.text.slice(0, 100) + '...' : p.text;
|
|
100
|
+
return `${num}. [${statusLabel}] (${p.id})\n ${preview}`;
|
|
101
|
+
});
|
|
102
|
+
const { pagination: pg } = result;
|
|
103
|
+
return {
|
|
104
|
+
content: [{
|
|
105
|
+
type: 'text',
|
|
106
|
+
text: `Tweets (page ${pg.page}/${pg.pages}, ${pg.total} total):\n\n${lines.join('\n\n')}`,
|
|
107
|
+
}],
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
catch (error) {
|
|
111
|
+
return {
|
|
112
|
+
content: [{ type: 'text', text: `Error: ${error.message}` }],
|
|
113
|
+
isError: true,
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
});
|
|
117
|
+
server.tool('opentweet_get_tweet', 'Get full details of a specific tweet by its ID.', {
|
|
118
|
+
id: z.string().describe('The tweet/post ID'),
|
|
119
|
+
}, async ({ id }) => {
|
|
120
|
+
try {
|
|
121
|
+
const post = await client.getPost(id);
|
|
122
|
+
const statusLabel = post.posted
|
|
123
|
+
? `Posted on ${post.posted_date}`
|
|
124
|
+
: post.failed
|
|
125
|
+
? `Failed: ${post.failed_reason}`
|
|
126
|
+
: post.scheduled_date
|
|
127
|
+
? `Scheduled for ${post.scheduled_date}`
|
|
128
|
+
: 'Draft';
|
|
129
|
+
let text = `Tweet Details:\n\nID: ${post.id}\nStatus: ${statusLabel}\nCategory: ${post.category}\nText: ${post.text}`;
|
|
130
|
+
if (post.is_thread && post.thread_tweets) {
|
|
131
|
+
text += `\n\nThread (${post.thread_tweets.length + 1} tweets):\n1. ${post.text}`;
|
|
132
|
+
post.thread_tweets.forEach((t, i) => {
|
|
133
|
+
text += `\n${i + 2}. ${t}`;
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
if (post.x_post_id)
|
|
137
|
+
text += `\nX Post ID: ${post.x_post_id}`;
|
|
138
|
+
if (post.media_urls?.length)
|
|
139
|
+
text += `\nMedia: ${post.media_urls.join(', ')}`;
|
|
140
|
+
return { content: [{ type: 'text', text }] };
|
|
141
|
+
}
|
|
142
|
+
catch (error) {
|
|
143
|
+
return {
|
|
144
|
+
content: [{ type: 'text', text: `Error: ${error.message}` }],
|
|
145
|
+
isError: true,
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
});
|
|
149
|
+
server.tool('opentweet_update_tweet', 'Update an existing tweet. Can change text, category, schedule, or media. Cannot edit already-posted tweets.', {
|
|
150
|
+
id: z.string().describe('The tweet/post ID to update'),
|
|
151
|
+
text: z.string().max(280).optional().describe('New tweet text'),
|
|
152
|
+
category: z.string().optional().describe('New category'),
|
|
153
|
+
scheduled_date: z.string().nullable().optional().describe('New schedule date (ISO 8601), or null to unschedule'),
|
|
154
|
+
media_urls: z.array(z.string()).optional().describe('New media URLs (replaces existing)'),
|
|
155
|
+
}, async ({ id, text, category, scheduled_date, media_urls }) => {
|
|
156
|
+
try {
|
|
157
|
+
const updated = await client.updatePost(id, {
|
|
158
|
+
text,
|
|
159
|
+
category,
|
|
160
|
+
scheduled_date,
|
|
161
|
+
media_urls,
|
|
162
|
+
});
|
|
163
|
+
return {
|
|
164
|
+
content: [{
|
|
165
|
+
type: 'text',
|
|
166
|
+
text: `Tweet updated.\n\nID: ${updated.id}\nText: ${updated.text}\nCategory: ${updated.category}\nScheduled: ${updated.scheduled_date || 'Not scheduled (draft)'}`,
|
|
167
|
+
}],
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
catch (error) {
|
|
171
|
+
return {
|
|
172
|
+
content: [{ type: 'text', text: `Error: ${error.message}` }],
|
|
173
|
+
isError: true,
|
|
174
|
+
};
|
|
175
|
+
}
|
|
176
|
+
});
|
|
177
|
+
server.tool('opentweet_delete_tweet', 'Permanently delete a tweet. This cannot be undone.', {
|
|
178
|
+
id: z.string().describe('The tweet/post ID to delete'),
|
|
179
|
+
}, async ({ id }) => {
|
|
180
|
+
try {
|
|
181
|
+
await client.deletePost(id);
|
|
182
|
+
return {
|
|
183
|
+
content: [{ type: 'text', text: `Tweet ${id} deleted successfully.` }],
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
catch (error) {
|
|
187
|
+
return {
|
|
188
|
+
content: [{ type: 'text', text: `Error: ${error.message}` }],
|
|
189
|
+
isError: true,
|
|
190
|
+
};
|
|
191
|
+
}
|
|
192
|
+
});
|
|
193
|
+
}
|
|
194
|
+
//# 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":"scheduling.d.ts","sourceRoot":"","sources":["../../src/tools/scheduling.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEpE,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAEnD,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,eAAe,QA6DjF"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
export function registerSchedulingTools(server, client) {
|
|
3
|
+
server.tool('opentweet_publish_tweet', 'Publish an existing draft or scheduled tweet immediately to X/Twitter. Requires an active subscription and X account connection.', {
|
|
4
|
+
id: z.string().describe('The tweet/post ID to publish now'),
|
|
5
|
+
}, async ({ id }) => {
|
|
6
|
+
try {
|
|
7
|
+
const result = await client.publishPost(id);
|
|
8
|
+
return {
|
|
9
|
+
content: [{
|
|
10
|
+
type: 'text',
|
|
11
|
+
text: `Tweet published to X!\n\nID: ${result.id}\nText: ${result.text}\nX Post ID: ${result.x_post_id}\nURL: https://x.com/i/status/${result.x_post_id}`,
|
|
12
|
+
}],
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
catch (error) {
|
|
16
|
+
return {
|
|
17
|
+
content: [{ type: 'text', text: `Error: ${error.message}` }],
|
|
18
|
+
isError: true,
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
});
|
|
22
|
+
server.tool('opentweet_batch_schedule', 'Schedule multiple tweets at once. Each tweet must already exist as a draft. Provide an array of post IDs with their scheduled dates.', {
|
|
23
|
+
schedules: z.array(z.object({
|
|
24
|
+
post_id: z.string().describe('The tweet/post ID'),
|
|
25
|
+
scheduled_date: z.string().describe('ISO 8601 date-time (e.g. "2026-03-15T09:00:00Z")'),
|
|
26
|
+
})).min(1).max(50).describe('Array of {post_id, scheduled_date} pairs (max 50)'),
|
|
27
|
+
community_id: z.string().optional().describe('Optional X Community ID to post to'),
|
|
28
|
+
share_with_followers: z.boolean().optional().describe('Share community posts with followers too'),
|
|
29
|
+
}, async ({ schedules, community_id, share_with_followers }) => {
|
|
30
|
+
try {
|
|
31
|
+
const result = await client.batchSchedule(schedules, community_id, share_with_followers);
|
|
32
|
+
let text = `${result.message}\n\nScheduled:`;
|
|
33
|
+
result.scheduled.forEach(p => {
|
|
34
|
+
text += `\n- ${p.id}: "${p.text.slice(0, 60)}${p.text.length > 60 ? '...' : ''}" → ${p.scheduled_date}`;
|
|
35
|
+
});
|
|
36
|
+
if (result.errors?.length) {
|
|
37
|
+
text += `\n\nErrors:`;
|
|
38
|
+
result.errors.forEach(e => {
|
|
39
|
+
text += `\n- ${e.post_id}: ${e.error}`;
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
return { content: [{ type: 'text', text }] };
|
|
43
|
+
}
|
|
44
|
+
catch (error) {
|
|
45
|
+
return {
|
|
46
|
+
content: [{ type: 'text', text: `Error: ${error.message}` }],
|
|
47
|
+
isError: true,
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=scheduling.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scheduling.js","sourceRoot":"","sources":["../../src/tools/scheduling.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
export interface OpenTweetConfig {
|
|
2
|
+
apiKey: string;
|
|
3
|
+
baseUrl: string;
|
|
4
|
+
}
|
|
5
|
+
export interface PaginatedResponse<T> {
|
|
6
|
+
posts: T[];
|
|
7
|
+
pagination: {
|
|
8
|
+
page: number;
|
|
9
|
+
limit: number;
|
|
10
|
+
total: number;
|
|
11
|
+
pages: number;
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
export interface Post {
|
|
15
|
+
id: string;
|
|
16
|
+
category: string;
|
|
17
|
+
text: string;
|
|
18
|
+
scheduled_date: string | null;
|
|
19
|
+
posted: boolean;
|
|
20
|
+
posted_date: string | null;
|
|
21
|
+
failed: boolean;
|
|
22
|
+
failed_reason?: string;
|
|
23
|
+
is_thread: boolean;
|
|
24
|
+
thread_tweets?: string[];
|
|
25
|
+
media_urls?: string[];
|
|
26
|
+
thread_media?: string[][];
|
|
27
|
+
community_id?: string;
|
|
28
|
+
share_with_followers?: boolean;
|
|
29
|
+
x_post_id?: string;
|
|
30
|
+
review_status?: string;
|
|
31
|
+
created_at: string;
|
|
32
|
+
updated_at?: string;
|
|
33
|
+
}
|
|
34
|
+
export interface AccountStatus {
|
|
35
|
+
authenticated: boolean;
|
|
36
|
+
subscription: {
|
|
37
|
+
has_access: boolean;
|
|
38
|
+
status: string;
|
|
39
|
+
is_trialing: boolean;
|
|
40
|
+
trial_ends_at: string | null;
|
|
41
|
+
current_period_ends_at: string | null;
|
|
42
|
+
};
|
|
43
|
+
limits: {
|
|
44
|
+
can_post: boolean;
|
|
45
|
+
posts_published_today: number;
|
|
46
|
+
remaining_posts_today: number;
|
|
47
|
+
daily_limit: number;
|
|
48
|
+
} | null;
|
|
49
|
+
stats: {
|
|
50
|
+
total_posts: number;
|
|
51
|
+
scheduled_posts: number;
|
|
52
|
+
posted_posts: number;
|
|
53
|
+
draft_posts: number;
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
export interface AnalyticsOverview {
|
|
57
|
+
stats: {
|
|
58
|
+
total_posts_created: number;
|
|
59
|
+
total_posts_published: number;
|
|
60
|
+
total_posts_scheduled: number;
|
|
61
|
+
publishing_rate: number;
|
|
62
|
+
total_active_days: number;
|
|
63
|
+
avg_posts_per_week: number;
|
|
64
|
+
most_active_day: string;
|
|
65
|
+
most_active_hour: number;
|
|
66
|
+
total_characters_written: number;
|
|
67
|
+
total_threads_created: number;
|
|
68
|
+
total_media_posts: number;
|
|
69
|
+
};
|
|
70
|
+
streaks: {
|
|
71
|
+
current: number;
|
|
72
|
+
longest: number;
|
|
73
|
+
last_posted_date: string | null;
|
|
74
|
+
streak_start_date: string | null;
|
|
75
|
+
};
|
|
76
|
+
trends: {
|
|
77
|
+
this_week: number;
|
|
78
|
+
last_week: number;
|
|
79
|
+
this_month: number;
|
|
80
|
+
last_month: number;
|
|
81
|
+
best_month: {
|
|
82
|
+
month: string;
|
|
83
|
+
count: number;
|
|
84
|
+
} | null;
|
|
85
|
+
};
|
|
86
|
+
categories: {
|
|
87
|
+
name: string;
|
|
88
|
+
count: number;
|
|
89
|
+
percentage: number;
|
|
90
|
+
}[];
|
|
91
|
+
recent_activity: {
|
|
92
|
+
last_7_days: number[];
|
|
93
|
+
last_30_days: number[];
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
export interface UploadResponse {
|
|
97
|
+
url: string;
|
|
98
|
+
}
|
|
99
|
+
export interface ApiError {
|
|
100
|
+
error: string;
|
|
101
|
+
details?: string | string[];
|
|
102
|
+
remaining?: number;
|
|
103
|
+
}
|
|
104
|
+
//# 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,52 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@opentweet/mcp-server",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "OpenTweet MCP Server - Manage your Twitter/X presence from any AI assistant",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"bin": {
|
|
8
|
+
"opentweet-mcp": "dist/index.js"
|
|
9
|
+
},
|
|
10
|
+
"scripts": {
|
|
11
|
+
"build": "tsc",
|
|
12
|
+
"dev": "tsc --watch",
|
|
13
|
+
"start": "node dist/index.js",
|
|
14
|
+
"prepublishOnly": "npm run build"
|
|
15
|
+
},
|
|
16
|
+
"keywords": [
|
|
17
|
+
"mcp",
|
|
18
|
+
"mcp-server",
|
|
19
|
+
"model-context-protocol",
|
|
20
|
+
"opentweet",
|
|
21
|
+
"twitter",
|
|
22
|
+
"x",
|
|
23
|
+
"tweet",
|
|
24
|
+
"scheduling",
|
|
25
|
+
"ai",
|
|
26
|
+
"claude",
|
|
27
|
+
"automation"
|
|
28
|
+
],
|
|
29
|
+
"author": "OpenTweet <hello@opentweet.io>",
|
|
30
|
+
"license": "MIT",
|
|
31
|
+
"repository": {
|
|
32
|
+
"type": "git",
|
|
33
|
+
"url": "https://github.com/opentweetio/mcp-server"
|
|
34
|
+
},
|
|
35
|
+
"homepage": "https://opentweet.io/mcp",
|
|
36
|
+
"dependencies": {
|
|
37
|
+
"@modelcontextprotocol/sdk": "^1.12.0",
|
|
38
|
+
"zod": "^3.24.0"
|
|
39
|
+
},
|
|
40
|
+
"devDependencies": {
|
|
41
|
+
"typescript": "^5.7.0",
|
|
42
|
+
"@types/node": "^22.0.0"
|
|
43
|
+
},
|
|
44
|
+
"engines": {
|
|
45
|
+
"node": ">=18.0.0"
|
|
46
|
+
},
|
|
47
|
+
"files": [
|
|
48
|
+
"dist",
|
|
49
|
+
"README.md",
|
|
50
|
+
"LICENSE"
|
|
51
|
+
]
|
|
52
|
+
}
|