spectre-mcp 1.1.0__tar.gz

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.

Potentially problematic release.


This version of spectre-mcp might be problematic. Click here for more details.

@@ -0,0 +1,30 @@
1
+ # Python
2
+ __pycache__/
3
+ *.py[cod]
4
+ *.egg-info/
5
+ dist/
6
+ build/
7
+ *.egg
8
+
9
+ # Virtual env
10
+ .venv/
11
+ venv/
12
+
13
+ # Data files (user-specific)
14
+ *.db
15
+ accounts.db
16
+ spectre.db
17
+
18
+ # IDE
19
+ .idea/
20
+ .vscode/
21
+ *.swp
22
+ *.swo
23
+
24
+ # OS
25
+ .DS_Store
26
+ Thumbs.db
27
+
28
+ # Env
29
+ .env
30
+ .env.local
@@ -0,0 +1 @@
1
+ 3.11
@@ -0,0 +1,395 @@
1
+ Metadata-Version: 2.4
2
+ Name: spectre-mcp
3
+ Version: 1.1.0
4
+ Summary: X/Twitter automation for AI agents — 83 MCP tools. Search, post, media upload, DMs, scheduled tweets, drafts, bookmark folders, lists, communities, topics, community notes, account settings, profile management. No paid API keys.
5
+ Author: Pranjal Richhariya
6
+ License-Expression: MIT
7
+ Keywords: agent,ai-agent,automation,mcp,scraper,social-media,twitter,x
8
+ Classifier: Development Status :: 3 - Alpha
9
+ Classifier: Intended Audience :: Developers
10
+ Classifier: License :: OSI Approved :: MIT License
11
+ Classifier: Programming Language :: Python :: 3
12
+ Classifier: Topic :: Software Development :: Libraries
13
+ Requires-Python: >=3.11
14
+ Requires-Dist: curl-cffi>=0.15.0
15
+ Requires-Dist: fastmcp>=3.4.2
16
+ Requires-Dist: loguru>=0.7.3
17
+ Requires-Dist: pydantic>=2.13.4
18
+ Requires-Dist: twscrape>=0.19.0
19
+ Description-Content-Type: text/markdown
20
+
21
+ <div align="center">
22
+
23
+ # Spectre MCP
24
+
25
+ **The fastest X/Twitter automation for AI agents.**
26
+
27
+ 83 tools · Direct API calls · Cookie auth · No browser needed · Account pool with auto-rotation
28
+
29
+ [![Python 3.11+](https://img.shields.io/badge/python-3.11+-3776AB?style=flat-square&logo=python&logoColor=white)](https://python.org)
30
+ [![License: MIT](https://img.shields.io/badge/license-MIT-green?style=flat-square)](LICENSE)
31
+ [![MCP Compatible](https://img.shields.io/badge/MCP-compatible-8B5CF6?style=flat-square)](https://modelcontextprotocol.io)
32
+
33
+ [Quick Start](#-quick-start) · [Why Spectre?](#-why-spectre) · [All 83 Tools](#all-83-tools) · [Safety Guide](#%EF%B8%8F-safety-guide-for-ai-agents) · [Comparison](#-how-spectre-compares)
34
+
35
+ </div>
36
+
37
+ ---
38
+
39
+ ## Why Spectre?
40
+
41
+ > Spectre makes **direct HTTP calls** to X's internal GraphQL and REST APIs. No browser, no Puppeteer, no DOM scraping. It's the fastest and lightest way for AI agents to automate X/Twitter.
42
+
43
+ | | **Spectre** | **XActions** | **twikit** |
44
+ |--|:-:|:-:|:-:|
45
+ | **Architecture** | Direct GraphQL/REST API | Puppeteer (headless browser) | Python API wrapper |
46
+ | **Speed** | <1s per request | 3-10s (browser startup + page load) | ~1s per request |
47
+ | **Resource usage** | ~10MB (just HTTP client) | ~200MB+ (Chromium process) | ~10MB |
48
+ | **MCP Server** | ✅ 83 real API tools | ⚠️ ~50 API tools + 40 AI wrappers | ❌ None |
49
+ | **Account Pool** | ✅ Multi-account auto-rotation | ❌ Single auth_token | ❌ Single session |
50
+ | **Browser Required** | ❌ Never | ✅ Always | ❌ Never |
51
+ | **DOM Breakage Risk** | ❌ None (no DOM) | ⚠️ Breaks when X changes UI | ❌ None |
52
+ | **Community Notes** | ✅ Create, read, rate | ❌ | ❌ |
53
+ | **Bookmark Folders** | ✅ Full CRUD + timeline | ❌ Basic only | ❌ |
54
+ | **Draft Tweets** | ✅ Create, list, delete | ❌ | ❌ |
55
+ | **Scheduled Tweets** | ✅ Create, list, delete | ⚠️ Basic | ❌ |
56
+ | **DM Search** | ✅ Search by text | ❌ | ❌ |
57
+ | **Profile Highlights** | ✅ Create, delete, get | ❌ | ❌ |
58
+ | **Pin/Unpin Tweet** | ✅ | ❌ | ❌ |
59
+ | **Profile Image Upload** | ✅ Direct file upload | ⚠️ Basic update | ❌ |
60
+ | **Destructive Tool Warnings** | ✅ Every tool marked ⚠️ | ❌ Generic disclaimer | ❌ |
61
+ | **Language** | Python | JavaScript | Python |
62
+ | **Install** | `uvx spectre-mcp` | `npm install xactions` | `pip install twikit` |
63
+
64
+ **Spectre is the only MCP server that makes direct API calls with multi-account rotation.** No browser overhead, no DOM fragility, no wasted resources.
65
+
66
+ ---
67
+
68
+ ## Quick Start
69
+
70
+ ### 1. Install (10 seconds)
71
+
72
+ ```bash
73
+ uvx spectre-mcp
74
+ ```
75
+
76
+ ### 2. Add Your Account
77
+
78
+ ```bash
79
+ spectre add myaccount "auth_token=xxx; ct0=yyy"
80
+ ```
81
+
82
+ > Get cookies: x.com → DevTools (F12) → Application → Cookies → copy `auth_token` and `ct0`
83
+
84
+ ### 3. Configure Your MCP Client
85
+
86
+ **Hermes Agent** (`~/.hermes/config.yaml`):
87
+ ```yaml
88
+ mcp_servers:
89
+ spectre:
90
+ command: "uvx"
91
+ args: ["spectre-mcp"]
92
+ timeout: 120
93
+ ```
94
+
95
+ **Claude Desktop / Cursor** (`.json`):
96
+ ```json
97
+ {
98
+ "mcpServers": {
99
+ "spectre": {
100
+ "command": "uvx",
101
+ "args": ["spectre-mcp"]
102
+ }
103
+ }
104
+ }
105
+ ```
106
+
107
+ ### Example Prompts
108
+
109
+ > **"Search for tweets about AI startups from the last week"**
110
+ > → Calls `search("AI startups since:2026-06-15", mode="latest")`
111
+
112
+ > **"Find everyone I follow who doesn't follow me back"**
113
+ > → Calls `get_following` + `get_followers` → computes diff
114
+
115
+ > **"Post a tweet with an image, then pin it to my profile"**
116
+ > → Calls `upload_media` → `post_tweet(media_ids=...)` → `pin_tweet`
117
+
118
+ > **"Update my bio to 'Building in public' and change my avatar"**
119
+ > → Calls `update_profile(bio="Building in public")` + `update_profile_image(path)`
120
+
121
+ > **"Search my DMs for 'meeting' and send a follow-up"**
122
+ > → Calls `search_dm("meeting")` → `send_dm(user_id, "Following up on...")`
123
+
124
+ ---
125
+
126
+ ## All 83 Tools
127
+
128
+ ### Account Pool (5)
129
+
130
+ | Tool | Description |
131
+ |------|-------------|
132
+ | `list_accounts()` | List all accounts with status |
133
+ | `set_active_account(username)` | Set primary account |
134
+ | `set_auto_rotate(enabled)` | Enable/disable auto-rotation on rate limits |
135
+ | `remove_account(username)` | Remove account from pool |
136
+ | `pool_status()` | Pool health stats |
137
+
138
+ ### Search (2)
139
+
140
+ | Tool | Description |
141
+ |------|-------------|
142
+ | `search(query, limit, mode)` | Search tweets. Supports `from:username`, `since:2026-01-01`, `#hashtag`, `filter:media` |
143
+ | `search_users(query, limit)` | Search users by name/keyword |
144
+
145
+ ### Users (5)
146
+
147
+ | Tool | Description |
148
+ |------|-------------|
149
+ | `get_user(username)` | User profile by @handle |
150
+ | `get_user_tweets(username, limit)` | User's recent tweets |
151
+ | `get_user_media(username, limit)` | User's photos/videos/GIFs |
152
+ | `get_followers(username, limit)` | User's followers |
153
+ | `get_following(username, limit)` | Who a user follows |
154
+
155
+ ### Tweets (4)
156
+
157
+ | Tool | Description |
158
+ |------|-------------|
159
+ | `get_tweet(tweet_id)` | Single tweet by ID |
160
+ | `get_tweet_replies(tweet_id, limit)` | Replies to a tweet |
161
+ | `get_thread(tweet_id, limit)` | Full conversation thread |
162
+ | `get_retweeters(tweet_id, limit)` | Users who retweeted |
163
+
164
+ ### Timeline & Discovery (3)
165
+
166
+ | Tool | Description |
167
+ |------|-------------|
168
+ | `get_trends(category, limit)` | Trending topics |
169
+ | `get_home_timeline(limit)` | Home feed |
170
+ | `get_bookmarks(limit)` | Your bookmarked tweets |
171
+
172
+ ### Post & Media (3)
173
+
174
+ | Tool | Description |
175
+ |------|-------------|
176
+ | `post_tweet(text, reply_to?, quote_tweet?, media_ids?)` | Post a tweet with optional media |
177
+ | `upload_media(file_path)` | Upload image or video (jpg, png, gif, mp4, mov) |
178
+ | `delete_tweet(tweet_id)` | ⚠️ Delete a tweet |
179
+
180
+ ### Engagement (6)
181
+
182
+ | Tool | Description |
183
+ |------|-------------|
184
+ | `like_tweet(tweet_id)` / `unlike_tweet(tweet_id)` | Like/unlike |
185
+ | `retweet(tweet_id)` / `unretweet(tweet_id)` | Retweet/undo |
186
+ | `bookmark_tweet(tweet_id)` / `unbookmark_tweet(tweet_id)` | Bookmark/undo |
187
+
188
+ ### Social (6)
189
+
190
+ | Tool | Description |
191
+ |------|-------------|
192
+ | `follow_user(user_id)` / `unfollow_user(user_id)` | ⚠️ Follow/unfollow |
193
+ | `mute_user(user_id)` / `unmute_user(user_id)` | Mute/unmute |
194
+ | `block_user(user_id)` / `unblock_user(user_id)` | ⚠️ Block/unblock |
195
+
196
+ ### DMs (6)
197
+
198
+ | Tool | Description |
199
+ |------|-------------|
200
+ | `send_dm(user_id, text)` | ⚠️ Send a direct message |
201
+ | `get_dm_inbox(limit)` | List DM conversations |
202
+ | `get_dm_conversation(conversation_id, limit)` | Read messages in a conversation |
203
+ | `search_dm(query, limit)` | Search DMs by text |
204
+ | `dm_block_user(user_id)` / `dm_unblock_user(user_id)` | Block/unblock in DMs |
205
+
206
+ ### Scheduled Tweets (3)
207
+
208
+ | Tool | Description |
209
+ |------|-------------|
210
+ | `schedule_tweet(text, execute_at, reply_to?)` | Schedule a tweet for future posting |
211
+ | `get_scheduled_tweets()` | List all scheduled tweets |
212
+ | `delete_scheduled_tweet(tweet_id)` | ⚠️ Delete a scheduled tweet |
213
+
214
+ ### Draft Tweets (3)
215
+
216
+ | Tool | Description |
217
+ |------|-------------|
218
+ | `create_draft(text)` | Save a tweet draft |
219
+ | `get_drafts()` | List all drafts |
220
+ | `delete_draft(tweet_id)` | ⚠️ Delete a draft |
221
+
222
+ ### Bookmark Folders (7)
223
+
224
+ | Tool | Description |
225
+ |------|-------------|
226
+ | `get_bookmark_folders()` | List all bookmark folders |
227
+ | `create_bookmark_folder(name)` | Create a folder |
228
+ | `delete_bookmark_folder(folder_id)` | ⚠️ Delete a folder |
229
+ | `edit_bookmark_folder(folder_id, name)` | Rename a folder |
230
+ | `add_tweet_to_folder(folder_id, tweet_id)` | Add tweet to folder |
231
+ | `remove_tweet_from_folder(folder_id, tweet_id)` | Remove tweet from folder |
232
+ | `get_bookmark_folder_timeline(folder_id, limit)` | Get tweets in a folder |
233
+
234
+ ### Lists (7)
235
+
236
+ | Tool | Description |
237
+ |------|-------------|
238
+ | `get_list_timeline(list_id, limit)` | Tweets from a list |
239
+ | `get_list_members(list_id, limit)` | Members of a list |
240
+ | `create_list(name, description)` | Create a new list |
241
+ | `update_list(list_id, name, description)` | Update list details |
242
+ | `delete_list(list_id)` | ⚠️ Delete a list |
243
+ | `add_list_member(list_id, user_id)` | Add user to list |
244
+ | `remove_list_member(list_id, user_id)` | Remove user from list |
245
+
246
+ ### Communities (4)
247
+
248
+ | Tool | Description |
249
+ |------|-------------|
250
+ | `get_community_tweets(community_id, limit)` | Community feed |
251
+ | `get_community_info(community_id)` | Community details |
252
+ | `join_community(community_id)` | Join a community |
253
+ | `leave_community(community_id)` | ⚠️ Leave a community |
254
+
255
+ ### Topics (2)
256
+
257
+ | Tool | Description |
258
+ |------|-------------|
259
+ | `follow_topic(topic_id)` | Follow a topic |
260
+ | `unfollow_topic(topic_id)` | Unfollow a topic |
261
+
262
+ ### Community Notes (3)
263
+
264
+ | Tool | Description |
265
+ |------|-------------|
266
+ | `create_community_note(tweet_id, text)` | Create a note on a tweet |
267
+ | `get_community_notes(tweet_id)` | Get notes on a tweet |
268
+ | `rate_community_note(note_id, rating)` | Rate a note as helpful/not helpful |
269
+
270
+ ### Account Settings (5)
271
+
272
+ | Tool | Description |
273
+ |------|-------------|
274
+ | `get_account_settings()` | View account settings (language, timezone, etc.) |
275
+ | `update_profile(name?, bio?, location?, website?)` | ⚠️ Update profile info |
276
+ | `update_profile_image(file_path)` | ⚠️ Change avatar image |
277
+ | `update_profile_banner(file_path)` | ⚠️ Change banner image |
278
+ | `delete_profile_banner()` | ⚠️ Remove banner |
279
+
280
+ ### Pin & Highlights (5)
281
+
282
+ | Tool | Description |
283
+ |------|-------------|
284
+ | `pin_tweet(tweet_id)` | ⚠️ Pin tweet to profile (replaces existing pin) |
285
+ | `unpin_tweet(tweet_id)` | Unpin tweet |
286
+ | `create_highlight(tweet_ids)` | ⚠️ Add tweets to profile highlights |
287
+ | `delete_highlight(highlight_id)` | ⚠️ Remove a highlight |
288
+ | `get_user_highlights(user_id, limit)` | Get user's highlighted tweets |
289
+
290
+ ### Safety & Privacy (4)
291
+
292
+ | Tool | Description |
293
+ |------|-------------|
294
+ | `get_muted_accounts(limit)` | List all muted accounts |
295
+ | `get_blocked_accounts(limit)` | List all blocked accounts |
296
+ | `get_verified_followers(user_id, limit)` | Get Blue-verified followers |
297
+ | `get_user_likes(user_id, limit)` | Get a user's liked tweets |
298
+
299
+ ---
300
+
301
+ ## ⚠️ Safety Guide for AI Agents
302
+
303
+ Spectre marks every destructive tool with **⚠️** in its docstring. Agents should respect these warnings.
304
+
305
+ ### Always Confirm Before Calling
306
+
307
+ | Tool | Why |
308
+ |------|-----|
309
+ | `update_profile` | Changes your public bio/name/website immediately |
310
+ | `update_profile_image` / `update_profile_banner` | Replaces existing images |
311
+ | `pin_tweet` | Replaces any existing pinned tweet |
312
+ | `post_tweet` | Tweets are public and live immediately |
313
+ | `delete_tweet` | Permanent, cannot be undone |
314
+ | `follow_user` / `unfollow_user` | Visible to the other user |
315
+ | `block_user` | The blocked user loses access to your content |
316
+ | `send_dm` | Messages are sent immediately, no recall |
317
+
318
+ ### Safe to Use Freely (Read-Only)
319
+
320
+ All `get_*`, `search_*`, `list_*` tools. `pool_status`, `get_muted_accounts`, `get_blocked_accounts`, `get_scheduled_tweets`, `get_drafts`, `get_bookmarks`, `get_trends`, `get_home_timeline`.
321
+
322
+ ### Rate Limits
323
+
324
+ - ~300 requests/hour/account
325
+ - Spectre auto-rotates to the next account when one hits a rate limit
326
+ - Use `set_auto_rotate(false)` to lock to a single account
327
+ - Rate limit errors include `retry_after_seconds`
328
+
329
+ ---
330
+
331
+ ## X Query Operators
332
+
333
+ | Operator | Example | Description |
334
+ |----------|---------|-------------|
335
+ | `from:username` | `from:elonmusk` | Tweets by a user |
336
+ | `since:YYYY-MM-DD` | `since:2026-01-01` | After date |
337
+ | `until:YYYY-MM-DD` | `until:2026-06-01` | Before date |
338
+ | `#hashtag` | `#python` | Hashtag search |
339
+ | `filter:media` | `AI filter:media` | Only media tweets |
340
+ | `filter:links` | `AI filter:links` | Only tweets with links |
341
+ | `lang:en` | `AI lang:en` | Language filter |
342
+ | `min_retweets:N` | `AI min_retweets:100` | Minimum retweets |
343
+ | `min_faves:N` | `AI min_faves:50` | Minimum likes |
344
+ | `-"term"` | `AI -"GPT"` | Exclude term |
345
+ | `OR` | `python OR rust` | Either term |
346
+
347
+ ---
348
+
349
+ ## CLI
350
+
351
+ ```bash
352
+ spectre add <username> <cookies> Add account via browser cookies
353
+ spectre remove <username> Remove an account
354
+ spectre list List all accounts
355
+ spectre status Pool health check
356
+ spectre serve Start MCP server (default)
357
+ spectre help Show help
358
+ ```
359
+
360
+ ---
361
+
362
+ ## Environment Variables
363
+
364
+ | Variable | Default | Description |
365
+ |----------|---------|-------------|
366
+ | `SPECTRE_DB` | `~/.spectre/accounts.db` | Account pool path |
367
+ | `SPECTRE_PROXY` | none | Global proxy (`socks5://user:pass@host:port`) |
368
+ | `TWS_HTTP_BACKEND` | `httpx` | Set to `curl` for TLS fingerprinting |
369
+ | `TWS_TELEMETRY` | `0` | Disable telemetry |
370
+ | `SPECTRE_OP_*` | built-in | Override GraphQL operation IDs (when they rotate) |
371
+
372
+ ---
373
+
374
+ ## Limitations
375
+
376
+ - **Requires authenticated accounts** — X blocks unauthenticated access
377
+ - **Rate limited** — ~300 requests/hour/account (rotation handles this)
378
+ - **~3200 tweet cap** on user timelines (X's own limit)
379
+ - **ToS risk** — automated access violates X's terms
380
+
381
+ ---
382
+
383
+ ## License
384
+
385
+ MIT
386
+
387
+ ---
388
+
389
+ <div align="center">
390
+
391
+ **Built for AI agents, by an AI agent.**
392
+
393
+ [GitHub](https://github.com/pranrichh/spectre-mcp) · [Issues](https://github.com/pranrichh/spectre-mcp/issues)
394
+
395
+ </div>