关于 TossInvest OpenAPI MCP
TossInvest OpenAPI MCP 是供开发者访问 Toss Securities 账户和市场数据的本地 MCP 服务。默认提供只读工具;真实下单操作须通过明确的开关、确认和金额限制。
主要功能
- 01只读市场与账户数据
- 02投资组合与交易前检查
- 03基于预览的订单工作流
- 04默认禁用交易
- 05凭证与令牌脱敏
适用场景
- 01查看持仓与购买力
- 02检查市场价格和订单簿
- 03审批前预览订单
- 04核对近期订单状态
MCP 相关
这个本地 stdio MCP 服务向 MCP 客户端提供 Toss Securities Open API 数据及受保护的订单工具。订单工具默认执行模拟;真实操作需要配置安全开关。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
我们还没有获取到这个服务的安装包或远程地址,请按项目 README 中的说明安装。
工具
本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。
详细介绍
tossinvest-openapi-mcp
默认安全的本地 stdio MCP 服务,适用于官方 Toss Securities / 토스증권 Open API。
此软件包是独立的开发者工具,与 Toss Securities 无关联,也未获得其认可或赞助。
此软件包面向希望在 MCP 客户端中读取账户、市场和订单数据的开发者,并提供可选的订单操作,这些操作受多个明确的安全门控保护。
默认安全设置
- 仅使用官方 Toss Open API 服务:
https://openapi.tossinvest.com - 启动时不需要凭据;如果缺少配置,
auth_status会报告缺少配置,而不会崩溃。 - OAuth 访问令牌仅保存在内存中。
- 对符合条件的 GET
401 invalid-token或401 token-revoked响应,会替换受影响的缓存令牌并重试一次;同一客户端实例中的并发令牌签发请求会合并处理。 auth_status会分别报告令牌签发状态和数据端点可达性,并报告是否配置了默认的TOSS_ACCOUNT_SEQ。- 会从工具输出和错误中删去 API 密钥、机密、Bearer 令牌、账户标头和账号。
- 默认禁用交易。
- v0.2 工作流工具优先保障安全,并基于预览:
portfolio_snapshot → pre_trade_check → order_preview → approval → order_execute → order_status_summary。 order_preview仅在内存中存储预览合约,绝不会调用 Toss 订单 POST 端点。order_execute有意设计为快速执行:仅重新检查预览、确认、哈希、环境变量和委托权限门控;最多提交一个订单 POST;对于超时或网络状态不明确的情况,会报告unknown_execution_state,以便在任何手动重试前进行核对。- 订单工具默认使用
dryRun=true。 - 实际创建、修改或取消订单需要设置
ENABLE_TRADING=true,并启用相应操作的专用门控。 - 默认要求确认。
- 默认最大订单金额为
0KRW 和0USD。 BLOCKED_SYMBOLS的优先级高于ALLOWED_SYMBOLS。
安装并运行
此仓库目前仅通过 GitHub 源代码分发,尚未以由 EthanKlocked 所有的软件包名发布到 npm。
重要提示:未限定作用域的 npm 名称 tossinvest-openapi-mcp 已被另一个 npm 软件包使用,因此请勿安装或运行该软件包并期待它包含此仓库的代码。
克隆此仓库,然后在本地安装并构建:
git clone https://github.com/EthanKlocked/tossinvest-openapi-mcp.git
cd tossinvest-openapi-mcp
npm install
npm run build
npm test
在本地运行:
TOSS_API_KEY=... TOSS_SECRET_KEY=... node dist/index.js
请勿将真实机密放入已提交的文件中。建议通过本地 shell 或 MCP 客户端的机密管理器传递环境变量。
MCP 客户端配置示例
使用本地克隆路径:
{
"mcpServers": {
"tossinvest": {
"command": "node",
"args": ["/absolute/path/to/cloned/tossinvest-openapi-mcp/dist/index.js"],
"env": {
"TOSS_API_KEY": "${TOSS_API_KEY}",
"TOSS_SECRET_KEY": "${TOSS_SECRET_KEY}",
"TOSS_ACCOUNT_SEQ": "${TOSS_ACCOUNT_SEQ}"
}
}
}
}
如果此项目之后发布到 npm,请使用由维护者所有的软件包名,例如 @ethanklocked/tossinvest-openapi-mcp,而不是已被占用的未限定作用域名称。
环境变量
| 名称 | 默认值 | 用途 |
|---|---|---|
TOSS_API_KEY | 未设置 | Toss Open API 客户端 ID / API 密钥。 |
TOSS_SECRET_KEY | 未设置 | Toss Open API 客户端机密。 |
TOSS_ACCOUNT_SEQ | 未设置 | 账户范围工具的可选默认账户序列。 |
ENABLE_TRADING | false | 执行任何实际订单操作的全局门控。 |
ENABLE_ORDER_CREATE | false | 实际创建订单的门控。 |
ENABLE_ORDER_MODIFY | false | 实际修改订单的门控。 |
ENABLE_ORDER_CANCEL | false | 实际取消订单的门控。 |
REQUIRE_CONFIRMATION | true | 执行实际订单操作时需要输入完全一致的确认文本。 |
MAX_ORDER_KRW | 0 | 允许的最大计算韩元订单金额。 |
MAX_ORDER_USD | 0 | 允许的最大计算美元订单金额。 |
ALLOWED_SYMBOLS | 未设置 | 可选的逗号分隔允许列表。 |
BLOCKED_SYMBOLS | 未设置 | 可选的逗号分隔屏蔽列表;始终优先于允许列表。 |
TOSS_REQUEST_TIMEOUT_MS | 15000 | OAuth、只读和订单请求的超时时间。仅在本地调试时设为 0,以禁用超时。 |
实际订单操作的确认文本:
I understand this may place a real Toss Securities order
工具
只读工具:
auth_statusaccountsholdingspricesorderbooktradesprice_limitscandlesstock_infostock_warningsexchange_ratemarket_calendarorders_openorders_closedorder_detailbuying_powersellable_quantitycommissions
工作流工具:
portfolio_snapshot— 读取持仓、KRW/USD 购买力、未结订单、可计算的持仓权重、账户/账户序号状态、警告标志和部分失败信息。持仓权重使用以 KRW 折算且包含现金的分母(持仓 + KRW/USD 现金购买力);当cashStatus为partial时,omittedCashCurrencies会列出未纳入的现金币种。pre_trade_check— 针对候选订单的独立读取/检查层;返回canProceedDryRun、realOrderBlockedByDefault、checks、warnings、blockers、missing、estimate和dataFreshness。order_preview— 创建内存中的预览合约;返回previewId、requestHash、ttlSeconds、expiresAt、准确的confirmationText、预估金额/费用/现金/数量检查、门控状态、风险标志和可计算性说明。它不会调用订单 POST 端点。默认 TTL:90 秒;接受的最大 TTL:300 秒。order_execute— 基于预览快速提交;需要previewId、匹配的requestHash、准确确认文本(I approve this exact Toss order preview)、未过期的预览、环境门控以及可选的委托权限限制。它不会在快速路径中运行pre_trade_check,也不会自动重试订单 POST。order_status_summary— 只读对账摘要,涵盖未结/近期已结订单、状态计数、已成交/部分成交/已取消/已拒绝/与替换相关的状态(如有),以及订单消失或被替换时的注意事项。
交易工具:
order_validate— 仅检查本地门控,绝不会调用 Toss 订单 POST 端点。order_create— 默认为模拟运行;真实执行需要满足所有创建门控。order_modify— 默认为模拟运行;真实执行需要满足所有修改门控。order_cancel— 默认为模拟运行;真实执行需要满足所有取消门控。配置了ALLOWED_SYMBOLS或BLOCKED_SYMBOLS时,真实取消还要求调用方提供request.symbol,以便在 POST 前评估本地标的策略。服务不会在取消前获取订单详情,因为这会增加第二个 API 依赖,而且用户应先使用有效凭证确认官方详情载荷的格式,再依赖它来保障安全。
身份验证状态和账户选择
auth_status 会有意将 OAuth 令牌签发与实际数据 API 连通性区分开来:
configured:必需的凭证环境变量已设置。tokenAvailable:POST /oauth2/token已成功。dataApiReachable:对GET /api/v1/accounts的真实只读数据检查已成功。authenticated:仅当令牌签发和数据端点检查均成功时为true。accountSeqConfigured:设置了TOSS_ACCOUNT_SEQ时为true。accountSeqRequiredForAccountTools:为true;账户范围工具需要按调用提供accountSeq或设置TOSS_ACCOUNT_SEQ。
大多数市场数据工具(如 prices、orderbook、trades 和 stock_info)不需要 accountSeq。账户范围工具(如 holdings、orders_open、orders_closed、order_detail、buying_power、sellable_quantity、commissions 以及真实/模拟订单工具)需要通过工具参数或 TOSS_ACCOUNT_SEQ 提供 accountSeq。
令牌恢复与诊断
令牌恢复仅在 HTTP 401 响应中匹配精确的结构化 code 或 error.code 值(invalid-token、token-revoked)。如果存在,error.code 优先,即使它与预期无关或存在冲突;仅当嵌套的 code 缺失时(例如,error 对象仅包含 message),才使用顶层的 code。消息、任意嵌套字符串以及无关的 401 错误都不会触发令牌签发。GET 请求最多允许一次身份验证重试;如果再次被拒绝,则返回 API 错误。现有的 POST invalid-token 重试行为保持不变,但绝不会重放 POST token-revoked 请求。内部选项 retryInvalidToken: false 会禁用这两种身份验证恢复码,包括已选择退出的订单执行路径。订单结果不明确时仍需进行核对,不会自动重放。
令牌仅保存在内存中,使用 expires_in,并沿用现有的 30 秒过期余量(以及现有的 60 秒最短有效期/3600 秒默认值)。并发冷启动和刷新会在每个客户端实例内共享一次正在进行的令牌签发。缓存代际通过对象标识区分,因此即使提供方返回相同的令牌字符串,较晚发生的拒绝也不会丢弃更新的代际。此机制不会协调不同进程或外部客户端。没有定期签发,也没有刷新令牌授权。
配置了凭据时,auth_status 会添加 tokenLifecycle,其中包含最新一次签发尝试的快照,并不能证明数据 API 已接受令牌。现有状态字段保持不变;使用 dataApiReachable/dataApiCheck 检查数据访问情况,包括令牌被反复拒绝的情况。
reason:cold-cache、expiry-margin、invalid-token或token-revoked。startedAt、completedAt、expiresAt:Unix 纪元毫秒;操作进行中或值不可用时,完成时间/过期时间可以为null。durationMs:签发耗时(毫秒);操作进行中时为null。outcome:pending、succeeded或failed。
诊断信息仅包含这些固定类别和时间值,绝不包含令牌、凭据、标头、提供方响应正文或原始网络消息。签发失败时会返回安全且可执行的配置/网络错误;后续请求可以再次尝试签发。不新增环境变量或必需的工具参数。
更新源代码后,运行 npm run build 并重启 MCP 子进程以加载新构建。部署和在使用环境中进行只读验证是独立的运维步骤;源代码测试无法证明运行时已升级。
端点映射
| 工具 | 方法/路径 | 副作用 |
|---|---|---|
auth_status | POST /oauth2/token;令牌签发成功后调用 GET /api/v1/accounts | 仅检查令牌/数据是否可访问 |
accounts | GET /api/v1/accounts | 只读 |
holdings | GET /api/v1/holdings | 只读 |
prices | GET /api/v1/prices | 只读 |
orderbook | GET /api/v1/orderbook | 只读 |
trades | GET /api/v1/trades | 只读 |
price_limits | GET /api/v1/price-limits | 只读 |
candles | GET /api/v1/candles | 只读 |
stock_info | GET /api/v1/stocks | 只读 |
stock_warnings | GET /api/v1/stocks/{symbol}/warnings | 只读 |
exchange_rate | GET /api/v1/exchange-rate | 只读 |
market_calendar | GET /api/v1/market-calendar/KR 或 GET /api/v1/market-calendar/US | 只读 |
orders_open | GET /api/v1/orders?status=OPEN | 只读 |
orders_closed | GET /api/v1/orders?status=CLOSED | 只读 |
order_detail | GET /api/v1/orders/{orderId} | 只读 |
buying_power | GET /api/v1/buying-power | 只读 |
sellable_quantity | GET /api/v1/sellable-quantity | 只读 |
commissions | GET /api/v1/commissions | 只读 |
portfolio_snapshot | 组合调用 GET /api/v1/holdings、GET /api/v1/buying-power 和 GET /api/v1/orders?status=OPEN | 只读工作流快照 |
pre_trade_check | 组合调用市场日历、警告、价格限制、购买力/可卖数量、佣金和未结订单 | 仅读取/检查;不发送订单 POST |
order_preview | 本地预览契约及读取/检查调用 | 不发送 Toss 订单 POST;仅在内存中存储预览 |
order_execute | 仅在通过预览/确认/哈希/环境门控后调用 POST /api/v1/orders | 最多发送一次订单 POST;不会自动重试订单 POST |
order_status_summary | GET /api/v1/orders?status=OPEN 和 GET /api/v1/orders?status=CLOSED | 只读对账 |
order_validate | 仅进行本地门控评估 | 不发送 Toss 订单 POST |
order_create | POST /api/v1/orders | 仅在通过所有门控后创建真实订单 |
order_modify | POST /api/v1/orders/{orderId}/modify | 仅在通过所有门控后修改真实订单 |
order_cancel | POST /api/v1/orders/{orderId}/cancel | 仅在通过所有门控后取消真实订单 |
v0.2 工作流示例
推荐采用安全优先的流程:
portfolio_snapshot → pre_trade_check → order_preview → user/delegated approval → order_execute → order_status_summary
市场日历检查根据请求市场进行路由:
currency=KRW或六位数的韩国股票代码使用market_calendar(KR)。- 美国股票代码 /
currency=USD使用market_calendar(US)。 - 当
result.today.dayMarket、preMarket、regularMarket和afterMarket全部为null时,根据官方日历的结构检测美国非营业日。 - 当
result.today.integrated为null时,检测韩国非营业日。 - 在这些情况下,
pre_trade_check和order_preview会返回包含market、date和nextBusinessDay的market_closed_non_business_day阻止项;不会在missing中报告market_open_unknown。
portfolio_snapshot 示例:
{
"accountSeq": 1,
"currencies": ["KRW", "USD"],
"limit": 50
}
pre_trade_check 示例。这是一个独立的读取/检查工具,特意不强行放入 order_execute 的热路径中:
{
"accountSeq": 1,
"request": {
"symbol": "005930",
"side": "BUY",
"orderType": "LIMIT",
"quantity": "1",
"price": "70000",
"currency": "KRW"
},
"delegatedAuthority": {
"remainingAmount": 100000,
"expiresAt": "2026-07-05T15:00:00.000Z"
}
}
order_preview 示例。它从不调用 Toss 订单 POST 端点,并会返回 previewId、requestHash、TTL 和准确的确认文本:
{
"accountSeq": 1,
"ttlSeconds": 90,
"request": {
"symbol": "005930",
"side": "BUY",
"orderType": "LIMIT",
"quantity": "1",
"price": "70000",
"currency": "KRW"
}
}
order_execute 示例。从预览响应中复制 previewId、requestHash 和准确的 confirmationText:
{
"previewId": "preview_...",
"requestHash": "<sha256-from-preview>",
"confirmation": "I approve this exact Toss order preview"
}
如果订单 POST 超时或返回含义不明的网络故障,order_execute 会返回 status: "unknown_execution_state",并指示调用方在任何手动重试之前,先通过 order_status_summary/order_detail 对账。服务端不会自动重试订单 POST。
order_status_summary 示例:
{
"accountSeq": 1,
"symbol": "005930",
"limit": 50
}
交易安全示例
试运行验证:
{
"request": {
"symbol": "005930",
"side": "BUY",
"orderType": "LIMIT",
"quantity": "1",
"price": "70000",
"currency": "KRW"
}
}
实际创建需要满足以下所有条件:
ENABLE_TRADING=true
ENABLE_ORDER_CREATE=true
REQUIRE_CONFIRMATION=true
MAX_ORDER_KRW=100000
ALLOWED_SYMBOLS=005930
并且工具调用必须包含:
{
"dryRun": false,
"confirmation": "I understand this may place a real Toss Securities order",
"request": {
"symbol": "005930",
"side": "BUY",
"orderType": "LIMIT",
"quantity": "1",
"price": "70000",
"currency": "KRW"
}
}
官方端点映射
此实现有意保持精简,将工具映射到 Toss 官方 Open API 路径:
- OAuth:
POST /oauth2/token - 市场/账户/订单数据:来自
https://openapi.tossinvest.com/openapi-docs/latest/openapi.json的/api/v1/...路径 - 创建/修改/取消订单:仅使用官方
/api/v1/ordersPOST 路径,并在尝试任何 POST 请求前进行本地防护。
开发
npm install
npm test
npm run lint
npm run audit:prod
所需测试套件使用 Node 内置的测试运行器和模拟的 fetch 调用。它不需要真实的 Toss 凭据,也不会调用实际订单端点。
自选只读集成冒烟测试
在本地配置好自己的 Toss 凭据后,可以运行安全的只读冒烟测试:
TOSS_API_KEY=... TOSS_SECRET_KEY=... npm run smoke:readonly
可选的账户范围检查可以使用 TOSS_ACCOUNT_SEQ,但默认冒烟测试路径只调用不会创建、修改或取消订单的只读工具:auth_status、accounts 和 market_calendar。如果缺少 TOSS_API_KEY 或 TOSS_SECRET_KEY,命令会成功退出并显示 SKIP 消息,且不会发出任何 Toss API 请求。输出会经过与 MCP 服务相同的脱敏辅助函数处理。
超时/重试策略
此服务会对 OAuth、只读调用和订单调用应用可配置的请求超时。GET 请求保留次数有限的瞬时错误重试:HTTP 429 最多重试三次,HTTP 502/503/504 最多重试两次,重试延迟上限为 10 秒。身份验证恢复机制单独限制为一次重试,如上所述。POST 请求不会进行瞬时错误重试,也不会新增 token-revoked 重放;现有的 invalid-token 行为和每次调用的退出选项保持不变。对于结果不明确的订单,未经核对切勿重试。
发布检查清单
发布或创建版本标签前:
- 确认软件包所有权和名称可用性;不要发布未加作用域的
tossinvest-openapi-mcp名称。 - 运行
npm test、npm run lint、npm run audit:prod和npm pack --dry-run。 - 确认试运行生成的压缩包仅包含运行时文件(不带源映射的
dist/JavaScript/声明文件)、scripts/smoke-readonly.mjs、README.md、LICENSE、.env.example和软件包元数据。 - 重新检查文档,确认其中不含密钥、账户号码、本地路径、私有工作流说明,或投资建议/自动化相关声明。
- 仅在维护者明确批准后发布。
发布卫生
.gitignore排除.env、.env.*、日志、覆盖率数据、node_modules和构建输出。.npmignore排除本地环境文件、日志、覆盖率数据、内部交接/QA 说明和本地运行产物。package.json中的files仅发布dist、公开文档、.env.example以及变更日志/安全/许可文件。
免责声明
本软件不构成投资建议,也不实现交易策略、再平衡、优化或自动交易循环。只有在明确启用并使用有效 Toss 凭据时,订单工具才能下达真实金融订单;使用风险由你自行承担。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。