iwym-assets-mcp
stdio MCP server that lets a Grok Bot maintain the iwym asset whitelist (assets + asset_venue_codes). It wraps the operator HTTP API. It does not open exchange orders and it does not turn on auto_exec.
The bot is expected to verify one asset at a time (1000SHIB vs SHIB, the same ticker on two venues, Kraken XBT, leveraged tokens) and then write. Catalog diff is the read side of that loop.
Requirements
- Python 3.11+
- uv
- A running iwym API (
IWYM_API_BASE_URL) - An operator API token from Settings → System → OPERATOR API (paste it as
IWYM_OPERATOR_TOKENhere)
1. API token
Log into the iwym console and open Settings → System. The OPERATOR API panel shows whether a token is set and when it was last rotated.
- Generate creates a token when none is stored.
- Reset rotates it. The previous Bearer stops working immediately.
- The plaintext is shown once. Copy it into
IWYM_OPERATOR_TOKEN. It is not written to.envon the API, and the API stores only a SHA-256 digest.
The token acts as the operator who generated it. It has the same power as that logged-in operator. Cookie login is unchanged. This Bearer works in any APP_ENV and does not need a CSRF cookie.
AUTH_ALLOW_BEARER is only for short-lived JWTs in development. Do not use it for this MCP.
2. Connect (Cursor / Grok Bot)
From a local checkout:
{
"mcpServers": {
"iwym-assets": {
"command": "uv",
"args": [
"--directory",
"/ABS/PATH/iwym-next/mcp/iwym-assets",
"run",
"iwym-assets-mcp"
],
"env": {
"IWYM_API_BASE_URL": "http://127.0.0.1:8000",
"IWYM_OPERATOR_TOKEN": "paste-from-settings-system-operator-api"
}
}
}
}
IWYM_API_BASE_URL is the API origin only (no /api/v1 suffix).
cd mcp/iwym-assets
uv sync
export IWYM_API_BASE_URL=http://127.0.0.1:8000
export IWYM_OPERATOR_TOKEN=paste-from-settings-system-operator-api
uv run iwym-assets-mcp
stdio waits for the host. Missing env vars exit 1 with a stderr hint.
3. Tools
| Tool | HTTP | Notes |
|---|---|---|
list_assets |
GET /api/v1/assets |
Includes disabled rows |
get_asset |
GET /api/v1/assets/{id} |
|
catalog_diff |
GET /api/v1/assets/catalog-diffs |
venue optional. Omit it to scan every seeded ticker venue. include_orphans defaults false |
create_or_upsert_asset |
PUT /api/v1/assets/{id} |
Create-or-attach. enabled defaults to false on this tool (the HTTP body default is true, matching Settings create). Does not rewrite scalars on an existing row |
update_asset |
PATCH /api/v1/assets/{id} |
Change kind / enabled / display_symbol / oracle_feed_type / anchor_asset_id on an existing row. Omitted fields unchanged |
set_enabled |
PATCH /api/v1/assets/{id} |
Toggle Radar whitelist only (enabled true/false). Use after soft_disable_asset to turn a row back on |
add_venue_code |
POST /api/v1/assets/{id}/venue-codes |
409 if the code is already taken |
soft_disable_asset |
DELETE /api/v1/assets/{id} |
Sets enabled=false; keeps the row and venue codes |
auto_exec is not touched.
Asset kind values
| kind | Meaning |
|---|---|
spot_crypto |
Normal CEX crypto base (Radar scan candidate when enabled) |
stable |
Stablecoin quote (USDT/USDC/…); not a funding scan base |
wrapped |
Wrapped / pegged asset priced off an anchor (e.g. tBTC) |
leveraged_token |
CEX leveraged token (3L/3S, UP/DOWN, BULL/BEAR); keep enabled=false for Radar |
equity |
Stock / equity-like ticker (UVXY, XLE, …); keep enabled=false for Radar |
Example — classify stock tickers and drop them from the scan set:
update_asset(asset_id="uvxy", kind="equity", enabled=false)
update_asset(asset_id="xle", kind="equity", enabled=false)
Or two calls: update_asset(..., kind="equity") then set_enabled(..., enabled=false).
catalog_diff
Spot and perp legs only. Unique base codes, not BTCUSDT rows. Tradable instruments only.
Each entry:
status:missing(no(venue, code)row),disabled(mapped, assetenabled=false),orphan(whitelist code absent from the catalog; only wheninclude_orphans=trueand that venue's spot and perp reads both succeeded)suggested_asset_id: lowercase slug, or null when the code cannot be an id (1000SHIB)already_mapped_asset_id/mapped_asset_enabledmarket_types:spotand/orperpalias_note: catalog folds (XBT→BTC,XDG→DOGE), multiplier prefixes, leveraged-token suffixes
errors[] means that market was not read. Do not treat orphans as complete for a venue listed there.
create_or_upsert_asset
One asset per call. Pass venue + code, or venue_codes_json as [{"venue":"binance","code":"SHIB"}].
- Asset missing: create it (tool default
enabled=false) and attach codes that are free. Response HTTP 201,created: true. - Asset exists and kind/oracle/anchor match: attach free codes. Codes already on this asset are unchanged. HTTP 200. Scalar fields are not updated (
enabledstays as stored) — useupdate_asset/set_enabled.kind=spot_cryptoalso matches a storedleveraged_tokenorequityrow so a retry can attach codes without rewriting the product class. - Code belongs to another asset, or kind/oracle/anchor differ: HTTP 409, nothing written.
error.details.conflictslists{venue, code, asset_id}.
update_asset / set_enabled
update_asset maps to PATCH /api/v1/assets/{id}. Pass only the fields to change. kind must be one of the values in the table above.
set_enabled(asset_id, enabled) is the narrow form for the Radar whitelist flag (including re-enabling after soft_disable_asset).
4. Suggested bot loop
catalog_diff(venue="binance").- Read one
missingentry. Ifalias_notementions a multiplier, leverage suffix, or folded alias, stop and ask. get_asset(suggested_asset_id)when the suggestion is non-null.create_or_upsert_assetwithenabled=falseand that one venue code.- On 409, stop. Do not pick a new id to steal the code.
- Leave the row disabled until a human wants it in the Radar scan set.
- If the ticker is a leveraged token or equity (UVXY, XLE, …),
update_assetwithkind=leveraged_tokenorkind=equityandenabled=false(do not rely on create_or_upsert to rewrite kind).
5. Security
- Never commit
IWYM_OPERATOR_TOKEN. The API does not readOPERATOR_API_TOKENfrom the environment. - The token is not a trading key. It can still change the whitelist.
- Settings UI CRUD (
POST /assets, PATCH, venue codes, contract paste) is unchanged.
Metadata
Release files for iwym-assets-mcp 0.1.2
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 |
|---|---|---|---|---|
| iwym_assets_mcp-0.1.2.tar.gz | 57.9 kB | Without provenance | Details for iwym_assets_mcp-0.1.2.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| iwym_assets_mcp-0.1.2-py3-none-any.whl | Python 3 | none | any | Details for iwym_assets_mcp-0.1.2-py3-none-any.whl |
Total release size: 66.9 kB
Release files / iwym_assets_mcp-0.1.2.tar.gz
| Download URL | iwym_assets_mcp-0.1.2.tar.gz |
|---|---|
| Size | 57.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
0a5ce54e74aa115b47c6cb89b5eac65305121fb288c69bc2ed3b1d5c81f0b13b
|
|
BLAKE2b-256 checksum How to use checksums |
e432abcd7d8460c9b60a2680a4806166c21207a5a8a8bb826d2cd5055546344c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.7.8
|
Release files / iwym_assets_mcp-0.1.2-py3-none-any.whl
| Download URL | iwym_assets_mcp-0.1.2-py3-none-any.whl |
|---|---|
| Size | 9.0 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
57f2e3460a16c03d3066663a7f55ab42e6d6bbd73b03d84cbf9bcb1aa0d64361
|
|
BLAKE2b-256 checksum How to use checksums |
dae6b807495cacf1eab4cf765e5d854f195ba700189d6241d7a011bb56167aa8
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.7.8
|
Security for iwym-assets-mcp 0.1.2
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.