Oracle3
Open-source trading engine and MCP server for prediction markets. Fee-aware no-arbitrage trading across related contracts, live on Kalshi, Polymarket and Solana or on paper.
Pay-per-call crypto sentiment API over x402. News sentiment from 9 outlets plus the Fear & Greed Index. USDC on Base, no signup.
FinancePython · DockerfileGitHub @whatevercat-creatorOnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
Owners of public repositories under a personal GitHub account can sign in to verify ownership and manage the introduction themselves. No administrator approval is needed.
Sign in, generate a verification file, and commit it to this repository’s default branch within 30 minutes. Files on other branches or forks do not count. Then check the file below to manage the project without administrator approval. Keep the file to retain your access.
If needed, you will go to sign-in. After signing in, return here and press your chosen verification button again.
Run /nomorevibe verify in your project folder to verify ownership and manage the introduction yourself.
Verify in one minuteAsk about other verification options
The maker's introduction consists of the line above. Read the repository README for more details. Repository README ↗
Loading the full README.
Read the full README ↗Pay-per-call crypto sentiment API for AI agents. No API keys, no subscriptions — agents discover it, get an HTTP 402, pay in USDC on Base, and get the data.
Sentiment sources (all free, no keys required):
Scoring: VADER sentiment analysis, extended with a crypto slang lexicon
(moon, rekt, rug, hodl, bullish/bearish, etc.) so slang isn't scored as neutral.
Each headline is matched and scored on its title plus its feed description with
HTML tags, entities, feed footers and the outlet's own name removed
(clean_text in app/sources/news.py; method 72h-hl24-v2 from 2026-10-21).
Only headlines published in the last 72 hours count, and each headline's
weight halves for every 24 hours of age (app/window.py). When the effective
sample size is below 5, the label is insufficient recent news.
You need an address to receive USDC payments. Any standard Ethereum-style wallet works on Base (e.g. Coinbase Wallet, MetaMask configured for Base). You do not need to give this app your private key — only the public address, to receive funds.
cd crypto-sentiment-x402
cp .env.example .env
# edit .env and set PAY_TO_ADDRESS to your wallet address
pip install -r requirements.txt
uvicorn app.main:app --reload
Visit http://localhost:8000 — you'll see the API description.
Calling http://localhost:8000/sentiment/BTC without payment returns an
HTTP 402 with payment instructions, exactly what an agent's x402 client
would see and act on automatically.
To actually test a paid call, use the official x402 test client (needs Base Sepolia testnet USDC — free from the Base Sepolia faucet):
pip install x402
python -m x402.examples.client --url http://localhost:8000/sentiment/BTC
render.yaml automatically.PAY_TO_ADDRESS environment variable to your
wallet address.Dockerfile and gives you a public HTTPS
URL like https://crypto-sentiment-x402.onrender.com.That's it — testnet mode is on by default, so nothing costs real money
until you flip X402_NETWORK to mainnet (step 4 below).
X402_NETWORK=mainnetCDP_API_KEY_ID=...CDP_API_KEY_SECRET=...PAY_TO_ADDRESS = your mainnet Base address (double-check it's
not a testnet-only address)Start with a low price (X402_PRICE_USD, default $0.01) while you
validate everything works end-to-end.
This is the x402 Bazaar — Coinbase's discovery layer, essentially a search engine for agents looking for x402 services.
description field in app/main.py's RouteConfig clear and specific
(already set) — that text is what shows up in Bazaar search results.https://api.cdp.coinbase.com/platform/v2/x402/discovery/resources
(public, no key needed) to confirm your service appears after going live.Prefer agents calling this over MCP instead of raw HTTP? mcp_server.py
wraps the same API as MCP tools (crypto_sentiment, get_hourly_history
and three free info tools) -- the server pays
for each call from its own CDP-managed wallet, so callers never touch
crypto directly. See MCP.md for setup.
Three tools need no wallet, no CDP key and pay nothing. The server starts without any CDP variables, so you can install it and try these first:
list_supported_coins — the 24 supported ticker symbols and names.archive_coverage — what the hourly archive holds (GET /archive):
first reading, row counts and missing hours per symbol.price_quote(symbol) — makes one unpaid request and reads the 402
payment requirements: price, network, asset and the payTo address.Two tools are paid, from your own CDP wallet in USDC on Base:
crypto_sentiment(symbol) — the current reading, $0.01 per call.
Unsupported coins and coins with too little recent news are refused and
not charged.get_hourly_history(symbol, start, end) — past hourly readings
(GET /history/{symbol}), $0.05 per call. Recorded live and never
backfilled; start/end are ISO 8601, default the last 7 days, at most
30 days per call. The symbol has to be one archive_coverage lists as
logged. Unlogged symbols, invalid ranges and ranges with no readings are
refused and not charged.Wallet setup is in MCP.md.
Prefer a monthly bill over pay-per-call USDC? GET /v1/sentiment/{symbol}
takes an X-API-Key header instead of an x402 payment, backed by Free /
Starter ($15/mo) / Pro ($59/mo) tiers. See BILLING.md for
setup, or GET /billing/pricing on a running instance for current pricing.
Watch a symbol and get pinged (webhook / Discord / Telegram) when its
sentiment moves, instead of polling /sentiment yourself. Bundled into the
Starter/Pro subscription tiers -- see ALERTS.md.
Sells access to the history of sentiment readings, not just the current
one -- a background job takes one snapshot per symbol per day, and
subscribers on the Pro or "Data Access" tier can export everything
collected so far as CSV or JSON via GET /dataset/export. See DATASET.md
(there's no backfilled history -- it only has data from whenever you turn
the snapshot loop on).
Listed on the RapidAPI Hub
for developers who'd rather discover and pay for it through RapidAPI's
marketplace instead of Stripe or x402 directly. Same underlying data,
served from GET /rapidapi/sentiment/{symbol} -- traffic is only accepted
when it's routed through RapidAPI's proxy (validated via a shared secret
header), so this endpoint isn't meant to be called directly. Plans there
mirror the Stripe tiers: Free (100 req/mo), $15/mo (3,000 req), $59/mo
(15,000 req).
Route sentiment-shift alerts into Zapier (via the existing webhook channel -- no new endpoint needed) or enrich TradingView price alerts with live sentiment before relaying them to your webhook/Discord/ Telegram. See INTEGRATIONS.md.
| Endpoint | Price | Description |
|---|---|---|
GET / | Free | Service info |
GET /health | Free | Health check |
GET /sentiment/{symbol} | $0.01 (configurable) | Aggregate sentiment for a symbol, e.g. /sentiment/BTC |
Example paid response:
{
"symbol": "BTC",
"name": "Bitcoin",
"overall_sentiment": {
"sample_size": 42,
"average_compound": 0.21,
"label": "bullish",
"positive_pct": 55.0,
"negative_pct": 15.0,
"neutral_pct": 30.0,
"unweighted_compound_72h": 0.17,
"effective_sample_size": 31.4,
"newest_headline_age_hours": 1.6,
"window": "72h-hl24-v2"
},
"drivers": [{ "title": "...", "source": "CoinDesk", "link": "https://...", "published": "...", "score": 0.62, "weight": 0.93, "effect": 0.03 }],
"drivers_summary": "3 of the top 5 headlines are positive, 2 are negative.",
"breakdown": {
"news": { "...": "..." },
"fear_greed_index": { "value": 62, "classification": "Greed" }
},
"sources": ["coindesk.com RSS", "..."]
}
app/sources/reddit.py is left in the repo
unused in case that changes in the future.app/coins.py has a starter list of ~15 symbols. Add more
as needed — unmapped symbols still work, just with slightly less accurate
news matching (falls back to matching on the symbol itself).exact payment scheme on Base/EVM. The x402 SDK also
supports Solana (ExactSvmServerScheme) if you want to accept SOL-based
USDC too — see the commented-out import in app/main.py's dependencies.routes dict in app/main.py.