Metadata-Version: 2.5
Name: usmart-mcp
Version: 1.0.2
Summary: Local MCP server for uSmart SG trading with user-owned credentials and a read-only safety mode
License: Proprietary
License-File: LICENSE
Keywords: mcp,openapi,singapore,trading,usmart
Classifier: Development Status :: 4 - Beta
Classifier: Environment :: Console
Classifier: Intended Audience :: Financial and Insurance Industry
Classifier: License :: Other/Proprietary License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Office/Business :: Financial :: Investment
Requires-Python: >=3.10
Requires-Dist: cryptography>=42
Requires-Dist: mcp<3,>=2.0.0
Provides-Extra: dev
Requires-Dist: pytest-asyncio>=0.24; extra == 'dev'
Requires-Dist: pytest>=8; extra == 'dev'
Description-Content-Type: text/markdown

# usmart-mcp

`usmart-mcp` 是面向 uSmart SG OpenAPI 用户的本地交易 MCP Server。它通过标准 MCP Tools
向 Kiro、Codex、Claude Desktop 等客户端提供订单预检、订单查询、下单和改单能力。

本项目采用本地运行模式：每位用户使用自己的 uSmart 账户、渠道号和签名密钥；凭证仅保存在
用户电脑中，不随 PyPI 包分发，也不通过 MCP 工具参数传递。

> 当前仅支持 SG。服务可连接生产交易账户；启用写工具后可能产生真实资金交易。
> 本工具不提供投资建议，所有委托均由账户所有者负责。

## 主要特性

- 基于官方 MCP Python SDK v2，使用 stdio 传输；
- 自动执行 SG 渠道密码登录，并在进程内短期缓存 Authorization；
- 凭证默认存放于 `~/.usmart`，支持 `USMART_HOME` 覆盖；
- 提供服务端只读模式，写工具在协议层完全不注册；
- 写操作要求显式确认，且绝不自动重试；
- 下单前可查询每手股数、最大可买卖数量和购买力；
- 支持单笔金额、单日金额和单日笔数限额；
- 写操作在本地生成脱敏审计流水；
- 不提供行情服务，也不解析股票名称。

## 使用前提

使用者必须拥有独立的 uSmart SG OpenAPI 权限，并准备：

- uSmart 账户区号、手机号和登录密码；
- 可选的 6 位交易密码；
- 与个人渠道配对的渠道号和签名私钥；
- uSmart 提供的隐私数据加密公钥；
- Python 3.10 或更高版本；
- [uv](https://docs.astral.sh/uv/getting-started/installation/)。

PyPI 包不包含任何账户、Token、渠道号或密钥。

## 快速开始

### 1. 创建本地凭证目录

```text
~/.usmart/                    # macOS/Linux 建议权限 700
├── config.json
├── credentials.json          # 建议权限 600
├── sign_private.pem          # 建议权限 600
├── privacy_public.pem
└── audit/                    # 自动创建
```
macOS/Linux：

```bash
mkdir -p ~/.usmart
chmod 700 ~/.usmart
```

`config.json`：

```json
{
  "region": "SG",
  "baseUrl": "https://open-jy.usmartsg.com",
  "channel": "<个人渠道号，须与签名私钥配对>",
  "lang": "1",
  "deviceType": "1",
  "appType": "12",
  "tokenTtlSeconds": 7200,
  "limits": {
    "enabled": true,
    "maxOrderAmount": { "HKD": 50000, "USD": 10000 },
    "maxDailyAmount": { "HKD": 200000, "USD": 40000 },
    "maxDailyOrderCount": 20,
    "allowUnpricedOrders": false,
    "timeZone": "Asia/Singapore"
  }
}
```

`credentials.json`：

```json
{
  "areaCode": "<区域号，例如新加坡为 65>",
  "phoneNumber": "<手机号>",
  "loginPassword": "<登录密码>",
  "tradePassword": "<可选的 6 位交易密码>"
}
```

将个人渠道签名私钥保存为 `sign_private.pem`，将隐私数据加密公钥保存为
`privacy_public.pem`。请勿把凭证目录放入代码仓库、云同步目录或聊天内容。

```bash
chmod 600 ~/.usmart/credentials.json ~/.usmart/sign_private.pem
```

Windows 用户应使用 `icacls` 限制目录仅当前账户可访问。

### 2. 接入 Kiro（推荐先只读）

在 Kiro 的 `mcp.json` 中加入：

```json
{
  "mcpServers": {
    "usmart": {
      "command": "uvx",
      "args": ["--from", "usmart-mcp==1.0.2", "usmart-mcp"],
      "env": { "USMART_READONLY": "1" },
      "disabled": false,
      "autoApprove": []
    }
  }
}
```

Kiro 用户级配置位于 `~/.kiro/settings/mcp.json`。如文件已有其他 Server，请合并
`usmart` 节点，不要覆盖原文件。首次启动时 `uvx` 会从 PyPI 下载固定版本，之后使用缓存。
### 3. 接入 Codex

```toml
[mcp_servers.usmart]
command = "uvx"
args = ["--from", "usmart-mcp==1.0.2", "usmart-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` 从服务端强制隐藏写工具。

### 4. 验证连接

客户端发现工具后，先调用：

```text
check_trade_credentials
```

该工具只检查本地文件并返回脱敏状态，不会登录、下单或返回密码、密钥和 Token。
随后可调用 `list_today_orders` 验证登录和只读查询链路。

## 工具列表

| 工具 | 说明 | 风险类型 |
|---|---|---|
| `check_trade_credentials` | 检查本地凭证和权限，输出脱敏 | 本地只读 |
| `clear_trade_session` | 清除进程内 Authorization 缓存 | 安全操作 |
| `preview_order` | 查询每手股数、可买卖量和购买力 | 上游只读 |
| `list_today_orders` | 查询今日订单 | 上游只读 |
| `list_all_orders` | 查询历史订单 | 上游只读 |
| `get_order_detail` | 查询订单明细 | 上游只读 |
| `place_order` | 提交真实委托 | 写操作 |
| `modify_order` | 改单或撤单 | 写操作 |

## 只读模式

设置以下环境变量后，`place_order` 和 `modify_order` 不会注册，在 MCP 协议层不存在：

```bash
USMART_READONLY=1
```

支持的开启值为 `1`、`true`、`yes`、`on`（不区分大小写）。建议所有新用户先以只读模式
完成凭证检查、订单查询和预检，再根据自身风控要求决定是否启用写工具。

不要把任何交易工具加入 `autoApprove`。

## 写操作安全机制

启用写工具并不代表可以跳过人工核对。每次下单、改单或撤单都应确认：

- 市场、股票代码和股票名称；
- 买卖方向、数量、价格和委托类型；
- 每手股数与最大可买卖数量；
- 预估金额和适用的交易限额。
服务端还会执行以下保护：

- 写操作必须显式传入 `confirmed=true`；
- 写操作出现超时或授权失效时不自动重试；
- 下单前校验整手数量（预检可用时）；
- 超过本地配置限额时在联网前拒绝；
- 写操作写入 `~/.usmart/audit/`；
- “上游已受理”不等于“订单已成交”，必须通过订单查询核验。

## 凭证与隐私

- 登录密码、交易密码和签名私钥只从本地凭证目录读取；
- MCP 工具不接受账号、密码、私钥或 Token 参数；
- Authorization 只缓存在当前进程内存，进程退出后失效；
- 日志和工具结果不回显敏感凭证；
- macOS/Linux 会检查敏感文件的 POSIX 权限；
- Windows 无法执行同等 POSIX 校验，用户必须自行配置 ACL；
- 本项目不提供远程 HTTP 服务，请勿通过公网隧道暴露本地进程。

## 协议说明

当前实现面向 uSmart SG OpenAPI：

- 登录使用渠道密码登录；
- `X-Type=12`，`X-Dt=1`；
- 请求签名为 MD5withRSA + 标准 Base64；
- 隐私字段使用 RSA PKCS#1 v1.5 + URL-safe Base64；
- 渠道号必须与签名私钥配对；
- 渠道模式不发送 `Client-Id`；
- 登录请求不携带 Authorization。

这些默认值已通过 SG 生产环境的登录、订单查询和交易预检验证。HK 目前不受支持。

## 常见问题

### 客户端找不到工具

确认 `uvx` 已安装且客户端能够执行。固定版本可避免升级后行为发生未预期变化：

```bash
uvx --from "usmart-mcp==1.0.2" usmart-mcp
```

该命令会保持运行并等待 MCP stdio 消息，属于正常行为，应由 MCP 客户端启动。

### 凭证检查失败

先检查 `USMART_HOME` 指向的目录、四个必需文件和权限。不要把真实凭证粘贴到聊天中。
渠道签名失败时，优先确认渠道号与签名私钥是否属于同一申请。

### 只需要查询，不需要交易

始终设置 `USMART_READONLY=1`。此时写工具不会出现在客户端工具列表中。

## 开发与验证

```bash
uv sync --extra dev
uv run pytest tests -q
uv build
uv run python scripts/check_artifact.py dist
```

测试使用临时凭证和本地 Mock，不访问真实 uSmart 服务。构建产物扫描会拒绝凭证文件和私钥。

## 支持范围

- Python：3.10–3.13；
- 平台：macOS、Linux、Windows；
- 区域：SG；
- 传输：stdio；
- 分发：PyPI。

## 许可证与免责声明

本项目采用专有软件许可，详见 `LICENSE`。本工具不构成投资建议，不保证委托成交或收益。
AI 可能误解用户意图，使用者必须独立核对每项交易参数，并对账户及交易结果承担责任。
