Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.xquik.com/llms.txt

Use this file to discover all available pages before exploring further.

Build a Microsoft Agent Framework agent that can search tweets, hand off IDs and cursors, post tweets, replay stored monitor events, and run extraction jobs - all through Xquik’s MCP server.

Prerequisites

  • Python 3.10+
  • Xquik API key (xq_...)
  • An LLM API key (OpenAI, Azure OpenAI, or any supported provider)

Install

pip install agent-framework mcp
The agent-framework meta-package installs all core and provider sub-packages. The mcp package enables MCPStreamableHTTPTool support.

Full Example

import asyncio
from pathlib import Path
from agent_framework import ChatAgent, MCPStreamableHTTPTool
from agent_framework.openai import OpenAIChatClient


async def main():
    mcp_tool = MCPStreamableHTTPTool(
        name="xquik",
        url="https://xquik.com/mcp",
        headers={"x-api-key": "xq_YOUR_KEY_HERE"},
        description="X (Twitter) data platform with 120 API endpoints",
    )

    async with mcp_tool:
        agent = ChatAgent(
            chat_client=OpenAIChatClient(model_id="gpt-4o"),
            name="xquik_agent",
            instructions="You help users interact with X (Twitter) via the Xquik API.",
            tools=[mcp_tool],
        )

        handoff_prompt = (
            "Search for tweets about AI agents. Return compact JSON with "
            "query, route_used, tweets[{tweet_id,text,author_username,created_at}], "
            "has_more, next_cursor."
        )
        response = await agent.run(handoff_prompt)
        Path("xquik-agent-handoff.json").write_text(response.text, encoding="utf-8")


asyncio.run(main())
The agent auto-discovers all Xquik tools (explore + xquik) and can call any of the 120 API endpoints. The MCP runtime returns normalized snake_case fields through xquik.request(), so keep prompts aligned with tweet_id, has_more, next_cursor, and returned job IDs.

Handoff Checklist

Tweet search rows

Store tweet_id, text, author_username, created_at, has_more, next_cursor, and the original q.

User profile rows

Store source id as user_id, plus username, name, followers, verified, profile_picture, has_more, next_cursor, and the source lookup or search query.

Trend rows

Store each trend name, rank, query, and description. Keep response count, woeid, and the requested region with the run checkpoint.

Monitor and webhook setup

Store the returned monitor id as monitor_id, event_types, next_billing_at, the returned webhook id as webhook_id, url, and the one-time secret in a secret manager. On production deliveries, store delivery_id for receiver retry de-dupe and stream_event_id when one monitor event should process once across endpoint changes.

Stored event replay

Store event_id, type, monitor_id, monitor_type, occurred_at, has_more, next_cursor, and the after query for the next page.

Extraction jobs

Store extraction_id, status, poll, and export_after_complete; poll before loading CSV, JSON, or XLSX rows.

Writes

Store tweet_id or write_action_id, reply_to_tweet_id, status, charged_credits, and poll; do not resend pending writes.

Media attachments

For tweets or replies, pass public URLs in media and store tweet_id or write_action_id. For DMs, upload first, pass one media_id in media_ids, store message_id, and leave reply_to_message_id unset.

Streaming Responses

Use run_stream for real-time token streaming:
async with mcp_tool:
    agent = ChatAgent(
        chat_client=OpenAIChatClient(model_id="gpt-4o"),
        name="xquik_agent",
        instructions="You help users interact with X (Twitter) via the Xquik API.",
        tools=[mcp_tool],
    )

    async for update in agent.run_stream("What are the trending topics on X right now?"):
        if update.text:
            print(update.text, end="")

Multi-Agent Orchestration

Use GroupChatBuilder to coordinate specialized agents sharing the same MCP tools:
import asyncio
from pathlib import Path
from agent_framework import ChatAgent, MCPStreamableHTTPTool, GroupChatBuilder
from agent_framework.openai import OpenAIChatClient


async def main():
    client = OpenAIChatClient(model_id="gpt-4o")

    mcp_tool = MCPStreamableHTTPTool(
        name="xquik",
        url="https://xquik.com/mcp",
        headers={"x-api-key": "xq_YOUR_KEY_HERE"},
        description="X (Twitter) data platform",
    )

    async with mcp_tool:
        researcher = ChatAgent(
            chat_client=client,
            name="researcher",
            instructions=(
                "Search X for tweets and user profiles. Return compact JSON with "
                "tweet_id, author_username, text, created_at, has_more, next_cursor, "
                "and route_used."
            ),
            tools=[mcp_tool],
        )

        analyst = ChatAgent(
            chat_client=client,
            name="analyst",
            instructions="Analyze tweet data and identify trends, sentiment, and key influencers.",
        )

        workflow = (
            GroupChatBuilder()
            .with_orchestrator(
                ChatAgent(
                    chat_client=client,
                    name="coordinator",
                    instructions="Coordinate research tasks. Delegate data collection to the researcher and analysis to the analyst.",
                )
            )
            .participants([researcher, analyst])
            .build()
        )

        result = await workflow.run(
            "Find the top 10 most engaged tweets about AI agents and analyze the sentiment."
        )
        Path("xquik-agent-workflow-handoff.json").write_text(
            result.text,
            encoding="utf-8",
        )


asyncio.run(main())

Per-Run Headers

Pass API keys dynamically via tool_resources for multi-tenant apps where each user has their own Xquik API key:
mcp_tool = MCPStreamableHTTPTool(
    name="xquik",
    url="https://xquik.com/mcp",
    description="X (Twitter) data platform",
)

async with mcp_tool:
    agent = ChatAgent(
        chat_client=OpenAIChatClient(model_id="gpt-4o"),
        name="xquik_agent",
        instructions="You help users interact with X (Twitter) via the Xquik API.",
        tools=[mcp_tool],
    )

    response = await agent.run(
        "Search for tweets about AI agents",
        tool_resources={"xquik": {"headers": {"x-api-key": user_api_key}}},
    )
Headers passed via tool_resources are available only for the current run and are not persisted.

Azure OpenAI

Swap OpenAIChatClient for AzureOpenAIChatClient to use Azure-hosted models:
from agent_framework.azure import AzureOpenAIChatClient

client = AzureOpenAIChatClient(
    endpoint="https://your-resource.openai.azure.com",
    deployment_name="gpt-4o",
    api_key="your-azure-key",
)

agent = ChatAgent(
    chat_client=client,
    name="xquik_agent",
    instructions="You help users interact with X (Twitter) via the Xquik API.",
    tools=[mcp_tool],
)

Environment Variables

Store your API keys in a .env file instead of hardcoding them:
.env
XQUIK_API_KEY=xq_YOUR_KEY_HERE
OPENAI_API_KEY=sk-...
import os
from dotenv import load_dotenv
from agent_framework import MCPStreamableHTTPTool

load_dotenv()

mcp_tool = MCPStreamableHTTPTool(
    name="xquik",
    url="https://xquik.com/mcp",
    headers={"x-api-key": os.environ["XQUIK_API_KEY"]},
    description="X (Twitter) data platform",
)

Package Versions

PackageVersion
agent-framework1.0.0+
agent-framework-core1.0.0+
mcp1.9.2+
Last modified on May 22, 2026