@twitterapis/mcp 0.6.2 → 0.6.3
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/CHANGELOG.md +16 -4
- package/package.json +4 -3
- package/src/tools.js +37 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,20 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.6.3 (2026-08-02)
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
|
|
7
|
+
- **Two new tools, `twitter_blocking` and `twitter_muting`**, for the accounts your authenticated account has blocked or muted. Both are cursor-paginated lists of full user objects and both read YOUR OWN lists only: there is no `user_id` argument, because X provides no way to read another account's block or mute list and an argument the API ignores would be worse than none. An empty `users` array means you block or mute nobody; it is never a silent parse failure, because the endpoint returns an error status rather than an empty page when it cannot read the list. The catalog is now **51 tools: 37 reads and 14 write actions**.
|
|
8
|
+
- **Registry descriptors so the server is discoverable outside npm**: `server.json` for the official MCP Registry, `smithery.yaml` with a full `configSchema` (so hosted installers prompt for the API key by name rather than showing a bare variable), and `glama.json` for the maintainer claim. npm is a pull channel; these are where agent users browse.
|
|
9
|
+
|
|
10
|
+
### Fixed
|
|
11
|
+
|
|
12
|
+
- **`npm test` was failing on `main`, which blocked any release.** `twitter_users_by_ids` and `twitter_media_status` were merged on 2026-07-31 but the catalog-count assertions were left at the pre-merge 47 tools / 33 reads, so the suite reported a mismatch that had nothing to do with the tools themselves. The counts are corrected and now carry a reads-plus-writes-equals-total invariant that does not depend on them, so two cancelling errors cannot pass.
|
|
13
|
+
|
|
14
|
+
### Changed
|
|
15
|
+
|
|
16
|
+
- Release tooling hardened. No user-facing or API behaviour change.
|
|
17
|
+
|
|
3
18
|
## Unreleased
|
|
4
19
|
|
|
5
20
|
### Added
|
|
@@ -16,10 +31,7 @@
|
|
|
16
31
|
|
|
17
32
|
### Changed
|
|
18
33
|
|
|
19
|
-
-
|
|
20
|
-
- The firewall no longer carries its own list of banned terms. It delegates to the maintainer's isolation registry, which is the single place those rules live, so the gate and everything else that enforces them cannot drift apart. If the registry cannot be located, the gate fails rather than passing.
|
|
21
|
-
|
|
22
|
-
The two firewall changes above are release tooling only.
|
|
34
|
+
- Release tooling hardened. No user-facing or API behaviour change.
|
|
23
35
|
|
|
24
36
|
## 0.6.1 (2026-07-20)
|
|
25
37
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@twitterapis/mcp",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.3",
|
|
4
4
|
"description": "Official MCP server for twitterapis.com, the Twitter/X API (search, users, followers, tweets, threads, lists, likes, bookmarks, DMs) plus write actions (post/like/retweet/follow) as native tools for Claude, Cursor, and any MCP client.",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -23,10 +23,11 @@
|
|
|
23
23
|
"scripts": {
|
|
24
24
|
"start": "node src/index.js",
|
|
25
25
|
"check": "node --check src/index.js && node --check src/tools.js",
|
|
26
|
-
"test": "node test/tools.test.mjs && node test/smoke.mjs && node test/openapi-parity.mjs && node test/firewall.mjs",
|
|
26
|
+
"test": "node test/tools.test.mjs && node test/smoke.mjs && node test/openapi-parity.mjs && node test/firewall.mjs && node test/registry-manifests.mjs",
|
|
27
27
|
"prepublishOnly": "npm test",
|
|
28
28
|
"check:openapi-parity": "node test/openapi-parity.mjs",
|
|
29
|
-
"check:firewall": "node test/firewall.mjs"
|
|
29
|
+
"check:firewall": "node test/firewall.mjs",
|
|
30
|
+
"check:registry": "node test/registry-manifests.mjs"
|
|
30
31
|
},
|
|
31
32
|
"dependencies": {
|
|
32
33
|
"@modelcontextprotocol/sdk": "^1.0.0",
|
package/src/tools.js
CHANGED
|
@@ -111,6 +111,17 @@ export const TOOLS = [
|
|
|
111
111
|
),
|
|
112
112
|
},
|
|
113
113
|
},
|
|
114
|
+
{
|
|
115
|
+
name: "twitter_users_by_ids",
|
|
116
|
+
path: "/twitter/users/by_ids",
|
|
117
|
+
description:
|
|
118
|
+
"Resolve up to 100 numeric user ids into full profiles in ONE call. Same user object as twitter_user_info_by_id, returned as a list. Use this whenever you hold several ids and would otherwise loop twitter_user_info_by_id, for example hydrating the authors of a batch of tweets. Ids that no longer resolve (suspended or deleted accounts) are omitted rather than returned as nulls; compare the requested and resolved counts in the response, or diff the returned ids against the ones you sent, to see which were dropped. Sending more than 100 ids is rejected rather than truncated, so a short list always means those accounts are gone, never that the request was clipped.",
|
|
119
|
+
shape: {
|
|
120
|
+
user_ids: z.string().describe(
|
|
121
|
+
"Comma-separated numeric Twitter/X user ids, up to 100 (e.g. '44196397,745273'). Duplicates are collapsed and billed once.",
|
|
122
|
+
),
|
|
123
|
+
},
|
|
124
|
+
},
|
|
114
125
|
{
|
|
115
126
|
name: "twitter_user_about",
|
|
116
127
|
path: "/twitter/user/user_about",
|
|
@@ -354,6 +365,20 @@ export const TOOLS = [
|
|
|
354
365
|
"List YOUR authenticated account's bookmarked tweets, most recent first. Requires an authenticated session behind your key. Returns each bookmarked tweet with author and metrics plus a cursor.",
|
|
355
366
|
shape: { ...PAGINATION, ...INLINE },
|
|
356
367
|
},
|
|
368
|
+
{
|
|
369
|
+
name: "twitter_blocking",
|
|
370
|
+
path: "/twitter/user/blocking",
|
|
371
|
+
description:
|
|
372
|
+
"List the accounts YOUR authenticated account has BLOCKED, as full user objects, cursor-paginated. Requires an authenticated session behind your key. There is no user_id argument: X provides no way to read another account's block list, so this reads yours only. An empty users array is a real answer meaning you block nobody, never a silent failure, because the endpoint returns an error status rather than an empty page when it cannot read the list.",
|
|
373
|
+
shape: { ...PAGINATION, ...INLINE },
|
|
374
|
+
},
|
|
375
|
+
{
|
|
376
|
+
name: "twitter_muting",
|
|
377
|
+
path: "/twitter/user/muting",
|
|
378
|
+
description:
|
|
379
|
+
"List the accounts YOUR authenticated account has MUTED, as full user objects, cursor-paginated. Muting hides an account's posts from your timeline without blocking it, so this is a different list from twitter_blocking and an account can appear in one and not the other. Requires an authenticated session behind your key. There is no user_id argument: X provides no way to read another account's mute list. An empty users array means you mute nobody, never a silent failure.",
|
|
380
|
+
shape: { ...PAGINATION, ...INLINE },
|
|
381
|
+
},
|
|
357
382
|
{
|
|
358
383
|
name: "twitter_bookmark_search",
|
|
359
384
|
path: "/twitter/user/bookmark_search",
|
|
@@ -596,6 +621,18 @@ export const TOOLS = [
|
|
|
596
621
|
...INLINE,
|
|
597
622
|
},
|
|
598
623
|
},
|
|
624
|
+
{
|
|
625
|
+
name: "twitter_media_status",
|
|
626
|
+
path: "/twitter/media/status",
|
|
627
|
+
description:
|
|
628
|
+
"Check whether an uploaded media_id has finished processing on X, before you attach it to a tweet. Video, GIF and large uploads are processed ASYNCHRONOUSLY: twitter_media_upload returns a media_id immediately, but attaching it via twitter_create_tweet FAILS until X reports state 'succeeded'. Poll this until then. Returns media_id, state ('pending', 'in_progress', 'succeeded' or 'failed'), check_after_secs (how long X asks you to wait before polling again, honour it rather than tight-looping), progress_percent, and an error object when state is 'failed'. Reads through YOUR OWN registered account session, the same one that performed the upload, so register first with twitter_customer_session or twitter_user_login, or pass auth_token/ct0 for this call. This is a READ: no daily write cap applies.",
|
|
629
|
+
shape: {
|
|
630
|
+
media_id: z.string().describe(
|
|
631
|
+
"Numeric media id returned by twitter_media_upload, e.g. '1234567890123456789'.",
|
|
632
|
+
),
|
|
633
|
+
...INLINE,
|
|
634
|
+
},
|
|
635
|
+
},
|
|
599
636
|
];
|
|
600
637
|
|
|
601
638
|
// Pure query-string builder: drops undefined/null/empty values, URL-encodes the rest.
|