stock-api: four data sources, one fallback chain, and a last resort that only covers A-shares
Query A-share, US, Hong Kong stock and listed fund quotes, with quick integration via Node.js, browser, CLI or MCP.
At a glance
- What is it?
- stock-api wraps Tencent, Sina and Eastmoney public quote interfaces behind one zero dependency TypeScript package reachable from Node, the browser, a CLI and MCP. The default chain tries Tencent then Sina then Eastmoney, which puts the one source with an explicit A-share restriction last, and the MCP configuration launches npx with auto approval so nothing is pinned.
- Who is it for?
- stock-api is a reasonable choice if you want quotes for A-shares, Hong Kong and US symbols without an API key, you are on Node 18 or later, and you accept that you are reading free public endpoints from three Chinese providers with none of the guarantees that implies.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository received new commits within the last day.
- What is it written in?
- Mainly TypeScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 8, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The default chain puts the A-share only source last
There are three named sources and one wrapper, and the wrapper is what you are told to use. The package description calls `stocks.auto` the default, and the feature list states the automatic fallback order as tencent, then sina, then eastmoney.
Now read the capability table against that order. The auto, Tencent and Sina rows all list the same five capabilities: single quote, batch quotes, K-lines, search and diagnostics. The Eastmoney row is the only one with a market restriction written into the capability, and it restricts the single quote to A-shares.
So the source with the narrowest documented reach is the last fallback. Every symbol that is not an A-share, which includes every Hong Kong and US code the package claims to support, reaches Eastmoney only after both general sources have failed, and the table does not say what Eastmoney returns for those codes.
The prefix scheme is what makes this concrete. Symbols are written with a market prefix, and the documented set is Shanghai, Shenzhen, Hong Kong and United States. The example that appears in the Node, browser, CLI and MCP sections is a Shanghai exchange traded fund code, and the second example is a Shanghai listed stock. So the canonical examples are both A-share instruments.
The repository description goes further than the feature list and names exchange traded funds as a supported category. The feature list does not mention funds at all; it names A-share, Hong Kong and US code formats. That difference is small, but it is the difference between a documented capability and one that only appears in the summary line.
Eastmoney search breaks on CI egress addresses, and quotes do not
One note under the data source table is the most operationally useful thing on the page, and it draws a boundary the capability table does not.
`stocks.eastmoney.searchStocks` depends on a search interface that returns an anti-scraping response to some network environments, and the environments named are overseas servers and CI egress addresses. The result is that search fails. Quotes and K-lines are explicitly unaffected.
That is a precise failure mode with a precise scope, and it is documented rather than discovered. It also happens to land on exactly the two audiences most likely to be reading the page: anyone running the browser demo from outside the region, and anyone whose tests execute on hosted infrastructure.
The prescribed fix is to stop calling the narrow source directly and use `stocks.auto` for search, because it falls back to Tencent and Sina when the Eastmoney search fails. That advice is correct and it also reveals the design. A single narrow failure is absorbed by the wrapper, so the wrapper is load bearing rather than a convenience, and a caller who has chosen a source explicitly has opted out of the fallback that would have saved them.
The search capability is therefore the one place where the source choice matters most, and the one place where the documentation asks you not to choose.
Five MCP tools, four CLI commands, four API methods, three naming conventions
The package exposes the same idea through four interfaces, and the surface area is not identical on any of them.
The MCP server advertises five built-in tools: `get_stock`, `get_stocks`, `get_klines`, `search_stocks` and `inspect_stock`. The CLI section documents four commands: `get-stock`, `get-stocks`, `get-klines` and `search-stocks`. The Node and browser sections each show four methods: `getStock`, `getStocks`, `getKlines` and `searchStocks`.
So the fifth tool, `inspect_stock`, exists in the MCP surface only. It corresponds to the diagnostics capability that all four sources in the capability table carry, which means diagnostics are reachable through the wrapper and through three sources from code, and through MCP, but the front page names no CLI command for it and no library method. Whether the CLI has an undocumented flag or simply does not expose it cannot be told from this page, and the CLI document is listed as covering commands, parameters, output and exit codes.
That last point is its own small gap. The documentation table says the CLI guide covers exit codes, and the front page then documents none of them. A CLI that writes to an exit code is being written to be consumed by something, and the something is left to the reader.
The three naming conventions are the visible symptom of four surfaces maintained in parallel. Snake case in MCP, kebab case in the CLI, camel case in the library. Each is idiomatic for its surface, and each is a place where a rename has to be made four times.
The MCP configuration launches npx with auto approval, so the client pins nothing
The MCP setup is a configuration block, and it is four lines that decide how the server starts:
{
"mcpServers": {
"stock-api": {
"command": "npx",
"args": ["-y", "stock-api", "mcp"]
}
}
}The `-y` flag is the interesting part. It answers the install confirmation without asking, which is what makes the block work unattended, and it also means the version resolved is whatever the registry serves at the moment the client starts the server. There is no version in the arguments and no lockfile consulted, so two clients starting a month apart can run different builds of a package whose releases move every few weeks, and the newest three tags are two patch lines and a minor line inside a single quarter.
The skill route has the same property by a different mechanism. The instructions tell you to send a line to any AI tool that asks it to read a `SKILL.md` from a raw URL on the main branch, then answer stock questions with the package. That document contains the npx commands, and the page notes it shares one data logic with MCP. So the agent path fetches its instructions from a moving branch and runs a moving package, with no version on either side.
Underneath, the executable is plain JavaScript. The package maps its bin to `dist/cli.js`, and the build script sets that file to mode 755 after compiling. There is no compiled launcher in the picture, which is the right call for a package that claims zero runtime dependencies.
Zero runtime dependencies means three response shapes parsed by hand
The package describes itself as having zero runtime dependencies, and states it twice more in the feature list. There is no HTTP client library, no date library, no parsing library and no normalisation helper in the manifest, and the engine floor is Node 18.
That is credible for a Node 18 target, where a global fetch exists, and it is a real advantage for a package whose selling point is being droppable into a browser bundle from a CDN as a single IIFE file. The cost is visible in the documentation table instead. One of the five documents is the architecture guide, and it is described as covering the directory structure, the provider factory, and the parsing and error model.
A parsing and error model is exactly what you have to write yourself when three providers return three different response shapes. The capability table makes the shapes different on purpose, since Eastmoney is the A-share source while Tencent and Sina are the general ones. So the normalisation between providers, and the decision about what a provider failure looks like as opposed to a missing symbol, is hand written, and it is the part of this package most likely to change when a provider changes a field.
The manifest fields bear this out. The `module` and `browser` entries point at the same file, the ESM browser build, so a bundler reading either gets the same artefact. The `exports` map repeats four of the six top level distribution fields by hand. The root export offers types, browser, import and require but no default condition, while the separate browser subpath does offer one. None of that is wrong, but it is the shape a package arrives at when a script maintains the manifest rather than a person.
The project schedules checks on the free endpoints it depends on
One of the five documented guides is a monitoring document, described as running scheduled checks against the third-party data sources and updating a status badge.
That is an unusual thing for a zero dependency library to do, and it explains the diagnostics capability that appears in all four rows of the source table. Diagnostics is not a debugging aid bolted on at the end; it is how a caller finds out which upstream is answering, which matters when the fallback chain can silently route a request to a different provider than the one you expected.
It also sets an expectation about what this package is. It wraps public endpoints provided by three companies for free, it does not guarantee accuracy, completeness, real-timeness or continued availability, it gives no investment advice, and it tells you to confirm the third-party sources' terms, licensing scope and compliance requirements yourself before commercial, high frequency or production use.
That disclaimer is the right one for the project, and it is more specific than the term of service most wrappers of this kind carry. It also means the status badge is the honest signal about whether anything works, and that the project already knows its own supply chain is not under its control.
The rest of the tree supports the same picture. Conventional commits drive releases through a release configuration file, a changelog is kept at the root, husky installs as the prepare script, linting runs through a flat config, three separate tsconfig files cover the build, the tests and the editor, and the manifest version matches the newest release tag exactly. There is also an ESLint config, an editorconfig, a directory of examples including a no-Jekyll marker for the Pages site, and a script that serves those examples locally.
Four badges, three of which are the same link, and a usage section with nothing in it
The header has two small defects that are worth naming only because they tell you how the page is maintained.
The badge row contains four links. One is a download comparison chart, and the other three point at the identical address, the npm package page. So a third of the header is one link repeated.
Above the description there is a section heading for the supported usage methods, and it is followed by an empty paragraph with nothing between the tags. The methods themselves are not missing from the page; Node.js, browser, CLI, MCP and the agent route each get their own top level section further down. So the summary heading renders as an empty block and the reader has to discover the structure from the table of contents that is not there.
Neither of these affects anything. Together they are a reasonably honest signal about the state of the file: the substantive documentation is accurate, specific about its failure modes, and careful about where it wants you to be careful, while the surrounding scaffolding has not been revisited.
That split is worth holding on to when you read the rest of the page. The parts that carry engineering judgement, the fallback ordering, the source capability differences, the CI egress note and the disclaimer, are specific and checkable. The parts that are presentation are approximate.
Editorial conclusion
stock-api is a reasonable choice if you want quotes for A-shares, Hong Kong and US symbols without an API key, you are on Node 18 or later, and you accept that you are reading free public endpoints from three Chinese providers with none of the guarantees that implies. Use `stocks.auto` rather than naming a source, because the wrapper is what absorbs the Eastmoney search failure that overseas and CI networks hit, and because the fallback order is the part of this design that has been thought through. Pin your version in the MCP configuration rather than relying on the shipped block, because the recommended configuration launches npx with auto approval and resolves whatever is on the registry at start time, and pin the branch for the agent route too since its instructions come from a moving raw URL. Read the terms position yourself before using this commercially or at any frequency: the project places the burden of confirming the third-party sources' terms on you and disclaims accuracy, completeness, real-timeness and availability. Expect to check the status badge rather than assume the upstream is answering, and expect diagnostics to be the tool that tells you which provider replied. Note that the fifth MCP tool has no documented CLI or library counterpart, and that no CLI exit codes are given on the front page. For anything beyond spot queries, this is a thin wrapper whose value is convenience and zero dependencies, not coverage, speed or accuracy.
Frequently asked questions
What data sources does stock-api use?
Three public quote interfaces, Tencent, Sina and Eastmoney, plus stocks.auto which selects between them. The documented fallback order is tencent, then sina, then eastmoney, so Eastmoney is the last resort rather than the primary source, and its single-quote capability is the only one documented as restricted to A-shares.
Is stock-api free and does it need an API key?
The package states zero runtime dependencies and no key appears anywhere in its install or configuration. It uses third-party public quote interfaces, and its disclaimer tells you to confirm those sources' terms, licensing scope and compliance requirements yourself before commercial, high frequency or production use.
Does stock-api work from outside China or on CI?
Quotes and K-lines are documented as unaffected. The search function on the Eastmoney source depends on an interface that returns anti-scraping responses to some overseas servers and CI egress addresses, so the documentation recommends stocks.auto for search, since it falls back to Tencent and Sina when Eastmoney search fails.
Which tools does the stock-api MCP server expose?
Five, named get_stock, get_stocks, get_klines, search_stocks and inspect_stock. During the handshake it negotiates the protocol version, supporting 2025-11-25 and 2025-06-18, returning the client's requested version when it is supported and otherwise falling back to the newest one it offers.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/zhangxiangliang-stock-api)