MCP servers exposing the smartoption-ai APIs as tools for AI agents (Claude Desktop / Claude Code / any MCP client). Ships two CLIs: `smartoption-mcp` for customer-side workflows (copy-trading, agent ops, signal history, data center, quant strategy R&D, admin self-deploy platform, cloud-broker onboarding + manual trade) and `smartoption-admin-mcp` for admin back-office (user management, strategy management + review). Bundles the develop-quant-strategy Claude Code skill for one-command install.
Project description
smartoption-mcp
MCP server exposing smartoption-ai customer APIs as tools for AI agents
(Claude Desktop, Claude Code, any MCP client). 56 tools spanning
copy-trading rules, agent ops, broker config, signal history, virtual
ledger, quant strategy products, quant strategy R&D, the data
center (dark-pool / option flow / trader feeds), cloud-broker MCP
onboarding (Tiger / Futu / Moomoo / IB / smartoption_virtual), and
cloud-broker manual trade (list/detail/submit_order/cancel_order/
list_working_orders/list_recent_fills).
Also ships the
develop-quant-strategy Claude Code skill as wheel data — one
command (smartoption-mcp install-skill) drops it into
~/.claude/skills/.
Architecture
Claude / Agent
│ MCP stdio
▼
smartoption-mcp ──HTTP + Bearer JWT──▶ backend /api/customer/*
Thin wrapper: each tool maps to one customer API endpoint, authenticated with a per-user JWT (or long-lived API token) loaded from env at startup.
Install
pip install smartoption-mcp
# or, in an isolated venv:
python3.11 -m venv ~/.smartoption-mcp && ~/.smartoption-mcp/bin/pip install smartoption-mcp
Published on PyPI. Installs
the smartoption-mcp CLI. Upgrade with pip install -U smartoption-mcp.
Local dev from this repo:
cd mcp-server
python3.11 -m venv .venv && source .venv/bin/activate
pip install -e .
Configure auth
Log into portal.smartoption.ai → 个人中心 → "API Token(用于 MCP / 脚本)" → 起个名字 → 复制 token. 1-year expiry, revocable any time from the same page.
Set:
SMARTOPTION_JWT— the token (noBearerprefix)SMARTOPTION_API_BASE—https://api.smartoption.ai
Smoke test:
export SMARTOPTION_API_BASE="https://api.smartoption.ai"
export SMARTOPTION_JWT="eyJ..."
.venv/bin/python -c "from smartoption_mcp.client import SmartoptionClient; \
print(SmartoptionClient().list_agents())"
Register with Claude Code / Claude Desktop
Claude Code — edit ~/.claude.json, add under mcpServers:
{
"mcpServers": {
"smartoption": {
"command": "smartoption-mcp",
"env": {
"SMARTOPTION_API_BASE": "https://api.smartoption.ai",
"SMARTOPTION_JWT": "eyJ..."
}
}
}
}
Restart Claude Code. All 44 smartoption tools should appear.
Claude Desktop — same JSON shape at
~/Library/Application Support/Claude/claude_desktop_config.json.
Restart the app after editing.
Install the develop-quant-strategy Claude Code skill
The wheel ships the develop-quant-strategy skill (SKILL.md + reference
docs + strategy templates) so Claude Code can drive end-to-end quant
strategy development from chat (validate → save draft → backtest →
deploy). Install it with one command:
smartoption-mcp install-skill
# Installed develop-quant-strategy skill:
# target: /Users/<you>/.claude/skills/develop-quant-strategy
# files: 9
# ...
# Restart Claude Code; the skill should appear as /develop-quant-strategy.
Custom target dir (e.g. for Claude Code in a non-standard config):
smartoption-mcp install-skill --target-dir /path/to/my/skills
Or run from inside a Claude conversation via the
install_strategy_dev_skill MCP tool. Either way, restart Claude Code
after install so the new skill is picked up; then trigger it by typing
/develop-quant-strategy. Re-running the install is the upgrade path —
it overwrites the previously installed copy.
Once registered, you can ask things like:
- "查一下最近一周苹果相关的喊单"
- "我现在的虚拟仓有哪些标的?"
- "我的跟单 agent 在线吗?最近一次心跳是什么时候?"
- "今天 agent 跑了几条信号,有没有被跳过的?"
- "帮我写一个 MA crossover 策略,先 validate 一遍"
- "解读一下今天 NVDA 的暗盘大单"
Tools
Copy-trading rules
| Tool | Endpoint | Purpose |
|---|---|---|
list_copy_rules |
GET /copy-rules |
Current copy-trading rules + toggles |
update_copy_rules |
PUT /copy-rules |
Replace full settings; confirmed-gated with structured diff |
Agent provisioning & ops
| Tool | Endpoint | Purpose |
|---|---|---|
ensure_agent |
POST /agents/ensure |
Create / provision the user's agent pod (idempotent; force_redeploy gated) |
get_agent_status |
GET /agents |
Online / heartbeat / broker snapshot summary |
get_agent_logs |
GET /agents/<id>/logs |
Tail recent agent-pod stdout |
restart_agent_client |
POST /agents/<id>/restart-client |
Restart in-pod agent process — gated |
stop_agent |
POST /agents/<id>/stop |
Scale agent deployment to 0 — gated |
Broker configuration
| Tool | Endpoint | Purpose |
|---|---|---|
list_broker_configurations |
GET /broker-configurations |
All saved brokers + active flag (no creds returned) |
get_active_broker |
GET /broker-configurations |
Just the active broker name + display name |
set_active_broker |
PUT /active-broker |
Switch active broker — gated |
test_broker_connection |
POST /broker-configurations/test-{ib,tiger,futu,moomoo} |
Verify creds against broker; does NOT save |
refresh_broker_snapshot |
POST /broker-account-snapshot/refresh |
Ask agent to push fresh broker snapshot |
Signal history & run logs
| Tool | Endpoint | Purpose |
|---|---|---|
query_signal_history |
GET /signal-history |
Search parsed alerts (大单 / 喊单) |
get_signal_detail |
GET /signal-history/<id> |
Full SignalForwardRecord for one signal |
get_signal_chain |
GET /signal-history/<id>/chain-slots |
Paired / chained signal context (ROLL_UP pairs etc.) |
list_run_logs |
GET /copy-run-logs |
Per-signal execution outcomes |
Virtual ledger & followers
| Tool | Endpoint | Purpose |
|---|---|---|
list_virtual_lots |
GET /virtual-ledger |
Open virtual lots + qty_by_key |
list_virtual_followers |
GET /virtual-followers |
User's virtual-follower accounts + equity summary |
Quant strategy products (copy-trade catalog)
| Tool | Endpoint | Purpose |
|---|---|---|
list_quant_strategies |
GET /quant-strategies/list |
Available / subscribed quant strategies |
get_quant_strategy_snapshot |
GET /quant-strategies/<id>/snapshot |
One strategy's positions + canonical valuation |
Quant strategy R&D
| Tool | Endpoint | Purpose |
|---|---|---|
validate_strategy_code |
POST /strategy-ai/strategies/validate |
RestrictedPython compile + protocol check (mirrors deploy gate) |
create_strategy |
POST /strategy-ai/strategies |
New draft + dedicated VirtualAccount |
list_strategies |
GET /strategy-ai/strategies |
User's strategies + per-strategy account summary |
get_strategy |
GET /strategy-ai/strategies/<id> |
One strategy's full doc (draft_code, deployed_code, state) |
save_strategy_draft |
POST /strategy-ai/strategies/<id>/save-draft |
Persist editor source; does NOT disturb running runner |
run_strategy_backtest |
POST /strategy-ai/strategies/<id>/backtest |
Submit backtest (queued, returns run_id) |
get_backtest_run |
GET /strategy-ai/strategies/<id>/backtest-runs/<run_id> |
Summary mode (KPI + equity + capped trades + last 5 days' decisions); mode='full' or decisions_for_day=YYYY-MM-DD for deeper dives |
cancel_backtest_run |
POST /strategy-ai/strategies/<id>/backtest-runs/<run_id>/cancel |
Cooperative cancel |
deploy_strategy |
POST /strategy-ai/strategies/<id>/deploy |
Promote draft → deployed + lift K8s runner pod — gated |
stop_strategy |
POST /strategy-ai/strategies/<id>/stop |
Scale runner to 0 — gated |
Paired with the develop-quant-strategy skill (in .claude/skills/),
this lets Claude take a strategy from "natural-language intent" to
"deployed runner" entirely from chat: validate → create → save_draft →
run_backtest → poll get_backtest_run → deploy (with dry-run + operator
approval) → observe via list_quant_strategies +
get_quant_strategy_snapshot. get_backtest_run defaults to a
summary mode (≤100KB) tuned for LLM context; raw replay payloads can be
multi-MB.
Data Center (暗盘大单 / 期权大单 / 交易员)
| Tool | Endpoint | Purpose |
|---|---|---|
list_data_center_tags |
GET /data-center/overview |
Available tags + counts |
list_data_center_channels |
GET /data-center/overview |
Active channels under one tag |
list_data_center_messages |
GET /data-center/messages |
Paged messages with filters |
get_data_center_message_detail |
GET /data-center/messages/<id> |
One message by id |
interpret_data_center_message |
POST /data-center/messages/<id>/interpret (SSE) |
LLM "解读"; stream collected server-side |
chat_about_data_center_message |
POST /data-center/messages/<id>/chat (SSE) |
Per-message free-form chat |
list_data_center_message_chat_history |
GET /data-center/messages/<id>/chat |
Prior chat turns + quota |
Admin self-deploy platform
Lets admins (super_admin / admin role) push a local Python project as a
persistent K8s Deployment in the isolated admin-deployments namespace.
Paired with the smartoption-deploy Claude Code skill (see
.claude/skills/smartoption-deploy/), the admin can say "deploy this
folder as my-cron" and the skill tars + base64-encodes + calls
deploy_admin_project for them.
| Tool | Endpoint | Purpose |
|---|---|---|
list_admin_deployments |
GET /admin/admin-deployments |
List deployments visible to caller (super_admin sees all) |
deploy_admin_project |
POST /admin/admin-deployments |
Upload tar.gz bundle + apply K8s Deployment + Secret |
get_admin_deployment |
GET /admin/admin-deployments/<name> |
Metadata + live pod-status snapshot |
get_admin_deployment_logs |
GET /admin/admin-deployments/<name>/logs |
Tail bundle-fetch + runner container logs |
restart_admin_deployment |
POST /admin/admin-deployments/<name>/restart |
kubectl rollout restart equivalent — gated |
delete_admin_deployment |
DELETE /admin/admin-deployments/<name> |
Tear down Deployment + Secret — gated |
The pod runs as a zero-permission admin-runner ServiceAccount; no
platform credentials (Mongo / Redis / broker / OpenRouter) are injected.
NetworkPolicy permits egress only.
Local maintenance
| Tool | Purpose |
|---|---|
install_strategy_dev_skill |
Copy bundled develop-quant-strategy skill into ~/.claude/skills/ (or target_dir). No network call. Re-run = overwrite = upgrade. |
Confirmation model
Destructive writes accept a confirmed: bool argument, defaulting to
False (dry-run):
update_copy_rules(new_settings, confirmed=False)→ returns a structured diff (toggle changes + rules added / removed / modified byrule_id). Nothing is written. Show the diff, then re-call withconfirmed=True.ensure_agent(force_redeploy=True, confirmed=False)→ returns a description of the redeploy. Defaultforce_redeploy=Falseis idempotent and skips the gate.set_active_broker,restart_agent_client,stop_agent— same dry-run pattern.deploy_strategy,stop_strategy— same dry-run pattern. Deploy also surfaces the current vs targetruntime_symbolsanddeployment_statefor the operator preview.restart_admin_deployment,delete_admin_deployment— same dry-run pattern. Restart preview includes current bundle_version + status; delete preview warns that the latest bundle in COS will be removed.refresh_broker_snapshot,cancel_backtest_run— no gate (non-destructive / reversible).
The host (Claude Code / Desktop) also shows tool arguments before each
call, so confirmed=True is always visible in the approval UI — the
in-tool flag is belt + suspenders.
Full-doc replacement. update_copy_rules rejects partial settings:
the proposed doc must contain auto_buy_enabled, auto_sell_enabled,
use_all_matched_rules, and rules. Start from list_copy_rules,
mutate locally, pass the full doc back — preserving every rule's
rule_id so the diff stays stable.
SSE tools
interpret_data_center_message and chat_about_data_center_message
hit a backend SSE endpoint but collect the full stream and return one
payload:
{status, content, duration_ms, event_count} # interpret
{status, content, duration_ms, event_count,
remaining_quota} # chat
status ∈ done / cached / error / quota_exceeded. Time inputs
(start_at / end_at) are pass-through ISO 8601 — include timezone
offset (e.g. -04:00 for ET); the server does not normalize "today" /
"now-7d".
Admin MCP server (smartoption-admin-mcp)
A second CLI in the same wheel, smartoption-admin-mcp, exposes 18
admin-only tools for the back-office (user management, AI strategy
management, strategy review). It mounts under a different MCP server
name (smartoption-admin) so Claude Code can hold the customer + admin
surfaces side by side without confusing tool names.
The wire format mirrors the customer side: stdio MCP, ResponseFormatter
envelope unwrapped, confirmed=False dry-run gate on every write.
Configure auth
Log into admin.smartoption.ai →
Operations → "API Token 管理" → 起个名字 → 复制 token. 1-year expiry,
revocable any time from the same page. Backed by AdminApiToken (jti
on the blocklist when revoked); requires the admin / super_admin /
ops_admin role at issue time.
Set:
SMARTOPTION_ADMIN_JWT— the token (noBearerprefix)SMARTOPTION_API_BASE—https://api.smartoption.ai(or staging URL)
Smoke test:
export SMARTOPTION_API_BASE="https://api.smartoption.ai"
export SMARTOPTION_ADMIN_JWT="eyJ..."
.venv/bin/python -c "from smartoption_mcp.admin_client import SmartoptionAdminClient; \
print(SmartoptionAdminClient().list_users(page=1, page_size=3))"
Register with Claude Code / Claude Desktop
Run the customer and admin MCP servers side by side:
{
"mcpServers": {
"smartoption": {
"command": "smartoption-mcp",
"env": {
"SMARTOPTION_API_BASE": "https://api.smartoption.ai",
"SMARTOPTION_JWT": "eyJ..."
}
},
"smartoption-admin": {
"command": "smartoption-admin-mcp",
"env": {
"SMARTOPTION_API_BASE": "https://api.smartoption.ai",
"SMARTOPTION_ADMIN_JWT": "eyJ..."
}
}
}
}
Restart Claude Code. The 18 admin tools should appear under the
smartoption-admin server.
Tools
User management (9) — /api/admin/users
| Tool | Endpoint | Purpose |
|---|---|---|
find_user |
GET /users?search= |
Free-text lookup (email / username / wechat / discord) |
list_users |
GET /users |
Paginated list with search + subscribed_only filters |
get_user_detail |
composite | Bundles user row + Stripe sub + broker configs |
list_user_broker_configurations |
GET /users/<id>/broker-configurations |
Saved brokers (secrets redacted) |
get_user_stripe_charges |
GET /users/<id>/stripe-charges |
Stripe charge history |
create_user |
POST /users |
New user (email + username + password + optional tier dates) — gated |
update_user |
PATCH /users/<id> |
General edit (is_active / roles / email / wechat / discord / …) — gated |
update_user_subscription |
PATCH /users/<id> |
Same endpoint, subscription-only field set + purpose-shaped preview — gated |
reset_user_password |
POST /users/<id>/password |
Force-set password — gated |
Strategy management (5) — /api/admin/strategies
| Tool | Endpoint | Purpose |
|---|---|---|
list_strategies |
GET /strategies |
All Strategy rows + virtual-account snapshot |
get_strategy_detail |
GET /strategies/<id>/detail (+ optional /source-code) |
Deployment state, KV-state, signal/tick log heads, optionally source |
update_strategy_access_policy |
PATCH /strategies/<id>/access-policy |
visibility (PRIVATE/UNLISTED/PUBLIC) + access_policy (allow_all/allow_user_ids/subscription_tier) — gated |
redeploy_strategy |
POST /strategies/<id>/redeploy |
Rebuild runner pod (skips review gate) — gated |
stop_strategy_admin |
POST /strategies/<id>/stop |
Scale runner to 0 — gated (named _admin to disambiguate from the customer-scoped stop_strategy) |
Strategy review (4) — /api/admin/strategy-review
| Tool | Endpoint | Purpose |
|---|---|---|
list_strategy_review_queue |
GET /queue?status= |
Pending / approved / rejected / withdrawn reviews |
get_strategy_review_detail |
GET /<id> |
Full submission + linked strategy + SLA |
approve_strategy_review |
POST /<id>/approve |
Approve + auto-deploy — gated |
reject_strategy_review |
POST /<id>/reject |
Reject with category + text — gated |
Confirmation model (admin)
Every write tool uses the same shape:
- Call with
confirmed=False(the default). Returns a dry-run JSON describing the action, target, and the exact next-call arguments to repeat withconfirmed=True. - Show the preview to the admin operator.
- After approval, call again with the same args +
confirmed=True.
This mirrors the customer MCP gate the team has been using for two
months without misfires (#469 PR 2 deploy_strategy / update_copy_rules
diff). Audit log integration is intentionally deferred to #76 — until
then, the backend's per-route logger.info lines are the only audit
trail, written to the standard backend pod logs.
Roadmap
- Remote MCP server (OAuth 2.1) — deferred until a multi-user use
case justifies the operational cost. Until then, each user runs
smartoption-mcplocally with their own API token. - Audit log integration — once #76 ships an
AdminAuditLogmodel + UI, the admin MCP server will write a row for every tool invocation (success + failure). Spec'd as a deferred follow-up so #644 ships without blocking on #76.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file smartoption_mcp-0.11.0.tar.gz.
File metadata
- Download URL: smartoption_mcp-0.11.0.tar.gz
- Upload date:
- Size: 100.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
de8c49078f7f9e7f0922e3ba1d6ed10bc53efbbb8bf12715c1939b5585e83bed
|
|
| MD5 |
f5b550f04a8d3f811ce2eae41b8c1de5
|
|
| BLAKE2b-256 |
ca17ba30a1d9402a58e40df332645e898d4f91fc06ded1f358d95161801164c1
|
Provenance
The following attestation bundles were made for smartoption_mcp-0.11.0.tar.gz:
Publisher:
publish-mcp.yml on SmartOption/smartoption-ai
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
smartoption_mcp-0.11.0.tar.gz -
Subject digest:
de8c49078f7f9e7f0922e3ba1d6ed10bc53efbbb8bf12715c1939b5585e83bed - Sigstore transparency entry: 1936757577
- Sigstore integration time:
-
Permalink:
SmartOption/smartoption-ai@d4bc1d258d28c9748ca3a75afbfc6f9ffc69d645 -
Branch / Tag:
refs/tags/mcp-v0.11.0 - Owner: https://github.com/SmartOption
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-mcp.yml@d4bc1d258d28c9748ca3a75afbfc6f9ffc69d645 -
Trigger Event:
push
-
Statement type:
File details
Details for the file smartoption_mcp-0.11.0-py3-none-any.whl.
File metadata
- Download URL: smartoption_mcp-0.11.0-py3-none-any.whl
- Upload date:
- Size: 96.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
995ec8ff9423cd58ce2a17d5126a0d54bf80fb63df2d42617f04f6a4824eea4c
|
|
| MD5 |
a18694f3d1783ffb229d2018bb604105
|
|
| BLAKE2b-256 |
0b7f7754d8951bc845545d3c5dec48a1e9ad9b83b41017f401018c8925bbb4b9
|
Provenance
The following attestation bundles were made for smartoption_mcp-0.11.0-py3-none-any.whl:
Publisher:
publish-mcp.yml on SmartOption/smartoption-ai
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
smartoption_mcp-0.11.0-py3-none-any.whl -
Subject digest:
995ec8ff9423cd58ce2a17d5126a0d54bf80fb63df2d42617f04f6a4824eea4c - Sigstore transparency entry: 1936757729
- Sigstore integration time:
-
Permalink:
SmartOption/smartoption-ai@d4bc1d258d28c9748ca3a75afbfc6f9ffc69d645 -
Branch / Tag:
refs/tags/mcp-v0.11.0 - Owner: https://github.com/SmartOption
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-mcp.yml@d4bc1d258d28c9748ca3a75afbfc6f9ffc69d645 -
Trigger Event:
push
-
Statement type: