One URL and one API key. The URL is the same for everyone; the key is yours, issued in the dashboard.
MCP server URL https://mcp.twmarketdata.com/mcpTransport streamable HTTPAuth header X-API-Key: sk_live_...
Connecting and using are two different steps, and they fail differently — worth knowing before you start, because a client can look connected while every call is refused.
Connecting needs no key. Any MCP client that reaches the server will list its tools — 34 of them, read from the server on 2026-08-25 — and six reference resources. If your client shows that list, the transport is working.
Calling a tool needs the key. Without it the server answers 401 unauthorized. So "the tools are listed" is not yet proof you are authenticated — the proof is a tool call that returns data.
The quickest check: ask the agent to run list_datasets. Data back means both steps are done.
The shortest path if you already use Claude Code. Replace sk_live_... with your own key; everything else is literal.
claude mcp add --transport http twmd \
https://mcp.twmarketdata.com/mcp \
--header "X-API-Key: sk_live_..."
Run /mcp inside Claude Code. twmd should be listed as connected, with its tools available. Then ask for a dataset list — if rows come back, the key is being sent correctly.
Add this block to ~/.codex/config.toml. The section name after mcp_servers. is the name the agent will use.
[mcp_servers.twmd]url = "https://mcp.twmarketdata.com/mcp" [mcp_servers.twmd.http_headers]"X-API-Key" = "sk_live_..."
Some clients only accept a command to run, not a URL. mcp-remote bridges the two: it speaks stdio to the client and streamable HTTP to us.
Point your client at this as the command. It needs Node.js on the machine; nothing is installed permanently.
npx -y mcp-remote https://mcp.twmarketdata.com/mcp \
--header "X-API-Key: sk_live_..."
Claude's Connectors screen and ChatGPT's developer-mode custom connector both take the server URL and sign you in with OAuth. There is no key to paste, and nothing to keep out of a config file — which is why this is the route to try first.
The three methods above still work and are not deprecated. They carry the key in a header, which is what you want for a script, a CI job, or anywhere a browser sign-in is not available.
- Open your client's connector settings — Claude: Connectors; ChatGPT: developer mode, custom connector.
- Paste the server URL below. It is the same URL used by every method on this page.
- Sign in when the OAuth prompt appears. The connection is bound to your account from there; no API key is entered at any point.
https://mcp.twmarketdata.com/mcp
34 tools and six reference resources. The count, the names and the arguments are read from the server with a tools/list call rather than kept by hand, so a tool listed here is a tool the server actually serves. An agent discovers them itself after connecting; there is nothing to configure per tool.
- list_datasets — the discovery entry point. Start here to find the right data.
- describe_dataset — what one row means, field units, and the time-correctness rules. Read this before backtesting.
- query_dataset — rows, with look-ahead protection: pass as_of and the agent only sees what was public on that date.
- find_related — cross-table and supply-chain reasoning across the knowledge graph.
- Same official data and same credits as REST. The MCP tools are a protocol wrapper, not a second dataset.
Where a session starts: what exists, and what a row in it actually means.
- list_datasets — Lists the available Taiwan-market datasets — the discovery entry point. Use it when: first call of a session, when you do not yet know which dataset holds what you need. Key arguments: category, tier.
- describe_dataset — Full semantics of one dataset: what a row is, field meanings and units, and its time rules. Use it when: before querying anything unfamiliar. Reading it is what stops a unit or a grain being guessed. Key arguments: dataset_id.
Getting rows out, with look-ahead protection and a provenance trail attached.
- query_dataset — Returns rows with built-in look-ahead protection; `as_of` filters by disclosure date, so only what was public at that moment comes back. Use it when: any time you need actual numbers. For a backtest or agent learning, pass `as_of` — omitting it is a present-day lookup and the response says so. Key arguments: dataset_id, tickers, start, end, as_of, limit.
- find_related — Traverses the knowledge graph for cross-table and supply-chain reasoning. Use it when: when the question spans tables — a supplier's exposure to a customer, or which datasets join with this one. Key arguments: dataset_id, ticker.
- search_filings — Semantic search over MOPS filings, financial-statement notes and company announcements. Use it when: when the answer is in prose rather than in a numeric table — a note, a disclosure, a stated reason. Key arguments: query, tickers, doc_type, source_tier, as_of, limit.
- ask — Answers a plain-language question in Taiwanese-market vocabulary, taking the real numbers rather than composing them. Use it when: when you do not yet know which dataset the question maps to. It routes; it does not invent an answer it cannot source. Key arguments: question.
- read_primary_text — Reads the full text of a filing or announcement, with links back to the proof of what was published. Use it when: when a summary is not enough and the wording itself is the evidence. Key arguments: source.
Multi-step passes that produce a sourced report rather than a single answer.
- run_research — Runs a multi-agent research pass and returns a structured, sourced report. Use it when: for an open question that needs several steps and should end in something citable, not a one-shot answer. Key arguments: prompt, tickers, start, end, as_of, max_backtests.
- get_research — Retrieves one of your previous research reports by id. Other tenants' runs are not visible. Use it when: to re-read or cite a run you already paid for, instead of running it again. Key arguments: research_id.
- list_factor_findings — Verdicts from the overnight factor search on your namespace — including the ones that failed. Use it when: to see what was tried while you were away. The rejections are the informative half. Key arguments: limit.
Point-in-time runs, retrievable by id and re-runnable to check they still agree.
- run_backtest — Runs a point-in-time backtest and returns its run_id, metrics and sources. Use it when: to test a rule over history without the run seeing anything that was not knowable at the time. Key arguments: strategy_id, start, end, as_of, tickers, universe_kind, rebalance, cost_bps.
- get_backtest — Retrieves a previous backtest by run_id — the full record, including why it was run. Use it when: when you need the original numbers and the reasoning behind a run you are about to cite. Key arguments: run_id.
- list_backtests — Lists your recent backtest runs, newest first. Use it when: to find a run_id you did not write down. Key arguments: limit, strategy_id.
- replay_backtest — Re-runs a stored backtest and reports whether it still produces the same numbers. Use it when: before relying on an old result. A run that no longer reproduces is the thing you want to find out about early. Key arguments: run_id.
- risk_assess — Measures a portfolio you state against limits you state, on official point-in-time data. Use it when: to check a proposed book against constraints before acting. It measures; it does not advise. Key arguments: positions, as_of, max_position_weight, max_drawdown.
What an agent chose to remember, with the knowledge time it was true at.
- memory_save — Remembers something, together with its sources and the knowledge time it was true at. Use it when: when a conclusion should outlive the conversation. Saving the source ids is what makes it checkable later. Key arguments: key, kind, content, as_of, source_query_ids, agent_id.
- memory_search — Recalls your own memories — hybrid semantic and exact-term, with provenance. Use it when: before re-deriving something. `include_superseded` is how you see what you used to believe. Key arguments: query, key, kinds, as_of, include_superseded, limit.
- memory_replay_query — Re-runs a remembered query by its `twmd_q_…` id, through the read API's original path. Use it when: to reproduce the exact data a past decision was made on, rather than today's version of it. Key arguments: query_id.
- memory_get_watchlist — Returns the active version of your watchlist. Use it when: at the start of a session that should act on a standing list rather than an ad-hoc one. Key arguments: key.
Standing instructions that outlive the conversation that created them.
- set_price_alert — Leaves a standing instruction: tell me when this symbol crosses this price. Use it when: when the trigger is a market event rather than the end of this conversation. Key arguments: symbol, threshold, direction, edge_triggered, label, rule_id.
- list_alerts — Lists your standing alert rules. Another customer's alerts are simply not visible. Use it when: to see what is already watching before adding another rule. Takes no arguments.
- delete_alert — Removes one of your standing alerts. Use it when: when a rule has served its purpose. Naming an id that is not yours changes nothing. Key arguments: rule_id.
The human-approval boundary, and the audit trail of what agents actually did.
- list_pending_actions — Financial actions proposed by your research runs that are waiting for a human. Use it when: the queue an operator reads. Nothing here has happened yet — that is the point of the queue. Takes no arguments.
- approve_action — Records a human's approval of a proposed action. Use it when: the boundary an agent cannot cross on its own. The approver is recorded, not inferred. Key arguments: action_id, approver.
- agent_activity — What your agents have actually done, from the durable audit trail. Use it when: for review after the fact, and for answering the question an auditor will ask. Key arguments: limit.
Turning rows you already have into a shortlist, a comparison, a chart or a repeatable routine.
- compare — Lays two to five named companies side by side on the same measures. Use it when: for a like-for-like read across a small, named set — not for screening a universe. Key arguments: tickers, metrics.
- screen — Turns a spoken shortlist description into explicit numeric cut-offs, and applies them. Use it when: when the universe is unknown and the criteria are. The cut-offs it chose are returned, so a vague ask does not become a silent one. Key arguments: conditions.
- chart — Turns rows you already fetched into a Vega-Lite drawing the chat client can render. Use it when: after a query, not instead of one — it draws what you pass it and fetches nothing itself. Key arguments: rows, x_field, y_field.
- calendar — Sorts corporate dates into what is still ahead and what has already happened. Use it when: when the question is about timing — an ex-date that has passed reads very differently from one that has not. Takes no arguments.
- run_recipe — Replays a saved multi-step routine over rows you fetched, showing each step. Use it when: for an analysis you repeat. The steps are shown rather than folded into a single number. Key arguments: recipe.
For a caller who has not integrated yet: a runnable snippet, and a look at real data.
- get_code_example — Emits a copy-pasteable HTTP snippet wired to the real endpoint. Use it when: when moving from the chat to your own code, and the endpoint and parameter names have to be right. Key arguments: intent.
- try_sample — Hands an unregistered caller a short taste of an open dataset. Use it when: to see the real shape of a dataset before integrating anything. Key arguments: dataset.
Checking a row was in the snapshot we published, without taking our word for it.
- get_inclusion_proof — Proves a row was in the snapshot TWMD published — and gives you what you need to check it yourself. Use it when: when a number has to survive someone else's scrutiny, not just your own. Key arguments: dataset, row_key, snapshot_version.
- cite_this — Produces a bibliographic citation for TWMD data — APA, BibTeX and a verify link. Use it when: when the output goes into a paper, a memo or a DDQ and the source has to be stated properly. Key arguments: dataset.
The server is live and connectable, and it is beta rather than GA: the tool surface may change before general availability. The REST API remains the stable path for anything you cannot afford to have move.
A model that was never trained on this company will guess our API and get it wrong — wrong host, invented parameters, plausible nonsense. It cannot guess an MCP server: it connects, asks what is available, and is told. That is the argument for publishing this metadata rather than hoping to end up in a training set.
The path matters. The bare host answers 404, so a client given only the hostname concludes the server is down.
Server name com.twmarketdata/tw-market-dataVersion 1.28.1Endpoint https://mcp.twmarketdata.com/mcpTransport streamable-httpHandshake verified 2026-08-21Machine manifest /.well-known/mcp.json
- Point-in-time is a query parameter, not a convention. Pass as_of and the response states point_in_time, as_of_applied and which knowledge-time field it used.
- coverage.missing lists what was asked for and not returned, with a reason. An empty result beside a populated missing list is a complete answer, not an invitation to estimate.
- Proof endpoints need no key. An agent can verify a row belongs to a signed snapshot before quoting it.
- Authentication is required for data tools: an API key or an OAuth login. Connecting without one returns a structured 401 rather than empty results.
Stated here because a registry listing is exactly where an over-claim gets copied onward by somebody who never reads the page.
- Taiwan listed and OTC equities, derivatives and regulatory disclosure. No US equities, no VIX, no order-book depth.
- A proof establishes integrity and origin, not correctness. If an official source published a wrong figure, the proof attests faithfully to the wrong figure.
- Not investment advice, and the tools will not produce a buy, sell or target price.
This is the exact payload served at /.well-known/mcp.json — rendered from the same module, not transcribed.
{
"$schema": "https://modelcontextprotocol.io/schemas/server.json",
"name": "com.twmarketdata/tw-market-data",
"description": "Taiwan equities market data with point-in-time safety and cryptographic proof. Every value can be checked against a signed Merkle snapshot using public, keyless endpoints and a standard-library verifier, so an agent's citations can be verified rather than trusted.",
"version": "1.28.1",
"websiteUrl": "https://twmarketdata.com",
"remotes": [
{
"type": "streamable-http",
"url": "https://mcp.twmarketdata.com/mcp"
}
],
"_meta": {
"com.twmarketdata/verified_on": "2026-08-21",
"com.twmarketdata/requires_auth": true,
"com.twmarketdata/coverage": "Taiwan (TWSE, TPEx, TAIFEX, MOPS) only",
"com.twmarketdata/proof_endpoints_keyless": true,
"com.twmarketdata/not_investment_advice": true
}
}