usmartsg-mcp
面向 uSmart SG OpenAPI 用户的本地交易 MCP Server。它通过标准 MCP Tools 向 Kiro、Codex、Claude Desktop、Cursor 等客户端提供订单预检、订单查询、下单和 改单能力。
本项目在本地以 stdio 运行:每位用户使用自己的 uSmart 账户和授权,凭证只保存在本机, 不随 PyPI 包分发,也不通过 MCP 工具参数传递。
当前仅支持 SG。服务可连接生产交易账户;启用写工具后可能产生真实资金交易。 本工具不提供投资建议,所有委托均由账户所有者负责。
主要特性
- 基于官方 MCP Python SDK,默认使用 stdio 传输;
- 使用 OAuth2 授权码 + PKCE:在浏览器用 uSmart 账户授权,令牌自动续期,无需自行申请 App ID 或密钥;
- 首次运行自动生成 OAuth2 配置,装完即可授权,无需手写 JSON;
- 凭证默认存放在
~/.usmart,支持USMART_HOME覆盖; - 服务端只读模式:写工具在 MCP 协议层完全不注册;
- 写操作必须显式确认,且绝不自动重试;
- 下单前可查询每手股数、最大可买卖数量和购买力;
- 写操作在本地生成脱敏审计流水;
- 查询类工具返回结构化结果,失败统一为错误信封;
- 不提供行情服务,也不解析股票名称。
环境要求
- Python 3.10 或更高版本;
- uv;
- 独立的 uSmart SG OpenAPI 权限:使用 uSmart 账户在浏览器完成 OAuth2 授权即可,无需自行申请 App ID 或密钥。
PyPI 包不包含任何账户、Token 或密钥。
安装
推荐用 uvx 固定版本运行:
uvx --from "usmartsg-mcp==1.0.0" usmartsg-mcp
也可以先安装再运行:
pip install "usmartsg-mcp==1.0.0"
usmartsg-mcp
从源码安装:克隆本仓库后执行
cd usmartsg-mcp
uv sync --extra dev
uv run usmartsg-mcp
该命令会保持运行并等待 MCP stdio 消息,属于正常行为,应由 MCP 客户端启动。
快速开始
1. 首次运行自动生成配置
不需要手工创建配置文件:首次启动时,如果 ~/.usmart/config.json 不存在,服务会按内置
默认值自动生成一份;随后调用 oauth_login 在浏览器完成授权即可使用。
| 配置项 | 生产(默认) | UAT(USMART_ENV=uat) |
|---|---|---|
baseUrl |
https://open2-jy.usmartsg.com |
https://open2-jy-uat.usmartsg.com |
auth.oauth.baseUrl |
https://jy.usmartsg.com |
https://jy-uat.usmartsg.com |
auth.oauth.clientId |
ai-agent |
agent-uat |
auth.oauth.redirectUri |
http://localhost:5100/callback |
同左 |
auth.oauth.scopes |
order:all |
同左 |
生成后的目录:
~/.usmart/ # macOS/Linux 建议权限 700
├── config.json # 自动生成:固定 OAuth2 配置,可按需修改
├── oauth_session.json # OAuth 授权成功后自动生成(600)
├── credentials.json # 可选:账户开启交易密码校验时创建,只写 tradePassword
└── audit/ # 自动创建,写操作审计流水
- 在客户端
env中加入"USMART_ENV": "uat"即可切换 UAT; - 仅本地单用户(stdio)形态会自动生成配置;远程部署 / 目录版必须显式提供
config.json; - OAuth 授权在浏览器完成,本机只保存授权会话,不保存账号密码;
若账户开启交易密码校验且需要下单,可在
~/.usmart/credentials.json写入{"tradePassword": "<6 位数字>"}; - 删除
~/.usmart/oauth_session.json相当于本地登出,下次调用会重新要求授权; - 需要自定义时直接编辑
~/.usmart/config.json(OAuth2 参数见下方示例)。
OAuth2 模式的 config.json(默认已自动生成,通常无需改动;如需自定义可参考):
{
"region": "SG",
"baseUrl": "https://open2-jy.usmartsg.com",
"auth": {
"mode": "oauth2",
"oauth": {
"baseUrl": "https://jy.usmartsg.com",
"clientId": "ai-agent",
"redirectUri": "http://localhost:5100/callback",
"scopes": ["order:all"]
}
},
"lang": "1",
"deviceType": "1",
"appType": "12"
}
redirectUri必须与开放平台登记值逐字符一致(含端口),默认固定为http://localhost:5100/callback;请使用localhost,127.0.0.1形式会被 uSmart 网关拒绝;configs/prod.local.config.json是同一份默认值的参考副本,可复制为~/.usmart/config.json;- 切换到 UAT 设置
USMART_ENV=uat即可,无需手改地址。
可选的 credentials.json(只在账户开启交易密码校验且需要下单时创建):
{
"tradePassword": "<可选的 6 位交易密码>"
}
chmod 600 ~/.usmart/credentials.json
凭证目录本身建议 chmod 700 ~/.usmart。Windows 用户应使用 icacls 限制目录仅当前账户
可访问。请勿把凭证目录放入代码仓库、云同步目录或聊天内容。
2. 接入客户端
Kiro(~/.kiro/settings/mcp.json,已有其他 Server 时合并 usmart 节点):
{
"mcpServers": {
"usmart": {
"command": "uvx",
"args": ["--from", "usmartsg-mcp==1.0.0", "usmartsg-mcp"],
"env": { "USMART_READONLY": "1" },
"disabled": false,
"autoApprove": []
}
}
}
Claude Desktop(claude_desktop_config.json):
{
"mcpServers": {
"usmart": {
"command": "uvx",
"args": ["--from", "usmartsg-mcp==1.0.0", "usmartsg-mcp"],
"env": { "USMART_READONLY": "1" }
}
}
}
Codex(~/.codex/config.toml):
[mcp_servers.usmart]
command = "uvx"
args = ["--from", "usmartsg-mcp==1.0.0", "usmartsg-mcp"]
enabled = true
startup_timeout_sec = 60
enabled_tools = [
"check_trade_credentials",
"preview_order",
"list_today_orders",
"list_all_orders",
"get_order_detail",
]
建议所有客户端先以 USMART_READONLY=1 接入,确认查询链路正常后再按需启用写工具。
不要把交易工具加入 autoApprove。如需 UAT 环境,在客户端 env 里追加 "USMART_ENV": "uat"。
3. 验证连接
客户端发现工具后,先调用:
check_trade_credentials
该工具只检查本地文件并返回脱敏状态,不会发起授权、下单,也不会返回密码、密钥和 Token。
如显示「未授权」,依次调用 oauth_login(浏览器完成授权)和 oauth_login_status;
随后可调用 list_today_orders 验证只读查询链路。
远端部署
本包默认以本地 stdio 单用户方式运行,无需额外配置文件;如需自定义,见
configs/README.md。
工具列表
| 工具 | 说明 | 风险类型 |
|---|---|---|
check_trade_credentials |
检查本地凭证与授权状态,输出脱敏 | 本地只读 |
oauth_login |
发起 OAuth2 授权,返回授权链接 | 安全操作 |
oauth_login_status |
等待/查询授权结果并兑换令牌 | 安全操作 |
oauth_logout |
删除本地 OAuth 会话 | 安全操作 |
clear_trade_session |
清除进程内 Authorization 缓存 | 安全操作 |
preview_order |
查询每手股数、可买卖量和购买力 | 远程只读 |
list_today_orders |
查询今日订单 | 远程只读 |
list_all_orders |
查询历史订单 | 远程只读 |
get_order_detail |
查询订单明细 | 远程只读 |
place_order |
提交真实委托 | 写操作 |
modify_order |
改单或撤单 | 写操作 |
工具返回值
查询与预检工具返回结构化结果;数量、价格、金额均为十进制字符串,时间为 RFC 3339
(+08:00)。
订单(list_today_orders / list_all_orders 的 orders,以及 get_order_detail 的 order):
| 字段 | 说明 |
|---|---|
order_id |
订单号,即 get_order_detail 的 entrust_id |
serial_no |
流水号,与 order_id 是不同的编号;上游未返回时为 null |
market、symbol、symbol_name |
市场枚举、交易代码、标的名称 |
side、order_type、status |
买卖方向、委托类型、订单状态枚举 |
quantity、filled_quantity |
委托数量、已成交数量 |
price |
当前委托价格;改过价的订单返回改单后的价格 |
filled_average_price |
成交均价 |
filled_amount |
成交金额(币种见 currency);仅订单明细可能有值,订单列表恒为 null |
currency、order_session、created_at |
币种、交易时段、创建时间 |
分页字段:orders、page(从 1 开始)、page_size、total、has_more。
preview_order 返回:
| 字段 | 说明 |
|---|---|
lot_size |
每手股数 |
max_buy_quantity_with_margin |
最大可买数量,含融资额度;不传 entrust_price 时为 null |
max_buy_quantity_cash_whole_lots |
仅用现金、按整手取整的最大可买数量;不传 entrust_price 时为 null |
max_sell_quantity、max_sell_whole_shares |
最大可卖数量 |
cash_purchasing_power、cash_currency |
现金购买力及币种;cash_currency 只在港股(HKD)和美股(USD)返回 |
quantity_check |
传入 entrust_amount 时返回,只校验整手,不校验资金是否足够 |
失败时返回 isError=true,文本内容是「SDK 固定前缀 + 紧凑 JSON」,例如:
Error executing tool <tool_name>: {"error":{"code":"AUTH_EXPIRED","message":"uSmart 授权已失效。","recoverable":"reauth","hint":"重新完成 uSmart 授权后重试。"}}
code 取值包括 AUTH_REQUIRED、AUTH_EXPIRED、PERMISSION_DENIED、
INVALID_ARGUMENT、INVALID_QUANTITY、CONFIRMATION_REQUIRED、RATE_LIMITED、
UPSTREAM_UNAVAILABLE、UPSTREAM_REJECTED、ORDER_OUTCOME_UNKNOWN、INTERNAL_ERROR;
recoverable 说明是否可以重试或需要重新授权。
只读模式
设置以下环境变量后,place_order 和 modify_order 不会注册,在 MCP 协议层不存在:
USMART_READONLY=1
支持的开启值为 1、true、yes、on(不区分大小写)。
写操作安全机制
每次下单、改单或撤单都应确认市场、股票代码、买卖方向、数量、价格和委托类型。 服务端还会执行以下保护:
- 写操作必须显式传入
confirmed=true; - 写操作出现超时或授权失效时不自动重试;
- 下单前校验整手数量(预检可用时);
- 写操作写入
~/.usmart/audit/; - 「已受理」不等于「已成交」(
accepted=true仅表示受理),必须通过订单查询核验。
本服务不做本地金额或笔数限额,因此金额较大或频繁下单时,请务必向用户复述完整订单摘要并 等待明确确认。
凭证与隐私
- 交易密码只从本地凭证文件读取,不进入 MCP 工具参数;
- refresh_token 保存在
~/.usmart/oauth_session.json(600),access_token 只驻留内存; - MCP 工具不接受账号、密码、私钥、授权码或 Token 参数;
- 日志和工具结果不回显敏感凭证;
- macOS/Linux 会检查敏感文件的 POSIX 权限;Windows 无法执行同等校验,需自行配置 ACL;
- 请勿通过公网隧道暴露本地进程,也不要把凭证粘贴到聊天内容中。
常见问题
客户端找不到工具
确认 uvx 已安装且客户端能够执行:
uvx --from "usmartsg-mcp==1.0.0" usmartsg-mcp
该命令会保持运行并等待 MCP stdio 消息,属于正常行为。
OAuth 授权后仍提示未授权
确认 auth.oauth.redirectUri 与开放平台登记值完全一致(含端口、路径和大小写),且
oauth_login_status 返回「授权成功」。删除 ~/.usmart/oauth_session.json 相当于本地登出。
回调端口被占用
oauth_login 会监听 redirectUri 里的端口(默认 5100)。端口被占用时换一个端口,
并先在开放平台登记新的回调地址;不要使用非回环地址。
凭证检查失败
检查 USMART_HOME 指向的目录、config.json 是否存在且可读,以及文件权限是否符合要求。
OAuth 授权失败时优先核对 auth.oauth.clientId 和 auth.oauth.redirectUri 是否与开放平台
登记值一致。不要把真实凭证粘贴到聊天中。
只需要查询,不需要交易
始终设置 USMART_READONLY=1,此时写工具不会出现在客户端工具列表中。
开发与测试
uv sync --extra dev
uv run pytest tests -q
uv run ruff check src tests
uv build
uv run python scripts/check_artifact.py dist
测试使用临时凭证和本地 Mock,不访问真实 uSmart 服务;构建产物扫描会拒绝凭证文件和密钥材料。
许可证与免责声明
本项目采用 Apache License 2.0 发布, 许可全文见 LICENSE。
本工具不构成投资建议,不保证委托成交或收益。AI 可能误解用户意图,使用者必须独立核对 每项交易参数,并对账户及交易结果承担责任。
Metadata
Release files for usmartsg-mcp 1.0.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| usmartsg_mcp-1.0.0.tar.gz | 207.7 kB | Without provenance | Details for usmartsg_mcp-1.0.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| usmartsg_mcp-1.0.0-py3-none-any.whl | Python 3 | none | any | Details for usmartsg_mcp-1.0.0-py3-none-any.whl |
Total release size: 305.9 kB
Release files / usmartsg_mcp-1.0.0.tar.gz
| Download URL | usmartsg_mcp-1.0.0.tar.gz |
|---|---|
| Size | 207.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
34f869587dbec09bba62a6652d688110bb01cbc84009d0ff608cff8998461c7a
|
|
BLAKE2b-256 checksum How to use checksums |
98cad7e11ef11cf24fd602143f342b6f43720637bcdcd7949af419b90ffa2f50
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.11.13 {"installer":{"name":"uv","version":"0.11.13","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Release files / usmartsg_mcp-1.0.0-py3-none-any.whl
| Download URL | usmartsg_mcp-1.0.0-py3-none-any.whl |
|---|---|
| Size | 98.2 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
1d20c7a7b4b964c1142467937a43bc99c7fb6e657daf6c8e8440ea29c5538ad0
|
|
BLAKE2b-256 checksum How to use checksums |
0b74bdb4bfcf17887f10bfd5024a8394b5372f0c352da3146fd9f0e651a75387
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.11.13 {"installer":{"name":"uv","version":"0.11.13","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Security for usmartsg-mcp 1.0.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.