# Moby

> Bearer agent key. Codex, Claude Code CLI, Gemini CLI (paid key), Grok CLI. ChatGPT: workspace plans.

- name: win.moby/moby
- version: 1.0.2
- connection class: R1 (autonomous)
- trust: 83/100 flags: no-repository
- quality: 79/100 (good)
- owner: not claimed
- descriptor: https://api.protogrid.dev/v1/servers/win.moby%2Fmoby
- tools: https://api.protogrid.dev/v1/servers/win.moby%2Fmoby/tools

**An agent can connect on its own if it already holds `agent_key`.** Remote endpoint behind a static API key or header. The registry never sees the value; the agent fills the placeholder.

## Connection (mcpServers)

```json
{
  "mcpServers": {
    "moby": {
      "type": "http",
      "url": "https://mcp.moby.win/mcp",
      "headers": {
        "Authorization": "Bearer ${agent_key}"
      }
    }
  }
}
```

Placeholders to fill: `${agent_key}`.

## Trust

- hygiene: 80
- liveness: 100
- freshness: 100
- provenance: 55
- drivers: +dns-namespace +website +reachable +uptime-100% +updated-11d-ago -no-repository
- Derived from observable signals (official registry feed and our own credential-free probes); no code audit performed.

## Quality 79/100 (good)

### protocol: 100 (weight 25)

- pass `protocol.modern`: supports 2026-07-28 (server/discover)
- pass `protocol.stateless`: answers without a session
- pass `protocol.transport`: streamable HTTP
- pass `protocol.list_ttl`: tool list is cacheable (ttlMs 900000)

### authorization: n/a (weight 15)

- n/a `auth.prm`, `auth.as_metadata`, `auth.cimd`: no remote uses OAuth
- n/a `auth.secret_in_url`: no templated URL

### tool hygiene: 75 (weight 30)

- pass `tools.descriptions`: every tool has a description
- warn `tools.description_length`: 13 tools have descriptions over 1,024 characters, which crowds the context
- pass `tools.schemas`: every tool has an object input schema
- pass `tools.annotations`: 84 of 84 tools declare readOnlyHint or destructiveHint
- pass `tools.directory_hints`: every tool declares readOnlyHint, destructiveHint, idempotentHint and openWorldHint
- fail `tools.token_cost`: about 27,038 tokens to load every tool, a large share of an agent's context
- warn `tools.api_dump`: 84 tools, 83% named like REST operations: looks like an API mapped one endpoint per tool
- pass `tools.hidden_text`: no hidden text in tool names, descriptions, schemas or annotations

### stability: 50 (weight 15)

- warn `stability.changes`: 218 tool changes in 30 days
- fail `stability.rug_pull`: 39 tools kept their name but changed most of their description in 30 days; review before trusting them
- pass `stability.new_links`: no tool change named a new site

### dependencies: n/a (weight 15)

- n/a `deps.known_vulns`, `deps.mcp_sdk_version`, `deps.resolvable`: no npm or PyPI package

- tools: 84, about 27,038 tokens to load them all
- tool set hash: d86b75eb06f7119d0904fa8db31d8009
- tools last changed: 2026-11-12T01:05:49.231Z
- badge: [![protogrid quality](https://protogrid.dev/badge/win.moby/moby.svg)](https://protogrid.dev/servers/win.moby/moby)
- Checks run on what our credential-free, read-only probes observe; tools are never called and no code audit is performed.

### Tool changes

- 2026-11-12 `get_updates` changed (description)
  - before: What's new on Moby: dated tool changes, each with the exact call to make. Call it when the user says update, catch up or what's new, or a Moby feature seems missing from your tools. Send each `how_to_use` call as written, even if your tool list doesn't show it.
  - after: What's new on Moby: dated tool changes, each with the exact call to make. Call it when the user says update, catch up or what's new, or a Moby feature seems missing from your tools. If the tool is in your list, send `how_to_use` as written (new values work); if not, ask the user to start a new chat.
- 2026-11-12 `get_my_feedback` changed (annotations)
- 2026-11-12 `get_my_active_strategies` changed (annotations)
- 2026-11-12 `get_my_invite_payouts` changed (annotations)
- 2026-11-12 `get_my_invite_codes` changed (annotations)
- 2026-11-12 `get_my_trading_profile` changed (annotations)
- 2026-11-12 `get_my_following_feed` changed (annotations)
- 2026-11-12 `get_my_followed_wallets` changed (annotations)
- 2026-11-12 `unfollow_wallet` changed (annotations)
- 2026-11-12 `follow_wallet` changed (annotations)

Full history: https://api.protogrid.dev/v1/servers/win.moby%2Fmoby/changes

## Remotes

- https://mcp.moby.win/mcp (streamable-http, auth api_key ${agent_key}, reachable true, uptime30d 1)

## Packages

_none_

## Tools (84)

- `cancel_order`: Cancel one open order or a whole DCA schedule. Moves no funds; not reversible. Pass EXACTLY ONE of `order_id` (from `get_my_orders`) or `schedule_id` (stops every remaining DCA slice; filled slices stay filled). A cancelled stop-loss stops protecting the position, and re-placing it gets whatever price is available then. Confirm which order when there are several. Cancels are never blocked by the user's order-type switches.
- `check_positions`: THE first call of every scheduled run, before the scan: what each held position needs now under a strategy's exit rules. One call for position upkeep: for each held token, the live exit legs, age, PnL and the actions due (time-stop sell or sell-now, missing SL/TP, cancel the orphan leg) under the strategy's rules, plus today's counts (buys, stop-outs, open positions, closed-at-loss 7d) so you never recompute them. Do what `actions` says with quick_sell / create_order / cancel_order, then scan. Each action's `params` are the arguments for that tool; `verdict` is `sell_now`, `fix_exits` or `hold`. Nothing is placed or sold by this call. Pass the `strategy` you run; with no strategy and no rule it runs under the user's active strategy, else as a rules-free report (`rules` in the result says which).
- `create_order`: Place a limit buy or sell, take-profit, stop-loss, bracket (SL + TP), trigger buy or DCA on a Solana token. Real money when it fires. Buy orders are checked against app-set limits. ⚠️ SPENDS REAL MONEY from the user's agent wallet; cannot be undone. Get an explicit yes on the exact amount and token BEFORE calling. It can fire later: read back the type, token, amount and every price first.
Trade limits: SELL orders never count toward or get blocked by `maxTradeUsd` / `dailyVolumeUsd`. A BUY is checked against both and reserves its USD value in the daily volume; the unfilled part comes back if it is cancelled, expires or fails.
A timeout or `order_in_flight` is NOT a failure: the order may be live. Retry only with the same arguments and `client_order_id` (the error names it), never as a new order.
`order_type` selects what to place and which price arguments it needs:
- `limit_buy` / `limit_sell` — buy when the price falls to, or sell when it rises to, `limit_price`. Needs `limit_price`.
- `tp_only` — sell when the price rises to `take_profit_price`. Needs it.
- `sl_only` — sell when the price falls to `stop_loss_price`. Needs it.
- `trigger_buy` — buy when the price DROPS to the trigger, which goes in `stop_loss_price`; no other price.
- `sl_and_tp` — a BRACKET: stop loss AND take profit on one position in one call. Needs both prices; both legs cover `amount`. When one fills, Moby cancels the other. It places TWO orders, listed in `legs` (`order_id` + `order_type`; also `stop_loss_order_id` / `take_profit_order_id`). If ONE leg could not be placed, `failed_leg` / `failed_leg_error` say which and why: the other leg is LIVE, so place only the missing one with `sl_only` / `tp_only`, never the bracket again.
- `dca_buy` / `dca_sell` — `order_count` equal slices `interval_seconds` apart. Needs both, NO price.
`tp_only` and `sl_only` as two calls protect both sides too, but cancelling one does NOT cancel the other. When a fill sells the whole position, Moby cancels your remaining exits on that token within a minute or two (`get_my_orders` `status="terminal"`, `cancel_reason`); after a PARTIAL exit the other stays live.
- `trailing_stop` — sell at market when the price falls `trail_pct`% from its high (the high only moves up). Needs a position you already hold: buy first. Needs `trail_pct` (0.5 to 50), no other price; optional `activation_price` arms it once the price reaches it. No edit: cancel and recreate. `trailing.watermark_price` / `watermark_updated_at` move ONLY on a new high (flat or falling = unchanged, not stale).
All prices are USD prices of the token. `amount` is always what the user SPENDS: the funding asset on a buy, the token itself on a sell.
Refusals that are NOT argument problems: `no_market` (no sell route yet: retry the same call later) and `stop_above_market` / `tp_below_market` (price already past the trigger: re-check it and pick a new one). Moby does not retry or re-arm for you.
To CLOSE or trim at market now use `quick_sell`, not an order. EXITS ARE YOURS: Moby attaches no automatic TP/SL to your buys, so place them here after the buy. SOL positions: use quick_sell; TP/SL on SOL is not supported.
- `discover_wallets_to_follow`: Suggested profitable public Solana wallets to follow or copy trade, or search one by name or address. Each row has `is_following`. With `query`: search by name, brand or an exact pasted address (followed wallets included). Without: a ranked pool EXCLUDING wallets already followed (`get_my_followed_wallets`). Following shows a wallet's trades in the user's feed; it never copies them automatically.
- `execute_swap`: Execute a quoted swap from the user's agent wallet. Real money. Only after the user approves the quote. Buys are checked against the app-set limits. ⚠️ SPENDS REAL MONEY from the user's agent wallet; cannot be undone. Get an explicit yes on the exact amount and token BEFORE calling. Only pass a `quote_id` from `get_swap_quote` in this conversation, after the user saw its numbers and said yes. Never call it to 'check' anything. An expired quote needs a fresh quote, never the old id. When `fill_pending` is true, call `get_swap_status(quote_id=...)`. AMOUNTS: quote the `_ui` fields (whole tokens); un-suffixed amounts are the smallest unit. Null = unknown, never zero; `fill_pending: true` = fill not booked yet (`get_swap_status`). A full sell cancels every resting TP/SL on the token, all lots (`cancelled_order_ids`; `cancel_failed_order_ids` / `cancel_pending_order_ids` + `cancel_note` are retried); a partial sell or a buy leaves them (null).
- `follow_wallet`: Follow a public Solana wallet so its trades appear in the user's following feed. Moves no money and does not copy trades automatically. Idempotent: following an already-followed wallet is a no-op and does not count against `max_follows` (see `get_my_followed_wallets`). Fails when the user is at the cap. Needs no agent wallet.
- `get_degen_leaderboard`: Newer, smaller, high-risk Solana memecoins ranked by activity. Say plainly they can lose most of their value fast. Riskier than `get_screener_leaderboard`, and many are short-lived. Ranked best-first; page 1 is the top. `whale_windows` (any of h1/h4/h8/h24) adds a per-row `whale` block per window: whale_count (distinct tracked wallets that bought OR sold — buyers plus sellers, not buyers alone), whale_buyers_count (distinct buyers only), whale_buys_count, whale_sells_count and whale_net_flow_usd. The row's `whale_count_h24` is the same buyers-plus-sellers count. Null figures mean unknown. `safety_tier`: grey is NOT a red flag; red = caution, and Moby refuses agent buys on red.
- `get_group_leaderboard`: Ranked tokens in one category: majors (`home_majors`), tokenized stocks such as NVDAx, SPYx, GLDx (`home_stocks`), Pulse (`home_pulse`) or a theme from get_screener_groups. Source of truth for major and tokenized-stock mint addresses. `group_id` comes from `get_screener_groups` (a group's `group_id` or a `home_tabs` `tab_id`); never invent one. Take `token_address` from the row and never keep your own mint list. Ranked best-first; page 1 is the top. `whale_windows` (any of h1/h4/h8/h24) adds a per-row `whale` block per window: whale_count (distinct tracked wallets that bought OR sold — buyers plus sellers, not buyers alone), whale_buyers_count (distinct buyers only), whale_buys_count, whale_sells_count and whale_net_flow_usd. The row's `whale_count_h24` is the same buyers-plus-sellers count. Null figures mean unknown. `safety_tier`: grey is NOT a red flag; red = caution, and Moby refuses agent buys on red.
- `get_kol_top_held`: Named crypto influencers (KOLs) holding one Solana token. The KOL-only slice of `get_token_key_holders`. Use for 'which influencers hold X'; their trades are in `get_whalewatch_kol_feed`.
- `get_launchpads`: Recently launched Solana tokens grouped by launchpad such as pump.fun. Highest-risk category. Use for 'what launched recently' and 'new pump.fun coins'; pair with `get_smart_money_pulse` (`fresh_launch`) to see which launches whales are buying.
- `get_market_movers`: What just happened on Solana: sudden price and volume moves, newest first, with smart-money flow. Use for "what pumped in the last hour", "what changed". Use it for what CHANGED, not what ranks highest now. Poll with `after_timestamp`; page back with `before_timestamp`; valid filter values come from `get_screener_event_filters`. Each event has `token_symbol` / `token_address`, `liquidity_usd` and h1/h4 smart-money flow (`smart_money_net_flow_usd`, `smart_money_buys_count`, `smart_money_sells_count`) AS OF NOW, while `market_cap_usd` and `price_usd` are AT THE TIME OF THE EVENT.
- `get_my_active_strategies`: Strategies the agent is running for this user. Check before starting one. Saved on Moby so every client and session sees them: `name`, `strategy_id` (the starter card, null = custom), `settings`, `schedule`, `status` (active / paused; pass `include_stopped=true` for stopped ones too), `started_at`, `last_run_at`. Call it at the start of every session to learn what is already running, and before starting a strategy, so two sessions never run the same one twice. Resume what is `active` on its `schedule`; leave `paused` ones alone unless the user asks. `app_links` are Moby app deep links to hand to the user; they open the Moby app on their phone.
- `get_my_activity`: The user's recent trades, deposits and transfers timeline. Newest first and CURSOR-paginated: pass the response's `cursor` back; there are no page numbers. Choosing between the two history feeds: `get_my_activity` is the merged, human-readable timeline the app shows, cursor-paginated. `get_my_transactions` is the raw transaction list, page-numbered and filterable by transaction type. Prefer activity for 'what have I been doing'; use transactions when you need a specific type such as deposits.
- `get_my_balances`: Per-token balances in the Solana agent wallet, with available USDC to size a buy. USDC is your cash (`is_cash: true`). SOL and every other token are positions; sell with quick_sell to raise USDC. `tokens` is EVERYTHING held, SOL (`is_native`) and USDC (`is_quote`) included; empty means the wallet is empty. `native_token` / `usd_token` repeat those two as fixed slots: never add them to the total. Quantities are read on the CHAIN (`balance_source: "chain"`; `"ledger"` = a stale snapshot, say so; `ledger_disagrees: true` = the snapshot was wrong). `swap_user_tokens` is the ledger: cost and PnL, not amounts held. `get_my_closed_positions` is exited positions ONLY; what the user holds now is `get_my_balances`. Never say they hold nothing from an empty closed list. `available_usdc` is spendable now; `reserved_usdc` is held by resting DCAs and buy orders (`reserved_breakdown`) until `cancel_order`; not the guardrails' `daily_volume_reserved_usd`. One wallet: the total is `get_my_portfolio`. `app_links.deposit` adds funds. `interview_due: true` = onboarding was skipped: go back to `get_my_trading_profile` and the 5-question interview (onboarding FIRST) before acting on these numbers.
- `get_my_closed_positions`: Positions the user fully exited, with realized PnL. `get_my_closed_positions` is exited positions ONLY; what the user holds now is `get_my_balances`. Never say they hold nothing from an empty closed list. An empty result says nothing about what they hold today. Choosing between the two history tools: `get_my_closed_positions` is the POSITION-level rollup — one entry per token the user entered and fully exited, with total realised PnL. `get_my_closed_trades` is the individual TRADES underneath, one entry per fill. Use positions for 'how did I do on X', trades for 'show me every trade'.
- `get_my_closed_trades`: Each closed buy and sell cycle for one token, with fills and tx hashes. Newest first; each cycle has `fills` (timestamp, side, price_usd, token_amount, usd_amount, tx_hash; `include_fills=false` skips them) and your `rationale`. ONE TOKEN AT A TIME: `token_address` is required; for the whole history use `get_my_closed_positions`. Choosing between the two history tools: `get_my_closed_positions` is the POSITION-level rollup — one entry per token the user entered and fully exited, with total realised PnL. `get_my_closed_trades` is the individual TRADES underneath, one entry per fill. Use positions for 'how did I do on X', trades for 'show me every trade'. `get_my_closed_positions` is exited positions ONLY; what the user holds now is `get_my_balances`. Never say they hold nothing from an empty closed list.
- `get_my_dca_schedules`: The user's recurring DCA buys and sells with progress. The same rows `get_my_orders` returns as `dca_schedules`. `get_my_orders` answers 'what is running' in ONE call: `orders` (limit, TP, SL) plus `dca_schedules` (one row per DCA; slices never appear in `orders`). `get_my_dca_schedules` is the DCA rows alone. A null `dca_schedules` means the DCA read failed (`dca_schedules_error`): call `get_my_dca_schedules` before saying there is none. `include_terminal` adds finished and cancelled ones. Pass a `schedule_id` to `cancel_order` to stop the whole DCA.
- `get_my_feedback`: Status and team replies for earlier feedback. Mention a shipped one to the user when relevant. Each has `id`, `kind`, `title`, `status` (new / reviewed / planned / shipped / wont_fix) and the team's `reply` when there is one, newest first.
- `get_my_followed_wallets`: Wallets the user follows, with the follow cap. `max_follows` lets you say 'N of 50' in one call; rows carry list associations and any nickname set with `follow_wallet`.
- `get_my_following_feed`: Recent trades by the wallets the user follows. Newest first. ⚠️ EMPTY means the user follows nobody or nobody they follow traded lately, NOT 'no whale activity'; the market-wide feed is `get_whalewatch_feed`. Same filters as that tool, minus lists.
- `get_my_guardrails`: The user's app-set limits on max per trade, daily buy volume and market-cap range, allowed order types and pause state. Read-only. Use for "what can my agent spend", "what are my limits". READ-ONLY: you cannot change them, only the user. Read them before planning instead of learning by refusal.
- `maxTradeUsd` / `dailyVolumeUsd`: per-trade and rolling-24h limits (null = uncapped). `maxTradeUsd` caps BUYS only. Sells into USDC (swaps and TP/SL/limit sells) never count or get blocked; other swaps count when placed or filled. A resting buy order reserves its value (`dailyVolumeReservedUsd`) until it fills or is cancelled. Room left = `dailyVolumeUsd - dailyVolumeUsedUsd`.
- `defaults_applied`: Moby's defaults, not the user's.
- `minCapUsd` / `maxCapUsd`: market-cap range for BUYS (null = no bound). Red safety tier buys are always refused.
- `orderTypes`: what you may place (`market` = swaps, `quick_buy`, `quick_sell`); cancels are never blocked. `paused: true` = every trade is refused.
- `platform_limits`: rate QUOTAS (0 = off, not blocked); `usage.writes_today` = USED today vs `usage.daily_writes`. `app_links`: settings, deposit. `limits_note` explains null/0.
- `get_my_invite_codes`: The user's AI Trading (AGENT-) invite codes with share links, the friends who redeemed them and the USDC earned from their trading fees. Read-only. Use for "my invite codes", "invite a friend", "how much have my referrals earned".
- `codes[]`: each `AGENT-` code with `status` (unused / redeemed / activated), `share_url` (the https invite link) and `share_text` (the app's share message, code and link filled in). `share_text` / `invite_link` at the top are the NEXT unused code's: hand that text to the user to send to a friend, one code per friend; `unused_count` is how many are left (Moby tops them up).
- `friends[]`: who redeemed a code (`joined_at`, `activated`, `earned_usdc` from them, their `agent_wallets` and `agent_trades_count`).
- `pending_usdc` (not yet swept), `swept_usdc` (paid to the agent wallet), `earned_usdc` (all time), `fee_share_pct` (the share of each friend's trading fees the user earns), `sweep_threshold_usdc`.
Never Copy Trading (`COPY-`) codes: those are a different product and are not on this surface. `enabled: false` = the referral program is off; say so instead of sharing.
- `get_my_invite_payouts`: The USDC referral payouts swept to the user's agent wallet, paged. Read-only, newest first. Each payout has `amount_usdc`, `status` (pending / success / failure), `tx_hash` (the Solana transfer to the user's agent wallet, once sent) and `created`. `total` is the count across pages. For what is still accruing, read `pending_usdc` from `get_my_invite_codes`. Never Copy Trading payouts.
- `get_my_limits`: Moby's rate limits for this API key: per-minute and daily limits, today's usage, the fee tier and what raises it. Costs nothing (never rate-limited). Use for "what are my API limits", "why was I rate limited". - `limits`: per-minute (`*_per_minute`) and daily QUOTAS (`daily_*`); 0 = that limit is off.
- `usage`: calls USED today (`*_today`) and `*_remaining_this_minute`; null = unreadable.
- `tier` and `fees_window_usd` (trading fees paid over `window_days`); `next_tier` / `fees_to_next_tier_usd` = the fees that raise the limits. They rise on their own.
Read it before a large pass instead of learning the limits from a refusal.
- `get_my_orders`: The user's open and past limit, take-profit, stop-loss orders and DCA schedules. Live orders by default: check before placing one (no duplicates) and to find an `order_id` for `cancel_order`. History: `status="terminal"` (with `since` / `until`), paged by `limit` / `page`. Filled rows carry `filled_price`, `fill_tx_hash`, `slippage_vs_trigger_pct`; cancelled rows `cancel_reason` (`sibling_filled` = the other exit sold the position). `input_*` is what the user SPENDS and `token_*` the subject token: name an order by `token_symbol`. A row with `data_warning` contradicts itself: call its state unclear. `origin: agent` = yours; `agent_auto_exit` = an older Moby-attached exit, still live. DCA rows: `schedule_id` (what `cancel_order` takes), progress `filled_order_count` / `order_count`. Trailing stops: `trail_pct` and `trailing` (live high and sell level). `get_my_orders` answers 'what is running' in ONE call: `orders` (limit, TP, SL) plus `dca_schedules` (one row per DCA; slices never appear in `orders`). `get_my_dca_schedules` is the DCA rows alone. A null `dca_schedules` means the DCA read failed (`dca_schedules_error`): call `get_my_dca_schedules` before saying there is none.
- `get_my_portfolio`: Total value and holdings of the user's agent wallet. Use for "how am I doing". Counts the AGENT's wallets only (`scope: agent_wallets`): Copy Trading and manual wallets are left out (`excluded_wallets`); never add them back. Quote `summary.hero_usd`, the agent's equity; `summary.wallets` breaks it down (do not re-add it), `holdings.items` is every position, `trading_balances.items` the funding balances. USDC is your cash; SOL and every other token are positions. Per-token detail and the affordability check: `get_my_balances`. `interview_due: true` = onboarding was skipped: go back to `get_my_trading_profile` and the 5-question interview (onboarding FIRST) before acting on these numbers.
- `get_my_position`: Holding, cost basis and unrealized PnL for one token. Use for "am I up on X". Quantities come from the CHAIN; cost basis and PnL from Moby's swap ledger, which only sees Moby swaps. Never size a sell from a ledger quantity.
- `balance_token_amount` / `balance_usd`: held ON CHAIN now ('how much do I have').
- `cost_basis_usd` / `current_pnl_usd` / `current_pnl_pct`: UNREALISED, over `basis_known_token_amount` only; when that is below the balance, the rest has no known cost: say so.
- `invested_usd` / `sold_usd`: LIFETIME totals; `balance_usd + sold_usd - invested_usd` will NOT equal `current_pnl_usd`, and both are right.
- `realized_total_usd`: realised PnL including partial sells (`closed_trades_count` can be 0).
- `ledger_present: false`: no swap history, so every money field is unknown. A null profit field is UNKNOWN, never zero.
`take_profit_orders_count` / `stop_loss_set` include your `create_order` legs. `closed_cycles`: the last 5 closed cycles (fills: get_my_closed_trades(token_address)). `rationale`: your thesis on the open cycle.
- `get_my_recommended_wallets`: Tracked wallets that hold the same tokens as the user. 'For you', in the same shape as `get_whalewatch_wallet_list_detail`. Holding nothing Moby tracks gives `total: 0, rows: []`, a real answer, not an error.
- `get_my_token_balance`: How much of one token the user holds now. Use to size a sell. `balance_token_amount` IS THE ANSWER: the on-chain balance, same as `get_my_balances`; 0 means they do not hold it. `ledger_balance_token_amount` and `cost_basis_usd` are the ledger's, for cost context only: check `ledger_present` first (false = both unknown, and `ledger_disagrees: false` then means nothing to compare). A disagreeing ledger is normal after transfers; never average the two or sell the larger. Quantities come from the CHAIN; cost basis and PnL from Moby's swap ledger, which only sees Moby swaps. Never size a sell from a ledger quantity. Use `get_my_position` for unrealised PnL.
- `get_my_trading_profile`: The user's saved trading preferences and onboarding state. Call first on every connect. 🔴 BEFORE ANY OTHER TOOL.
- `agent`: this key's agent (`name`).
- `interview_due: true`: show `onboarding_brief` verbatim, then run the skippable 5-question interview in `interview_questions`, then its closing step (TWO-line playback, `save_trading_profile`, strategy offer, ONE starter buy). The scan schedule is kept on the agent's side, never saved to Moby: keep it in your own memory or as a recurring task in your own app, and recreate it at the start of each session.
- `access_state` / `access_expires_at`: the user's AI Trading invite. `unlocked` = code redeemed but wallet unfunded; access is LOST at `access_expires_at` unless USDC is deposited: warn once, with `agent_wallet.solana_address`. `active` = kept; null = unknown.
- `recommended_strategies`: starter-strategy ids for the user's assets (names from `list_strategies`).
- `agent_wallet`: `solana_address` (deposit here), `usdc_available`, `funded`.
- `status`: `missing` / `saved` / `skipped` (re-ask only if `interview_due`).
- Profile = INTENT: `guardrail_conflicts` = wishes over an app cap; `get_my_guardrails` wins.
- `get_my_transaction`: One transaction by id. Get the id from `get_my_transactions` first; this tool does not search or list. The row carries the full detail of that one transaction.
- `get_my_transactions`: Raw transaction list, filterable by type (swaps, deposits, withdrawals, transfers, order fills). Newest first, page-numbered. `bridge` rows are inbound deposits only; there is no bridge tool. Choosing between the two history feeds: `get_my_activity` is the merged, human-readable timeline the app shows, cursor-paginated. `get_my_transactions` is the raw transaction list, page-numbered and filterable by transaction type. Prefer activity for 'what have I been doing'; use transactions when you need a specific type such as deposits.
- `get_my_wallets`: The user's Solana agent wallet address, for deposits. AI Trading is Solana only for now: tell the user to deposit to the Solana one. The user's regular app wallets are NOT here; every `get_my_*` tool reads one of these agent wallets.
- `get_my_watchlists`: The user's watchlist names and ids. Pass an id to `get_my_watchlist_tokens` for a list's contents. Start here for 'what's on my watchlist'. A watchlist is tokens the user chose to follow, NOT what they hold (`get_my_balances`). Read-only: no adding or removing tokens.
- `get_my_watchlist_tokens`: Tokens on a watchlist with price, 24h change, market cap and safety tier. One call instead of a `get_token_overview` per token: `price_usd`, `price_change_24hr` (no 1h figure), `market_cap`, `liquidity_usd`, `whale_count`, `key_holder_count` and `token` (address, symbol, `safety_tier`). `safety_tier`: grey is NOT a red flag; red = caution, and Moby refuses agent buys on red. Omit `watchlist_id` for the default list, or pass an id from `get_my_watchlists`. Read-only.
- `get_screener_event_filters`: Valid event_types, period and market_cap_group values for get_market_movers. Call it BEFORE filtering `get_market_movers`: an invented filter value returns an empty list that reads as 'no events found'.
- `get_screener_groups`: List Moby's token categories and themes on Solana, and their group_id values. Pass a `group_id` to `get_group_leaderboard`. `home_tabs` lists the app's Home boards by `tab_id` (`home_majors`, `home_stocks`, `home_pulse`), also valid `group_id`s.
- `get_screener_leaderboard`: What's trending and moving on Solana right now, ranked by Moby's 24h activity score with whale counts and safety tier. Use for "what's hot", "top gainers", "trending coins". Page 1 is the top of the board; for 'what is hot right now' the default page is the whole answer. `whale_windows` (any of h1/h4/h8/h24) adds a per-row `whale` block per window: whale_count (distinct tracked wallets that bought OR sold — buyers plus sellers, not buyers alone), whale_buyers_count (distinct buyers only), whale_buys_count, whale_sells_count and whale_net_flow_usd. The row's `whale_count_h24` is the same buyers-plus-sellers count. Null figures mean unknown. `safety_tier`: grey is NOT a red flag; red = caution, and Moby refuses agent buys on red.
- `get_smart_money_pulse`: Market-wide whale, KOL and smart-money buying and selling on Solana for 1h, 4h, 24h, with top net-bought and net-sold tokens. Use first for "what are whales buying today". Tells 'whales are dumping everything' from 'this one coin is weak' before you read a single token. Each window (`h1`, `h4`, `h24`) has `totals`, `by_wallet_type` (whale / kol / smart_money, overlapping), `fresh_launch` (`under_24h` / `under_1h`) and the top 5 `top_net_buy` / `top_net_sell` tokens. Every slice has trades, tokens, buys, sells, buy/sell volume, net_flow_usd, distinct buyers and sellers, dump_sells (sold half or more), dump_wallets and first_buys. Swaps under `min_trade_usd` are left out. Refreshed every ~2 minutes (`data_as_of`).
- `get_strategy`: The full prompt and editable settings for one starter strategy. `prompt` is ready to run: the same text the app copies. Run that prompt as the user's standing instructions for this session. Before starting: confirm the editable numbers (`chips`: amounts, exits, schedule) with the user, and check `get_my_active_strategies` so you never run one twice. Once the user says go, record it with `save_active_strategy` (pass `strategy_id`). `ask_before_every_trade=true` adds the 'ask me before every trade' line, on cards that support it (`ask_line_supported`). `app_links` are Moby app deep links to hand to the user; they open the Moby app on their phone.
- `get_swap_quote`: Price a Solana swap before doing it: output, price impact, fees, slippage, and a quote_id. Moves nothing. Quote `output_amount_ui` and `minimum_output_amount_ui` (the least the route delivers) to the user; `output_amount` is the smallest unit. `pricing_basis` says what produced it. This only prices the trade. It does not move funds and nothing is submitted on-chain. `execute_swap` takes the `quote_id`. Quotes go stale in seconds: show the numbers, get an answer, re-quote if the user hesitates. If `execute_swap` returns `pending` or `fill_pending`, only `get_swap_status` can confirm it. `fee_usd` / `fee_pct_of_trade` = Moby's fee.
- `get_swap_status`: Status and fill of a swap by quote_id or signature. Safe to repeat. Moves nothing. Pass `quote_id` (from the swap result, or a failure message's Reference ID) OR `transaction_signature`. `status`: `not_executed` (quoted, never executed, nothing traded; executable until `quote_expires_at`), `expired` (never executed, too old), `pending`, `confirmed`, `failed`. Once booked, `filled_input_amount_ui` / `filled_output_amount_ui` are what was spent and received, `effective_slippage_bps` the gap to the quote. `failed` carries `failure_details` (`stage`, `error_class`: `slippage_exceeded`, `insufficient_funds` / `insufficient_lamports`, `program_error`, `unknown_revert`; `dropped_tx_blockhash_expired` = never landed, nothing moved: re-quote and try once more). A `confirmed` sell lists `resting_order_ids`. 🔴 Call this whenever `execute_swap` or `quick_buy` returned a `next_step`: until it says `confirmed`, never tell the user tokens arrived, and never re-execute to find out (that trades twice).
- `get_token_chart`: Price history line for one Solana token over a `period` (5m to 365d). Use to describe a trend. Prices are USD; `period` defaults to `1d`. Choosing between the two price tools: `get_token_chart` returns a ready-to-read price line for describing a trend; `get_token_ohlcv` returns raw open/high/low/close/volume candles for calculation and technical analysis. Prefer the chart unless you need per-candle numbers.
- `get_token_dca_orders`: Other people's open on-chain DCA orders on one Solana token (who is accumulating). Not the user's DCAs. ⚠️ The user's own DCAs are `get_my_dca_schedules`; the two datasets are unrelated.
- `get_token_holders`: Every top holder of one Solana token by size, not only tracked wallets. Use for supply concentration ("does one wallet own 30%"). `get_token_key_holders` is the tracked whale and KOL subset of this population, with win rates.
- `get_token_holdings`: Bucketed holder distribution for one Solana token (how supply is spread). For the itemised top holders use `get_token_holders`; for tracked whales and KOLs use `get_token_key_holders`.
- `get_token_key_holders`: Tracked whale, KOL and trader holders of one Solana token, with position size, entry, 30-day win rate and PnL, and concentration. Use for "who holds X", "are the holders good wallets". ⚠️ OTHER people's wallets, not the user's position (that is `get_my_position`). State high concentration as a risk. `whale_count` / `trader_count` / `kol_count` (and `tag_count`) are true totals; rows and counts include positions >= `min_position_usd` (default $100). Rows carry 30-day `win_rate` / `realized_pnl_30d_usd` and `days_since_prev_trade`. `position` = the wallet's tracked buys / sells of THIS token: `bought_usd`, `sold_usd`, `realized_pnl_usd`, `buys_count`, `sells_count`, `pct_of_peak_held`, `first_buy_at`, `entry_known`; sells can exceed buys. With `entry_known` false, P/L and `pct_of_peak_held` are null (unknown, not 0). An untagged KOL's `platform` is `unknown` with `platform_reason` `not_tagged`; `distinct_kol_platforms` has `unknown` excluded. Wallet quality: use get_whale_wallet_track_record(wallet_address) for a wallet's win rate and PnL.
- `get_token_live_feed`: Newest trades by tracked whales, KOLs and traders in one Solana token, with quick-flip flags. NOT the whole market: only wallets Moby tracks; every tracked trade (no $ floor), one row per swap (`identities`, `is_whale`, `is_kol`), from when Moby began tracking the token's traders. Pass `next_cursor` back as `cursor` until null. `wallet.win_rate` / `wallet.realized_pnl_30d_usd` are 30-day quality. Each row's `days_since_prev_trade` / `prev_trade_at` say how long the wallet was quiet before the trade (any token; null = no earlier trade on record). Rows sort by `timestamp`, then `sequence` (ingest order), so trades by one wallet in the same second stay in order. Rows carry `wallet_list_type` (whale, trader, kol); SELL rows carry `held_seconds` and `quick_flip: true` when sold within 15 minutes of the first buy: check it before reading that wallet's buy as conviction.
- `get_token_ohlcv`: Open/high/low/close/volume candles for one Solana token, for technical analysis (RSI, moving averages, returns). Series is newest-first. Prices are USD. Candle size: `interval` (`1m`, `5m`, `15m`, `1h`, `4h`, `1d`; wins over `timeframe` / `aggregate`; default 15m). An unsupported size is rejected; the response echoes `interval` and `candle_seconds`. `t` is Unix MILLISECONDS; time arguments take seconds or milliseconds.
🔴 NEWEST-FIRST, unlike TradingView: `c[0]` is the LATEST close and `c[-1]` the OLDEST, so a return is `(c[0] - c[-1]) / c[-1]` (the other way round flips the sign; `order` says so). Every candle is CLOSED: the forming one is dropped unless `include_in_progress_candle` is true (then it is index 0). Choosing between the two price tools: `get_token_chart` returns a ready-to-read price line for describing a trend; `get_token_ohlcv` returns raw open/high/low/close/volume candles for calculation and technical analysis. Prefer the chart unless you need per-candle numbers.
- `get_token_overview`: Price, market cap, FDV, liquidity, volume, holders, safety tier and smart-money read for one Solana token. Use for "tell me about X", "what's the market cap of X". `liquidity_source`: `bonding_curve` (`liquidity` = curve reserve) or `dex_pool`. `market_cap` is circulating (`market_cap_basis` is `circulating`), else the FDV (`fully_diluted`). `fdv` = price x total supply; `ath_market_cap` (alias `ath_mc`) shares `market_cap`'s basis and `ath_fdv` pairs with `fdv`: never compare `market_cap` with `ath_fdv`. `safety_tier`: grey is NOT a red flag; red = caution, and Moby refuses agent buys on red. `stats.untouched_pct` equals the `detail.tags` Untouched cell (one window, one denominator). `smart_money_read_v2`: `tier`/`label`/`verdict` grade the LAST HOUR of tracked flow; `text`/`bullets`/`stats` describe the 7-DAY holder base. They can disagree: say both, gate entries on `tier`. `stats.left_*` = every tracked wallet that sold out; `stats.exited_*` = the entry-known subset. `concentration.flagged` or `tier_cap_reason: concentration` = one wallet carries the read. `data_notes` lists fields Moby lacks or knows only in part; verify those on the web before quoting them.
- `get_token_overviews`: Overviews for up to 50 Solana tokens in one call. Use for many tokens at once (watchlists, scan qualifiers, portfolio marks): one call replaces up to 50 `get_token_overview` calls. Results are in request order: `found: true` with `overview` (the `get_token_overview` body, compacted) or `found: false` with `error`; one bad token never fails the call. Costs 1 read per 10 tokens. `data_notes` lists fields Moby lacks or knows only in part; verify those on the web before quoting them.
- `get_token_price`: Current USD price of one Solana token. Cheapest price check. Use `get_token_overview` when you also need market cap, liquidity or volume.
- `get_token_risk_signals`: Rug-pull and scam risk for one Solana token: honeypot, buy/sell tax, mint and freeze authority, dev hold, sniper, insider, bundler and fresh-wallet shares. Use for "is this a honeypot", "check mint authority". Same fields and rules as the app's Risk Signals block. `status`: `ok`, `pending` (retry in a few seconds), `unavailable` / `unsupported` (no data; do not hammer). Nulls mean no data, not zero; early buyers stay `unavailable`. `fetched_at` says how fresh the read is.
- `get_token_smart_money`: Which tracked whales, KOLs and proven traders are buying or selling one Solana token over 1h, 4h and 24h. Use for "is smart money in X", "are whales buying X". These are OTHER people's wallets. Each window (`h1`, `h4`, `h24`) has `last_buy_at` / `last_sell_at`; `data_as_of` is when the windows were rolled up. A net that flips with no newer `last_sell_at` means older buys aged out, not new selling.
- `get_token_trade_brief`: One-call pre-buy research and rug check for a Solana token: safety tier, risk signals (snipers, insiders, bundlers, dev hold, mint/freeze authority), smart-money flow, top holders and recent trades by winning wallets. Use for "should I buy X", "is X a rug", "research this coin". Sections: `about` (socials, age, launchpad, `liquidity_source`, `graduation_pct`), `safety`, `smart_money_flow` (h1/h4/h24 net $, buys vs sells, `last_buy_at` / `last_sell_at`), `smart_money_read` (`tier` over the last hour, `concentration`, `tier_cap_reason`), `risk_signals` (`status`), `key_holders` (top 10 positions >= $100: entry MC, `position`, 30-day `win_rate`), `recent_quality_trades` (by wallets with win_rate >= 0.5 and positive 30-day P/L) and `market` (`fdv`, `ath_market_cap`, `ath_fdv`, `pct_from_ath` on the `market_cap_basis` pair). A failed section is null with its reason in `errors`. Cached 15 s. Go deeper with `get_token_key_holders`, `get_token_live_feed` and `get_whale_wallet_profiles`. `data_notes` lists fields Moby lacks or knows only in part; verify those on the web before quoting them.
- `get_token_whale_holders`: Tracked whales holding one Solana token, grouped by whale list. `get_token_key_holders` is the same population ungrouped (whales and KOLs together, with win rates); use this for 'which KIND of whale is in this'.
- `get_token_x_profile`: Follower count, age and verification of a Solana token's X (Twitter) account. Paid per lookup; use sparingly. Answers 'is this project's social presence real or a two-day-old burner'. Not for routine enrichment of every token in a list.
- `get_top_held`: Tokens ranked by total USD held by tracked whales (default) or by Moby users. Use for "what are whales holding most". Always TOKENS, never a ranking of people. `holder_type=whale` for 'what are whales piling into', `holder_type=user` for 'what do Moby users hold most'.
- `get_updates`: What's new on Moby: dated tool changes, each with the exact call to make. Call it when the user says update, catch up or what's new, or a Moby feature seems missing from your tools. If the tool is in your list, send `how_to_use` as written (new values work); if not, ask the user to start a new chat.
- `get_whale_wallet_holdings`: Current holdings of one tracked wallet. ⚠️ Somebody else's portfolio, not the user's (that is `get_my_balances`). Take `wallet_address` from a whale feed row; opaque references work. `get_whale_wallet_positions` adds cost basis and PnL.
- `get_whale_wallet_pnl_chart`: One wallet's cumulative realized PnL curve (1d, 7d, 30d, 1y). Is the record a steady climb or one lucky trade? ⚠️ Somebody else's equity curve, never the user's.
- `get_whale_wallet_positions`: One tracked wallet's positions with cost basis and unrealized PnL. Richer than `get_whale_wallet_holdings` (amount and USD only). ⚠️ Somebody else's positions; the user's own are `get_my_balances` / `get_my_position`.
- `get_whale_wallet_profile`: Identity, 7d and 30d win rate and PnL, holdings and recent trades for one public Solana wallet. Use for "is this wallet any good". Also whether Moby stopped tracking it (`identity.tracking_paused_at`). Prefer it over `get_whale_wallet_track_record` + `get_whale_wallet_positions`. `windows.d7` / `windows.d30`: realized P/L, closes, win rate, avg/median hold days, share of closes held under 24h. Read `read.situation` with the window stats. `include_holdings=false` = stats only, much smaller; to rate many wallets use `get_whale_wallet_profiles`. A wallet Moby has seen but not indexed returns null sections, not an error. ⚠️ Somebody else's profile, never the user's.
- `get_whale_wallet_profiles`: Win rate and PnL for up to 20 wallets in one call. Rate 10-20 key holders before a buy; stats only. Pass the `wallet_address` refs from `get_token_key_holders`. Each profile has `windows.d7` / `windows.d30` (realized P/L, closes, win rate, median hold, short-hold share), `track_record`, `realized` and `identity`. An unknown wallet is left out: match rows on `wallet_ref`. ⚠️ Other people's wallets.
- `get_whale_wallet_track_record`: Win rate, realized PnL, trade count and hold time for one wallet. Prefer the profile tool. Also `backfill_state` (whether Moby finished indexing it). `get_whale_wallet_profile` has this plus holdings and follow state in one call. ⚠️ Somebody else's record, never the user's.
- `get_whale_wallet_wins`: Top 5 closed trades by profit for one wallet. Judge a wallet before weighting its trades. ⚠️ Somebody else's track record, not the user's (theirs is `get_my_closed_positions`). An empty list means no wins data, not that the wallet never won.
- `get_whalewatch_feed`: Buys and sells by tracked Solana whale wallets, filterable by token, wallet, list and time. Newest first. Filter by `token_address`, `wallet_address` (a TRACKED wallet, never the user's; their trades are `get_my_activity`) or `list_ids` from `get_whalewatch_lists`. For a whole time window use `get_whalewatch_feed_window`. Rows sort by `timestamp`, then `sequence` (ingest order), so trades by one wallet in the same second stay in order. Rows carry `wallet_list_type` (whale, trader, kol); SELL rows carry `held_seconds` and `quick_flip: true` when sold within 15 minutes of the first buy: check it before reading that wallet's buy as conviction. `include_context=true` adds a per-row `context`: pnl_pct_vs_entry (trade price vs the wallet's average entry, a fraction), tags, hold_days_at_trade, share_sold_of_position, position_before_usd, entry_vwap_before, days_since_prev_trade / prev_trade_at and the wallet's 30-day wallet_win_rate / wallet_realized_pnl_30d_usd. Unknown values are null: pnl_pct_vs_entry is null when the wallet's entry was never seen. Wallet quality: use get_whale_wallet_track_record(wallet_address) for a wallet's win rate and PnL.
- `get_whalewatch_feed_window`: Every tracked whale trade in a window up to 48h, one row per swap, cursor paged. Unlike `get_whalewatch_feed`: ONE ROW PER SWAP (`list_id` is one matching list) and cursor paged (pass `next_cursor` back as `cursor` until null; new trades never shift a page). Filter by side, minimum trade size, minimum market cap, `actions`, `list_ids` and `min_days_since_prev_trade`. A window over 48h is rejected. Rows sort by `timestamp`, then `sequence` (ingest order), so trades by one wallet in the same second stay in order. Rows carry `wallet_list_type` (whale, trader, kol); SELL rows carry `held_seconds` and `quick_flip: true` when sold within 15 minutes of the first buy: check it before reading that wallet's buy as conviction. `include_context=true` adds a per-row `context`: pnl_pct_vs_entry (trade price vs the wallet's average entry, a fraction), tags, hold_days_at_trade, share_sold_of_position, position_before_usd, entry_vwap_before, days_since_prev_trade / prev_trade_at and the wallet's 30-day wallet_win_rate / wallet_realized_pnl_30d_usd. Unknown values are null: pnl_pct_vs_entry is null when the wallet's entry was never seen.
- `get_whalewatch_home_feed`: The latest headline whale buy on Solana ($10k or more), as the Moby app's home screen shows it. For anything filtered (one token, one wallet, lists, a time window, more rows) use `get_whalewatch_feed`; for market-wide flow use `get_smart_money_pulse`.
- `get_whalewatch_kol_feed`: What crypto influencers (KOLs) are buying and selling on Solana. Same rows as `get_whalewatch_feed`, pre-filtered to KOLs server-side (no `list_ids`). For one KOL's trades use `get_whalewatch_feed` with its `wallet_address`. `include_context=true` adds a per-row `context`: pnl_pct_vs_entry (trade price vs the wallet's average entry, a fraction), tags, hold_days_at_trade, share_sold_of_position, position_before_usd, entry_vwap_before, days_since_prev_trade / prev_trade_at and the wallet's 30-day wallet_win_rate / wallet_realized_pnl_30d_usd. Unknown values are null: pnl_pct_vs_entry is null when the wallet's entry was never seen. Wallet quality: use get_whale_wallet_track_record(wallet_address) for a wallet's win rate and PnL.
- `get_whalewatch_legend`: Static legend for badges on whale feed rows. Static reference data: call it once to explain a marker on a feed row, never poll it. It has no market data and no wallets.
- `get_whalewatch_lists`: Tracked whale, KOL and trader lists and their list_ids, for filtering whale feeds. Pass `list_ids` to `get_whalewatch_feed`. Not the browse-and-follow lists (`get_whalewatch_wallet_lists`).
- `get_whalewatch_wallet_list_detail`: Ranked wallets in one curated list (slug from the browse lists tool). Pre-ranked. `slug` MUST come from `get_whalewatch_wallet_lists`: an invented or stale slug is a 404, not an empty list.
- `get_whalewatch_wallet_lists`: Curated wallet lists to browse for copy trading, with their slugs. The Find-wallets tab: a 'picks' strip, then one summary per curated list (whale groups, KOL groups, proven traders). Pass a `slug` to `get_whalewatch_wallet_list_detail`. Not `get_whalewatch_lists`, which is for filtering `get_whalewatch_feed`.
- `list_strategies`: Moby's ready-made strategies (Large Cap Allocator, Smart Money Confirmed, others) with risk labels. From the Strategies section of AI Trading in the Moby app: each card's `id`, `name`, `summary`, `how_it_works`, `chips` (the editable defaults), `risk_label`, `warning` and the Moby `tools` it uses, with the user's max per trade filled in. Use it during or after onboarding to recommend a card, and whenever the user asks what strategies there are. To match a card to the user, offer the one or two ids in `recommended_strategies` from `get_my_trading_profile` / `save_trading_profile` (majors or stocks → Large Cap Allocator, BTC <> ZEC Barbell; launches or memes → StonkFun Trend Rider, StonkFun Whale Swarm, Early Launch Hunter; mix → Smart Money Confirmed). Read each card's `summary`, `how_it_works` and `risk_label` before you recommend it, and only recommend cards this tool returned. The full prompt is NOT here: call `get_strategy(strategy_id)` for it. `app_links` are Moby app deep links to hand to the user; they open the Moby app on their phone.
- `quick_buy`: Buy a Solana token or tokenized stock with USDC in one step. Real money. Confirm token and amount first. Checked server-side against max per trade, daily buy volume and market-cap range. ⚠️ SPENDS REAL MONEY from the user's agent wallet; cannot be undone. Get an explicit yes on the exact amount and token BEFORE calling. No quote step, so the user sees no price first: prefer `get_swap_quote` + `execute_swap` when they may want it. Exactly one of `amount_usd` or `amount_in`. Red safety tier buys are refused. The result has `quote_id`; when `fill_pending`, call `get_swap_status(quote_id=...)`. AMOUNTS: quote the `_ui` fields (whole tokens); un-suffixed amounts are the smallest unit. Null = unknown, never zero; `fill_pending: true` = fill not booked yet (`get_swap_status`). `fee_usd` / `fee_pct_of_trade` = Moby's fee. Moby attaches no exits: place this position's TP/SL yourself with `create_order`.
- `quick_sell`: Sell all or part of a held token to USDC at market. Real money. Full sells also cancel that token's open exits. Quote + execute in one call (no expired quotes): THE tool to close or trim. ⚠️ SPENDS REAL MONEY from the user's agent wallet; cannot be undone. Get an explicit yes on the exact amount and token BEFORE calling. `pct` = percent of the CURRENT on-chain balance (default 100 = all); proceeds land in USDC in the same wallet. Result: `sold_amount`, `transaction_signature`, `quote_id`; if `fill_pending`, call `get_swap_status(quote_id=...)`. AMOUNTS: quote the `_ui` fields (whole tokens); un-suffixed amounts are the smallest unit. Null = unknown, never zero; `fill_pending: true` = fill not booked yet (`get_swap_status`). `fee_usd` / `fee_pct_of_trade` = Moby's fee. A full sell cancels all lots' resting TP/SL (`cancelled_order_ids`; `cancel_failed_order_ids` / `cancel_pending_order_ids` + `cancel_note` are retried). Never blocked by market cap, safety tier or trade limits; the `market` switch applies.
- `save_active_strategy`: Record a strategy start, pause, resume, stop or run heartbeat. Moves no money. So other sessions and clients see what you run:
- START: omit `active_strategy_id`; pass `strategy_id` for a starter card (its name is used if you omit `name`) or `name` for a custom one, plus `settings` (the numbers the user confirmed: amounts, mix, exits, the ask-first flag) and `schedule` in plain words ('every 4 hours').
- PAUSE / RESUME / STOP: pass `active_strategy_id` and `status` paused / active / stopped.
- EDIT: pass `active_strategy_id` and only the fields that changed (an empty value clears `settings`, `schedule` or `notes`).
- HEARTBEAT: after each run, pass `active_strategy_id` and `last_run_at` (now, ISO 8601).
At most 20 active or paused per user; stop one to start another. This moves no money and changes no guardrail.
- `save_trading_profile`: Save onboarding answers or a skip. Changes no limit and moves no money. Call after the TWO-line playback and the user's yes, or with `skipped: true` when they decline. Pass `profile` OR `skipped`, not both.
- `replace: false` (default) MERGES: for 'update my trading profile' send only the changed fields. `replace: true` overwrites the whole profile.
- Amounts are USD.
- The result's `recommended_strategies` and `strategies_followup` drive the closing step: follow `strategies_followup` once, do not read it out.
- The scan schedule has no field here. The scan schedule is kept on the agent's side, never saved to Moby: keep it in your own memory or as a recurring task in your own app, and recreate it at the start of each session.
Changes NO guardrail and moves no money.
- `scan_tokens`: THE first call of a scheduled scan: Moby applies a strategy's thresholds server-side and returns only the Solana tokens that pass, already deduplicated for this user. Empty `qualifiers` = end the run silently. Pass the previous run's `next_since` back as `since`: tokens returned to you for the same rules in the last <window> (the preset's scan interval, 5-15 min) are dropped. Deep-check ONLY the qualifiers, with `get_token_trade_brief` and `get_whale_wallet_profiles`; `agent_checks` is what the scan did NOT check, so apply it yourself. `rejected` counts why candidates failed; null fields are left out. At most 12 candidates are enriched per scan (wallets desc, liquidity desc, market cap desc, smart-money h1 desc, address asc); the rest come back as `not_enriched` in that order, first = next in line. An override replaces that one rule of the preset. `safety_tier`: grey is NOT a red flag; red = caution, and Moby refuses agent buys on red.
- `search_tokens`: Find a Solana token's mint address by name, ticker, symbol or pasted contract address (CA). Use first whenever the user names a token. For majors and tokenized stocks (NVDAx, SPYx, GLDx) take the address from the Majors / Stocks boards instead. Never guess an address. Every other token tool needs the address, and impostor tokens share popular symbols: buying the wrong one is unrecoverable. If several results look plausible, show them and ask which one. `safety_tier`: grey is NOT a red flag; red = caution, and Moby refuses agent buys on red.
- `search_whalewatch_wallets`: Find a public whale or KOL wallet by name or list brand. By KOL name or whale-list brand, NOT by pasted address, and not a token search (`search_tokens`). `discover_wallets_to_follow` also says which results the user already follows.
- `submit_feedback`: Log a bug, wrong data or feature idea for the Moby team. Once per issue; tell the user it was logged, with its id. Not for payments, lost funds or account problems: send those to support in the Moby app.
`kind`: bug (something broke), data_issue (a Moby number looks wrong; `tool_name` is required, and `expected` / `actual` help), idea (a missing tool or 'they should add X'). `title` is one line (max 160 chars); `details` is what happened (max 2000 chars). The same title within 24 hours returns the earlier submission with `duplicate: true` instead of a new one. At most 10 a day. Moves no money.
- `unfollow_wallet`: Stop following a wallet. Moves no money. Idempotent: a no-op if the user does not follow it. Also clears that wallet from `get_my_following_feed` at once.
