weex-mcp
Enables interaction with WEEX exchange for market data, account details, and controlled trade execution through Model Context Protocol tools. Supports local stdio integration and a standalone HTTP service.
README
WEEX MCP
<!-- mcp-name: io.github.enzo108216/weex-mcp -->
WEEX MCP is a Python 3.11+ implementation of Model Context Protocol (MCP) tools for WEEX market data, account information, and controlled trade execution. The package supports both local integration and a standalone HTTP service while maintaining the same tool definitions and request contracts.
The core package has no mandatory runtime dependencies. Optional dependencies are provided for the standalone ASGI server and development verification.
Contents
- Capabilities
- Installation
- Runtime modes
- Client configuration
- Protocol compatibility
- Tool catalog
- Credential handling
- Trade authorization model
- Project layout
- Development and verification
- Troubleshooting
- Known issues
- Operational boundary
Capabilities
- 47 typed tools covering public Market data, read-only Account data, and guarded Trade operations (11 Market, 10 Account, and 26 Trade tools).
- Local stdio transport for MCP client integration.
- Embeddable service and ASGI application factories for host applications.
- Standalone Streamable HTTP deployment through Uvicorn.
- Strict JSON Schema validation for tool arguments. Output schemas are published and checked for schema validity, with representative response conformance tests.
- Request-scoped credential handling without credential persistence.
- Stateless, signed preview IDs for two-phase trade execution.
- Redacted audit metadata for authenticated account and trade operations.
Trade operations are disabled by default and must be enabled explicitly. The
service does not persist API credentials, approval state, idempotency results,
or user sessions.
When Trade is disabled, its 26 tools are omitted from tools/list; direct
calls still fail closed with module_disabled. Explicit enablement exposes the
full 47-tool catalog.
Installation
Install the published core package:
python -m pip install weex-mcp
Install the standalone server dependencies:
python -m pip install 'weex-mcp[server]'
Source checkout and editable development installation are covered in Development and verification.
Runtime modes
Local stdio transport
Start the newline-delimited JSON-RPC stdio server:
weex-mcp stdio
An MCP client can register weex-mcp as the command and stdio as its
argument. Protocol responses are written to standard output; diagnostics are
written to standard error.
Embedded service
Applications can use the transport-independent service directly:
from weex_mcp.service import build_default_service
service = build_default_service(trade_enabled=False)
Applications with an ASGI host can construct the HTTP application separately:
from weex_mcp.asgi_app import build_asgi_app
from weex_mcp.service import build_default_service
service = build_default_service(trade_enabled=False)
app = build_asgi_app(service=service)
Explicit Settings should be supplied when multiple application instances
must share protocol, authentication, or approval-token configuration.
Standalone HTTP service
Cloud mode requires an approval-token signing secret and a service bearer
token before the listening socket is opened. The process binds to
127.0.0.1 by default:
export WEEX_APPROVAL_TOKEN_SECRET='replace-with-at-least-32-random-bytes'
export WEEX_SERVICE_AUTH_TOKEN='replace-with-at-least-32-random-ascii-characters'
export WEEX_TRADE_ENABLED='false'
weex-mcp serve --port 8080 --workers 1
Use --host 0.0.0.0 or set WEEX_MCP_BIND_HOST only when the process must
accept connections through external interfaces. An explicit --host takes
precedence over the environment value.
GET /healthz provides liveness status. GET /readyz provides readiness
status. Complete configuration, container, scaling, rotation, and rollback
requirements are documented in
DEPLOYMENT.md.
One-command Docker startup
With Docker Engine and Compose v2 installed, run:
./scripts/docker-start.sh
On first run the script creates a private .env with two random service
secrets, keeps Trade disabled, builds the image, starts the container in the
background, and waits for /readyz. It never overwrites an existing .env
and never generates or stores a WEEX user API credential. The default endpoint
is http://127.0.0.1:8080/mcp; the generated service bearer token is in the
local .env file. Docker also writes redacted account/trade audit events to
logs/weex_mcp_audit.log on the host by mapping the container path configured
by WEEX_AUDIT_LOG_FILE (/var/log/weex-mcp/weex_mcp_audit.log by default).
The startup script creates ./logs and records the current host UID/GID in
.env so the non-root container process can append to the mounted audit file.
Stop it with:
docker compose down
To use a different host/container port, export WEEX_MCP_HOST_PORT and
WEEX_MCP_PORT before the first run, or edit the generated .env. The default
host binding is loopback (WEEX_MCP_BIND_HOST=127.0.0.1). To publish on all
host interfaces, set the bind host on the first run:
WEEX_MCP_BIND_HOST=0.0.0.0 ./scripts/docker-start.sh
To expose only one host interface, use that interface's IP instead:
WEEX_MCP_BIND_HOST=192.168.1.20 ./scripts/docker-start.sh
The first-run value is saved in the generated .env. Because the script never
overwrites an existing .env, edit WEEX_MCP_BIND_HOST there for later runs,
or export a value to override Compose interpolation for a single run.
0.0.0.0 publishes on every IPv4 interface; it is a bind address, not a URL
that remote clients should use. Clients connect to a reachable DNS name or
host IP and must still send the service Bearer token. Before exposing the
service beyond localhost, provide TLS, firewall or network policy, request-body
log suppression, monitoring, and appropriate gateway traffic controls.
For manual Compose operation, copy .env.example to .env and run
docker compose up -d --build --wait after filling both required service
secret values; the example intentionally leaves them empty so unchanged
placeholder credentials cannot start the service.
WEEX_SPOT_BASE_URL and WEEX_FUTURES_BASE_URL select approved deployment
upstreams for local, staging, or production use. They must be HTTPS origins
without credentials, paths, query strings, or fragments and are never accepted
inside a tool request. Public Market GET transport timeouts use bounded retry;
Account, Trade, HTTP/business, and response-validation failures do not.
Client configuration
Install the package in an environment visible to the client before using the stdio examples. Keep WEEX account credentials out of client configuration; Account and Trade tools receive them in the individual tool call only.
Codex
Register the local stdio server in Codex configuration:
[mcp_servers.weex]
command = "weex-mcp"
args = ["stdio"]
Restart or reload the MCP client after changing its configuration. The server negotiates the Codex-compatible legacy protocol over stdio.
Claude Code
Add the same stdio command to the project or user MCP configuration:
{
"mcpServers": {
"weex": {
"command": "weex-mcp",
"args": ["stdio"]
}
}
}
Claude Code negotiates its supported legacy protocol during initialize.
HTTP MCP clients
For Docker or cloud deployments, configure a Streamable HTTP connection with:
URL: http://127.0.0.1:8080/mcp
Authorization: Bearer <service-auth-token>
Client-specific HTTP configuration formats vary. The service bearer token protects the MCP endpoint; it is separate from the request-scoped WEEX credential used by Account and Trade tools. Production URLs must use HTTPS.
Protocol compatibility
The stdio transport supports the current protocol plus legacy initialize
compatibility. HTTP supports the current stateless POST contract and legacy
POST initialize compatibility; it does not implement the session-oriented
GET behavior of older Streamable HTTP revisions.
| Protocol version | Compatibility mode | Negotiation |
|---|---|---|
2025-06-18 |
Codex-compatible legacy initialize | stdio and HTTP POST initialize |
2025-11-25 |
Claude Code-compatible legacy initialize | stdio and HTTP POST initialize |
2026-07-28 |
Current project contract | protocol header (HTTP) and request metadata |
Legacy responses use the response shape associated with the negotiated
protocol. The 2026-07-28 contract validates request metadata, result type,
cache scope, and TTL metadata. HTTP additionally validates
MCP-Protocol-Version, Mcp-Method, and method-specific Mcp-Name headers.
HTTP protocol selection is evaluated for each request and is not stored as
user session state. server/discover belongs to the current contract and
therefore advertises 2026-07-28; the two older versions are compatibility
modes reached through initialize, not additional current discovery targets.
Tool catalog
| Module | Tools | Access model |
|---|---|---|
| Market (11) | market_get_symbol_price, market_get_depth, market_get_klines, market_get_exchange_info, market_get_ticker_24h, market_get_book_ticker, market_get_recent_trades, market_get_funding_rate, market_get_open_interest, market_get_advanced_klines, market_get_catalog |
Public market data |
| Account (10) | account_get_balance, account_get_positions, account_get_orders, account_get_trades, account_get_bills, account_get_config, account_get_commission_rate, account_get_symbol_config, account_get_conditional_orders, account_get_transfer_records |
Request-scoped USER_DATA credential |
| Trade (26) | Existing order/cancel/leverage/margin-mode pairs plus batch_order, batch_cancel, cancel_scope, conditional_order, conditional_cancel, tp_sl, close_positions, position_margin, and auto_append_margin preview/confirm pairs |
Explicit enablement and two-phase confirmation |
Every tool publishes an input schema, output schema, client-facing title, module metadata, and MCP risk annotations. Invalid arguments are rejected before an adapter operation is executed.
Credential handling
Account and trade requests may provide a complete WEEX credential in the tool arguments:
credential = {
"type": "plaintext",
"api_key": "...",
"api_secret": "...",
"api_passphrase": "...",
}
Plaintext credentials are resolved in memory for the current request only. Credential values are excluded from responses and audit records. Credentials must not be placed in URLs or query parameters. HTTP deployments must use TLS and must disable request-body capture in proxies, application monitoring, tracing, and error-reporting systems.
When WEEX_AUDIT_LOG_FILE is set, the default service appends local audit
records as JSON Lines. Each line is one redacted account or trade tool event
with fields such as tool name, module, success status, request identity, and
credential fingerprint; raw API keys, secrets, passphrases, and credential refs
are not written. The Docker Compose configuration sets this variable to
/var/log/weex-mcp/weex_mcp_audit.log and mounts it to
logs/weex_mcp_audit.log on the host. Without WEEX_AUDIT_LOG_FILE, audit
events are emitted through the weex_mcp.audit Python logger instead of being
written by the MCP to a file.
The credential_ref and encrypted_envelope forms remain extension points
for hosts that provide a compatible secret resolver. Tenant, user, and session
headers are optional; absent values resolve to an anonymous internal context.
Trade authorization model
Trade operations use a stateless preview-and-confirm sequence:
- A preview request validates required fields, market rules, and action-specific
parameters without private network access. It then authenticates the
request-scoped key through a signed, read-only WEEX request and requires
canTrade=true. Spot usesGET /api/v3/account; futures live and demo useGET /capi/v3/account/accountConfig. - The response returns a short-lived, HMAC-signed
preview_id, an execution summary, and risk information. - A confirmation request resubmits the complete action parameters, the same
request-scoped credential, the preview ID, and explicit confirmation. During
client migration, confirm tools also accept the deprecated
approval_tokenalias whenpreview_idis not present. - The service first validates the token signature and expiry, then resolves
the credential again, repeats all pre-execution validation (including the
read-only
canTradeprobe), compares the token binding, and only then invokes the write adapter.
The optional credential.permissions request field can only narrow a call; it
does not prove what WEEX granted to the API key. A failed authentication,
canTrade=false, or malformed permission response never produces a preview
ID. Preview itself sends no private write request.
Explicit confirmation uses the language-independent object
{"accepted": true}. Confirmation is still bound to the signed preview and
does not replace the requirement to display the preview to the user.
Preview IDs can be replayed until expiry. Order operations therefore
require a stable client_order_id for exchange-side correlation and recovery.
The package does not claim exactly-once execution semantics.
MCP tool arguments use stable snake_case names for callers, while the REST
adapters translate them to WEEX's official request fields before signing. For
example, client_order_id maps to newClientOrderId, position_side maps to
positionSide, client_algo_id maps to clientAlgoId, and
trigger_price_type maps to triggerPriceType. Safety fields such as
scope, acknowledge_all_symbols, acknowledge_all_positions, and
acknowledge_full_position are MCP-only guard fields; they are never forwarded
to WEEX.
Project layout
src/weex_mcp/ Core service, transports, adapters, schemas, and tools
tests/ Unit, protocol, package, and runtime contract tests
scripts/ Docker startup and explicitly authorized smoke helpers
Dockerfile Non-root production image definition
compose.yaml Local/development one-command HTTP deployment
DEPLOYMENT.md Configuration, scaling, security, and rollback contract
KNOWN_ISSUES.md Confirmed external defects and their retest boundaries
The installable package contains runtime code only. Deployment and known-issue documents remain repository documentation and are not imported by the service.
Development and verification
Create a Python 3.11+ environment and install all development and server dependencies:
python -m pip install -e '.[dev,server]'
The repository defines the following local checks:
PYTHONDONTWRITEBYTECODE=1 PYTHONPATH=src python3 -m unittest discover -s tests
PYTHONDONTWRITEBYTECODE=1 PYTHONPATH=src python3 -m compileall -q src tests scripts
python -m build --sdist --wheel
twine check dist/*
check-wheel-contents dist/*.whl
ruff check src tests scripts
mypy src/weex_mcp
PYTHONPATH=src python3 -m weex_mcp --smoke
PYTHONPATH=src python3 -m weex_mcp serve --help
Unit tests use injected transports and adapters. Network-dependent demo smoke execution requires explicit authorization and is not part of the default test suite.
Generated build/, dist/, *.egg-info/, virtual environments, .env, and
local logs are ignored. Do not commit real service secrets or WEEX credentials.
Troubleshooting
module_disabled: Trade is off by default. Enable it only in an explicitly approved environment, then restart the service.weex-mcp serveexits with code 2: check the required cloud service secrets, numeric settings, allowed origins, and HTTPS upstream origins.- HTTP
/mcpreturns 401: supply the configured service bearer token. This is not a WEEX API key. - A modern HTTP request reports
header_mismatch: send the negotiatedMCP-Protocol-Versionand required modern request metadata, or perform a supported legacyinitializefirst. - A preview ID becomes invalid after restart or rotation: local instances without an explicit approval secret generate a per-process secret; cloud replicas must share one configured secret. Rotation invalidates old tokens.
- A Trade result is unknown after a timeout: do not blindly retry. Reconcile by
the stable
client_order_idthrough a read-only query before any new write. - Container readiness fails: run
docker compose config, inspect/readyz, and confirm that the container and published port settings match.
Known issues
Confirmed external platform defects and their safe retest conditions are tracked in KNOWN_ISSUES.md. These records do not constitute authorization to submit new trade requests.
Operational boundary
The package provides MCP protocol handling, strict configuration validation, request-scoped credential resolution, WEEX REST adapters, health endpoints, and a container entry point. External infrastructure remains responsible for TLS termination, secret distribution, gateway policy, request-body log suppression, monitoring, alerting, rate limiting, deployment rollout, and reconciliation of unknown trade outcomes. The service intentionally does not implement built-in rate limiting.
License
This project is licensed under the MIT License. See LICENSE.
推荐服务器
Baidu Map
百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。
Playwright MCP Server
一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。
Magic Component Platform (MCP)
一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。
Audiense Insights MCP Server
通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。
VeyraX
一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。
graphlit-mcp-server
模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。
Kagi MCP Server
一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。
e2b-mcp-server
使用 MCP 通过 e2b 运行代码。
Neon MCP Server
用于与 Neon 管理 API 和数据库交互的 MCP 服务器
Exa MCP Server
模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。