X Twitter Scraper
Server Details
Real-time X (Twitter) data platform with 2 MCP tools covering 120+ REST API endpoints: tweet search, user lookup, timelines, 23 bulk extraction tools, account monitoring, webhooks, giveaway draws, write actions (tweet, like, retweet, follow, DM), media download, trending topics, and more. Reads from $0.00015/call.
- Status
- Unhealthy
- Last Tested
- Transport
- Streamable HTTP
- URL
- Repository
- Xquik-dev/x-twitter-scraper
- GitHub Stars
- 49
Glama MCP Gateway
Connect through Glama MCP Gateway for full control over tool access and complete visibility into every call.
Full call logging
Every tool call is logged with complete inputs and outputs, so you can debug issues and audit what your agents are doing.
Tool access control
Enable or disable individual tools per connector, so you decide what your agents can and cannot do.
Managed credentials
Glama handles OAuth flows, token storage, and automatic rotation, so credentials never expire on your clients.
Usage analytics
See which tools your agents call, how often, and when, so you can understand usage patterns and catch anomalies.
Tool Definition Quality
Average 4.7/5 across 2 of 2 tools scored.
The two tools have perfectly distinct purposes: 'explore' is for discovering endpoints in the API specification without making live calls, while 'xquik' is for executing authenticated API calls to interact with X/Twitter. There is no overlap or ambiguity; each tool's role is clearly defined and complementary.
The tool names are inconsistent in style and clarity. 'explore' is a vague verb that doesn't follow a clear pattern, while 'xquik' is a branded name that doesn't indicate its function. They lack a common naming convention like verb_noun, making the set feel disjointed and less predictable for an agent.
With only 2 tools, the server feels thin for its broad domain of X/Twitter scraping and interaction. While the tools cover discovery and execution, many typical operations (e.g., separate tools for read vs. write actions) are bundled into 'xquik', which could lead to complexity. A slightly higher count might better distribute functionality.
The tool set covers the core workflows for X/Twitter interaction: discovery of endpoints and execution of API calls. However, there are minor gaps, such as no dedicated tools for common high-level operations (e.g., 'post_tweet' or 'search_tweets'), requiring agents to handle low-level details within 'xquik'. The surface is functional but could be more intuitive.
Available Tools
2 toolsexploreARead-onlyIdempotentInspect
Search and browse the Xquik X (Twitter) API specification to discover endpoints before making live API calls with the 'xquik' tool.
When to use
Use 'explore' FIRST to find the right endpoint path, parameters, and response shape before calling 'xquik'.
Use when the user asks what capabilities are available or how to accomplish a task on X/Twitter.
Use to check whether an endpoint is free or requires a subscription.
When NOT to use
Do NOT use 'explore' to fetch live data from X - use 'xquik' instead.
Do NOT use if you already know the endpoint path and parameters.
Behavior
Read-only, idempotent. No network calls - runs against an in-memory catalog of 122 endpoints.
Always free, no authentication or credits required.
Returns the result of your filter function (e.g., empty array if no endpoints match).
Returns an error message if the code is syntactically invalid or throws at runtime.
Execution timeout: 60 seconds.
Each EndpointInfo contains: method, path, summary, category (account, bot, composition, credits, extraction, integrations, media, monitoring, support, twitter, x-accounts, x-write), free (boolean), parameters (array), and responseShape (string).
Input format
Write an async arrow function. The sandbox provides spec.endpoints (EndpointInfo[]). Filter, search, or return them.
Examples
Find all free endpoints: async () => spec.endpoints.filter(e => e.free)
Find by category: async () => spec.endpoints.filter(e => e.category === 'composition')
Search by keyword: async () => spec.endpoints.filter(e => e.summary.toLowerCase().includes('tweet'))
Get full details: async () => spec.endpoints.find(e => e.path === '/api/v1/x/tweets/search')
| Name | Required | Description | Default |
|---|---|---|---|
| code | Yes | JavaScript async arrow function to execute. For explore: filters spec.endpoints (EndpointInfo[]). For xquik: calls xquik.request(path, options?) to execute X/Twitter API operations. Auth is injected automatically. |
Tool Definition Quality
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations confirm read-only/idempotent/destructive hints, but the description adds crucial behavioral context: it explains the sandboxed execution environment, available TypeScript interfaces, and the 'spec' variable in scope. This discloses the code execution model beyond what annotations provide.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Though lengthy due to interface definitions and multiple examples, every section is essential for a code execution tool. Information is front-loaded (purpose first, then technical details), with clear code blocks for the complex 'code' parameter syntax.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Comprehensive given the tool's complexity (arbitrary code execution sandbox). Documents the return structure (EndpointInfo array) via TypeScript interface and implies return behavior through examples. Lacking explicit error handling documentation but sufficient for an explore tool without output schema.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
While the schema describes 'code' as merely 'Async arrow function to execute', the description adds substantial semantic value: it specifies the exact function format expected, documents the EndpointInfo interface structure, details available sandbox variables, and provides three working code examples that demonstrate valid inputs.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description explicitly states the tool searches X/Twitter API endpoints and clarifies it operates against an in-memory catalog with no network calls. It provides a specific verb (search), resource (API spec), and scope (in-memory only), distinguishing it from typical API clients.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides extensive examples demonstrating when to use the tool: finding free endpoints, filtering by category, and keyword searching. While it doesn't explicitly mention when NOT to use it versus sibling 'xquik', the examples create clear usage patterns for API exploration tasks.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
xquikADestructiveInspect
Execute authenticated X (Twitter) API calls to read data, publish content, and manage accounts across 122 REST endpoints.
When to use
Use after calling 'explore' to discover the endpoint path and parameters.
Use for any live X/Twitter operation: search tweets, look up users, post tweets, like, retweet, follow, send DMs, run giveaway draws, monitor accounts, extract bulk data, compose tweets, and more.
When NOT to use
Do NOT use to discover endpoints - use 'explore' first.
Do NOT pass API keys or auth headers - authentication is injected automatically.
Behavior
Executes the provided async function in a sandboxed environment with
xquik.request(path, options?)andspec.endpointsavailable.Sandboxed via Node.js VM: no filesystem, no global network access - only xquik.request() is available. Console calls are silently ignored.
Execution timeout: 60 seconds per invocation, 60 seconds per individual API request.
Read operations (GET) return JSON objects with the requested data. Write operations (POST/DELETE) return
{ success: true }or{ success: true, warning: '...' }.Pagination: responses include
has_next_page(boolean) andnext_cursor(string). Passcursoras a query param for the next page.Can be destructive: write operations (POST/DELETE) modify data on X (tweets, follows, DMs, profile).
Input format
Write an async arrow function using xquik.request(path, { method?, body?, query? }). Auth is automatic.
Workflows
1. Send a tweet (Subscription required)
async () => {
// First, find connected accounts
const { accounts } = await xquik.request('/api/v1/x/accounts');
// Post the tweet directly
return xquik.request('/api/v1/x/tweets', {
method: 'POST',
body: { account: accounts[0].xUsername, text: 'Hello world!' }
});
}2. Reply to a tweet
async () => {
const { accounts } = await xquik.request('/api/v1/x/accounts');
return xquik.request('/api/v1/x/tweets', {
method: 'POST',
body: { account: accounts[0].xUsername, text: 'Great point!', reply_to_tweet_id: '1234567890' }
});
}3. Like, retweet, unretweet, follow (follow requires user ID lookup)
async () => {
const { accounts } = await xquik.request('/api/v1/x/accounts');
const account = accounts[0].xUsername;
// Like a tweet (tweet ID in path)
await xquik.request('/api/v1/x/tweets/1234567890/like', {
method: 'POST', body: { account }
});
// Retweet
await xquik.request('/api/v1/x/tweets/1234567890/retweet', {
method: 'POST', body: { account }
});
// Unretweet
await xquik.request('/api/v1/x/tweets/1234567890/retweet', {
method: 'DELETE', body: { account }
});
// Follow - requires numeric user ID, look up first
const user = await xquik.request('/api/v1/x/users/elonmusk');
await xquik.request(`/api/v1/x/users/${user.id}/follow`, {
method: 'POST', body: { account }
});
}4. Undo actions (unlike, unfollow, delete tweet)
async () => {
const { accounts } = await xquik.request('/api/v1/x/accounts');
const account = accounts[0].xUsername;
await xquik.request('/api/v1/x/tweets/1234567890/like', {
method: 'DELETE', body: { account }
});
await xquik.request('/api/v1/x/users/44196397/follow', {
method: 'DELETE', body: { account }
});
await xquik.request('/api/v1/x/tweets/1234567890', {
method: 'DELETE', body: { account }
});
}5. Send DM (uses recipient user ID in path)
async () => {
const { accounts } = await xquik.request('/api/v1/x/accounts');
return xquik.request('/api/v1/x/dm/44196397', {
method: 'POST',
body: { account: accounts[0].xUsername, text: 'Hey, check this out!' }
});
}6. Upload media via URL and tweet with image
async () => {
const { accounts } = await xquik.request('/api/v1/x/accounts');
const account = accounts[0].xUsername;
const media = await xquik.request('/api/v1/x/media', {
method: 'POST',
body: { account, url: 'https://example.com/photo.jpg' }
});
return xquik.request('/api/v1/x/tweets', {
method: 'POST',
body: { account, text: 'Check this out!', media_ids: [media.mediaId] }
});
}7. Get a user's tweets (Subscription required)
async () => {
// Use /api/v1/x/users/:id/tweets for user timelines (up to ~3,200 tweets)
// Do NOT use search with "from:username" - search caps at ~40 results
return xquik.request('/api/v1/x/users/elonmusk/tweets', {
query: { cursor: '' } // omit cursor for first page
});
}8. Search tweets with keywords (Subscription required)
async () => {
// Use search for keyword filtering (limit for multi-page server-side pagination)
return xquik.request('/api/v1/x/tweets/search', {
query: { q: 'AI agents', limit: '100' }
});
}9. Browse trending topics (FREE)
async () => {
return xquik.request('/api/v1/radar');
}10. Analyze a user's writing style
async () => {
// Returns cached style if available (free for all users)
// Auto-refreshes from X if cache is older than 7 days (subscription required)
return xquik.request('/api/v1/styles', {
method: 'POST',
body: { username: 'dbdevletbahceli' }
});
}11. Save tweet style from screenshots (FREE)
async () => {
// When user shares tweet screenshots, extract the texts and save as a style.
// This lets free users clone any writing voice without a subscription.
return xquik.request('/api/v1/styles/elonmusk', {
method: 'PUT',
body: {
label: 'Elon Musk style',
tweets: [
{ text: 'The most entertaining outcome is the most likely' },
{ text: 'Mars, here we come!!' }
]
}
});
// Then compose with: POST /api/v1/compose { step: 'compose', topic: '...', styleUsername: 'elonmusk' }
}12. Download media and get gallery link (Subscription required)
async () => {
// Returns galleryUrl only (shareable gallery page with all media)
return xquik.request('/api/v1/x/media/download', {
method: 'POST',
body: { tweetInput: '1234567890' } // tweet ID or full URL
});
}13. Subscribe (FREE - returns Stripe checkout URL)
async () => {
return xquik.request('/api/v1/subscribe', { method: 'POST' });
}14. Draft & optimize tweet text (3-step compose flow, FREE)
async () => {
// Use this ONLY when the user wants help WRITING tweet text.
// To SEND a tweet, use POST /api/v1/x/tweets instead.
// Step 1: Get algorithm data
const compose = await xquik.request('/api/v1/compose', {
method: 'POST',
body: { step: 'compose', topic: 'AI agents' }
});
return compose; // Returns contentRules, followUpQuestions, scorerWeights
// After user answers: call with body { step: 'refine', goal, tone, topic }
// After drafting: call with body { step: 'score', draft }
}Cost
Free: /api/v1/compose, /api/v1/styles (cached lookup/save/delete/compare), /api/v1/drafts, /api/v1/radar, /api/v1/subscribe, /api/v1/account, /api/v1/api-keys, /api/v1/bot/, /api/v1/integrations/, /api/v1/x/accounts, /api/v1/support/*
Subscription required: /api/v1/styles (X API refresh when cache >7 days), /api/v1/x/tweets, /api/v1/x/articles, /api/v1/x/users, /api/v1/x/followers, /api/v1/x/media, /api/v1/x/profile, /api/v1/x/communities, /api/v1/x/lists, /api/v1/x/dm, /api/v1/x/bookmarks, /api/v1/x/notifications, /api/v1/x/timeline, /api/v1/x/trends, /api/v1/credits, /api/v1/extractions, /api/v1/draws, /api/v1/monitors, /api/v1/events, /api/v1/webhooks, /api/v1/styles/:username/performance, /api/v1/trends
Publish actions (subscription required): POST /api/v1/x/tweets, DELETE /api/v1/x/tweets/:id, POST|DELETE /api/v1/x/tweets/:id/like, POST|DELETE /api/v1/x/tweets/:id/retweet, POST|DELETE /api/v1/x/users/:id/follow, POST /api/v1/x/dm/:userId, POST /api/v1/x/media, PATCH /api/v1/x/profile, PATCH /api/v1/x/profile/avatar, PATCH /api/v1/x/profile/banner, POST|DELETE /api/v1/x/communities, POST|DELETE /api/v1/x/communities/:id/join
IMPORTANT: Always attempt the request. Never assume subscription status. The API returns a clear error if subscription is missing.
Rate limits
The API enforces per-user rate limits: 120 reads/min, 30 writes/min, 15 deletes/min
429 responses with error "rate_limit_exceeded" include a retryAfter field (seconds) - wait before retrying
This is different from x_rate_limited (429) which is an X API downstream limit
Space out API calls, especially writes. Avoid rapid-fire loops
Error handling
402 / "no_subscription" / "subscription_inactive" / "no_credits" / "insufficient_credits": You MUST make another xquik tool call right now:
async () => { return xquik.request('/api/v1/subscribe', { method: 'POST' }); }- this returns a checkout URL. Present that URL as a clickable link. Also mention free features (compose, styles, drafts, radar, account, API keys, support). NEVER tell the user to "visit the website" instead - always call subscribe and show the URLNEVER combine free and paid calls in Promise.all - a 402 on one call kills all results. Call free endpoints first, then paid ones separately
If a paid call fails, still use free data already fetched (radar, styles, compose). Never discard free data or fall back to web search
API errors include status code and message
Publish error response: { error: code, message, retryable: boolean, details: { reason, action, account, suggestion } }
Retryable errors (retry after wait): x_rate_limited (429), x_transient_error (503)
Non-retryable 422 errors: x_duplicate_action, x_content_too_long, x_account_feature_required, x_account_suspended, x_account_protected, x_target_not_found, x_rejected
Auth errors: x_auth_failure (401, session expired - re-add account), account_needs_reauth (403, re-add account)
Ambiguous: x_write_unconfirmed (202, action sent but confirmation failed - check timeline before retrying, do NOT retry blindly)
Fallback: x_write_failed (500, unclassified failure - contact support if persists)
x_rejected (422): X rejected the request without a specific reason - wait 2-3 minutes before retrying, ensure unique content
Check the retryable field to decide whether to retry
200 with a "warning" field means probable success - do NOT retry. The details object includes action, account, reason, and suggestion fields
| Name | Required | Description | Default |
|---|---|---|---|
| code | Yes | JavaScript async arrow function to execute. For explore: filters spec.endpoints (EndpointInfo[]). For xquik: calls xquik.request(path, options?) to execute X/Twitter API operations. Auth is injected automatically. |
Tool Definition Quality
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations provide boolean hints (destructiveHint: true, openWorldHint: true), but the description adds crucial context: automatic auth injection, rate limits (120 reads/min, 30 writes/min), cost tiers (free vs subscription endpoints), specific error codes with retry instructions (402, 429, etc.), and warnings about Promise.all behavior with mixed free/paid calls. This is extensive behavioral disclosure beyond the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Though lengthy, the description is well-structured with clear headers (Workflows, Cost, Rate limits, Error handling) and front-loaded with the core purpose. Every section is necessary for a generic code-execution tool wrapping a complex API. Minor repetition exists ('Auth is injected automatically' appears multiple times), but overall the density is appropriate for the tool's complexity.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a destructive, open-world tool with a single generic 'code' parameter and no output schema, the description achieves completeness by covering: endpoint discovery via sibling, 14 usage patterns, authentication model, cost/subscription requirements, rate limiting, and comprehensive error handling with specific resolution steps. No critical gaps remain.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
While the schema has 100% coverage ('Async arrow function to execute'), the description massively enhances the single 'code' parameter by providing the complete sandbox TypeScript declarations (xquik.request, spec) and 14 concrete, copy-pasteable workflow examples showing valid function bodies. This provides essential semantic context that the schema cannot convey.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb+resource ('Execute X (Twitter) API calls') and explicitly distinguishes from sibling tool 'explore' ('First use explore to find endpoints, then write code here'). It clearly states the core action (execute API calls) and the mechanism (write an async arrow function), leaving no ambiguity about what the tool does.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides explicit workflow guidance ('First use explore... then write code here') and specific when-to-use guidance for specific workflows (e.g., 'Use this ONLY when the user wants help WRITING tweet text. To SEND a tweet, use POST /api/v1/x/tweets instead'). The 14 numbered workflows act as clear usage patterns covering free vs subscription requirements.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Claim this connector by publishing a /.well-known/glama.json file on your server's domain with the following structure:
{
"$schema": "https://glama.ai/mcp/schemas/connector.json",
"maintainers": [{ "email": "your-email@example.com" }]
}The email address must match the email associated with your Glama account. Once published, Glama will automatically detect and verify the file within a few minutes.
Control your server's listing on Glama, including description and metadata
Access analytics and receive server usage reports
Get monitoring and health status updates for your server
Feature your server to boost visibility and reach more users
For users:
Full audit trail – every tool call is logged with inputs and outputs for compliance and debugging
Granular tool control – enable or disable individual tools per connector to limit what your AI agents can do
Centralized credential management – store and rotate API keys and OAuth tokens in one place
Change alerts – get notified when a connector changes its schema, adds or removes tools, or updates tool definitions, so nothing breaks silently
For server owners:
Proven adoption – public usage metrics on your listing show real-world traction and build trust with prospective users
Tool-level analytics – see which tools are being used most, helping you prioritize development and documentation
Direct user feedback – users can report issues and suggest improvements through the listing, giving you a channel you would not have otherwise
The connector status is unhealthy when Glama is unable to successfully connect to the server. This can happen for several reasons:
The server is experiencing an outage
The URL of the server is wrong
Credentials required to access the server are missing or invalid
If you are the owner of this MCP connector and would like to make modifications to the listing, including providing test credentials for accessing the server, please contact support@glama.ai.
Discussions
No comments yet. Be the first to start the discussion!