x-relay-mcp 1.0.0 → 1.2.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/.claude/skills/x-relay/SKILL.md +27 -1
- package/dist/{cli-DZkaLoUg.d.ts → cli-B4ohNfa7.d.ts} +65 -1
- package/dist/cli.d.ts +1 -1
- package/dist/cli.js +674 -21
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +32 -3
- package/dist/index.js +686 -21
- package/dist/index.js.map +1 -1
- package/dist/mcp-shim.js +724 -20
- package/dist/mcp-shim.js.map +1 -1
- package/package.json +1 -1
|
@@ -100,7 +100,33 @@ xrelay sync bookmarks|posts|all [--handle <you>] [--repair] [--max N]
|
|
|
100
100
|
```
|
|
101
101
|
- Pulls ONLY tweets newer than the last sync (snowflake-id watermark + newest-first early-break) — never a
|
|
102
102
|
full refetch. `--repair` refetches everything and patches records; `--max N` caps a run (good for a first
|
|
103
|
-
sync). `posts`
|
|
103
|
+
sync). `posts` auto-detects your handle from the session (override/remember with `--handle`). Returns
|
|
104
|
+
`{ source, added, total, watermark }`.
|
|
105
|
+
|
|
106
|
+
### More endpoints
|
|
107
|
+
|
|
108
|
+
```
|
|
109
|
+
xrelay list <list-id> [--limit N] # tweets from a Twitter List (curated sources)
|
|
110
|
+
xrelay user-media <handle> [--limit N] # a user's images/videos only (visual evidence)
|
|
111
|
+
xrelay followers <handle> [--limit N] # a user's followers (network mapping)
|
|
112
|
+
xrelay following <handle> [--limit N] # who a user follows
|
|
113
|
+
xrelay retweeters <id|url> [--limit N] # who retweeted a tweet (amplification graph)
|
|
114
|
+
xrelay likers <id|url> [--limit N] # who liked a tweet (engagement graph)
|
|
115
|
+
xrelay quoters <id|url> [--limit N] # tweets quoting a tweet (reactions; recency-windowed)
|
|
116
|
+
xrelay trends [--woeid N] [--limit N] # what's hot now (woeid 1 = worldwide, default)
|
|
117
|
+
xrelay article <id|url> # a long-form X Article → Markdown
|
|
118
|
+
xrelay media <id|url> [--out <dir>] # a tweet's image/video URLs; --out downloads the files
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
- **`retweeters`/`followers`/`following`** return `{ users:[<profile>...], nextCursor }` — the
|
|
122
|
+
amplification/audience graph. Use them to answer "who is paying attention to / amplifying X".
|
|
123
|
+
- **`likers`** also returns `{ users }`, but X made likes private in 2024, so it's usually **empty** for
|
|
124
|
+
tweets you don't own (only the like *count* is public — read that from the tweet's `metrics.likes`).
|
|
125
|
+
- **`quoters`** is search-based (`quoted_tweet_id:`), so it's recency-windowed, not the full historical set.
|
|
126
|
+
- **`trends`** is a cheap zoomed-out entry point before drilling into `search`.
|
|
127
|
+
- **`article`** returns `{ id, title, markdown, url }` — the full long-form read for a finalist.
|
|
128
|
+
- **`media`** returns `{ tweetId, media:[{type,url,...}], files? }`; `--out <dir>` saves the actual
|
|
129
|
+
image/video files (for OCR / transcription / multimodal analysis).
|
|
104
130
|
|
|
105
131
|
---
|
|
106
132
|
|
|
@@ -84,6 +84,37 @@ type ThreadResult = {
|
|
|
84
84
|
nextCursor?: string;
|
|
85
85
|
};
|
|
86
86
|
type SearchProduct$1 = 'Top' | 'Latest' | 'Media' | 'People';
|
|
87
|
+
/** A paginated set of users (followers / following / retweeters / likers). */
|
|
88
|
+
type UserPage = {
|
|
89
|
+
users: UserProfile[];
|
|
90
|
+
nextCursor?: string;
|
|
91
|
+
};
|
|
92
|
+
/** A trending topic. */
|
|
93
|
+
type Trend = {
|
|
94
|
+
name: string;
|
|
95
|
+
rank?: number;
|
|
96
|
+
/** Volume blurb as X reports it, e.g. "42.1K posts". */
|
|
97
|
+
volume?: string;
|
|
98
|
+
url?: string;
|
|
99
|
+
};
|
|
100
|
+
/** A downloadable media asset attached to a tweet. */
|
|
101
|
+
type MediaItem = {
|
|
102
|
+
type: MediaKind;
|
|
103
|
+
url: string;
|
|
104
|
+
thumbnail?: string;
|
|
105
|
+
width?: number;
|
|
106
|
+
height?: number;
|
|
107
|
+
durationMs?: number;
|
|
108
|
+
bitrate?: number;
|
|
109
|
+
};
|
|
110
|
+
/** A long-form X Article rendered to Markdown. */
|
|
111
|
+
type Article = {
|
|
112
|
+
id: string;
|
|
113
|
+
title: string;
|
|
114
|
+
markdown: string;
|
|
115
|
+
url: string;
|
|
116
|
+
author?: Author;
|
|
117
|
+
};
|
|
87
118
|
|
|
88
119
|
/** The two load-bearing cookies, plus any others the jar carries. */
|
|
89
120
|
type Cookies = {
|
|
@@ -150,6 +181,22 @@ declare const OPS: {
|
|
|
150
181
|
readonly queryId: "7UuJsFvnWuZo0HmxrzU42Q";
|
|
151
182
|
readonly operationName: "ListLatestTweetsTimeline";
|
|
152
183
|
};
|
|
184
|
+
readonly Retweeters: {
|
|
185
|
+
readonly queryId: "TZsWuSj7vGmncVnq7KWDUQ";
|
|
186
|
+
readonly operationName: "Retweeters";
|
|
187
|
+
};
|
|
188
|
+
readonly Favoriters: {
|
|
189
|
+
readonly queryId: "LLkw5EcVutJL6y-2gkz22A";
|
|
190
|
+
readonly operationName: "Favoriters";
|
|
191
|
+
};
|
|
192
|
+
readonly GenericTimelineById: {
|
|
193
|
+
readonly queryId: "_dGVIf1cY6xFanFNPsAzPQ";
|
|
194
|
+
readonly operationName: "GenericTimelineById";
|
|
195
|
+
};
|
|
196
|
+
readonly TweetResultByRestId: {
|
|
197
|
+
readonly queryId: "Xl5pC_lBk_gcO2ItU39DQw";
|
|
198
|
+
readonly operationName: "TweetResultByRestId";
|
|
199
|
+
};
|
|
153
200
|
};
|
|
154
201
|
type OpName = keyof typeof OPS;
|
|
155
202
|
type Vars = Record<string, unknown>;
|
|
@@ -204,13 +251,30 @@ interface Engine {
|
|
|
204
251
|
search(query: string, opts?: SearchOpts): Promise<SearchResult>;
|
|
205
252
|
user(handle: string): Promise<UserProfile | null>;
|
|
206
253
|
userTweets(handle: string, opts?: UserTweetsOpts): Promise<TweetPage>;
|
|
254
|
+
userMedia(handle: string, opts?: PageOpts): Promise<TweetPage>;
|
|
207
255
|
bookmarks(opts?: PageOpts): Promise<TweetPage>;
|
|
208
256
|
thread(id: string): Promise<ThreadResult>;
|
|
257
|
+
list(listId: string, opts?: PageOpts): Promise<TweetPage>;
|
|
258
|
+
followers(handle: string, opts?: PageOpts): Promise<UserPage>;
|
|
259
|
+
following(handle: string, opts?: PageOpts): Promise<UserPage>;
|
|
260
|
+
retweeters(tweetId: string, opts?: PageOpts): Promise<UserPage>;
|
|
261
|
+
likers(tweetId: string, opts?: PageOpts): Promise<UserPage>;
|
|
262
|
+
quoters(tweetId: string, opts?: SearchOpts): Promise<SearchResult>;
|
|
263
|
+
trends(opts?: {
|
|
264
|
+
woeid?: number;
|
|
265
|
+
limit?: number;
|
|
266
|
+
}): Promise<Trend[]>;
|
|
267
|
+
article(tweetId: string): Promise<Article | null>;
|
|
268
|
+
media(tweetId: string): Promise<MediaItem[]>;
|
|
269
|
+
/** The authenticated user's own @handle (from the session), or null. Memoized. */
|
|
270
|
+
me(): Promise<string | null>;
|
|
209
271
|
}
|
|
210
272
|
interface EngineDeps {
|
|
211
273
|
/** Cookies for auth. Omit to auto-extract from the local browser (getCookies). */
|
|
212
274
|
cookies?: Cookies;
|
|
213
275
|
fetchImpl?: typeof fetch;
|
|
276
|
+
/** Backoff between cold-start retries. Injectable (tests pass a no-op). */
|
|
277
|
+
sleep?: (ms: number) => Promise<void>;
|
|
214
278
|
/** Injectable transport (tests). Defaults to a real client over the X API. */
|
|
215
279
|
client?: EngineClient;
|
|
216
280
|
/** Injectable transaction provider (tests). Defaults to the xctid generator. */
|
|
@@ -229,4 +293,4 @@ declare function parseArgs(argv: string[]): ParsedArgs;
|
|
|
229
293
|
declare function dispatch(parsed: ParsedArgs, engine: Engine): Promise<Envelope<unknown>>;
|
|
230
294
|
declare function run(argv: string[], engine?: Engine): Promise<number>;
|
|
231
295
|
|
|
232
|
-
export { type
|
|
296
|
+
export { type Article as A, type Cookies as C, type Err as E, type MediaItem as M, type Ok as O, type PageOpts as P, type SearchResult as S, type Tweet as T, type UserPage as U, type Engine as a, type Envelope as b, type TweetPage as c, type SearchProduct as d, type ThreadResult as e, type Trend as f, type UserProfile as g, type Author as h, type EngineDeps as i, EngineError as j, type MediaKind as k, type Metrics as l, type SearchOpts as m, type SearchProduct$1 as n, type UserTweetsOpts as o, createEngine as p, dispatch as q, parseArgs as r, parseCookies as s, run as t, type ParsedArgs as u };
|
package/dist/cli.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
export {
|
|
2
|
+
export { u as ParsedArgs, q as dispatch, r as parseArgs, t as run } from './cli-B4ohNfa7.js';
|