How to Build an Optionomics MCP Chatbot in Python with Chainlit

Create a complete browser chatbot that lets an AI assistant call Optionomics market data tools through MCP

Introduction

The Optionomics MCP server lets AI assistants connect directly to Optionomics market intelligence through the Model Context Protocol. Instead of copying quotes, options flow, gamma exposure, unusual activity, volatility metrics, or event context into a prompt by hand, your chatbot can retrieve that data through MCP while it is answering the user.

This tutorial builds a complete Python chatbot for Optionomics MCP.

The chatbot will:

  • Run in the browser with a polished chat interface
  • Keep Optionomics credentials server-side
  • Use the OpenAI Responses API for model orchestration
  • Attach the Optionomics MCP server as a remote MCP tool source
  • Preserve conversation state across chat turns
  • Let the model choose the right Optionomics tools for each market question
  • Return clear, caveated, research-oriented answers

The stack:

  • Python 3.11+ for the runtime
  • Chainlit for the chatbot UI and chat lifecycle
  • OpenAI Python SDK for the Responses API
  • OpenAI Responses API remote MCP tools for standards-based tool use
  • Optionomics MCP for authenticated market intelligence
  • Pydantic Settings for environment-based configuration

By the end, you will be able to run:

chainlit run app.py -w

Then open a browser chat and ask questions like:

Use Optionomics data to summarize the current options flow sentiment for SPY. Include bullish evidence, bearish evidence, and key levels to watch.

The model can call the Optionomics MCP server while answering. Your Python app does not need to manually implement a separate function for every market data workflow.

This is not a trading bot. It does not place trades, connect to a brokerage account, or make decisions for the user. It is a market research chatbot that uses Optionomics data to explain what is happening.

Optionomics MCP chatbot screenshot

What Is MCP?

MCP stands for Model Context Protocol. It is a standard way for AI applications to connect to external tools and data sources.

Without MCP, you often have to write custom integration code for every capability:

  • One function for quotes
  • One function for options chains
  • One function for options flow
  • One function for unusual activity
  • One function for gamma exposure
  • One function for news
  • One function for earnings
  • One function for IV term structure

That approach works, but it creates a lot of custom glue code. MCP gives the model a standard tool interface. The model can discover the available tools, decide when a tool is relevant, call it, and use the result in the final answer.

Optionomics exposes market data and analytics through a remote MCP server:

https://optionomics.ai/mcp

In this tutorial, we attach that server to each model request as a remote MCP tool. The chatbot sends the user’s question to the model, the model decides which Optionomics tools to call, and the final response comes back to Chainlit.

Why Use Chainlit for the Chatbot?

Chainlit is a modern Python framework for building conversational AI applications. It is a strong fit for this example because it gives us a real browser chatbot without requiring a separate frontend project.

With Chainlit, you get:

  • A ready-to-use chat UI
  • Chat lifecycle hooks such as on_chat_start and on_message
  • Per-chat user session state
  • Starter prompts for common workflows
  • Local development with hot reload
  • A path to authentication, persistence, and production deployment later

FastAPI is excellent when you want to build an HTTP API. For this tutorial, the user asked for a chatbot, so Chainlit is the better example. It lets us focus on the AI and MCP integration instead of frontend scaffolding.

What the Optionomics MCP Server Provides

The Optionomics MCP server exposes market intelligence tools that are useful for traders, analysts, developers, and AI-assisted research workflows.

Available tools include:

Tool What it helps answer
Stock Quote What is the current or historical OHLC, volume, and price change for a symbol?
Options Chain What strikes, expirations, prices, open interest, and Greeks are available?
Option Metrics What are the put/call ratio, IV rank, IV percentile, GEX, DEX, max pain, and call/put walls?
Options Flow Is recent options flow more bullish or bearish? What are the top calls and puts?
Net Flow How has net call or put premium changed over time?
Unusual Activity What high-premium or high-volume options activity stands out?
Dark Pool Levels Where are large dark pool derived support and resistance levels?
Support and Resistance What key levels are implied by options flow activity?
Market Overview How are major index ETFs such as SPY, QQQ, DIA, and IWM moving?
Gamma Exposure Where are important GEX strike levels and gamma regime context?
Trend Analysis What does price trend, momentum, volatility, and level context look like?
IV Term Structure How do IV30, IV60, IV90, IV rank, and realized-vs-implied volatility compare?
Price History What has daily OHLCV, return, drawdown, average volume, and realized volatility looked like?
Earnings Calendar What earnings events are coming up?
News What recent ticker or market headlines are relevant?
Events What macro, Fed, Treasury, commodity, filing, earnings, or company events may matter?

Available resources include:

Resource What it provides
Available Symbols The list of tracked symbols
Trading Days The list of available trading dates

The model can use these tools when a question needs current or historical market data.

Requirements

Before writing code, make sure you have the following.

1. Optionomics Vega Subscription

MCP access requires an Optionomics Vega subscription.

2. Optionomics API Credentials

You need:

  • The email address on your Optionomics account
  • An Optionomics API token from Account > API Keys

See the API Key Management guide if you need help creating a token.

3. OpenAI API Key

This tutorial uses the OpenAI Responses API because it supports remote MCP servers programmatically. You need an OpenAI API key in OPENAI_API_KEY.

4. Python 3.11+

Check your Python version:

python --version

If your system uses python3, run:

python3 --version

Authentication Patterns

Optionomics supports two authentication styles for MCP clients.

Header Authentication

Many MCP clients can send custom headers directly:

X-USER-EMAIL: [email protected]
X-USER-TOKEN: your-api-token

This is commonly used by editor integrations such as Cursor, VS Code, Windsurf, and Gemini CLI.

Bearer Authentication

Some programmatic clients prefer a single Authorization header. Optionomics also accepts this format:

Authorization: Bearer base64(email:token)

For example, if your email is [email protected] and your token is abc123, encode this string:

The encoded value is sent as a bearer token.

Important: Base64 is not encryption. Treat the encoded value exactly like the original API token. Do not commit it, log it, paste it into support tickets, or expose it in browser code.

The chatbot below builds the bearer token at runtime from environment variables.

Architecture

The chatbot flow looks like this:

Browser chat UI
      |
      v
Chainlit app.py
      |
      v
OpenAI Responses API request
      |
      v
Model decides whether to call Optionomics MCP tools
      |
      v
Optionomics MCP server at https://optionomics.ai/mcp
      |
      v
Structured market data returns to the model
      |
      v
Final answer returns to Chainlit
      |
      v
Assistant message appears in the chat UI

The Python app stays small because the market data integration lives behind MCP. The chatbot does not need to know every possible Optionomics tool ahead of time. It gives the model access to the server, and the model chooses the right tool calls based on the user’s question.

Create the Project

Create a new directory:

mkdir optionomics-mcp-chatbot
cd optionomics-mcp-chatbot

Create and activate a virtual environment:

python -m venv .venv
source .venv/bin/activate

On Windows PowerShell:

python -m venv .venv
.venv\Scripts\Activate.ps1

Create this project structure:

optionomics-mcp-chatbot/
  .env
  .env.example
  .gitignore
  requirements.txt
  app.py

Install Dependencies

Create requirements.txt:

chainlit
openai
pydantic-settings

Install dependencies:

pip install -r requirements.txt

If you use uv, install the same dependencies with:

uv pip install -r requirements.txt

For a production application, pin versions after testing. For example:

chainlit==2.0.0
openai==2.0.0
pydantic-settings==2.7.0

The exact latest versions will change over time, so check your dependency resolver and test before deploying.

Configure Environment Variables

Create .env.example:

OPENAI_API_KEY=sk-your-openai-key
OPENAI_MODEL=gpt-5.5

OPTIONOMICS_EMAIL=[email protected]
OPTIONOMICS_TOKEN=your-optionomics-api-token
OPTIONOMICS_MCP_URL=https://optionomics.ai/mcp

Copy it to .env:

cp .env.example .env

Edit .env and replace the placeholder values.

Create .gitignore:

.env
.venv/
__pycache__/
.chainlit/

Do not commit .env. The chatbot runs server-side, so your OpenAI key and Optionomics token should never be sent to the browser.

Complete Chatbot Code

Create app.py with the complete code below.

from __future__ import annotations

import base64
from functools import lru_cache
from typing import Any

import chainlit as cl
from openai import AsyncOpenAI, OpenAIError
from pydantic import Field
from pydantic_settings import BaseSettings, SettingsConfigDict


SYSTEM_INSTRUCTIONS = """
You are an options market research chatbot powered by Optionomics data.

Use Optionomics MCP tools whenever the user asks for current or historical
market data, including quotes, options chains, options flow, unusual activity,
net flow, gamma exposure, dark pool levels, support and resistance, IV term
structure, price history, earnings, news, or market-moving events.

When answering:
- Be clear about the symbol, timeframe, and data type being discussed.
- Separate observed data from interpretation.
- Summarize bullish evidence, bearish evidence, and neutral or mixed evidence when useful.
- Mention important caveats such as stale data, missing data, liquidity, event risk, and market regime.
- Do not claim certainty about future price movement.
- Do not provide personalized financial advice.
- Do not tell the user to buy, sell, short, hold, or enter a specific trade.
- Keep answers readable for an options-aware but busy trader.
""".strip()


WELCOME_MESSAGE = """
Welcome to the Optionomics MCP chatbot.

Ask about options flow, unusual activity, gamma exposure, IV term structure,
support and resistance, earnings, news, or market overview. I will use
Optionomics MCP tools when current market data is needed.

Example: "Use Optionomics data to summarize SPY options flow, gamma exposure,
and key levels to watch today."
""".strip()


class Settings(BaseSettings):
    """Application settings loaded from environment variables."""

    openai_api_key: str = Field(alias="OPENAI_API_KEY")
    openai_model: str = Field(default="gpt-5.5", alias="OPENAI_MODEL")

    optionomics_email: str = Field(alias="OPTIONOMICS_EMAIL")
    optionomics_token: str = Field(alias="OPTIONOMICS_TOKEN")
    optionomics_mcp_url: str = Field(
        default="https://optionomics.ai/mcp",
        alias="OPTIONOMICS_MCP_URL",
    )

    model_config = SettingsConfigDict(env_file=".env", env_file_encoding="utf-8")


@lru_cache
def get_settings() -> Settings:
    """Load settings once and reuse them across chat turns."""

    return Settings()


@lru_cache
def get_openai_client() -> AsyncOpenAI:
    """Create one AsyncOpenAI client for the Chainlit process."""

    settings = get_settings()
    return AsyncOpenAI(api_key=settings.openai_api_key)


def build_optionomics_bearer_token(settings: Settings) -> str:
    """Build the bearer token for Optionomics MCP authentication."""

    raw_credentials = f"{settings.optionomics_email}:{settings.optionomics_token}"
    encoded_credentials = base64.b64encode(raw_credentials.encode("utf-8")).decode("ascii")

    return f"Bearer {encoded_credentials}"


def optionomics_mcp_tool(settings: Settings) -> dict[str, Any]:
    """Return the remote MCP tool configuration for the Responses API."""

    return {
        "type": "mcp",
        "server_label": "optionomics",
        "server_description": "Optionomics market intelligence, options flow, Greeks, volatility, levels, news, events, and earnings data.",
        "server_url": settings.optionomics_mcp_url,
        "headers": {
            "Authorization": build_optionomics_bearer_token(settings),
        },
        "require_approval": "never",
    }


def build_user_input(message: cl.Message) -> list[dict[str, str]]:
    """Build a Responses API input message from the Chainlit user message."""

    content = f"""
User question:
{message.content.strip()}

Use Optionomics MCP tools if current or historical market data would improve the answer.
If the available data is mixed, incomplete, or inconclusive, say that clearly.
""".strip()

    return [{"role": "user", "content": content}]


def extract_mcp_tool_names(response: Any) -> list[str]:
    """Return MCP tool names used in a response without exposing raw tool output."""

    names: list[str] = []

    for item in getattr(response, "output", []) or []:
        if getattr(item, "type", None) != "mcp_call":
            continue

        name = getattr(item, "name", None)
        if name and name not in names:
            names.append(name)

    return names


@cl.set_starters
async def set_starters() -> list[cl.Starter]:
    """Show useful starter prompts in the Chainlit UI."""

    return [
        cl.Starter(
            label="SPY flow and levels",
            message="Use Optionomics data to summarize SPY options flow, gamma exposure, and key levels to watch today.",
        ),
        cl.Starter(
            label="TSLA unusual activity",
            message="Find notable unusual options activity for TSLA and explain what makes it unusual. Do not make a trade recommendation.",
        ),
        cl.Starter(
            label="NVDA volatility context",
            message="Analyze NVDA IV term structure and options flow. Explain whether the data looks directional, volatility-driven, or mixed.",
        ),
        cl.Starter(
            label="Market overview",
            message="Give me an Optionomics market overview for SPY, QQQ, DIA, and IWM. Focus on price change, volume, and options context.",
        ),
    ]


@cl.on_chat_start
async def on_chat_start() -> None:
    """Initialize per-chat state and greet the user."""

    cl.user_session.set("previous_response_id", None)
    await cl.Message(content=WELCOME_MESSAGE).send()


@cl.on_message
async def on_message(message: cl.Message) -> None:
    """Handle one user chat turn with Optionomics MCP enabled."""

    settings = get_settings()
    client = get_openai_client()
    previous_response_id = cl.user_session.get("previous_response_id")

    response_message = cl.Message(content="Researching with Optionomics MCP...")
    await response_message.send()

    request: dict[str, Any] = {
        "model": settings.openai_model,
        "instructions": SYSTEM_INSTRUCTIONS,
        "tools": [optionomics_mcp_tool(settings)],
        "input": build_user_input(message),
    }

    if previous_response_id:
        request["previous_response_id"] = previous_response_id

    try:
        response = await client.responses.create(**request)
    except OpenAIError as exc:
        response_message.content = (
            "I could not complete the market research request right now. "
            "Check your OpenAI key, Optionomics credentials, model access, and MCP access."
        )
        await response_message.update()
        raise RuntimeError("OpenAI or MCP request failed") from exc

    answer = (response.output_text or "").strip()

    if not answer:
        response_message.content = "The model returned an empty response. Try a more specific market question."
        await response_message.update()
        return

    cl.user_session.set("previous_response_id", response.id)

    tool_names = extract_mcp_tool_names(response)
    tool_note = ""

    if tool_names:
        tool_note = "\n\n_Data checked with Optionomics MCP tools: " + ", ".join(tool_names) + "._"

    response_message.content = answer + tool_note
    await response_message.update()

That is the complete chatbot.

You now have:

  • A browser chat UI
  • Starter prompts
  • Per-chat state with cl.user_session
  • OpenAI Responses API integration
  • Remote MCP server configuration
  • Optionomics bearer token generation
  • Conversation continuity with previous_response_id
  • Tool usage notes that show which Optionomics MCP tools were called
  • Server-side credential handling

Run the Chatbot

Start Chainlit:

chainlit run app.py -w

Chainlit will print a local URL, usually:

http://localhost:8000

Open the URL in your browser. You should see the welcome message and starter prompts.

Try this first prompt:

Use Optionomics data to summarize the current options flow sentiment for SPY. Include bullish evidence, bearish evidence, and key levels to watch.

The chatbot should respond with a market research summary. If the model used Optionomics MCP tools, the answer will include a short note like:

Data checked with Optionomics MCP tools: options_flow, gamma_exposure.

The exact tool names and answer content depend on the current question and available market data.

How Conversation State Works

A chatbot should remember the prior turn. If the user asks:

Analyze SPY options flow today.

They may follow up with:

Now compare that with QQQ.

The second question depends on the first. The code handles this with previous_response_id:

previous_response_id = cl.user_session.get("previous_response_id")

if previous_response_id:
    request["previous_response_id"] = previous_response_id

response = await client.responses.create(**request)
cl.user_session.set("previous_response_id", response.id)

The Responses API can use the previous response as conversation context. This avoids manually copying the entire chat transcript into every request and keeps the example aligned with current Responses API conversation-state patterns.

You still send the Optionomics MCP tool configuration on each request. This keeps tool availability explicit and makes the chatbot resilient if a future request needs to call Optionomics again.

How MCP Is Attached to the Model

This function is the bridge between OpenAI and Optionomics:

def optionomics_mcp_tool(settings: Settings) -> dict[str, Any]:
    return {
        "type": "mcp",
        "server_label": "optionomics",
        "server_description": "Optionomics market intelligence, options flow, Greeks, volatility, levels, news, events, and earnings data.",
        "server_url": settings.optionomics_mcp_url,
        "headers": {
            "Authorization": build_optionomics_bearer_token(settings),
        },
        "require_approval": "never",
    }

The fields mean:

Field Meaning
type Tells the Responses API this is an MCP tool server
server_label A short name for the server inside the model context
server_description Helps the model understand when this server is useful
server_url The remote Optionomics MCP endpoint
headers Authentication headers sent to Optionomics
require_approval Whether MCP tool calls need explicit approval before running

For this server-side chatbot, require_approval: "never" lets the model call Optionomics tools without pausing for a separate approval step. That keeps the chat experience smooth.

If you are building a regulated workflow or a tool that sends sensitive user data to a third-party MCP server, consider an approval flow. For this tutorial, the MCP server is Optionomics and the chatbot is explicitly designed to use Optionomics market data.

Why the Code Uses Bearer Auth

The code builds this header:

Authorization: Bearer base64(email:token)

The implementation:

def build_optionomics_bearer_token(settings: Settings) -> str:
    raw_credentials = f"{settings.optionomics_email}:{settings.optionomics_token}"
    encoded_credentials = base64.b64encode(raw_credentials.encode("utf-8")).decode("ascii")

    return f"Bearer {encoded_credentials}"

This keeps the MCP tool configuration compact. If you are using a client that supports custom headers directly, Optionomics also accepts:

X-USER-EMAIL: [email protected]
X-USER-TOKEN: your-api-token

For the Chainlit chatbot, bearer auth works well because the Python backend creates the header and sends it to the remote MCP server. The browser never sees the token.

Try More Chat Prompts

Use these prompts to test different Optionomics tools.

Market Overview

Give me an Optionomics market overview for SPY, QQQ, DIA, and IWM. Focus on price change, volume, and options context.

Unusual Options Activity

Find notable unusual options activity for TSLA and explain what makes it unusual. Separate bullish and bearish evidence.

Gamma Exposure and Levels

Analyze AAPL gamma exposure and support/resistance. What strikes or levels look important? Keep it educational and avoid trade recommendations.

IV Term Structure

Use Optionomics data to explain NVDA implied volatility term structure. Compare short-term and longer-term IV and explain what could make the interpretation wrong.

Earnings and Event Context

Are there upcoming earnings, news, or market-moving events that could matter for MSFT options? Summarize the key risks.

Follow-Up Question

After asking about one symbol, try a follow-up:

Now compare that setup with QQQ and tell me what is different.

Because the chatbot stores previous_response_id, the model has context from the prior turn.

Verifying Optionomics MCP Credentials Directly

If the chatbot cannot connect, first verify your Optionomics credentials outside Python.

Run this curl request:

curl -s -w "\n%{http_code}" \
  -X POST \
  -H "Content-Type: application/json" \
  -H "X-USER-EMAIL: [email protected]" \
  -H "X-USER-TOKEN: your-api-token" \
  -d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"chainlit-test","version":"1.0"}}}' \
  https://optionomics.ai/mcp

Expected outcomes:

Status Meaning
200 Credentials and MCP access are working
401 Email or token is incorrect
403 Credentials are valid, but the account does not have MCP access

If curl fails, fix credentials or subscription access before debugging Chainlit or OpenAI.

Common Errors and Fixes

401 Unauthorized

This usually means the email or token is wrong.

Check:

  • The email exactly matches your Optionomics account email
  • The token was copied correctly
  • There are no leading or trailing spaces in .env
  • You did not accidentally include shell quotes as part of the value

403 Forbidden

This usually means the credentials are valid but the account does not have the required plan access. MCP access requires a Vega subscription.

OpenAI Authentication Error

If OpenAI authentication fails, check:

  • OPENAI_API_KEY is set
  • The key is active
  • The project has access to the selected model
  • OPENAI_MODEL points to a model that supports the Responses API and MCP tools

Chainlit Starts, but the Chatbot Fails on First Message

This usually means an environment variable is missing or invalid.

Check:

  • .env exists in the same directory as app.py
  • OPENAI_API_KEY is set
  • OPTIONOMICS_EMAIL is set
  • OPTIONOMICS_TOKEN is set
  • OPTIONOMICS_MCP_URL is https://optionomics.ai/mcp

Tool Calls Are Not Happening

The model decides whether tool use is needed. If it answers without calling Optionomics MCP, make the prompt more explicit:

Use Optionomics MCP tools to retrieve the latest SPY options flow and gamma exposure before answering.

You can also make your system instructions stricter if every answer in your app must use fresh Optionomics data.

The Answer Is Too Long

Add formatting guidance to the user prompt:

Keep the answer under 250 words and use sections: Flow, Levels, Volatility, Caveats.

Or adjust SYSTEM_INSTRUCTIONS to enforce your preferred answer style.

Follow-Up Questions Lose Context

Make sure this line runs after every successful response:

cl.user_session.set("previous_response_id", response.id)

Also make sure you are not refreshing the browser or starting a new Chainlit chat session between turns.

Security Best Practices

When connecting any chatbot to market data tools, treat credentials carefully.

Keep Tokens Server-Side

Never expose your Optionomics token in browser JavaScript, mobile apps, public repositories, screenshots, logs, or analytics events.

This tutorial keeps the token inside the Chainlit server process.

Use Environment Variables

Local development can use .env. Production should use your deployment platform’s secret manager.

Examples:

  • Docker secrets
  • Kubernetes secrets
  • Fly.io secrets
  • Render environment variables
  • Railway environment variables
  • AWS Secrets Manager
  • Google Secret Manager
  • Azure Key Vault

Do Not Log Headers

Do not log the MCP Authorization header. If you add request logging, redact credentials.

Add User Authentication Before Deploying

The tutorial app has no user login. That is acceptable for local development, but not for a public deployment.

Before exposing it, add authentication so only approved users can access the chatbot.

Common options:

  • Chainlit authentication
  • OAuth through your identity provider
  • SSO for an internal research tool
  • A private VPN or internal network boundary

Add Abuse Controls

For production, consider:

  • Per-user rate limits
  • Message length limits
  • Request timeout limits
  • Token and cost monitoring
  • Prompt logging with sensitive data redaction
  • Monitoring for repeated failed auth

Improving the Chatbot for Production

The sample app is complete for local development, but production systems usually need a few more pieces.

1. Streaming Responses

The example uses a simple non-streaming Responses API call. This keeps the code easier to understand. For production chat, streaming improves perceived speed because users see text appear as the model writes.

The Responses API supports streaming events, and Chainlit supports token streaming with stream_token. If you add streaming, handle non-text events carefully because MCP tool calls also appear in the response event stream.

2. Persistent Chat History

The example uses previous_response_id stored in the Chainlit user session. That is enough for a live chat session. If you want users to resume old chats, add persistence.

You can store:

  • Chainlit session ID
  • User ID
  • Latest previous_response_id
  • User messages
  • Assistant answers
  • Tool names used
  • Timestamps

Do not store raw credentials or authorization headers.

3. Tool Use Transparency

The example adds a small note showing MCP tool names used:

Data checked with Optionomics MCP tools: options_flow, gamma_exposure.

That gives users confidence that the chatbot retrieved data rather than guessing. For production, you can make this more polished with Chainlit steps or metadata panels.

Avoid exposing raw tool traces to end users unless you have reviewed them for privacy and readability.

4. Prompt Profiles

You may want different modes:

  • Quick summary
  • Deep research
  • Volatility-focused
  • Flow-focused
  • Earnings-focused
  • Education mode

Chainlit supports chat profiles and settings. You can map each profile to different system instructions.

5. Caching

Market overview questions can be repetitive. Short-lived caching can reduce latency and cost.

Use cache durations carefully:

  • Very short cache for active market questions
  • Longer cache for historical explanations
  • No cache for sensitive user-specific prompts

6. Evaluation

Create a small set of test prompts and review answers regularly.

Useful evaluation prompts:

  • “Summarize SPY flow without making a recommendation.”
  • “Explain mixed bullish and bearish evidence for TSLA.”
  • “Compare NVDA IV term structure before earnings.”
  • “Give key caveats for a gamma exposure interpretation.”

Check whether the chatbot:

  • Uses tools when it should
  • Avoids trade recommendations
  • Separates data from interpretation
  • Mentions uncertainty
  • Keeps answers concise enough for users

Prompting Tips for Better Results

MCP gives the model tools, but the prompt still matters. Clear prompts lead to better tool selection and better answers.

Be Specific About Symbols

Less effective:

What is going on today?

More effective:

Use Optionomics data to summarize today's options flow, gamma exposure, and key levels for SPY.

Ask for Evidence

Less effective:

Is TSLA bullish?

More effective:

Use Optionomics options flow and unusual activity data to summarize bullish and bearish evidence for TSLA. Do not make a trade recommendation.

Define the Output Format

Less effective:

Analyze NVDA.

More effective:

Analyze NVDA using Optionomics data. Return four sections: price context, options flow, volatility context, and key risks.

Ask for Caveats

Good research answers should explain uncertainty:

If the data is mixed or inconclusive, say that clearly and explain what would change the interpretation.

Full Local Test Checklist

Use this checklist if something is not working.

  1. Confirm Python is installed:
python --version
  1. Confirm dependencies are installed:
pip freeze
  1. Confirm .env exists:
ls -la .env
  1. Confirm Optionomics MCP credentials with curl:
curl -s -w "\n%{http_code}" \
  -X POST \
  -H "Content-Type: application/json" \
  -H "X-USER-EMAIL: [email protected]" \
  -H "X-USER-TOKEN: your-api-token" \
  -d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"chainlit-test","version":"1.0"}}}' \
  https://optionomics.ai/mcp
  1. Start Chainlit:
chainlit run app.py -w
  1. Open the browser:
http://localhost:8000
  1. Ask a direct MCP-backed question:
Use Optionomics data to summarize the current market overview for SPY and QQQ.
  1. Ask a follow-up to test conversation state:
Now compare that with IWM.

Frequently Asked Questions

Can I call the Optionomics MCP server without OpenAI?

Yes. MCP is a protocol, not an OpenAI-only feature. You can connect with any MCP-compatible client that supports remote Streamable HTTP transport and custom headers. This tutorial uses the OpenAI Responses API because it gives Python developers a compact way to combine model reasoning, conversation state, and remote MCP tool use.

Can I use X-USER-EMAIL and X-USER-TOKEN instead of bearer auth?

Yes. Optionomics supports those headers. This tutorial uses bearer auth because it is convenient for remote MCP tool configuration in Python.

Does the chatbot place trades?

No. The chatbot is for market research and explanation. It does not place orders, manage brokerage accounts, or make trading decisions.

Does the model always call an MCP tool?

No. The model decides whether tool use is needed. If you want fresh Optionomics data for every answer, make that explicit in the system instructions or user prompt.

Can I deploy this chatbot?

Yes. Chainlit apps can be deployed like other Python web apps. Before deploying publicly, add authentication, rate limits, monitoring, and secure secret management.

Can I still build this with FastAPI?

Yes. FastAPI is a good choice if you want to expose an API endpoint to your own frontend. Chainlit is better for a tutorial chatbot because it gives you a complete browser chat UI with less code.

Conclusion

Using the Optionomics MCP server from Python is a powerful way to build market-aware AI applications. With Chainlit, the OpenAI Responses API, and remote MCP tools, you can create a browser chatbot that answers natural-language options market questions while retrieving relevant Optionomics data behind the scenes.

The key ideas are:

  • Use Chainlit when you want a complete Python chatbot UI.
  • Use the Responses API for current remote MCP tool support.
  • Attach https://optionomics.ai/mcp as the remote MCP server.
  • Keep Optionomics credentials server-side.
  • Use previous_response_id for conversation continuity.
  • Let the model call Optionomics tools when market data is needed.
  • Require clear, caveated, research-oriented answers.
  • Add authentication and abuse controls before production deployment.

For more setup options, see the full Optionomics MCP Server guide. For token creation and credential management, see API Key Management.


Disclaimer: Optionomics MCP tools provide market data and analytics for research and education. They do not guarantee outcomes and should not be treated as personalized financial advice. Always do your own research, understand the risks, and never trade with money you cannot afford to lose.

mcp python chainlit chatbot api ai options flow developer

Master options trading with Optionomics

Get real-time options flow, AI-powered insights, and advanced analytics.

Get started

Optionomics Documentation

Getting Started
Main Features
Daily Analytics
Historical Analytics

Optionomics Documentation