# SDKs and integrations

> Official TwittrAPI clients for Python, Node.js and Go, an MCP server for AI agents (local or hosted), and nodes and tools for n8n, LangChain, LlamaIndex, Apify and Make.

HTML page: https://www.twittrapi.com/docs/integrations

All of these are open source under [github.com/twittrapi](https://github.com/twittrapi). They cover the read endpoints; [account actions](https://www.twittrapi.com/docs/account-actions) are plain HTTP calls. Every tool accepts a direct key (`TWITTRAPI_API_KEY`) or a RapidAPI key (`RAPIDAPI_KEY`), and every call they make is one billed API call.

## SDKs

| Language | Install | Repository |
| --- | --- | --- |
| Python 3.9+ | `pip install twittrapi` | [twittrapi-python](https://github.com/twittrapi/twittrapi-python) |
| Node.js 18+ / TypeScript | `npm install twittrapi` | [twittrapi-node](https://github.com/twittrapi/twittrapi-node) |
| Go 1.21+ | `go get github.com/twittrapi/twittrapi-go` | [twittrapi-go](https://github.com/twittrapi/twittrapi-go) |

The three SDKs work the same way: one method per endpoint, X's raw JSON returned unchanged, retries for 429 and 5xx with backoff, typed errors, and a paginator that follows X's bottom cursor.

```python
from twittrapi import TwittrAPI

client = TwittrAPI()  # reads TWITTRAPI_API_KEY
tweets = client.users.tweets(username="jack", count=20)
```

```js
import { TwittrAPI } from "twittrapi";

const client = new TwittrAPI(); // reads TWITTRAPI_API_KEY
const tweets = await client.users.tweets({ username: "jack", count: 20 });
```

```go
client, _ := twittrapi.NewClient() // reads TWITTRAPI_API_KEY
user, err := client.Users.GetByUsername(context.Background(), "jack")
```

Endpoints without a wrapper method can be called through the Node.js client with `client.get({ path, query })`, or with any HTTP client. Each [reference page](https://www.twittrapi.com/docs/reference) shows both.

## AI agents

| Tool | Install | Repository |
| --- | --- | --- |
| Hosted MCP server (Claude.ai, ChatGPT, Claude Code, Cursor, VS Code) | Nothing to install: `https://mcp.twittrapi.com/mcp` | [Hosted MCP server](https://www.twittrapi.com/docs/hosted-mcp) |
| MCP server, local (stdio) | `npx -y twittrapi-mcp` | [twittrapi-mcp](https://github.com/twittrapi/twittrapi-mcp) |
| LangChain / LangGraph | `pip install -U langchain-twittrapi` | [langchain-twittrapi](https://github.com/twittrapi/langchain-twittrapi) |
| LlamaIndex | `pip install -U llama-index-tools-twittrapi` | [llama-index-tools-twittrapi](https://github.com/twittrapi/llama-index-tools-twittrapi) |

All agent tools are read-only and return the [simple format](https://www.twittrapi.com/docs/simple-format) unless you ask for raw JSON.

### Hosted MCP server

The quickest way to connect an AI app: the tools run at `https://mcp.twittrapi.com/mcp`, so nothing has to be installed. Apps sign in with your TwittrAPI account (OAuth) or send your API key in a header, and every call is billed to your balance. Full guide: [Hosted MCP server](https://www.twittrapi.com/docs/hosted-mcp).

Claude Code:

```bash
claude mcp add --transport http twittrapi https://mcp.twittrapi.com/mcp
```

| Client | Setup |
| --- | --- |
| Claude.ai, Claude Desktop | Settings > Connectors > Add custom connector, URL `https://mcp.twittrapi.com/mcp`, then Connect and allow access |
| ChatGPT | Settings > Apps & Connectors > Advanced settings > Developer mode, then Create with the URL above and OAuth |
| Claude Code | `claude mcp add --transport http twittrapi https://mcp.twittrapi.com/mcp` (OAuth in `/mcp`, or add `--header "Authorization: Bearer $TWITTRAPI_API_KEY"`) |
| Cursor | `"url": "https://mcp.twittrapi.com/mcp"` with `"headers": { "X-API-KEY": "${env:TWITTRAPI_API_KEY}" }` in `mcp.json` |
| VS Code | `.vscode/mcp.json`: `{ "servers": { "twittrapi": { "type": "http", "url": "https://mcp.twittrapi.com/mcp" } } }` |

Connected apps are listed in the dashboard under **Connected apps**, where you can disconnect them.

### Local MCP server (stdio)

For clients that only start local servers, or to keep the server on your own machine, run the [twittrapi-mcp](https://github.com/twittrapi/twittrapi-mcp) package. It needs Node.js 20 or newer and your key.

Claude Code:

```bash
claude mcp add twittrapi --env TWITTRAPI_API_KEY=your-key -- npx -y twittrapi-mcp
```

Claude Desktop (`claude_desktop_config.json`) and Cursor (`~/.cursor/mcp.json`):

```json
{
  "mcpServers": {
    "twittrapi": {
      "command": "npx",
      "args": ["-y", "twittrapi-mcp"],
      "env": { "TWITTRAPI_API_KEY": "your-key" }
    }
  }
}
```

- Set `TWITTRAPI_RESPONSE_FORMAT=raw` for raw JSON from the whole server, or pass `format` per tool call.
- Every tool takes `max_chars` (default 50,000). Longer output is cut with a `[TRUNCATED …]` marker; the cursor is printed above the JSON so it is never lost.
- Errors come back as tool errors (402 balance, 429 rate limit, 404 not found), so the model can react.

To run your own shared server for a team (for example inside a company network), start it in HTTP mode. It then ignores its own environment key and uses the key in each request (`X-API-KEY` or `Authorization: Bearer`), so usage is billed to each caller. Put it behind HTTPS if it is reachable from the internet.

```bash
# One server for the team; each request carries the caller's own key
npx -y twittrapi-mcp --http --port 3333 --host 0.0.0.0

claude mcp add --transport http twittrapi https://your-host.example.com/mcp \
  --header "X-API-KEY: your-key"
```

### LangChain and LlamaIndex

Both packages are built on the Python SDK, return the simple format and cut each result at `max_chars` (default 20,000). The SDK underneath retries 429 and 5xx with backoff. They work with any chat model that supports tool calling.

```python
from langchain.agents import create_agent
from langchain_twittrapi import TwittrAPIToolkit

# A small tool set keeps the model's choice simple; results are the simple format
tools = TwittrAPIToolkit(max_chars=8_000).get_tools(
    ["search_tweets", "get_tweet", "get_user_tweets"]
)

agent = create_agent(
    "anthropic:claude-opus-5-5",
    tools=tools,
    system_prompt="You research X with the tools you have. Quote tweet IDs for every claim.",
)
```

```python
from llama_index.core.agent.workflow import FunctionAgent
from llama_index.llms.anthropic import Anthropic
from llama_index.tools.twittrapi import TwittrAPIToolSpec

agent = FunctionAgent(
    tools=TwittrAPIToolSpec(max_chars=8_000).to_tool_list(
        spec_functions=[("search_tweets", "asearch_tweets"), ("get_tweet", "aget_tweet")]
    ),
    llm=Anthropic(model="claude-opus-5-5"),
)
```

For raw JSON (cards, polls, edit history, community notes) pass `api_response_format="raw"` to `TwittrAPIToolkit` or `TwittrAPIToolSpec`. The option has that name because LangChain tools already have a `response_format` field.

### Your own agent tool

If you run your own agent loop, the SDKs return the simple format when you ask for it (`response_format` in Python, `format` in Node.js, `WithFormat` in Go). Keep only the fields the agent needs and the result shrinks further.

```python
from twittrapi import TwittrAPI

client = TwittrAPI(response_format="simple")  # key from TWITTRAPI_API_KEY

def search_x(query: str, cursor: str | None = None) -> dict:
    """Search recent public tweets on X. Supports X operators such as
    from:user, lang:en, since:2026-10-01, min_faves:100, -filter:replies."""
    page = client.search.tweets(query, category="Latest", cursor=cursor)
    tweets = [
        {"id": t["id"], "author": (t["author"] or {}).get("username"),
         "createdAt": t["createdAt"], "text": t["text"], "likes": t["counts"]["likes"]}
        for t in page["data"]
        if not t.get("unavailable")
    ]
    return {"tweets": tweets, "nextCursor": page["nextCursor"]}
```

```ts
import { TwittrAPI, isUnavailableTweet } from "twittrapi";

const client = new TwittrAPI({ format: "simple" }); // key from TWITTRAPI_API_KEY

export async function searchX(query: string, cursor?: string) {
  const page = await client.search.tweets({ query, category: "Latest", cursor });
  return {
    tweets: page.data
      .filter((t) => !isUnavailableTweet(t))
      .map((t) => ({ id: t.id, author: t.author?.username, createdAt: t.createdAt, text: t.text, likes: t.counts.likes })),
    nextCursor: page.nextCursor,
  };
}
```

```go
client, err := twittrapi.NewClient(twittrapi.WithFormat(twittrapi.FormatSimple))
if err != nil {
	log.Fatal(err)
}
page, err := twittrapi.FetchSimplePage[twittrapi.SimpleTweet](ctx, client.Search.Tweets,
	twittrapi.SearchParams{Query: "from:XDevelopers", Category: twittrapi.CategoryLatest})
if err != nil {
	return err
}
for _, t := range page.Data {
	fmt.Println(t.ID, t.Text, t.Counts.Likes)
}
```

To keep an agent from burning through your balance: give it a small tool set, set `max_chars` low, cap the number of pages in the system prompt, and keep the balance small. At zero balance calls return 402 and are not charged. Example prompts and token sizes: [Twitter/X data for AI agents](https://www.twittrapi.com/use-cases/ai-agents). Agents that sign themselves up or pay on their own: [For AI agents](https://www.twittrapi.com/docs/for-agents).

## Automation platforms

| Platform | How to add it | Repository |
| --- | --- | --- |
| n8n | Settings > Community Nodes > Install > `n8n-nodes-twittrapi` | [n8n-nodes-twittrapi](https://github.com/twittrapi/n8n-nodes-twittrapi) |
| Make | Custom app; setup in the repository | [twittrapi-make](https://github.com/twittrapi/twittrapi-make) |
| Apify | Actor that returns flat JSON, CSV or Excel; runs on Apify's billing, no TwittrAPI key needed | [twittrapi-apify](https://github.com/twittrapi/twittrapi-apify) |

The n8n node can also be attached to an AI Agent node as a tool. On self-hosted n8n that needs `N8N_COMMUNITY_PACKAGES_ALLOW_TOOL_USAGE=true`. Step-by-step workflows for n8n and Make: [No-code: n8n and Make](https://www.twittrapi.com/docs/no-code).

## Examples

[github.com/twittrapi/examples](https://github.com/twittrapi/examples) has short, runnable programs in Python, Node.js, Go and shell: export followers to CSV, monitor a keyword into Slack, trends by country, replies to a tweet and more. Each folder has its own README.

```bash
git clone https://github.com/twittrapi/examples.git twittrapi-examples
```
