TickHub-US
Integrates Polygon as a market-data source within TickHub-US's fallback-chain architecture, enabling sourced retrieval of US market data while enforcing Polygon's tier-C compliance restrictions.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@TickHub-USget the latest quote and recent SEC filings for Apple"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
TickHub-US does one thing: it turns US / HK market data scattered across 20 sources into structured tools a model can call directly.
Every number must come from a tool call, and must carry its source and compliance tier. Quotes, K-lines, financial statements, options chains and unusual flow, short data, SEC filings and 13F, policy rates, energy — the service fetches, normalizes and caches them, then returns a single
DataEnvelopeinstead of asking the model to remember numbers or stitch URLs itself.It is a deployable standalone service, not a prompt. Three things come with that: process isolation (a real process exposing MCP stdio / Streamable HTTP plus a
th-usCLI), compliance interception (a commercial call against a disallowed tier raisesComplianceErrorand does not walk the fallback chain) and cache degradation (Redis when available, in-process LRU when not, with an explicit warning).
41 MCP tools + ten
th-usCLI groups, same response shape at every entry point.20 sources graded S / B / C / D (plus tier X, never integrated); the grade is enforced at the call site, not in documentation.
Fallback order and compliance grades live in YAML, so changing a source is a config change, not a release.
Optional Redis, automatic LRU fallback, and cache keys that separate commercial from non-commercial calls.
The wheel ships its own config, so
pip installworks from any directory.
This project distributes code, not market data. Data is fetched by the user under each source's own terms. For commercial use, rely only on tier-S sources.
Why TickHub-US
One sentence: direct API calls give you freedom, aggregation libraries give you breadth, and TickHub-US gives you "a model can retrieve sourced, compliance-tagged data without writing code".
Dimension | TickHub-US | Calling Yahoo / Eastmoney directly | Aggregator libraries (mostly A-shares) | Paid market-data APIs |
How you call it | MCP tools, CLI and Python share one response | Build URLs, supply UA / crumb, parse fields | Python functions, one DataFrame per function | SDK + subscription |
Auth | Zero-key quotes; SEC needs only a contact email | Maintain cookies, crumbs, throttling yourself | Zero-key | Signup, payment, quota |
Compliance | Every source graded S / B / C / D; commercial calls blocked and logged | Read the terms and judge yourself | Not distinguished | Covered by contract |
Multi-source fallback | Chains declared in YAML, every attempt recorded | Write your own retries and fallbacks | Partial | Usually single-source |
US / HK | US + HK quotes and K-lines; Taiwan via official open data | Inconsistent endpoints per site | Mostly A-shares | Bought per plan |
SEC depth | Filings, full-text search, XBRL, 13F, Form 4 — all free, tier S | Implement CIK mapping and paging yourself | Partial | Usually bought separately |
Response shape | One envelope with | Raw JSON that changes with the site | DataFrame | Varies |
License / cost | Apache-2.0; data under each source's terms | — | MIT / Apache | Commercial subscription |
Best for | AI agents and automation that needs a compliance stance | Deep customization of one endpoint | Data exploration and research | Institutions with SLAs |
Related MCP server: Stock MCP
Architecture
TickHub-US · MCP Server + CLI · v1.0.0
│
├── Access MCP stdio / Streamable HTTP (41 tools) + th-us CLI (10 command groups)
│ ↳ commercial_use is mandatory at the entry point; missing → ComplianceError
│
├── Orchestration
│ Fallback chain (config/sources.yaml) → try each source → record all attempts
│ Compliance gate (config/compliance.yaml) → tier decision → denial is final
│ Cache (Redis, auto-degrades to in-process LRU) → per-domain TTL
│
├── Domains quotes / K-lines / indicators / fund flow / short / volatility / Taiwan
│ fundamentals / statements / key metrics / analysts / institutional holders
│ options chain / unusual flow / CBOE quotes
│ SEC filings / daily feed / full-text / XBRL / insiders / 13F
│ macro / rates / FX / energy
│
└── Adapters 20 providers, each registering a compliance_source
SEC EDGAR · Treasury · CFTC · Fed Board · NY Fed · BIS · ECB · EIA · EIA spot
TWSE · TPEx · FINRA · CBOE · Eastmoney · Sina · Tencent · Polygon · Yahoo · Nasdaq · localDesign trade-off: source priority is written in YAML, not code — one line changes the fallback order. Compliance works the same way: the code only knows
compliance_source. When a source changes its terms, that is a config change, not a release.
Compliance tiers
Source terms differ a lot, and "official" does not mean "free to use". These grades come from reading each source's actual terms; the full text is in config/compliance.yaml.
A working HKEX shareholding layer was removed. Shipping scraping code that violates a source's terms would defeat the point of grading sources in the first place.
Why keep tier-D Yahoo and Nasdaq? The difference is whether a substitute exists: Yahoo is the only source for HK K-lines and for markets beyond the US and HK, and Nasdaq is the only key-free earnings calendar. So the code stays and the terms are quoted in full; whether to use them is the user's call under those terms.
The gate really fires, and it is not a documentation convention:
commercial_use=false: S / B / C / D are all callable; C / D carrywarnings.commercial_use=true: S passes; tier B is denied by default and can be whitelisted per source; C / D raiseComplianceErrorand never walk the fallback chain to get around it.If every source on the chain is denied by compliance, the call raises
ComplianceErrorinstead of silently degrading.
Quick start
Distribution name tickhub-us · Python package tickhub_us · CLI th-us. Requires Python ≥ 3.11.
3 steps, 2 minutes.
# 1. Install (PyPI 1.0.0, published 2026-10-26)
pip install tickhub-us
# or from a checkout
git clone https://github.com/QuotaFuse-ai/TickHub-US.git
pip install -e TickHub-US
# development
pip install -e "TickHub-US[dev]"
# 2. Declare your SEC contact (EDGAR requires a real name + email; missing → E_CONFIG)
export SEC_CONTACT="Zhang San zhangsan@example.com"
# 3. Try one call
th-us quote get AAPL
th-us quote get AAPL --output json # stdout is JSON only, logs go to stderrA real response, captured 2026-10-26 (fields elided):
{
"schema_version": "1.0",
"domain": "quote_us",
"symbol": "AAPL",
"payload": {
"symbol": "AAPL",
"price": 347.725,
"prev_close": 348.22,
"change_pct": -0.14,
"high_52w": 348.36,
"low_52w": 242.89,
"pe": 41.89,
"eps": 8.3,
"currency": "USD"
},
"source": "sina",
"compliance_tier": "C",
"freshness": "realtime",
"fetched_at": "2026-10-26T08:35:47Z",
"cache_hit": false,
"trace_id": "54dc2aebd9904304",
"warnings": ["新浪财经 属 Tier C:商用需事先书面许可,当前为非商用调用。"],
"attempts": [
{ "provider": "polygon", "status": "disabled" },
{ "provider": "sina", "status": "ok", "tier": "C" }
]
}Look at compliance_tier and warnings: this row came from Sina, a tier-C source, so the same call with commercial_use=true is rejected outright. attempts shows Polygon skipped for lack of a key and Sina answering.
One-click install
Four distribution channels, one code base — PyPI wheel / sdist, GitHub Release assets, GHCR container image, and source install. All three published channels are live as of v1.0.0. See Publishing.
# PyPI
pip install tickhub-us
th-us quote get AAPL
# Container (stdio, launched by the MCP client)
docker run --rm -i -e SEC_CONTACT="Zhang San zhangsan@example.com" \
ghcr.io/quotafuse-ai/tickhub-us
# Container (HTTP, published to loopback only)
# Binding a non-loopback address inside the container requires a bearer token
# and a Host allowlist, so the two env vars below are not optional.
docker run --rm -p 127.0.0.1:8001:8001 \
-e MCP_HTTP_TOKEN=change-me \
-e MCP_HTTP_ALLOWED_HOSTS=127.0.0.1:8001 \
ghcr.io/quotafuse-ai/tickhub-us \
mcp http --host 0.0.0.0 --port 8001pip install places config/sources.yaml and config/compliance.yaml under <prefix>/share/tickhub-us/config, so the CLI works from any directory. Source installs find the repo's config/ automatically; TICKHUB_US_CONFIG_DIR overrides both.
Connect to an MCP client
# stdio (preferred for local agents)
th-us mcp stdio
# Streamable HTTP
th-us mcp http --host 127.0.0.1 --port 8001
# Both at once
th-us start-allMCP client configuration (Claude Desktop style):
{
"mcpServers": {
"tickhub-us": {
"command": "th-us",
"args": ["mcp", "stdio"],
"env": { "SEC_CONTACT": "Zhang San zhangsan@example.com" }
}
}
}Commercial calls
Every data call requires an explicit commercial_use (an MCP tool argument, or --commercial-use on the CLI). That is the only mechanism that puts compliance at the call site — an agent cannot violate a source's terms without saying so.
# Whitelist specific tier-B sources (a non-empty whitelist is authoritative)
export TICKHUB_US_ALLOW_TIER_B_SOURCES=finra,eia_spot
# Or allow all tier-B sources (coarse switch)
export TICKHUB_US_ALLOW_TIER_B_COMMERCIAL=true
# Polygon commercial use: the key alone is not enough, confirm the subscription
export POLYGON_API_KEY=...
export TICKHUB_US_POLYGON_COMMERCIAL_BASIS=trueEndpoints
Price — Sina / Tencent / Eastmoney real-time quotes (US + HK) · Sina K-lines (US back to 1984) · Yahoo K-lines (HK and markets beyond US/HK) · MA / EMA / MACD / RSI / KDJ / BOLL computed locally.
Value — Eastmoney three statements + key indicators (including HK) · Yahoo quoteSummary structured statements / analyst estimates / institutional holders · SEC XBRL companyfacts.
Flow & positioning ⭐ — FINRA market-wide daily short volume and short interest (with days to cover and rankings) · CBOE options chains (IV + full Greeks) and unusual-flow detection · CBOE volatility indices (VIX since 1990) and the VIX term structure · Eastmoney daily fund flow.
Filings & events ⭐ — EDGAR submissions · daily index event stream (same-day Form 4 / 8-K / 13F) · full-text search back to 2001 · Form 4 insider trades line by line · 13F institutional holdings · XBRL frames market-wide cross-section (a free screener).
Macro / rates ⭐ — Treasury yield curve · CFTC COT · earnings calendar · Treasury auctions and federal debt · BIS central-bank policy rates · ECB FX / rates / yield curve · NY Fed SOFR / EFFR · Fed Board H.10 / H.6.
Taiwan / energy ⭐ — TWSE + TPEx official open APIs (quotes / P/E / monthly revenue / margin) · EIA weekly crude and natural gas inventories plus spot prices.
Tools — stock search · full-market list · per-symbol and keyword news · ticker ↔ CIK.
Quotes / K-lines / technical indicators
Endpoint | Sources (tier) | Data |
| Polygon(C) → Sina(C) → Tencent(C) → Eastmoney(C) | US / HK real-time snapshot: last, change, volume, 52-week high/low |
| Polygon(C) → Sina(C) → Yahoo(D) | Daily / weekly / monthly / minute OHLCV, US back to 1984 |
| local(S) | MA / EMA / MACD / RSI / KDJ / BOLL; the underlying K-line's tier is recorded in |
| Eastmoney(C) | Daily main / large / medium / small order fund flow |
| Eastmoney(C) | Full US / HK market list with paging |
| TWSE(S) → TPEx(S) → Yahoo(D) | Taiwan quotes, P/E, monthly revenue, margin trading |
| Yahoo(D) → Eastmoney(C) → SEC(S) | Stock search in Chinese and English |
| Yahoo(D) | News by ticker or keyword |
Short data / volatility ⭐
Endpoint | Sources (tier) | Data |
| FINRA(B) | Daily short volume: per-symbol series, market-wide, ratio ranking |
| FINRA(B) | Open short positions twice a month, days to cover, change vs prior period and rankings |
| CBOE(C) | VIX (since 1990) / VIX9D / VIX3M / VVIX / SKEW / OVX / GVZ daily |
| CBOE(C) | Latest VIX at each tenor, contango vs backwardation, long-short spread |
Fundamentals
Endpoint | Sources (tier) | Data |
| Eastmoney(C) → Yahoo(D) → SEC(S) | Valuation, earnings, growth, target price, company profile |
| Eastmoney(C) | Three statements (US / HK) |
| Yahoo(D) | Structured three statements (annual / quarterly) |
| Eastmoney(C) | Key financial indicators |
| Yahoo(D) | Analyst estimates and rating trend |
| Yahoo(D) | Institutional holdings overview and top ten |
Options
Endpoint | Sources (tier) | Data |
| CBOE(C) → Yahoo(D) | Full chain + IV + delta / gamma / vega / theta / rho |
| CBOE(C) → Yahoo(D) | Unusual-flow detection (vol/OI > 1 = new positioning), with a 0DTE filter |
| CBOE(C) | CBOE official delayed quotes for the underlying |
Filings / insiders / 13F ⭐
Endpoint | Sources (tier) | Data |
| SEC(S) | One company's filing list (10-K / 10-Q / 8-K …) |
| SEC(S) | EDGAR daily index event stream, whole market for the day |
| SEC(S) | Full-text search of filing bodies back to 2001 |
| SEC(S) | Form 4 line by line: type, shares, price, holdings after, 10b5-1 flag |
| SEC(S) | Quarterly institutional holdings, sorted by value with weights, reconcile against the cover total |
| SEC(S) | Raw companyfacts view |
| SEC(S) | XBRL frames market-wide cross-section = a free screener |
| SEC(S) | ticker → 10-digit CIK |
Macro / rates / FX ⭐
Endpoint | Sources (tier) | Data |
| Treasury(S) | Yield curve 1M ~ 30Y |
| CFTC(S) | COT positioning report |
| Nasdaq(D) | Earnings calendar (pre/post market and EPS estimates) |
| Treasury(S) | Treasury auctions, federal debt, average interest rates |
| BIS(S) → ECB(S) → NY Fed(S) → Fed(S) → Treasury(S) | Global central-bank policy rates (48 economies in one call) |
| ECB(S) | Euro reference rates, three key rates, euro-area curve, any series |
| NY Fed(S) | SOFR / EFFR / OBFR / TGCR / BGCR, with percentiles and volume |
| Fed Board(S) | H.10 FX, H.6 money stock |
Energy ⭐
Endpoint | Sources (tier) | Data |
| EIA spot(B) | WTI (since 1986) / Brent / Henry Hub daily spot prices |
| EIA(S) | Weekly crude (commercial + SPR), gasoline, distillate and natural gas inventories |
Diagnostics
Endpoint | Data |
| Look up a source's tier decision and the terms behind it |
| Show sources and fallback chains |
| Cache status and clearing |
| Current runtime settings (secrets redacted) |
Usage examples
Say these to your AI assistant to trigger the tools (the CLI equivalent is in parentheses):
Scenario | What to say |
US / HK quote | "What's AAPL trading at, and its PE?" · "How's Tencent 00700 today?" ( |
K-line | "Pull TSLA's daily K-line for the past six months" ( |
Technical analysis | "Is AAPL's MACD crossing its RSI?" ( |
Statements / valuation | "Apple's latest quarterly income statement" · "BABA's PE/PB/ROE and target price" |
Institutional holdings | "Which institutions hold NVDA, and what percentage?" |
0DTE options flow ⭐ | "Show me NVDA's 0DTE unusual options activity" ( |
Short volume ⭐ | "TSLA's short-volume ratio trend this week" |
Short interest ⭐ | "GME's recent short interest and days to cover" |
VIX term structure ⭐ | "Is the VIX term structure inverted right now?" ( |
Insider filings ⭐ | "Which Form 4 insider filings came out today?" ( |
Insider trades ⭐ | "How many shares have NVDA executives sold in the past six months?" ( |
13F holdings ⭐ | "Berkshire's top ten 13F holdings last quarter" ( |
Filing full-text ⭐ | "Which companies mention HBM4 in an 8-K for the first time?" ( |
Market-wide screen ⭐ | "Rank the whole market by R&D expense for CY2025Q1" ( |
Macro | "What's the 10Y-2Y Treasury spread right now?" ( |
Central banks ⭐ | "Current policy rates of the major central banks" ( |
FX / Treasuries ⭐ | "EUR/JPY this month" · "Next week's Treasury auction schedule" |
Taiwan ⭐ | "TSMC's latest close and P/E" ( |
Oil / gas ⭐ | "This week's EIA crude inventories" ( |
Other markets | "Toyota 7203.T daily K-line for the past year" (Yahoo, tier D) |
Batch compare | "Compare valuations of AAPL MSFT GOOGL" |
Data sources
Source | Tier | Auth | Coverage |
SEC EDGAR | S | real UA ( | Filing lists / daily event stream / full-text search / XBRL / frames / Form 4 / 13F / CIK |
US Treasury | S | none | Yield curve / auctions / federal debt / average rates |
CFTC | S | none | COT positioning reports |
Federal Reserve Board | S | none | H.10 FX / H.6 money stock (attribution required) |
NY Fed | S | none | SOFR / EFFR / OBFR / TGCR / BGCR (notice required when shown to others) |
BIS | S | none | Central-bank policy rates (attribution required) |
ECB | S | none | EUR FX / three key rates / euro-area yield curve (attribution; no modification) |
US EIA (inventories) | S | none | Weekly crude / natural gas inventories (attribution recommended) |
US EIA (spot prices) | B | none | WTI / Brent / Henry Hub spot (Refinitiv data republished by EIA; verify before commercial use) |
Taiwan Stock Exchange (TWSE) | S | none | Listed stocks' quotes / P/E / monthly revenue / margin trading (attribution) |
TPEx | S | none | OTC stocks' quotes / P/E / monthly revenue / margin trading (attribution; tier S is this project's judgment) |
FINRA | B | none | Market-wide daily short volume / short interest (verify before commercial use) |
CBOE | C | none | Options chains + Greeks + IV / VIX and other volatility indices (needs Cboe's prior approval) |
Eastmoney (push2 / push2his / datacenter / search) | C | none | US + HK quotes / fund flow / statements / key indicators / market list |
Sina | C | none | US + HK quotes, US K-lines |
Tencent | C | none | US + HK quotes |
Polygon | C | API key (optional) | US quotes and K-lines (commercial use needs the subscription terms confirmed) |
Yahoo Finance | D | cookie + crumb (auto) | HK / other-market K-lines, statements, analysts, holders, options fallback, search, news |
Nasdaq | D | none | Earnings calendar |
Local indicator computation | S | none | MA / EMA / MACD / RSI / KDJ / BOLL computed from fetched K-lines |
Tiers: S = government and central-bank data, commercial + redistribution OK (some require attribution) · B = published but terms-restricted, verify before commercial use and do not redistribute · C = needs prior approval or personal research only · D = terms prohibit automated access without permission; personal study and research only, at your own risk. Quoted basis: Compliance tiers.
All requests go through core/http.py: per-host rate limiting (SEC 8 req/s, CFTC / FINRA / CBOE 4 req/s, Nasdaq 2 req/s, default 5 req/s), exponential-backoff retries, an 8 MB response cap, and cross-host redirects allowed only to hosts registered in config/sources.yaml.
Configuration
Everything is environment variables. A .env file in the current directory (or its parent) is loaded automatically on first use. th-us config show prints the effective settings with secrets redacted.
Data-source access
Variable | Default | What it does |
| — | Real name + email placed in the EDGAR User-Agent. Required for every SEC tool; missing raises |
| — | Optional Polygon key. Without it the |
| — | Comma-separated tier-B whitelist ( |
|
| Coarse switch: allow all tier-B sources for commercial calls |
|
| Explicit acknowledgement that your Polygon subscription permits commercial use; the key alone is not enough |
|
| Set to |
Runtime and cache
Variable | Default | What it does |
| auto | Config directory override. Resolution order: this variable → |
| — | Global TTL override in seconds. Without it each domain uses the |
|
|
|
|
| Redis connection. Unreachable Redis degrades to the in-process LRU with a warning |
|
| Log level |
|
| Per-request timeout in seconds |
|
| Retry count per request |
| — | Standard proxy variables; |
MCP HTTP server
Variable | Default | What it does |
|
| Bind address. Non-loopback requires |
|
| Listen port |
|
| Streamable HTTP path |
| — | Bearer token. When set, every request except |
| — | Extra |
| — | Extra |
commercial_use is not an environment variable — it is a per-call parameter, deliberately, so that no deployment-wide setting can flip a whole process into commercial mode by accident.
Fallback chains and cache
config/sources.yaml defines one chain per domain. A failure (throttle / no data / compliance denial / upstream 5xx) is recorded in DataEnvelope.attempts and the next source is tried:
quote_us: polygon → sina → tencent → eastmoney # TTL 30s, realtime
fundamental: eastmoney → yahoo → sec_edgar # TTL 12h, eod
rates: bis → ecb → ny_fed → federal_reserve → treasury
options_flow: cboe → yahoo # TTL 60s, realtimeCache TTLs are per domain: quotes 30 s, options 60 s, news 5 min, statements and filings 12 h, CIK mapping 24 h. When Redis is unavailable the cache degrades to an in-process LRU and says so in the log — cache degradation never changes which data source is used. Cache keys include the commercial_use flag, so a commercial result is never served to a non-commercial call.
DataEnvelope
Every response uses the same envelope, so an agent can consume source / freshness / compliance_tier / attempts directly:
{
"schema_version": "1.0",
"domain": "quote_us",
"symbol": "AAPL",
"payload": { "...": "..." },
"source": "sina",
"compliance_tier": "C",
"freshness": "realtime",
"fetched_at": "2026-10-26T01:30:00Z",
"cache_hit": false,
"trace_id": "9f2c1e7a4b6d0c33",
"warnings": ["新浪财经 属 Tier C:商用需事先书面许可,当前为非商用调用。"],
"attempts": [{ "provider": "polygon", "status": "disabled" }]
}(The warnings string is read from config/compliance.yaml and is currently Chinese-only; callers should treat it as opaque text, not parse it.)
Technical indicators additionally carry underlying, which records the source and tier of the K-lines they were computed from: the indicator itself is tier-S local computation, but its trustworthiness depends on its input, and that tier stays visible to the caller.
MCP tools
41 tools in total, grouped below. The three signatures fixed by the product spec:
Tool | Purpose |
| Quotes / K-lines / indicators |
| SEC filing search |
| Options chain and unusual flow |
Category | Tools |
Quotes / technicals |
|
Fundamentals |
|
Options |
|
Filings / insiders |
|
Macro / rates / energy |
|
Tools / diagnostics |
|
(The th_us_ prefix is omitted above.)
MCP HTTP security
By default the server listens on loopback only (127.0.0.1 / localhost / [::1]) with DNS-rebinding protection always on. The Host / Origin allowlists are passed explicitly by create_app(); in the loopback case only loopback hosts are allowed.
Listening externally is an explicit action — missing one requirement fails startup with E_CONFIG:
Scenario | Requirement |
| none |
Bind a specific interface (e.g. |
|
Bind |
|
With MCP_HTTP_TOKEN set, every request except GET /healthz (kept anonymous for container probes) must carry Authorization: Bearer <token>. The check uses a constant-time comparison; failures return 401 with WWW-Authenticate: Bearer realm="tickhub-us". /healthz returns only {"status": "ok"} — no version, no tool count (SEC-12).
MCP_HTTP_HOST=0.0.0.0 \
MCP_HTTP_TOKEN="$(openssl rand -hex 32)" \
MCP_HTTP_ALLOWED_HOSTS=tickhub.internal:8001 \
th-us mcp httpFinanceCoffer event stream
On top of the MCP / CLI surface, TickHub-US can publish what it already collects as standard events for the downstream warehouse FinanceCoffer. The event contract (Event Contract v1) lives in the FinanceCoffer repository and is shared by both ends.
The publisher is a sidecar (us_collector), not part of the MCP server process — if you never start it, nothing is published.
# Dry run first: assemble events, print a summary, write nothing
python -m us_collector.scheduler --config us_collector/config.yaml --once --dry-run
# One real round
python -m us_collector.scheduler --config us_collector/config.yaml --once
# Scheduled sidecar: 17:30 America/New_York, weekdays
python -m us_collector.scheduler --config us_collector/config.yamlItem | Value |
Target stream |
|
Consumer group (downstream) |
|
Dead-letter stream |
|
|
|
Retention |
|
Event types |
|
Provider |
|
Compliance |
|
Design notes:
Sidecar, never fatal:
Publisher.publishdoes not raise into the collector. When Redis is unavailable the event goes to a SQLite outbox (var/us_collector/outbox.sqlite3) and is flushed later with bounded retries; a run that cannot publish still completes.Deterministic
event_id: anevt_prefix plus a hash of the business key, so retries and duplicates collapse into one row downstream.Exactly one instance: a PID lock (
var/us_collector/scheduler.lock) makes a second scheduler exit with code 2 instead of double-publishing.Heartbeat on non-trading days: US market holidays publish
data_type=heartbeatonly — no tool is called and no data event is emitted.Amounts stay strings: decimal amounts are validated as strings and never round-tripped through a float.
Field definitions, failure handling and versioning: docs/specs/event-contract.md.
Amount units and valuation fields (QUOT-249)
The contract requires amounts in the basic currency unit of that market — USD for US listings, HKD for HK. quote_us resolves through polygon → sina → tencent → eastmoney (config/sources.yaml), and the vendors do not publish market cap at the same scale, so the value the warehouse saw depended on which vendor answered first:
Provider | Vendor market-cap scale (recorded 2026-10-30, AAPL) | Event value |
| absolute USD — | passed through unchanged |
| 亿美元 / 亿港元 — | × 1e8 |
| none in the requested field list | absent + |
| not mapped out of the snapshot | absent + |
any other | not probed | absent + |
A provider that is not in the table is treated as unknown, not as scale 1 — the collector would rather publish no amount than a guessed order of magnitude. Scales are pinned by magnitude evidence (market cap ÷ price = shares outstanding) and per-provider fixtures, one file entry per vendor; see UNIT-AUDIT.md.
quote events also carry pb_mrq — the vendor's most-recent-quarter price-to-book, the same number as pb, published under that name because it is the ratio the downstream reference basis reads. It is emitted only when strictly greater than zero; otherwise the field stays absent and pb_mrq appears in quality_metrics.missing_fields. US/HK reference values are expected to stay null downstream this phase (no currency column in dwd.stock_quote_snapshot) — that is a recorded limitation, not a defect.
US biz_key values for quote end in a field-generation tag |g2 (the unit normalisation above). event_id hashes only provider|data_type|symbol|biz_key, and the downstream DWD layer is append-only and dedupes by that id, so a corrected amount re-published under the old key would be dropped as a replay. Cutover and existing data: UNIT-AUDIT.md §5.
Testing and CI
Suite | Cases | Covers |
Offline | 238 | Contracts, compliance interception, fallback-chain matrix, secret redaction, input and network hardening, MCP HTTP security, indicator tier inheritance, regression tests for live defects |
Live smoke | 13 | US / HK quotes · SEC filings and 13F · options flow · VIX history and term structure · EIA spot and inventories · BIS policy rates · Yahoo fundamentals; skipped by default |
# Full offline run (no network, no Redis needed)
pytest -m "not live"
# Live smoke (needs SEC_CONTACT; Eastmoney endpoints can be skipped outside mainland China)
SEC_CONTACT="you@example.com" TICKHUB_US_LIVE=1 pytest tests/contract/test_live_smoke.py -m live
TICKHUB_US_LIVE_SKIP_REGIONAL=1 ... # skip the two cases that depend on Eastmoney push2CI (.github/workflows/ci.yml):
push/pull_request: Python 3.11 + 3.12 matrix,ruff→compileall→ offline tests, as the merge gate;workflow_dispatchwithlivechecked: an extra networked job that reads the repository variableSEC_CONTACT(cases skip themselves when it is unset, so the job never goes red) and the optionalPOLYGON_API_KEYsecret, and skips the Eastmoney cases that are unreachable from overseas. Writing code needs no keys; running against live sources does.
Exact check names, copy-paste equivalents for Windows and Linux, and the current required-check status (main is unprotected and there are no rulesets, so CI is advisory only): docs/CI.md.
Two manual release workflows, neither triggered by a push:
Workflow | What it does |
|
|
| Build and push |
Operating steps and the one-time PyPI setup are in Publishing. If egress needs a proxy, set HTTPS_PROXY / HTTP_PROXY (the standard variables requests reads); keep proxy credentials in the environment only — never in config/ and never committed.
Publishing
Both channels are manual dispatch only — pushing a commit or a tag uploads nothing.
PyPI / TestPyPI (publish.yml, already live at 1.0.0):
Run Actions → Publish to PyPI → Run workflow, pick
pypiortestpypi. Auth is GitHub OIDC (Trusted Publishing); no token is stored in the repository.One-time setup, needed only for a new project or environment: on the index, Publishing → Add a new pending publisher with project
tickhub-us, ownerQuotaFuse-ai, repositoryTickHub-US, workflowpublish.yml, environmentpypi(ortestpypi, a separate account).A version, once uploaded, cannot be replaced — bump
versioninpyproject.tomlbefore re-running. Upload the exact artefacts that passedtwine check --strict; do not rebuild between check and upload.
Container (docker.yml): builds and pushes ghcr.io/quotafuse-ai/tickhub-us with the version tag plus latest, then pulls it back and smokes it (anonymous /healthz, authenticated MCP initialize, 401 on unauthenticated POST).
Directory layout
config/ sources.yaml (chains / rate limits / redirect allowlist), compliance.yaml (tiers)
src/tickhub_us/
core/ settings, errors, HTTP, logging, symbols, DataEnvelope
cache/ tiered TTL + Redis / in-process LRU fallback
compliance/ tier registry and interceptor
providers/ 20 source adapters + local indicator computation
market/ quotes, K-lines, indicators, fund flow, short, volatility, Taiwan
fundamental/ statements, key metrics, analyst estimates, institutional holders
options/ options chain, Greeks, 0DTE, unusual flow
filings/ SEC submissions / XBRL / daily index / full-text / Form 4 / 13F
mcp/ MCP server (stdio / HTTP)
cli/ th-us command tree
tests/
contract/ interface contracts + live smoke + defect regressions
compliance/ compliance interception tests
CHANGELOG.md update log (the only document in the repository)
SKILL.md compact agent-facing SOP
Dockerfile image (non-root, stdio by default)
.github/workflows/ ci.yml (gate) + publish.yml (PyPI / Release) + docker.yml (GHCR)FAQ
Does it need an API key? No, by default. Only Polygon is an optional source (POLYGON_API_KEY); SEC EDGAR needs a real SEC_CONTACT, which is an identity declaration, not a secret.
Will it silently switch sources when data is missing? It will walk the fallback chain, but it will not degrade around a compliance denial — if every source on the chain is denied, it raises ComplianceError and lists each denial in attempts.
Are HK options available? No. The options layer is US only; HK options would require HKEX's paid proprietary feed.
Can it look up stocks outside the US and HK? K-lines and Yahoo fundamentals, yes: Japan .T, Taiwan .TW, Korea .KS, India .NS, London .L, Germany .DE and more. Note that Yahoo is a tier-D source. Taiwan also has the official TWSE / TPEx APIs (tier S, latest trading day only).
How fresh are global rates and FX? ECB and NY Fed update every business day; Fed H.10 is published each Monday for the prior week; BIS lags by a few days to about three weeks depending on the country. Every value carries a date — check the central bank itself when you need today's exact number.
How often does short interest update? FINRA publishes it twice a month, for settlement dates on the 15th and at month-end (moved earlier for holidays), about 8 business days after settlement. The daily dataset is a different one — daily short volume, which counts that day's short-sale trades, not open short positions.
Can a server in mainland China reach Yahoo / SEC? They are overseas services and may be flaky on a direct connection. Use a proxy, or lean on the Eastmoney / Sina / Tencent sources. The CI live job runs on GitHub-hosted runners, which is why the Eastmoney cases are skipped there.
Can I use it without an MCP client? Yes. The th-us CLI covers every endpoint, and --output json feeds any script directly.
Can I install it from PyPI? Is there a Docker image? Yes to both. pip install tickhub-us installs 1.0.0 (PyPI), the same wheel / sdist ship as v1.0.0 release assets, and the container is public at ghcr.io/quotafuse-ai/tickhub-us (tags 1.0.0 and latest, docker pull needs no login). Publishing is a single manual dispatch of publish.yml / docker.yml; steps are in Publishing.
Version
v1.0.0 (2026-10-26) — first stable release, feature-complete against the spec and re-verified end to end against live sources:
Fixed BIS policy rates always returning 404 (the SDMX key duplicated the
D.dimension);Fixed Yahoo quoteSummary returning 401 across the board (a non-browser UA got 429, so no crumb could be obtained; now it cools down and retries instead of giving up permanently);
Added 13 live smoke cases and a
workflow_dispatchlive job, with an offline regression test for each of the two defects;Shipped four distribution channels: PyPI wheel / sdist (
publish.yml, PEP 639 metadata), GitHub Release assets, GHCR container image (docker.yml, with a real smoke), and source install; the wheel bundlesconfig/, so it runs from any directory. Verified by installing 1.0.0 from PyPI into a clean venv and running a live quote from outside the repository, and by an anonymousdocker pullofghcr.io/quotafuse-ai/tickhub-us:1.0.0.
Disclaimer
This project provides data-access tooling only. It is not investment advice. Markets carry risk. Data licensing follows each source's terms — see config/compliance.yaml.
License
Apache License 2.0. Author: QuotaFuse · https://github.com/QuotaFuse-ai
Update log: CHANGELOG.md · agent SOP: SKILL.md
This server cannot be deployed
Maintenance
Related MCP Connectors
Real SEC, 13F, insider, congress & macro data your AI agent can cite. Hosted MCP, 24 tools.
Your agent needs markets — prices and fundamentals for listed companies, the filings behind them, crypto, and what the prediction markets put the odds at. **What you can ask for** • "Pull this company's income statement, cash flow and balance sheet for the last 8 quarters." • "What did insiders buy or sell, and when?" • "Snapshot prices for these 50 tickers, then the OHLC history for the three that moved." • "What are the current odds on this event across Kalshi and Polymarket?" • "Screen for companies matching these financial criteria." **How to use it** Point any MCP client at https://mcp.aisa.one/finance/mcp and sign in with OAuth — there is no key to create or paste. 49 tools: prices and snapshots, income statements, balance sheets and cash flows, metrics and ratios, earnings and analyst estimates, filings and line-item search, insider trades, macro interest rates, news, a screener; CoinGecko spot prices, market tables, OHLC, per-venue tickers and trending; Kalshi and Polymarket markets and trades; plus EDINET filings for Japan. **Why this rather than the source** Equities, crypto and event markets behind one account, so a cross-asset question is one conversation. **It is also a door to the rest** The same login reaches 26 sources and 580+ operations. Read the number here, then ask the same agent what X is saying about the ticker today — without adding a second server. **What it costs** Finding and inspecting an operation is free. Running one is billed per call at API prices, with no seat and no monthly minimum, and every call takes max_price_usd so an agent cannot overspend by accident. **Where else it reaches** https://mcp.aisa.one/marketpulse/mcp · /crypto-market-data/mcp · /prediction-market-data/mcp · /stock-pulse/mcp for one slice each.
US stock market data for AI agents: SEC filings, financials, insider trades, 13F, options, macro.
Your agent needs company financials it can compute on — statements, ratios, earnings, estimates, filings and insider activity as structured data, not a PDF. **What you can ask for** • "Give me 8 quarters of income statement, balance sheet and cash flow for this ticker." • "What do analysts estimate for next quarter, and how did the last four surprise?" • "Find this exact line item across every filing." • "Who bought or sold as an insider in the last 90 days?" • "Screen for profitable companies under this valuation with growing revenue." **How to use it** Point any MCP client at https://mcp.aisa.one/marketpulse/mcp and sign in with OAuth — there is no key to create or paste. 21 tools: prices and snapshots, income statements, balance sheets, cash-flow statements, financial metrics and snapshots, earnings, analyst estimates, company facts, filings and filing items, line-item search, a screener, insider trades, macro interest rates, news, plus EDINET documents and filing digests for Japanese issuers. **Why this rather than the source** Statements as fields you can compute on, and a screener in the same place. **It is also a door to the rest** The same login reaches 26 sources and 580+ operations. Read the fundamentals here, then ask the same agent what social is saying about the ticker — without adding a second server. **What it costs** Finding and inspecting an operation is free. Running one is billed per call at API prices, with no seat and no monthly minimum, and every call takes max_price_usd so an agent cannot overspend by accident. **Where else it reaches** https://mcp.aisa.one/finance/mcp for equities, crypto and prediction markets in one place.
Related MCP Servers
- FlicenseNot gradedqualityAmaintenanceEnables AI agents and backend integrations to access standardized market data, technical indicators, fundamentals, news, filings, money-flow analysis, and code-export outputs across A-shares, US equities, ETFs, indices, and crypto. It exposes these capabilities through MCP tools and HTTP APIs.-
- FlicenseNot gradedqualityAmaintenanceEnables AI agents and backend workflows to access standardized multi-market financial data, technical indicators, fundamentals, news, filings, money flow, and CSV/JSON exports through MCP tools and HTTP endpoints.-
- FlicenseNot gradedqualityAmaintenanceEnables AI agents and backends to access standardized financial market data and analysis tools across A-shares, US equities, ETFs, indices, and crypto, including technical indicators, fundamentals, news, filings, and money flow. It exposes these capabilities through MCP tools and HTTP endpoints, with agent-friendly artifacts and CSV/JSON exports.-
- FlicenseNot gradedqualityAmaintenanceEnables AI agents and applications to access and analyze A-share, US equity, ETF, index, and crypto market data, including technical indicators, fundamentals, news, filings, money flow, and exportable CSV/JSON datasets through MCP tools and HTTP APIs.-