This is an experimental project that exposes an x.com account as API, it need you run Chrome with CDP enabled and login the x.com account first.
Retrieves the home timeline tweets.
Retrieves tweets from a specific user's timeline.
:screen_name- The Twitter screen name of the user- Query parameters:
tab(optional) - One oftweets(default),replies,media
Retrieves mentions for the authenticated user.
Retrieves a specific tweet.
:screen_name- The Twitter screen name of the user:tweet_id- The ID of the tweet- For article tweets, the response includes:
article- Resolved blocks with inlined entity data (media URLs, markdown, embedded tweets)article_markdown- The article content converted to Markdownarticle_title- The article titlearticle_cover- The cover image URL
Alternative endpoint to retrieve a specific tweet (same as above).
Retrieves a tweet thread with replies.
:screen_name- The Twitter screen name of the user:tweet_id- The ID of the tweet- Query parameters:
max(optional) - Maximum number of replies to fetch (default: 100)
- Response:
{ "mainTweet": { ... }, "replies": [ ... ], "totalCount": 42, "hasMore": false }
Search tweets with advanced filters.
- Query parameters:
q(required) - Search querysearchType(optional) - One oftop(default),latest,photos,videosfrom(optional) - Filter by authorto(optional) - Filter by recipientsince(optional) - Start date (YYYY-MM-DD)until(optional) - End date (YYYY-MM-DD)filter(optional) - One ofmedia,images,videos,links,replies,native_videominRetweets(optional) - Minimum retweet countminFaves(optional) - Minimum favorite countminReplies(optional) - Minimum reply countlang(optional) - Language code
Posts a new tweet.
- Request body:
{ "text": "Your tweet content here" }
Retrieves cookies for a specific domain.
:domain- The domain to get cookies for (e.g.,x.com)- Query parameters:
urls(optional) - Comma-separated list of specific URLs to get cookies for
Sets cookies for a specific domain.
:domain- The domain to set cookies for- Request body (JSON):
{ "cookies": [ { "name": "cookie_name", "value": "cookie_value", "path": "/", "secure": true } ] } - Or raw cookie string (Content-Type:
text/plain):cookie1=value1; cookie2=value2
Clears browser data (cookies, cache, storage).
:domain(optional) - Specific domain to clear data for. If omitted, clears all data.- Query parameters (all default to
true):cookies- Clear cookieslocalStorage- Clear local storagesessionStorage- Clear session storageindexedDB- Clear IndexedDBcache- Clear browser cacheall- Clear all data types
Alternative to DELETE for clearing browser data.
- Request body:
{ "cookies": true, "localStorage": true, "sessionStorage": true, "indexedDB": true, "cache": true, "all": false }
Fetches a web page and extracts content via CSS selector.
- The URL path after
/page/is treated as the target URL (withhttps://prefix) - Query parameters:
__selector__(optional) - CSS selector to extract. If omitted, returns full page HTML
Fetches a web page and extracts content via multiple CSS selectors.
- The URL path after
/page/is treated as the target URL (withhttps://prefix) - Request body:
{ "selectors": { "title": "h1", "content": ".main" }, "timeout": 10 }
Resets the browser by navigating to about:blank.
Plays back a recorded macro.
- Request body: Validated against
PlaybackRequestZod schema
The server exposes MCP endpoints for tool integration:
- GET /sse - SSE transport for MCP connections
- POST /messages?sessionId=... - Message handler for SSE transport
- POST /mcp - Streamable HTTP transport for MCP (stateless)
Available MCP tools:
readTweet- Read a tweet by URL, returns article markdown or thread text
The server implements a multi-layer timeout system to prevent hanging requests:
- Timeout: 120 seconds
- Response: HTTP 504 with message "Request timeout - the operation took too long"
- Excluded routes:
/sse,/mcp,/messages(streaming endpoints)
All timeouts are configurable via TimeoutConfig:
| Phase | Default | Error Type |
|---|---|---|
| CDP Connection | 5000ms | CDPConnectionTimeoutError |
| Page Enable | 100ms | PageEnableTimeoutError |
| Page Navigation | 30000ms | PageNavigationTimeoutError |
| Page Load | 30000ms | PageLoadTimeoutError |
| XHR Wait | 30000ms | XhrWaitTimeoutError |
| Idle Detection | 3000ms | PageLoadedWithoutMatchError |
When accessing Twitter endpoints, if the page loads but the expected API request is not detected (indicating session expiry), the server returns:
- HTTP 403 with
{ "error": "session_expired", "message": "Twitter session expired, please re-login" }
The server runs on port 3000 by default, or on the port specified by the PORT environment variable.
The development environment can be customized through a .env file in the project root. Below are the available configuration options:
# Chrome DevTools Protocol (CDP) port
# Default: 9222
CDP_PORT=9222
# Chrome user data directory
# If not specified, will use default directory based on OS:
# - macOS: ~/Library/Application Support/BrowserAgent
# - Windows: %APPDATA%/Local/BrowserAgent
# - Linux: ~/.browseragent
CHROME_USER_DATA_DIR=/path/to/your/chrome/profile
# Run Chrome in headless mode
# Set to 'true' to run Chrome without GUI
# Default: false
CHROME_HEADLESS=falseA complete .env file might look like this:
CDP_PORT=9333
CHROME_USER_DATA_DIR=/Users/username/Projects/browser-agent/chrome-data
CHROME_HEADLESS=true- All settings are optional and have sensible defaults
- The CDP URL will be automatically injected into your development environment as
process.env.CDP_URL - Chrome/Chromium executable is automatically detected on your system
- If running in CI/CD environments, it's recommended to set
CHROME_HEADLESS=true