mcpbeat Sign in

Tw Market Data MCP Server

by twmarketdata Your server? Claim it
answering

Tw Market Data is answering right now. Last checked 5 min ago. It exposes 41 tools.

Taiwan stock market data (TWMD): official-source, point-in-time-safe datasets via read-only tools.

Uptime history 47 days of history · worst day 82%
47 days agonow
90.2%
Uptime 24h
83 of 92 checks
41
Tools
read from the server
828 ms
Response time
average over 24h
open, no key
Access
streamable-http

What changed 53

Every tool that appeared, vanished or quietly changed what it asks for. Recorded since 9 August 2026. No other catalogue keeps this.

18 Sep a tool description was rewritten get_inclusion_proof
2 Sep a tool changed the parameters it asks for query_dataset
1 Sep a tool appeared explain_provenance
29 Aug a tool appeared query_dataset
29 Aug a tool disappeared _mint_and_record_query_id
28 Aug 7 tools appeared company_health_check, macro_regime_read, _mint_and_record_query_id and 4 more
28 Aug a tool disappeared query_dataset
25 Aug a tool description was rewritten try_sample
24 Aug 8 tools appeared calendar, cite_this, compare and 5 more
24 Aug 3 tool descriptions were rewritten delete_alert, get_research, memory_replay_query
and 28 more, back to 9 August 2026

What the code does

We have not read this server's code yet · tools taken from the live server

Evidence

Things with no honest explanation: a promise that contradicts the code, code that runs at install time while hiding what it does, data leaving the machine.

Claims read-only, but ships mutating tools delete_alert
заявлено «только чтение», но есть delete_alert

Is this your server and something here is wrong? Tell us — corrections are free and do not require a plan.

We found things in this code

Code changes quietly between releases, and nobody reads the diff of a dependency. We do, on every release — watch Tw Market Data and you get told the day something new turns up.

Three servers free · no card

Connect this server

Endpoint below is the one we actually reach during checks — not the one copied from a README. Last verified 5 min ago.

run in your terminal
claude mcp add tw-market-data --transport http https://mcp.twmarketdata.com/mcp
~/Library/Application Support/Claude/claude_desktop_config.json
{
  "mcpServers": {
    "tw-market-data": {
      "url": "https://mcp.twmarketdata.com/mcp"
    }
  }
}
~/.codex/config.toml
[mcp_servers.tw-market-data]
url = "https://mcp.twmarketdata.com/mcp"
.cursor/mcp.json
{
  "mcpServers": {
    "tw-market-data": {
      "url": "https://mcp.twmarketdata.com/mcp"
    }
  }
}
.vscode/mcp.json
{
  "mcpServers": {
    "tw-market-data": {
      "url": "https://mcp.twmarketdata.com/mcp"
    }
  }
}

Available tools 41

Read directly from the server with tools/list, grouped by what they act on. If a tool disappears, we record the date.

memory
memory_get_watchlist
Read the tickers on one named watchlist, as it stands right now. A curated roster you maintain — distinct from `memory_search`, which digs through everything you ever recorded, and from `list_alerts`, which is about price triggers rather than symbols you are following. Args: key — the roster's name, default 'default'.
memory_replay_query
Re-run a remembered query by its `twmd_q_…` id, through the read API's own replay store. This is what makes a recalled finding checkable: the memory says where it came from, and this fetches that same data again. It never re-executes the query by another route — two implementations of "replay" would be two answers to a question whose whole value is having one. `status` is one of: found the bytes are here, with `result_hash` to check them against too_large it WAS served, but exceeded the size ceiling: `result` is absent and `result_hash` is authoritative — you can still verify a copy you hold not_found never recorded (or pruned) — the citation cannot be resolved Args: query_id — the `twmd_q_…` reference carried on a remembered finding's citation.
memory_save
Remember something, with its sources and its knowledge time. Nothing is ever overwritten: saving a `factor_def` or `watchlist` under an existing key SUPERSEDES the previous version (both rows survive, so "what did I believe in June?" stays answerable), and saving identical content twice is a no-op rather than a duplicate. Args: kind: 'query' | 'factor_def' | 'watchlist' | 'finding' | 'note'. content: the thing to remember, as an object. key: the stable name — REQUIRED for 'factor_def' and 'watchlist' (that is what makes a definition reusable next session instead of re-invented). as_of: the knowledge time this memory is about. Recall can bound on it, which is what keeps a memory from leaking the future into a point-in-time question. source_query_ids: the `twmd_q_…` ids behind this. REQUIRED for 'finding' — a conclusion that cannot point at its data is not evidence, and will be refused. agent_id: optional label for which of your agents wrote this.
memory_search
Recall your own memories — hybrid (semantic + exact-term), with provenance attached. Every result carries where it came from (`source_query_ids`, replayable), when it was believed (`valid_from`/`valid_to`) and what knowledge time it is about (`as_of`), plus a `recall` block stating which model and which filters produced the answer. Args: query: what you are looking for, in words. kinds: restrict to some of 'query' 'factor_def' 'watchlist' 'finding' 'note'. as_of: knowledge-time bound — pass a backtest's as_of and nothing recorded later can come back. Use this for anything point-in-time. key: the stable name, when you know it (e.g. a factor name). agent_id: narrow to one of your agents. include_superseded: also return old versions (the audit view). Default is current only.
backtest
get_backtest
Retrieve a previous backtest by run_id — the full record, including why it was rejected. Only runs in YOUR namespace are visible; a run_id belonging to someone else is simply not found. Args: run_id (the `twmd_bt_…` handle returned by run_backtest).
run_backtest
Run a point-in-time backtest and return its run_id, metrics, sources and honesty checks. The run may only see data stamped on or before `as_of` — that is enforced structurally, not by convention. Results arrive with the data `query_ids` behind them and an anti-overfitting verdict (out-of-sample, deflated Sharpe, multiple-comparison, crash stress); a run that fails the gate is returned REJECTED with reasons rather than hidden. Args: strategy_id: a registered strategy, e.g. 'buy_and_hold' or 'cross_sectional_momentum'. start / end: the測試期間 (YYYY-MM-DD). `end` must not be after `as_of`. as_of: the knowledge cutoff. REQUIRED — there is no "today" default. tickers: required when universe_kind='explicit'; ignored for 'point_in_time'. universe_kind: 'point_in_time' (survivorship-safe, resolved from listing/delisting dates at each rebalance) or 'explicit' (a list you supplied). market: optional market filter for a point-in-time universe. rebalance: 'daily' | 'weekly' | 'monthly'. cost_bps: one-way transaction cost in basis points. params: strategy parameters, e.g. {'lookback_days': 60, 'top_k': 5}. This measures history. It is not advice and it places no orders.
research
get_research
Retrieve one of YOUR previous research reports. Others' runs are simply not found. Args: research_id — the identifier `run_research` returned when it started that run.
run_research
Run a multi-agent research pass and return a structured, sourced report. Six roles run in order — data analyst, factor researcher, backtest engineer, risk officer, portfolio manager, compliance officer. Each step's output carries the `query_ids` behind it; risks are reported alongside results, not beneath them; and anything the run could not do is listed as a limitation rather than filled in. The factor researcher checks memory first and SKIPS a hypothesis a previous run already rejected. The portfolio manager proposes nothing when the evidence failed the anti-overfitting gate, and any allocation it does propose is a PROPOSAL awaiting a human — this system places no orders and moves no money. Args: prompt: the research question, in your words. This is the only channel carrying instructions; anything a tool returns is treated as data. as_of: the knowledge cutoff. REQUIRED — nothing stamped after it is visible to the run. tickers: optional explicit universe. Omit for a point-in-time (survivorship-safe) one. start / end: optional test period; `end` must not be after `as_of`. max_backtests: per-run cap on backtests (cost control).
risk
risk_assess
Measure a portfolio you state against limits you state, on official point-in-time prices. Reports concentration and peak-to-trough drawdown, and NAMES every position it could not price rather than quietly assessing the rest — an assessment covering 60% of a portfolio without saying so is worse than none. Any breach produces a PROPOSAL (e.g. "reduce 2330") that requires a human decision. Approving a proposal records that decision; it executes nothing. TWMD has no order path. Args: positions: `[{"ticker": "2330", "quantity": 100}, ...]`. YOUR stated holdings — nothing is read from a brokerage account, because no such connection exists. as_of: knowledge cutoff, `YYYY-MM-DD`. Defaults to the latest available data. max_position_weight: single-name limit as a fraction (0.35 = 35%). max_drawdown: peak-to-trough limit as a fraction (0.25 = 25%).
risk_read
事件與市場結構風險:隱含波動率、注意處置、裁罰訴訟、放空限制、因子。 ★ ⚠️ **部位集中度與回撤不在這裡** —— 那是 `risk_assess` 的職責。重算一份會產生 第二個答案,而兩個都帶著我們的名字。 ★ `checked_and_clear` 是「查過而且確認沒有」(例如近一年無裁罰),和 `cannot_see` 的「不知道」是兩回事。 ★ 事實整理,不是投資建議、不是預測。輸出帶 `does_not_prove`。 ★ Args:`ticker`(例如 "2330")、`as_of`(選填)。 ★ Returns:誠實信封;事件風險 listed in `concerns`,查過確認沒有的 listed in `checked_and_clear`。 ★ PRECONDITIONS:自己取數;requires 一個已識別的 session。 ★ SIDE EFFECTS:read-only,does not 寫入。
agent
agent_activity
What YOUR agents have actually done, from the durable audit trail. Every resident agent records what it did and ON WHAT BASIS — the rule and the two closes behind an alert, the coverage and limits behind a risk finding, the run_id and declared trial count behind a factor verdict. This is that trail, and it survives deploys. Reports which agents have recorded NOTHING (`coverage.missing`), because "the monitor has been quiet" and "the monitor is not running" look identical from the records alone and only one of them means your alerts work. Args: limit: how many records to return, newest first (max 200).
alert
delete_alert
Cancel one armed price trigger permanently, by its rule id. Disarms a single watch so it will not fire again — the opposite of `set_price_alert`, and unlike `list_alerts` it changes state rather than reporting it. Cancellation is irreversible: re-arming means creating a fresh trigger. Naming somebody else's rule id cancels nothing at all. Args: rule_id.
alerts
list_alerts
Show the price-trigger rules you have armed, and whether each is still armed. A read-only inventory of thresholds you asked to be watched — it arms nothing and cancels nothing (`set_price_alert` arms, `delete_alert` cancels). Another customer's triggers are simply not visible here.
approve
approve_action
Record a HUMAN's approval of a proposed action. This writes an audit record naming who approved what, and when. It does NOT execute the action: TWMD has no order or funds path, by design. Execution, if any, happens elsewhere and is performed by a person. Args: action_id: from `list_pending_actions` or a report's `proposed_actions`. approver: who is approving. Required — an unattributed approval is not an approval.
ask
ask
Answer a plain-language question in Taiwanese-market vocabulary, sentence by sourced sentence. ★ FOR BEGINNERS WHO DO NOT KNOW WHICH DATASET THEY WANT. Ask "PBR 是什麼" or "什麼叫漲跌停" in ordinary words; routing happens on our side. `describe_dataset` explains a table you already named, `search_filings` digs through company disclosures, and `query_dataset` returns rows — this one turns a beginner's wording into a sourced explanation instead. ★ EVERY SENTENCE CARRIES A CITATION OR IS NOT RETURNED. Vocabulary sentences cite `glossary:<id>`. Figures cite the dataset row they came from. A sentence whose number cannot be traced to a retrieved row is DROPPED — it appears in `dropped[]` with status `unverifiable`, and never in `claims[]`. There is no path by which this tool composes a number from its own memory. ★ TERMS OUTSIDE THE GLOSSARY RETURN `unsupported_term`, NOT A GUESS. The corpus is 99 curated Taiwan-market terms. CAPM, options greeks and general finance vocabulary are not in it, and the honest answer is that we do not cover them. ⚠️ Explanations only. It states what a term means and what a figure was; it does not tell you what to do about either. Args: question, optional as_of (YYYY-MM-DD).
backtests
list_backtests
Browse an INDEX of your past backtest runs — ids and headline metrics only, no re-execution. Use when you want to find a run whose id you have forgotten. It never re-computes anything: `run_backtest` executes a new one, `get_backtest` opens a single record in full, and `replay_backtest` re-derives one to check reproducibility. This is the catalogue, not any of those three. Args: optional strategy_id filter, limit.
calendar
calendar
Sort corporate dates into what is still ahead and what has already passed. ★ TWO DATES, NOT ONE. What is "upcoming" is decided by the date the event HAPPENS; `as_of` filters on the date it was ANNOUNCED. An ex-dividend declared on 2026-08-01 for 2026-09-15 is both already known and still ahead on 2026-08-10. Collapsing the two fields either hides every future date or reports last month's ex-dividend as though it were coming. ★ ELAPSED DATES ARE SEPARATED, NOT DISCARDED. They come back under `past` — the previous ex-dividend is useful context for a question about the next one — but they can never appear under `upcoming`. ★ NOT `search_filings` AND NOT `query_dataset`. Those retrieve disclosures and rows; this one only arranges dated corporate events on a timeline relative to now. ⚠️ A scheduled date is a schedule, not a promise; companies move them. Args: rows (dated events), today (YYYY-MM-DD), optional as_of.
chart
chart
Turn rows you already fetched into a Vega-Lite drawing your chat window can render. ★ IT DRAWS; IT DOES NOT FETCH. Hand it the output of `query_dataset` — this tool never touches the database, so it cannot bypass the `as_of` filter those rows were selected under. A plotting tool that fetched its own numbers would be a second data path, and a second path eventually disagrees with the first about what was knowable when. ★ GAPS BREAK THE LINE INSTEAD OF BEING BRIDGED. A missing value is emitted as null, so the rendered line stops rather than sloping smoothly across a period where nothing was published. The absent positions are also listed in `data_gaps`, because a break is easy to misread as a flat stretch. Zero is never substituted — zero draws a real low point for something that never happened. ★ THE DRAWING POINTS BACK AT THE PROOF. `citation` and `inclusion_pointer` travel with the spec, so a picture and the rows behind it name the same published checkpoint. ⚠️ Rendering, not analysis. A shape you notice in a picture is not a forecast. Args: rows, x_field, y_field, optional title and mark (line/point/bar/area).
cite
cite_this
Produce a bibliographic citation for TWMD data — APA, BibTeX, and a re-verifiable token. ★ FOR PAPERS, REGULATORY FILINGS AND ANYTHING A REVIEWER WILL RE-CHECK LATER. A dataset is corrected, backfilled and re-run. Three years from now a reviewer opening our API sees different numbers than the paper, and nobody — author, reviewer, or us — can tell whether the data changed or the author mis-transcribed. So the citation carries `as_of`, the Merkle `checkpoint_root`, and a `verify_url`, plus a signed `reproducible_token` that binds those fields TO EACH OTHER. ★ PASS `as_of` IF YOUR WORK IS POINT-IN-TIME. Without it a citation is still produced, but it is marked `point_in_time: false` and the APA line reads "Retrieved <date>" instead of naming a knowledge horizon — because re-running the same query later can legitimately return different figures, and nothing in the data would mark the difference. ★ WHAT IT PROVES: which data was used, and that those fields were signed by us. **NOT that the figures are correct** — a faithfully committed wrong figure cites and verifies exactly like a right one. `limitations` says so in the response; keep it when you quote the citation. Args: dataset: the dataset id you queried, e.g. 'valuation'. as_of: the knowledge cutoff your work used (YYYY-MM-DD). Omit only for present-day lookups. row_key: pin the citation to one specific row, if you are citing one row.
code
get_code_example
Emit a copy-pasteable HTTP snippet wired to the real endpoint, header and parameter names. ★ FOR WRITING YOUR OWN CLIENT, NOT FOR GETTING DATA. Every other tool here answers a question; this one hands you source code so your program can ask it directly over HTTPS. Nothing is fetched and no rows come back. ★ THE CONSTANTS ARE READ OUT OF THE SERVER, NOT REMEMBERED. Base URL, the `X-API-Key` header spelling, and the route path all come from the code that serves them. The worst kind of broken example is one that looks right: a mistyped path 404s and the reader blames their own key. ★ AN INTENT IT HAS NO ROUTE FOR IS REFUSED. It will not point at a plausible-looking path it has not confirmed. Python output is passed through Python's own compiler before it is returned; the JavaScript variant is structure-checked only, and says so. ⚠️ The credential in the snippet is an obvious placeholder, never a realistic-looking string — a convincing fake gets pasted, sent, and then fails somewhere nobody can trace. Args: intent, language (python/javascript), ticker, optional as_of.
company
company_health_check
一檔股票的誠實體檢:成長、獲利品質、估值、籌碼、紅旗,每個數字可驗證。 ★ 這是**事實整理**,不是投資建議、不是預測、不是目標價。輸出帶 `does_not_prove`,轉述時請一併保留。 ★ POINT-IN-TIME:`as_of` 逐資料集尊重揭露時差 —— 月營收用法定截止日推得的 估計時點,財報用出表日,估值是當日。不給 `as_of` 就用「現在可知的最新」, **不是今天**。 ★ 沒看到的東西會列在 `cannot_see`,並說明是「查了沒有」「查詢失敗」還是 「散佈權未取得」—— 三者不同。⚠️ 不要替 `cannot_see` 裡的項目估算或補值。 ★ `checked_and_clear` 是「查過而且確認沒有」(例如近一年無裁罰), 和 `cannot_see` 的「不知道」是兩回事。 ★ 代號解析不到會回 `needs_disambiguation` 附候選 —— 請回問使用者,不要挑一個。 ★ PRECONDITIONS:這支工具**自己**去拿九個資料集,所以 rows 不需要先用 `query_dataset` 取好。它 requires 的是身分:呼叫端 must be 一個已識別的 session(X-API-Key 或已驗證的 OAuth 登入),因為體檢會寫進呼叫者的工作區 脈絡。方案沒有涵蓋某個資料集時,那一項會以 `not_licensed` 出現在 `cannot_see`,而不是讓整支工具失敗 —— 所以不需要 entitlement 先檢查。 ★ SIDE EFFECTS:read-only。does not 寫入任何資料表,不建立警示、不下單。
compare
compare
Lay two to five named companies side by side on the same measures, gaps marked as gaps. ★ AN ABSENT FIGURE STAYS ABSENT, AND THE COMPANY STAYS ON THE TABLE. A blank cell is reported as `available: false`, never filled with a zero, a previous period, or by quietly dropping the column. Dropping is the worst of the three: it converts "we do not hold this measure for that company" into "you did not ask about that company". ★ EACH CELL NAMES ITS OWN SOURCE. Margins and institutional flows come from different datasets, so one citation for the whole table would imply every figure came from one query. ★ NOT `screen` AND NOT `find_related`. `screen` finds symbols from a description when you have none; `find_related` walks supply-chain links. This one needs you to already know which two to five companies you mean. ⚠️ Placing figures next to each other is not ranking them. A measure one company publishes and another does not is a coverage difference, not evidence about either. Args: tickers (2-5), metrics, optional pre-fetched rows_by_ticker, optional as_of.
dataset
query_dataset
Query rows with built-in look-ahead protection. ★ POINT-IN-TIME: pass `as_of` (YYYY-MM-DD) for backtesting/agent-learning. For non-point-in-time-safe datasets (fundamentals, monthly_revenue, dividend_policy…) rows are filtered by DISCLOSURE date <= as_of, so the agent only sees what was public at that moment. Omit as_of only for present-day lookups (warned). ★ IF A VALUE IS IN `coverage.missing`, IT IS NOT AVAILABLE. Say it is not available. **Never estimate it, interpolate it, infer it from a neighbouring period, or carry the last known value forward.** `coverage.missing` lists exactly what was requested and not returned, with a reason (e.g. "9999 在 as_of 當日未上市"). An empty `data` array alongside a populated `missing` list is a complete and correct answer to "what do you have" — not an invitation to fill the gap. ★ EVERY VALUE IS ATTRIBUTABLE. `provenance` carries {source, source_role, ingested_at, revision, provenance_uri}; `meta.query_id` names this exact question. Quote the query_id when reporting a number — `replay_query(query_id)` returns the bytes that were served, so the claim can be checked later. `freshness.is_stale` is computed server-side against the dataset's own cadence budget; `null` means it could not be determined, which is NOT the same as fresh. Args: dataset_id: see list_datasets. tickers: e.g. ['2330','2317']. start/end: 'YYYY-MM-DD' range. as_of: knowledge-time cutoff 'YYYY-MM-DD' (use for backtests). limit: <=5000. Returns: {meta:{table,coverage,row_count,as_of_applied,point_in_time_safe,warnings,query_id}, data:[...], provenance:{...}, coverage:{requested,returned,missing,reason}, freshness:{status,latest_available,expected_lag,is_stale}} Example: query_dataset('fundamental_income', tickers=['2330'], as_of='2023-06-30')
datasets
list_datasets
List available Taiwan-market datasets (discovery entry point). Returns id / 中文名 / category / tier / one-line description for each. Use this first to find the right data. Args: category: optional, e.g. 'chip'(籌碼) 'fundamental'(基本面) 'price'(行情) 'macro'(總經) 'relation'(關聯/產業鏈) 'derivatives'(期權) 'event'(事件) 'rag_text'(文本). tier: optional minimum plan: 'free' 'starter' 'pro' 'max' 'developer' 'enterprise'.
describe
describe_dataset
FULL semantics of one dataset: grain (what a row is), field meanings+units, ★TIME-CORRECTNESS rules (knowledge_time_field / point_in_time_safe — read before backtesting), relations for cross-table reasoning, agent_hints (when to use), quant_use (which factors). Args: dataset_id.
explain
explain_provenance
Where did this number come from, and when could anyone have known it? (WP-6) ★ THIS IS THE GROUNDING TOOL. Every other tool's answer is supposed to be expandable through this one: given a ticker, a field and a date, it names the dataset that serves that field, the knowledge column, and WHICH as_of rule applies on that date. Use it whenever you are about to state a number as fact. ★ IT DOES NOT OVERLAP WITH THE OTHER TWO PROVENANCE TOOLS, and they are not substitutes: `get_inclusion_proof(dataset, row_key)` proves a ROW was in a published snapshot (Merkle). `cite_this(dataset, as_of)` produces a citation for a DATASET. `explain_provenance(ticker, field, date)` answers WHERE A CELL came from and WHEN it was knowable. Nothing else answered that. ★ FOUR VERDICTS, and `partial` is not `resolved`: resolved dataset, knowledge axis, as_of rule AND the official endpoint. partial ⚠️ the first three, but NOT the official endpoint — no dataset declares a per-cell endpoint today. "When was it knowable" and "which official endpoint produced it" are different questions; conflating them is exactly the vagueness this tool exists to remove. ambiguous_field ⚠️ the field lives in several datasets. Every candidate is listed and NONE is picked for you: picking one would hand you a confident wrong answer. Re-ask with `dataset=`. unknown_field no served dataset declares that field. This is "we do not have that column", NOT "no data found" — a different next step for you. ★ READ `limitations`. It says when the knowability date is DERIVED (statutory deadline, a conservative upper bound) rather than observed, and whether the rule came from declarations or from the live schema. A declared capability is not the same as a working one. Args: ticker: the security, e.g. '2330'. field: the column you are about to quote, e.g. 'close', 'revenue'. date: the date your claim is about (YYYY-MM-DD). dataset: pin the answer to one dataset when the field is ambiguous.
factor
list_factor_findings
Verdicts from the overnight factor search on YOUR namespace — including the rejections. The rejections are returned deliberately. A research log that keeps only the winners is the highlight reel overfitting lives in, and the acceptance RATE is the number that tells you whether the anti-overfitting gate is doing its job: a search that accepts most of what it tries has a broken gate, not a talent for finding alpha. Every verdict carries the trial count it was judged against, so it can be re-checked. `coverage.missing` names hypotheses that were proposed but never judged because a cost ceiling was reached — those are UNTESTED, not rejected. An accepted factor is a FINDING with a run_id, not an allocation. Nothing here trades. Args: limit: how many verdicts to return, newest first (max 100).
filings
search_filings
Semantic search over MOPS filings, financial-statement notes and company news. Answers questions a keyword filter cannot: "what risks did this company disclose this quarter?", "which companies mentioned CoWoS capacity expansion?" — matching on MEANING, so a paragraph that never uses your exact words still ranks. ★ POINT-IN-TIME: pass `as_of` (YYYY-MM-DD). Chunks are filtered `published_at <= as_of` in SQL BEFORE ranking, so a backtest cannot retrieve a filing that did not exist yet. `meta.as_of_applied` echoes the cutoff that actually ran — check it. **Without `as_of` the results include the most recent filings and are look-ahead UNSAFE for backtesting**; the response says so in `meta.warnings`. ★ REFERENCE CONTEXT, NOT AUTHORITY. Every hit carries `source`, `source_tier` ("official" = MOPS/exchange, "third_party" = press) and a `url`. Read the chunk and judge it yourself; the ranking is similarity, not importance, and similarity is not evidence. **Nothing here is investment advice** (`not_investment_advice: true`). ★ A ticker you asked about that returns nothing appears in `coverage.missing` with a reason. That means NOTHING IS INDEXED for it under those filters — it does NOT mean the company disclosed nothing. Do not fill the gap. Args: query: what to look for, in Chinese or English (e.g. '匯率風險', 'CoWoS capacity'). tickers: restrict to these codes, e.g. ['2330','2317']. doc_type: e.g. 'mops_major_event', 'financial_note', 'company_news'. as_of: knowledge-time cutoff 'YYYY-MM-DD' — use it for anything backtest-shaped. source_tier: 'official' to exclude third-party press. limit: <= 100. Returns: {data:[{ticker,doc_type,published_at,source,source_tier,url,chunk_text,similarity}], meta:{as_of_applied,point_in_time_safe,embedding_model,warnings,query_id}, provenance:{...}, coverage:{requested,returned,missing,reason}, freshness:{...}}
inclusion
get_inclusion_proof
Prove a row was in the snapshot TWMD published — and check it yourself. Returns the Merkle sibling path, the signed root, and the checkpoint it belongs to. It returns the PATH rather than a yes/no on purpose: a service that answers "yes, it is included, trust me" is the opposite of verifiable. Recompute the root from the leaf and the path; the verifier is ~30 lines and is written out in docs/VERIFIABLE_DATA.md. ★ WHAT IT PROVES: integrity (the row was not altered after publication) and origin (the root was signed by TWMD). **It does NOT prove the numbers are correct** — if the exchange published a wrong figure, TWMD faithfully committed to the wrong figure. Do not present a passing proof as a correctness guarantee. ★ THREE STATUSES, and they must not be collapsed: ok proof enclosed; verify it. not_in_snapshot that row_key was NOT a leaf of the snapshot. A true answer, NOT a failure and NOT evidence of tampering. no_checkpoint no snapshot was ever built for that dataset/version. 🔴 VERIFY ON THE CLIENT SIDE. There is deliberately NO `verify` tool here, and that is the point: this server is the ISSUER of the proof, so a "we checked our own proof and it is fine" tool would carry almost no evidential weight while looking exactly like independent verification. Run the check where you are: * Python SDK `twmd.Client.flight(..., proof_api=...).verify(dataset, row_key)` -> {"verified": bool, "verification": {status, proves, checkpoint, unverified_reason}} with FOUR values (verified / failed / unproven / absent) — `unproven` is NOT `failed`. * any language `scripts/twmd_verify_proof.py` — copy it; stdlib only, imports nothing from our package (a verifier that needs our package asks you to trust our package). * the core `twmd.proof_core` is the SAME SOURCE TEXT as that script, guarded per symbol by tests/test_proof_core_is_one_source.py, so the two cannot drift. Args: dataset: e.g. 'daily_price'. row_key: the dataset's LOGICAL key joined by '|', e.g. '2330|2026-08-14'. snapshot_version: omit for the most recent checkpoint.
macro
macro_regime_read
總經 Regime:景氣信號、利率與殖利率曲線、匯率、資金流。 ★ 這支講的是**整個市場**,不是任何一檔個股 —— 所以它不收 ticker。 ★ 事實整理,不是投資建議、不是預測。輸出帶 `does_not_prove`。 ★ ⚠️ `macro_worldbank` 類的來源會**回溯修訂**歷史年度:今天讀到的舊年度數字 和當時看到的不是同一個,`pit_notes` 會標出來。 ★ Args:只有 `as_of`(選填)—— 它**不收 ticker**,因為主體是整個市場。 ★ Returns:同一個誠實信封;`subject` 固定是 "TW_MARKET"。 ★ 例如問「現在景氣循環在哪個位置」就是這一支,而不是問某一檔。 ★ PRECONDITIONS:自己取數;requires 一個已識別的 session。 ★ SIDE EFFECTS:read-only,does not 寫入。
pending
list_pending_actions
Financial actions proposed by your research runs that are waiting for a human decision. Nothing here has been executed or ever will be by this system. These are proposals.
positioning
positioning_read
籌碼結構:法人分項、融資融券、借券使用率、大戶集中度、董監質押。 ★ 事實整理,不是投資建議、不是預測、不是目標價。輸出帶 `does_not_prove`。 ★ POINT-IN-TIME:`as_of` 逐資料集尊重揭露時差;不給就用「現在可知的最新」。 ★ 看不到的在 `cannot_see`,並分「查了沒有 / 查詢失敗 / 散佈權未取得」。 ⚠️ 逐券商分點進出**永遠**在 cannot_see —— 散佈權未取得,不要替它估算。 ★ PRECONDITIONS:自己取數,rows 不需要先用 `query_dataset` 備好;requires 一個 已識別的 session。方案沒涵蓋的資料集以 not_licensed 進 cannot_see,不整支失敗。 ★ Args:`ticker`(代號,例如 "2330")、`as_of`(選填的知識時間界線)。 ★ Returns:一個信封,`concerns`/`observations` 各帶觸發它的數字與驗證連結, 缺的東西 listed in `cannot_see`。 ★ SIDE EFFECTS:read-only,does not 寫入任何資料表。
price
set_price_alert
Leave a standing instruction: tell me when this symbol crosses this price. The alert OUTLIVES this conversation. It is evaluated against official daily closes by a resident agent and delivered to your realtime stream and to any webhook endpoints you have registered — signed, retried, and de-duplicated so one crossing is one notification. This is a NOTIFICATION, not an order. Nothing in TWMD can place a trade. Args: rule_id: your name for this alert. Re-using one UPDATES it rather than adding a second. symbol: the Taiwan ticker, e.g. "2330". direction: "below" or "above". threshold: the price level, in TWD. label: optional human-readable note carried on the alert. edge_triggered: True (default) fires on the CROSSING only — one long slump does not notify you every day. False fires on every bar that is past the level.
primary
read_primary_text
Read the FULL TEXT of filings and announcements — with proof links and a knowledge cutoff. ★ NOT `search_filings`. That one ranks passages by similarity and hands you fragments; this hands you whole documents so you can read what was actually said and where it sat in the filing. Similarity is not importance, and a fragment cannot show you its own context. ★ POINT-IN-TIME: pass `as_of` (YYYY-MM-DD). The cutoff is applied in SQL on the source's declared knowledge-time column BEFORE the row limit, so a bounded read is a true prefix of what was knowable, not a random subset of it. **Without `as_of` the read is NOT point-in-time** and says so in `warnings`. ★ NO SENTIMENT, NO SCORES — deliberately. Judging the text is your job. A stored score is one model's output on one day; after that model changes, the stale number still sits in the table looking exactly like a fresh one. ★ READ `corpus_reality` BEFORE CONCLUDING ANYTHING. The full-text corpus is SMALL and the response says how small. One source carries ~1M rows of TITLES ONLY — a large row count there is breadth, not depth, and "what did they say about it" is not answerable from titles. ★ A ticker that returns nothing appears in `coverage.missing`. That means nothing is held for it under those filters — NOT that the company disclosed nothing. Do not fill the gap. Args: source: which corpus, e.g. 'announcements_fulltext' or 'mops_major_event'. tickers: restrict to these codes, e.g. ['2330']. as_of: knowledge cutoff (YYYY-MM-DD). since: optional lower bound on the same knowledge-time column. limit: max documents (these are whole documents; keep it small).
recipe
run_recipe
Replay a saved multi-step routine over rows you fetched, with every step listed. ★ THREE ROUTINES: `momentum_scan` (rank by a return column), `earnings_surprise` (actual versus estimate), `dividend_capture` (which ex-dates are still ahead). ★ A SAVED ROUTINE IS NOT A TRADING VIEW. The names are conventional labels for well-known sequences; what runs is arithmetic over rows you supplied. `steps[]` spells out each operation so you can disagree with the routine rather than trust it, and nothing here says any of these sequences makes money. ★ SKIPPED SYMBOLS ARE LISTED, NEVER QUIETLY OMITTED. A symbol lacking the column a routine needs lands in `skipped[]` with the reason. A silently shorter list reads as "these were evaluated and did not qualify", when in fact they were never evaluated at all. ★ IT COMPOSES, IT DOES NOT FETCH. Rows come from `query_dataset`, so the routine inherits that call's `as_of` rather than defining a second point-in-time story of its own. ⚠️ Missing inputs are never substituted with zero — a zero estimate turns any positive result into an infinite surprise. Args: recipe, rows, as_of, today, top_n, min_yield.
regime
query_regime
The Taiwan business-cycle light (NDC monitoring indicator) as a monthly series. ★ THIS IS A REVISED FIGURE, NOT A POINT-IN-TIME ONE. Every response carries `revision_basis: as_revised`. Our source holds exactly one row per month — the CURRENT value, not the value as first published — and it records no publication date. ★ `as_of` IS REFUSED, AND THE REFUSAL IS THE POINT. There is no honest point-in-time answer here yet. Do NOT work around it by asking for a date range that ends at your as_of: the NDC publishes a month's light about 27 days AFTER that month ends, so a range ending 2026-03-05 still contains the February light that was not public until late March. That is look-ahead, it raises no error, and it makes a backtest look better than it was. ★ USE IT FOR CONTEXT, NOT AS A BACKTEST INPUT. Describing what regime the market is in today, or labelling historical periods for narrative, is fine. Feeding it into a simulated decision that claims to have been made at the time is not. Args: optional start/end (YYYY-MM-DD), limit. `as_of` returns a refusal explaining the above.
related
find_related
Traverse the knowledge graph for cross-table / supply-chain reasoning. - dataset_id: returns join-able datasets (+why) to plan multi-table analysis. - ticker: returns its industry value-chain node + peers in the same node (supply-chain reasoning). Args: dataset_id (e.g. 'equity_daily_prices') and/or ticker (e.g. '2330').
replay
replay_backtest
Re-run a stored backtest and report whether it still produces the same numbers. Same spec, same `as_of`, same data questions. If the numbers moved, either the engine version changed or the underlying data was restated — both are reported, neither is smoothed over. Args: run_id.
screen
screen
Turn a spoken shortlist description into explicit numeric cut-offs, and show the cut-offs. ★ THE THRESHOLDS COME BACK WITH THE SHORTLIST. "低本益比" becomes `per < 15`, and that 15 is printed in `applied[]` so you can disagree with it. A filter that hands over thirty names without saying where it drew the line cannot be checked by anyone — and whether the line was 15 or 20 completely changes which thirty. ★ PHRASES IT CANNOT MAP COME BACK IN `unparsed[]`. It will not quietly invent a boundary for a wording it did not recognise, because a list the caller believes they defined and actually did not is worse than a shorter list. ★ NOT `query_dataset` AND NOT `compare`. `query_dataset` returns rows for symbols you already chose; `compare` puts a handful of named symbols beside each other. This one is for when you have no symbols yet, only a description of what you are looking for. ⚠️ A shortlist is not a recommendation. Rows whose value is absent are excluded rather than assumed to pass — being unmeasured is not the same as qualifying. Args: conditions (plain words), optional as_of, optional pre-fetched rows.
supply
supply_chain_read
供應鏈與同業:產業鏈位置、同業分組、轉投資、外銷訂單 vs 營收。 ★ 事實整理,不是投資建議、不是預測。輸出帶 `does_not_prove`。 ★ ⚠️ `company_peer_groups` 無日期欄:指定過去的 `as_of` 時,回的是**現況**分組, `pit_notes` 會標「非當時分類」。 ★ ⚠️ 質化的客戶/供應商關係與分部營收在年報附註,那條來源**尚未建置** —— 固定列在 `cannot_see`(status=no_loader),不是這次查失敗。 ★ Args:`ticker`(例如 "2330")、`as_of`(選填)。 ★ Returns:誠實信封;外銷訂單與營收的背離會 listed in `concerns`。 ★ PRECONDITIONS:自己取數;requires 一個已識別的 session。 ★ SIDE EFFECTS:read-only,does not 寫入。
try
try_sample
Hand an unregistered caller a short taste of an open dataset, plus where to unlock the rest. ★ WHAT AN ACCOUNTLESS CALLER GETS INSTEAD OF A BARE REFUSAL. Somebody arriving through a chat connector with no plan would otherwise meet a flat rejection, which the host model relays as "this service turned you down". ★ WHAT IS ACTUALLY FREE, STATED CONCRETELY. The reference resources read with no key at all, and the five sample tickers (2330, 2317, 2454, 0050, 2603) answer through `query_dataset` with no plan. Querying beyond those over MCP starts at the Pro plan. ★ OPEN DATASETS YIELD A FEW MARKED ROWS; PAID ONES YIELD NONE. For a paid dataset the row list is not even consulted, so no figure can escape through this path regardless of what the caller passes in. `rows_withheld` states how many were held back, because a taste that does not say it is a taste reads as the whole thing. ★ NOT `query_dataset`. That one serves entitled callers in full. This exists only for the moment somebody hits the edge of what they are entitled to. ⚠️ Withdrawn datasets stay refused here too — a licence ruling is not a tier, so no amount of signing up unlocks them. Args: dataset, keyless_eligible, rows.

Tools removed

Tools this server used to expose. Anything built against them stopped working on the day they went.

_enforced_tier
removed 9 Aug 2026
_mint_and_record_query_id
removed 29 Aug 2026

Endpoints

URLTransportStateLatencyChecked
https://mcp.twmarketdata.com/mcp streamable-http answering 818 ms 5 min ago

Alternatives to Tw Market Data

same job, measured the same way
Alpaca
by pipeworx-io

Alpaca MCP — real-time US stock market data via the Alpaca Market Data API

34 tools answering
Financial Data API
by financialdatapi

Point-in-time macro, central bank rates and sentiment, COT positioning, from official sources.

answering
TWSE Open Data (Taiwan Stock Exchange)
by taux-io

Taiwan Stock Exchange (TWSE) open data as MCP tools: stock quotes, ETF data, 140+ public datasets.

5 tools answering
O
Market Data
by memoryapi

Real-time stock quotes, market indices, and institutional holdings

3 tools answering
True Markets Market Data
by truemarkets

Real-time crypto market data

10 tools answering
CoinMarketCap
by coinmarketcap

Official CoinMarketCap MCP server: real-time crypto prices, market cap, rankings and exchange data.

answering
Volcanodog
by volcanodog

Real-time and delayed market sentiment data with premium access via Stripe payments

answering
Zwldarren Akshare One MCP
by smithery

Provide access to Chinese stock market data including historical prices, real-time data, news, and…

answering

Tw Market Data — questions

Answers built from our own checks of this server.

What can Tw Market Data do?
It exposes 41 tools, read directly from the server on our last check. Among them: agent_activity, approve_action, ask, calendar, chart, cite_this and 35 more. The full list with descriptions is on this page — we take it from the server itself via tools/list, not from a README. How MCP servers expose tools in the first place →
What is Tw Market Data mostly used for?
Its tools cluster around memory, risk and backtest. That is what this server is built to work with — the grouping comes from the actual tool names, not from a category we assigned.
Is Tw Market Data working right now?
We send a real MCP handshake every 15 minutes. Over the last 24 hours 83 of 92 checks got a reply (90.2%), average response time 828 ms. The bar chart above shows every period we have measured.
Did Tw Market Data ever remove tools?
Yes. _enforced_tier, _mint_and_record_query_id are no longer exposed — we recorded the date each one disappeared. A tool vanishing usually means a breaking change for anything that depended on it.
How do I connect Tw Market Data?
Copy the ready config from this page — we generate it for Claude Code, Claude Desktop, Codex, Cursor and VS Code, each with the file path that client actually reads. It is a remote server, so there is nothing to install — the client connects to the address.
Does Tw Market Data need an API key?
No. Tw Market Data completed a full MCP handshake with us as an anonymous client and listed its tools without asking for anything. All 41 of them are readable on this page. This is what we observed, not what the docs claim.
How fast is Tw Market Data?
It answers our handshake in 828 ms on average, which is faster than 13% of all working MCP servers we measure. That is on the slow side — worth knowing if the tool sits inside an interactive loop. The comparison comes from our own checks across the whole registry, every 15 minutes.