X (Twitter)
Post, reply, message, and search X (Twitter) with XTools using consumer key/secret and access token credentials.
XTools allows an Agent to interact with X, providing functionality for posting, messaging, and searching tweets.
Prerequisites
Install the dependencies:
uv pip install -U agno openai tweepySetup
-
Create X Developer Account
- Visit developer.x.com and apply for developer access
- Create a new project and app in your developer portal
-
Configure App Permissions
- Select Read and write to create posts and replies
- Select Read, write, and DMs if the agent will send direct messages
- Regenerate the access token and secret after changing app permissions
-
Generate API Credentials
- Navigate to your app's "Keys and tokens" section
- Generate and copy these credentials:
- API Key & Secret
- Bearer Token
- Access Token & Secret
-
Configure Environment
export X_CONSUMER_KEY=your_api_key export X_CONSUMER_SECRET=your_api_secret export X_ACCESS_TOKEN=your_access_token export X_ACCESS_TOKEN_SECRET=your_access_token_secret export X_BEARER_TOKEN=your_bearer_token export OPENAI_API_KEY=your_openai_api_key
The current send_dm adapter reads an id field that the X DM response does not return. It can report an error after successfully sending a message. Disable it with XTools(exclude_tools=["send_dm"]) until this is corrected; retrying that reported error can send a duplicate.
The search adapter also omits author expansion, and the timeline request omits author fields, so author names and usernames may be absent even when posts are returned.
Example
Replace @AgnoAgi with the X username associated with your access token. In this cookbook excerpt, use XTools(exclude_tools=["send_dm"]) for the toolkit constructor and leave the DM example disabled.
from agno.agent import Agent
from agno.tools.x import XTools
# Initialize the X toolkit
x_tools = XTools()
# Create an agent with the X toolkit
agent = Agent(
instructions=[
"Use your tools to interact with X (Twitter) as the authorized user @AgnoAgi",
"When asked to create a post, generate appropriate content based on the request",
"Do not actually post content unless explicitly instructed to do so",
"Provide informative responses about the user's timeline and posts",
"Respect X's usage policies and rate limits",
],
tools=[x_tools],
)
# Get your home timeline
agent.print_response(
"Can you return my x profile with my home timeline?", markdown=True
)
# # Get information about a user
# agent.print_response(
# "Can you retrieve information about this user https://x.com/AgnoHQ ",
# markdown=True,
# )
# # Reply to a post
# agent.print_response(
# "Can you reply to this [post ID] post as a general message as to how great this project is: https://x.com/AgnoHQ",
# markdown=True,
# )
# # Send a direct message
# agent.print_response(
# "Send direct message to the user @AgnoAgi telling them I want to learn more about them and a link to their community.",
# markdown=True,
# )
# # Create a new post
# agent.print_response(
# "Create & post content about how 2025 is the year of the AI agent", markdown=True
# )See the full XTools cookbook example.
Toolkit Params
| Parameter | Type | Default | Description |
|---|---|---|---|
bearer_token | Optional[str] | None | Bearer token for authentication |
consumer_key | Optional[str] | None | Consumer key for authentication |
consumer_secret | Optional[str] | None | Consumer secret for authentication |
access_token | Optional[str] | None | Access token for authentication |
access_token_secret | Optional[str] | None | Access token secret for authentication |
include_post_metrics | bool | False | Include post metrics (likes, retweets, etc.) in search results |
wait_on_rate_limit | bool | False | Wait when a rate limit is reached |
Toolkit Functions
| Function | Description |
|---|---|
create_post | Creates and posts a new post |
reply_to_post | Replies to an existing post |
send_dm | Sends a direct message; currently reports an error on the provider success response (see limitation above). |
get_user_info | Retrieves information about an X user |
get_home_timeline | Gets the authenticated user's home timeline |
search_posts | Searches for tweets |
You can use include_tools or exclude_tools to modify the list of tools the agent has access to. Learn more about selecting tools.