finance-mcp-server
# Finance MCP Server
[](LICENSE)
[한국어 버전](https://github.com/mkkim2102/finance-mcp-server-ko)
A personal finance research and execution toolkit for LLM agents, built as one
[MCP](https://modelcontextprotocol.io) server that composes three
purpose-built sources: **DART**, **Telegram**, and **Toss Securities**.
## Why these three
Most "AI + finance" setups reach for one thing: a market data API, or a news
feed, or a broker connection. This project is built around the idea that
useful financial reasoning needs three different *kinds* of input, each
doing the job it's actually good at:
- **DART — structured data.** Korea's official disclosure system
(filings, financial statements, shareholder structure, dividends). This is
ground truth: audited, dated, and unambiguous. It's slow-moving and
backward-looking by nature — a company's last quarterly filing, not what's
happening right now.
- **Telegram — unstructured data.** Chosen deliberately, not as a generic
"news" source. Analysts and everyday investors post their actual research
and opinions on Telegram every day — it's where a lot of pre-publication
and off-the-record commentary in Korean stock investing circles actually
happens. Reading it isn't about ingesting news headlines; it's about
seeing what people who are actively trading are paying attention to
*right now*, which is a different signal than what any news wire reports.
- **Toss Securities — the execution layer.** Prices, order books, candles,
account holdings — and, increasingly, the ability to actually act: placing,
modifying, and canceling live orders, and managing a portfolio. This is
the layer that turns research into a position.
Put together: DART tells you what's true, Telegram tells you what people are
paying attention to, and Toss is how you act on either.
## Architecture
Each source is a complete, independent MCP server that also runs on its own:
```
finance-mcp-server/
├── server.py # composes the three below into one MCP server
├── dart/ # structured data
├── toss/ # execution layer
└── telegram/ # unstructured data
```
The root `server.py` doesn't fork or reimplement any of the three servers'
logic. At import time, it loads each `<source>/server.py` as an isolated
module and copies its registered tools onto one shared MCP server instance.
Editing a tool's behavior means editing it inside its own source folder —
the root file only wires things together, and picks up any change made
inside a source automatically on the next restart.
The only name collision across all three is `test_connection` (each ships
one); those are renamed to `dart_test_connection`, `toss_test_connection`,
and `telegram_test_connection`. Everything else keeps its original name.
There's also a `finance_test_connection` tool that checks all three sources'
credentials/connectivity in one call.
## Quick start
Each source needs its own credentials — see [USAGE.md](USAGE.md) for the
full setup walkthrough per source (including Toss's IP allow-list
requirement and Telegram's one-time login), the complete tool catalog, and
worked examples.
```sh
# in each of dart/, toss/, telegram/ you want to use:
cp .env.example .env # then fill in the real values
# from the repo root:
uv sync
uv run server.py
```
### Registering with an MCP client
```json
{
"mcpServers": {
"finance-mcp": {
"command": "/absolute/path/to/finance-mcp-server/.venv/bin/python",
"args": ["/absolute/path/to/finance-mcp-server/server.py"]
}
}
}
```
## Order placement is live (Toss)
`place_order` and `modify_order` submit real orders against a real account
and require an explicit `confirm=True` argument — calling without it raises
an error instead of submitting anything — with orders above a size threshold
additionally requiring `confirm_high_value_order=True`. `cancel_order` is
intentionally *not* gated behind `confirm=True`, since canceling is the safe
direction. None of this is a substitute for a human-in-the-loop check: an
autonomous agent can supply `confirm=True` on its own, so treat it as
recording caller intent, not as proof a human approved the trade. There is
no simulation/dry-run mode. Read `toss/README.md` before connecting this to
anything that can call tools autonomously.
## Documentation
- [USAGE.md](USAGE.md) — full setup per source, complete tool catalog, worked examples
- [DESIGN.md](DESIGN.md) — the rationale behind each source's guardrails: the
different kinds of limits in DART/Telegram (bounding data volume) versus
Toss (bounding irreversible intent), and what changed as a result of a
security review before this was made public
## Status
This is an evolving personal project, not a polished product. The three
sources were each built and hardened independently before being composed
here; expect rough edges, and expect the tool set to keep growing
(especially on the Toss side).
## License
[MIT](LICENSE)
TDQS
Scored across 46 tools
Most tools have distinct purposes, but several overlaps create ambiguity: multiple connection/credential checks (dart_test_connection, check_dart_api_key, finance_test_connection), two company-profile tools (get_company_profile vs get_company_profile_by_query), and two financial-statement tools (get_financial_statements vs get_full_financial_statement). Detailed descriptions help, but an agent could easily pick the wrong one based on name alone.
Most tools follow a readable get_/search_/check_/place_/cancel_/modify_ pattern, but there are minor inconsistencies: connection checks mix test_connection, check_*_api_key, and check_*_credentials; get_financial_statements vs get_full_financial_statement uses awkward singular/plural variation; Telegram tools use list_dialogs instead of get_dialogs.
46 tools is far beyond the 3-15 well-scoped range, and the count is inflated by redundant health-check/credential tools and by bundling three unrelated integrations (DART, Toss, Telegram) into one server. It is not an extreme 50+ count, but it is too heavy for a coherent single-purpose surface.
Within each bundled domain, coverage is reasonably complete: DART covers company search, financials, shareholder data, and disclosures; Toss covers quotes, orders, and accounts; Telegram covers listing chats, reading/searching messages, and downloading files. Minor gaps like no send_message and no broader historical order report exist, but agents can work around them.