crypto-sentiment-x402-mcp
# Crypto Sentiment API (x402)
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):**
- Crypto news RSS (9 outlets) — CoinDesk, Cointelegraph, Decrypt, Bitcoin
Magazine, The Block, CryptoSlate, NewsBTC, CryptoPotato, The Defiant
(DL News was removed on 2026-10-04: its feed served only April-May 2026 items)
- Fear & Greed Index — alternative.me
**Scoring:** VADER sentiment analysis, extended with a crypto slang lexicon
(moon, rekt, rug, hodl, bullish/bearish, etc.) so slang isn't scored as neutral.
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`.
---
## 1. Get a Base wallet address
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.
## 2. Run it locally (testnet — free, no real money)
```bash
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](https://docs.base.org/tools/network-faucets)):
```bash
pip install x402
python -m x402.examples.client --url http://localhost:8000/sentiment/BTC
```
## 3. Deploy (simplest path: Render.com)
1. Push this folder to a new GitHub repo.
2. Go to [render.com](https://render.com) → New → Blueprint → connect the repo.
Render will read `render.yaml` automatically.
3. When prompted, set the `PAY_TO_ADDRESS` environment variable to your
wallet address.
4. Deploy. Render builds the `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).
## 4. Go live with real USDC payments
1. Sign up for a free [Coinbase Developer Platform](https://portal.cdp.coinbase.com)
account and create an API key — this is required for the mainnet
facilitator (production-grade payment verification/settlement).
2. In Render, set:
- `X402_NETWORK=mainnet`
- `CDP_API_KEY_ID=...`
- `CDP_API_KEY_SECRET=...`
- `PAY_TO_ADDRESS` = your **mainnet** Base address (double-check it's
not a testnet-only address)
3. Redeploy. Calls now settle real USDC on Base mainnet.
Start with a low price (`X402_PRICE_USD`, default `$0.01`) while you
validate everything works end-to-end.
## 5. List it so AI agents can find and pay you
This is the **x402 Bazaar** — Coinbase's discovery layer, essentially a
search engine for agents looking for x402 services.
- If you're using the **CDP facilitator** (i.e. you're on mainnet per step
4), your service becomes automatically discoverable in the Bazaar once
you process your first real payment through it — no separate signup.
- To improve how well agents can find and understand it, keep the
`description` field in `app/main.py`'s `RouteConfig` clear and specific
(already set) — that text is what shows up in Bazaar search results.
- You can browse the current Bazaar listing yourself at
`https://api.cdp.coinbase.com/platform/v2/x402/discovery/resources`
(public, no key needed) to confirm your service appears after going live.
- Optional extra distribution: submit your API to
[x402bazaar.org](https://www.x402bazaar.org/), a community-run directory
of x402 services, separate from Coinbase's own Bazaar.
## MCP server (Claude Desktop / Claude Code)
Prefer agents calling this over MCP instead of raw HTTP? `mcp_server.py`
wraps the same API as an MCP tool (`crypto_sentiment`) -- the server pays
for each call from its own CDP-managed wallet, so callers never touch
crypto directly. See [MCP.md](MCP.md) for setup.
### Try it free
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.
`crypto_sentiment` is the paid reading: $0.01 per call in USDC on Base,
paid from your own CDP wallet (setup in [MCP.md](MCP.md)).
## Subscription tiers (Stripe, no crypto required)
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](BILLING.md) for
setup, or `GET /billing/pricing` on a running instance for current pricing.
## Sentiment-shift alerts
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](ALERTS.md).
## Historical dataset export
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](DATASET.md)
(there's no backfilled history -- it only has data from whenever you turn
the snapshot loop on).
## Also on RapidAPI
Listed on the [RapidAPI Hub](https://rapidapi.com/whatevercat/api/crypto-sentiment-analysis)
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).
## Zapier & TradingView integrations
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](INTEGRATIONS.md).
## API reference
| 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:
```json
{
"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"
},
"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", "..."]
}
```
## Notes and limitations
- Reddit was removed as a source: Reddit's Responsible Builder Policy
prohibits commercial use of their data without written approval, which
this paid API would violate. `app/sources/reddit.py` is left in the repo
unused in case that changes in the future.
- Coin coverage: `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).
- Only supports the `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.
- Add more paid endpoints (e.g. historical sentiment, multi-symbol batch
queries) by adding entries to the `routes` dict in `app/main.py`.
TDQS
Scored across 4 tools
Each tool has a clearly distinct purpose: crypto_sentiment fetches the paid sentiment reading, list_supported_coins enumerates symbols, archive_coverage reports what data exists, and price_quote reads pricing. There is no meaningful overlap between them.
Names are readable but follow mixed conventions: list_supported_coins uses a verb_noun pattern while crypto_sentiment, archive_coverage, and price_quote are noun phrases. The inconsistency is minor but present.
Four tools is well-scoped for a focused sentiment service, with one paid action and three free helper/metadata calls. This is appropriate, though on the lean side.
The core sentiment retrieval plus symbol listing, pricing, and archive metadata are covered. However, there is no tool to actually query the hourly archive readings—archive_coverage only reports what exists, leaving a notable gap for historical data access.