# Crank Protocol (remote · mcp.crank.ing)

Non-custodial DeFi tools for AI agents on Solana: swaps, perps, lending, staking, equities.

- Trust score: 62/100 (medium)
- Change this week: +4
- Registry status: active
- Liveness: live
- Owner verified: no
- Last scored: 2026-08-03

## Components

- remote · `mcp.crank.ing`: 62/100 (this document), [markdown](https://verifymcp.io/servers/ing-crank-crank/mcp.md), [page](https://verifymcp.io/servers/ing-crank-crank/mcp)

## Channel facts

- Endpoint: `https://mcp.crank.ing/mcp`
- Transports: `streamable-http`
- Auth: `none`
- Version: `1.0.0`

## Trust breakdown

How this component scores in each security and reliability category. Every signal is checked automatically against the live server, and we only credit what we can confirm. Scores are 0–100 per category. Scoring method: https://verifymcp.io/docs/scoring (what has changed: https://verifymcp.io/docs/scoring/changelog)

Scored 2026-08-03.

- **Endpoint Security**: 63/100
  - The endpoint's TLS certificate is valid, in date, and uses a strong key.
  - Authorisation check failed: no authorisation is required to call this server, and it exposes a tool marked destructive (jupiter_swap).
  - HTTPS is enforced; there's no plaintext access path.
  - The HSTS (Strict-Transport-Security) header is present.
  - DNSSEC check failed: this domain isn't protected by DNSSEC.
- **Transport & Reachability**: 100/100
  - Verified streamable-http transport via a live MCP handshake.
- **Schema Quality & AI Usability**: 56/100
  - 100% of prompts and resources have a non-trivial description (not blank, and not just the item's name).
  - AI-judged instruction clarity (poor).
  - Context-footprint check failed: tool/resource definitions use about 28037 tokens (~167/item across 167 items; 167 tools + 0 resources), over budget; trim descriptions and params.
  - Usage-examples check failed: none of the tools include examples.
- **Stability & Change Management**: 23/100
  - Stability observed for 7 of 30 days with no destabilising changes; credit accrues until the full window elapses.
- **Tool Coverage**: 71/100
  - 100% of tools have a non-trivial description (not blank, and not just the tool's name).
  - 0% of tool parameters carry a description.
  - Structured output schemas are declared (100% of tools); any adoption earns full credit.
- **Capabilities**: 100/100
  - Implements a supported MCP spec version (2025-11-25); the latest is 2026-07-28.

## Install

### Claude

```bash
claude mcp add --transport http ing-crank-crank https://mcp.crank.ing/mcp
```

### Codex

```toml
[mcp_servers.ing-crank-crank]
url = "https://mcp.crank.ing/mcp"
```

### opencode

```json
{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "ing-crank-crank": {
      "type": "remote",
      "url": "https://mcp.crank.ing/mcp",
      "enabled": true
    }
  }
}
```

### OpenClaw

```bash
openclaw mcp add ing-crank-crank --url https://mcp.crank.ing/mcp --transport streamable-http
```

### Hermes

```yaml
mcp_servers:
  ing-crank-crank:
    url: "https://mcp.crank.ing/mcp"
```

### Other

```json
{
  "mcpServers": {
    "ing-crank-crank": {
      "type": "http",
      "url": "https://mcp.crank.ing/mcp"
    }
  }
}
```

The mcpServers block is a cross-client convention. Remote transports vary, so check your client's docs.

## Changelog

Every change recorded for this component, newest first. Days that predate change tracking, or that we cannot explain, say so: "we were watching and nothing happened" and "we were not watching" are different claims.

### 2026-08-02 (score 62, +1)

No change was recorded against any check on this day. Stability & Change Management went from 17 to 20. That category is still filling its 30-day observation window: 5 days of observed history at the previous scan, 6 at this one. The score rises as the window fills, whether or not the server changes.

### 2026-08-01 (score 61, +3)

- [functional] We updated how we score, so this day's move reflects our rubric, not a change to the server

### 2026-07-31 (score 58, +1)

- [functional] We updated how we score, so this day's move reflects our rubric, not a change to the server

### 2026-07-29 (score 57, +1)

- [security] Tool “jupiter_swap” rewrote its description, which is the text the model reads
- [functional] Server version: 3.4.4 → 3.4.5
- [functional] New tool “list_webhooks”
- [functional] New tool “delete_webhook”
- [functional] New tool “register_webhook”
- [functional] New tool “strategy_modify”
- [functional] New tool “verify_transaction”
- [cosmetic] “jupiter_swap” added an optional parameter “verify”

### 2026-07-28 (score 56, −2)

- [functional improvement] Stability: unverified → 0.03
- [functional] Schema quality: fair → poor
- [functional] New tool “set_ooda_consent”
- [functional] New tool “get_ooda_status”

### 2026-07-27 (score 58)

First indexed and scored.

## MCP tools (167)

### `jupiter_swap` (~639 tokens)

Execute a token swap via Jupiter (non-custodial).

Without signed_transaction: returns an UNSIGNED base64 transaction for your
wallet to sign + broadcast. With signed_transaction: broadcasts the
caller-signed tx and returns tx_signature. amount is in base units of
input_token. Includes the Crank 0.75% technology service fee when a
referral fee account is configured -- collected ON-CHAIN via Jupiter's
platformFeeBps (MB#13601), deducted from swap output. Swaps are NOT
additionally gated by x402 (ENG-1521ec28: that would double-charge the same
fee); payment_header/pay_in_crank are accepted for API symmetry with other
tools but are no-ops here since jupiter_swap is not in x402 PAID_TOOLS.

SECURITY: the output_token is run through multi-layer authenticity
verification before any tx is built; an unverified/suspicious/fake token is
blocked (UNVERIFIED_TOKEN). Set allow_unverified=true to trade an unverified
token at your own risk (hard scam signals are never overridable).

\``venue_hint`` (ENG-fc290438/ENG-00ebde90, MB#18215) is ADVISORY, never
required -- spot routes via Jupiter aggregation (the only spot venue
today); an unknown hint raises, omitting it is unchanged from before.

Workflow: EXECUTE step -- deploy the directional/allocation leg after the risk
phase capped the size. Non-custodial. Get a price first with get_quotes.
See get_trading_workflow.

\``idempotency_key`` (ENG-7ded4fb8, optional): a client-generated UUID.
Retrying the SAME call (build or broadcast) with the same key + same args
replays the original result instead of re-executing -- guards against a
timeout-then-retry double-swap. Reuse the SAME key across the build call
and its signed_transaction broadcast retry (they dedupe independently);
a NEW key means a genuinely new swap.

\``verify`` (ENG-df8afe93, default True): when broadcasting
(signed_transaction supplied), await on-chain confirmation and re-read
the output_token balance -- the response gains a ``verification`` block
({confirmed, slot, pos…

Input parameters:

- `allow_unverified` (boolean)
- `amount` (integer, required)
- `caller_id` (string)
- `idempotency_key` (string)
- `input_token` (string, required)
- `output_token` (string, required)
- `pay_in_crank` (boolean)
- `payment_header` (string)
- `signed_transaction`
- `slippage_bps` (integer)
- `venue_hint`
- `verify` (boolean)
- `wallet_address` (string, required)

### `verify_transaction` (~333 tokens)

Verify any prior transaction signature on demand (FREE read).

Post-trade verification (ENG-df8afe93, harness spec MB#18289 R13): awaits
on-chain confirmation of ``tx_signature`` at ``commitment`` level (up to
\``timeout_s``) and, when a state hint is supplied, re-reads the relevant
state to compare against what was expected:

  \- ``mint`` (+ ``wallet_address``): re-reads that SPL/SOL token balance.
  \- ``market`` (+ ``wallet_address``): re-reads the Drift perp position.
  \- ``protocol`` (+ ``wallet_address``, optional ``market`` /
    ``marginfi_account``): re-reads the lending obligation health.

Returns ``{confirmed, slot, commitment, post_state, expected_vs_actual,
retry_guidance}``. ``confirmed`` is False (never True) on a timeout --
NEVER treat an unconfirmed/timed-out result as success; ``retry_guidance``
names the next step. Use this after signing + broadcasting a transaction
yourself (place_perp_order, lend_deposit/borrow/repay, and every other
unsigned-tx tool never broadcast server-side) to confirm it actually
landed before treating the position/balance as changed.

Input parameters:

- `caller_id` (string)
- `commitment` (string)
- `marginfi_account`
- `market`
- `mint`
- `protocol`
- `timeout_s` (number)
- `tx_signature` (string, required)
- `wallet_address` (string)

### `get_quotes` (~124 tokens)

Read-only Jupiter quote for a token pair (no execution).

amount is in base units of input_token. Returns routes, price impact, fees,
and estimated output. ``venue_hint`` (ENG-fc290438/ENG-00ebde90, MB#18215)
is ADVISORY, never required -- see jupiter_swap.

Input parameters:

- `amount` (integer, required)
- `caller_id` (string)
- `input_token` (string, required)
- `output_token` (string, required)
- `slippage_bps` (integer)
- `venue_hint`

### `get_balances` (~59 tokens)

Wallet token balances (SOL + all SPL tokens) with USD valuations.

Workflow: ORIENT step -- the starting read for any flow. See get_trading_workflow.

Input parameters:

- `caller_id` (string)
- `wallet_address` (string, required)

### `portfolio_snapshot` (~84 tokens)

Full portfolio summary: positions, total value, allocation %, 24h change.

Persisted as a PortfolioSnapshot for historical tracking.

Workflow: ORIENT step -- the denominator for position sizing. Call before
intelligence/risk so sizes are net of current holdings. See get_trading_workflow.

Input parameters:

- `caller_id` (string)
- `wallet_address` (string, required)

### `set_alert` (~132 tokens)

Create a price/position alert checked every 60s by Celery beat.

alert_type: price_above | price_below | position_change. token is a mint
address. Optional webhook_url is POSTed when the alert fires.

Workflow: MONITOR step -- arm after executing so a tripped level loops you back
to the risk/execute phase. See get_trading_workflow.

Input parameters:

- `alert_type` (string, required)
- `caller_id` (string)
- `threshold` (number, required)
- `token` (string, required)
- `wallet_address` (string, required)
- `webhook_url`

### `set_ooda_consent` (~184 tokens)

Opt in/out of the wake-on-condition worker (ENG-8c57afc3).

Default OFF. When opted in, a triggered alert may run a metered
background check (Haiku triage, escalating to Sonnet only if worth a
closer look) and propose one action. daily_wake_budget (default 10, 1-500)
hard-caps metered wakes per day. The worker never executes -- every
proposal is approved in your own wallet. See get_ooda_status for wake
history including skipped wakes.

Workflow: consent step -- run once (or to change budget) before wakes can
fire; check get_ooda_status afterward to confirm state.

Input parameters:

- `caller_id` (string)
- `daily_wake_budget`
- `opted_in` (boolean, required)
- `wallet_address` (string, required)

### `get_ooda_status` (~136 tokens)

Wake-on-condition consent + usage status (ENG-8c57afc3).

Returns opted_in, daily_wake_budget, wakes_used_today, skips_today, and
recent_wakes -- including SKIPPED_BUDGET / SKIPPED_SPEND_CAP rows, so a
skipped wake is exactly as visible as a completed one, never silent.

Workflow: status/observe step -- check this to see whether the background
worker is watching, and what it did (or skipped) recently.

Input parameters:

- `caller_id` (string)
- `recent_limit` (integer)
- `wallet_address` (string, required)

### `token_info` (~65 tokens)

Token metadata, price, liquidity, volume, holder count.

Provide token_address (mint) or a known symbol. Merges Helius (metadata)
with Birdeye (market data).

Input parameters:

- `caller_id` (string)
- `symbol`
- `token_address`

### `verify_token` (~136 tokens)

Multi-layer authenticity check for a token mint (read-only, no execution).

Runs the same five-layer verification the swap/trade tools enforce before
building a transaction: registry allow-list, Jupiter verified list, Metaplex
metadata authority, minimum liquidity, and token age + holder count. Returns
verification_status (verified | unverified | suspicious | blocked), the
reasons, non-blocking warnings, and the per-layer findings. Call this before
swapping into an unfamiliar token (ENG-a39caa6d).

Input parameters:

- `caller_id` (string)
- `symbol`
- `token_address` (string, required)

### `get_transaction_history` (~49 tokens)

Recent transactions for a wallet, parsed + human-readable (limit 1-100).

Input parameters:

- `caller_id` (string)
- `limit` (integer)
- `wallet_address` (string, required)

### `backtest_strategy` (~449 tokens)

Backtest a strategy on historical Solana OHLCV before deploying capital.

strategy_type is one of the 17 Crank strategy types (dca, momentum,
rebalance, stoploss, protect, snipe, sentiment, vault, yield_farm, hedge,
equity_dca, perp_grid, copy_wallet, market_make, arb, basis_trade,
composite). asset is a token mint; timeframe one of 1m/5m/15m/1h/4h/1d;
start_date/end_date are ISO-8601. params tunes the strategy (e.g.
{"fast":5,"slow":20} for momentum). For strategy_type="composite" pass the
signal-rule ``definition`` (see compose_strategy); the response includes a
per-stream signal_coverage honesty report -- streams with partial persisted
history are flagged, never silently zero-filled.
slippage_model: "fixed" (slippage_bps haircut) or "jupiter_replay" (realised
price-impact from the recorded quote corpus). Returns performance metrics
(Sharpe/Sortino/Calmar, max drawdown, win rate, profit factor, VaR/CVaR),
final equity, and trade + signal counts. Read-only simulation -- no fee, no
on-chain action.

Workflow: SIMULATE step -- validate a strategy on history before risking
capital; run twice (e.g. auto vs long_only) to compare. Poor Sharpe/deep
drawdown -> retune or fall back to the yield leg. Feeds get_risk_assessment ->
the strategy_*_create tools. See get_trading_workflow.

Input parameters:

- `asset` (string, required)
- `caller_id` (string)
- `definition`
- `end_date` (string, required)
- `fee_bps` (integer)
- `initial_capital` (number)
- `params`
- `slippage_bps` (integer)
- `slippage_model` (string)
- `start_date` (string, required)
- `strategy_type` (string, required)
- `timeframe` (string, required)
- `wallet_address` (string)

### `get_ml_signal` (~290 tokens)

ML ensemble directional forecast for a Solana asset (read-only).

Trains the ported Bybit ensemble (XGBoost + RandomForest + NeuralNet +
GradientBoost + a candle flow proxy) walk-forward on the last
lookback_candles of OHLCV, then returns the blended P(up move) for the latest
candle: score in [0,1], confidence (distance from 0.5), direction
(long/short/neutral via buy_threshold/sell_threshold), per-model
contributions and top feature importances. asset is a token mint; timeframe
one of 1m/5m/15m/1h/4h/1d; horizon is the forward-return label horizon in
candles. On spot, 'short' = exit-to-flat (no native short). Heuristic
forecast from price history only -- not financial advice. No wallet, no fee,
no on-chain action.

Workflow: INTELLIGENCE step -- a directional forecast that complements
detect_regime; low confidence -> cut size or stay flat. See get_trading_workflow.

Input parameters:

- `asset` (string, required)
- `buy_threshold` (number)
- `caller_id` (string)
- `horizon` (integer)
- `lookback_candles` (integer)
- `sell_threshold` (number)
- `timeframe` (string)

### `detect_regime` (~249 tokens)

Detect the current market regime for a Solana asset (read-only, advisory).

Classifies the latest candle of recent OHLCV as bull / bear / range /
volatile and returns a RegimeSignal: regime, confidence, trend_strength,
volatility_percentile, a SUGGESTED direction (long/short/neutral) and
position-size fraction (0-1), plus the raw ADX / +DI / -DI / SMA-slope /
volume readings for transparency. asset is a token mint; timeframe one of
1m/5m/15m/1h/4h/1d. A description + suggestion only -- not financial advice,
not a trade instruction (DYOR). No wallet, no fee, no on-chain action.

Workflow: INTELLIGENCE step -- pair with get_market_briefing (macro) +
get_ml_signal (forecast); feeds strategy choice + direction_mode at backtest +
create time. bear + allow_short -> consider a short. See get_trading_workflow.

Input parameters:

- `asset` (string, required)
- `caller_id` (string)
- `lookback_candles` (integer)
- `timeframe` (string)

### `get_risk_assessment` (~282 tokens)

Combined regime + risk recommendation for a strategy on an asset (read-only).

Folds the detected market regime together with the safe-default risk guards
(position / exposure / single-loss / drawdown / daily-loss limits) into one
advisory assessment: a suggested direction, a conviction-weighted position
size already capped to the position guard (in both percent-of-equity and USD
notional against ``equity``), a per-regime action note, and the full guard
set. strategy_type is one of the 16 Crank strategy types; asset is a token
mint; timeframe one of 1m/5m/15m/1h/4h/1d. Advisory only (DYOR) -- not
financial advice, not a managed-account recommendation. No wallet, no fee.

Workflow: RISK step -- after backtest_strategy, before execution. The returned
suggested_size_usd caps the order in the execute phase; do NOT exceed it. Check
asset_classification first (equity -> per-execution confirm). See get_trading_workflow.

Input parameters:

- `asset` (string, required)
- `caller_id` (string)
- `equity` (number)
- `lookback_candles` (integer)
- `strategy_type` (string, required)
- `timeframe` (string)

### `get_indicators` (~329 tokens)

Full standard technical-indicator set for one asset/timeframe (read-only).

Computes sma, ema, macd, adx (+DI/-DI), rsi, stochastic (%K/%D), roc,
bollinger (mid/upper/lower/width/%B), atr, keltner, realised_vol, vwap,
volume_ratio and volume_profile (POC / value area / high-volume-node
liquidity bands with 0-1 depth scores) from recent OHLCV via the canonical
backend/indicators library. asset is a token mint; timeframe one of
1m/5m/15m/1h/4h/1d; indicators selects a subset (empty = all); lookback
candles capped at 500; params overrides per indicator, e.g.
{"rsi": {"period": 21}}; include_series=true adds per-bar series (last 200
points). Readings are None while history is warming up. Computed readings
only -- not financial advice, not a trade instruction (DYOR). No wallet,
no fee, no on-chain action.

Workflow: INTELLIGENCE step -- raw indicator readings underlying
detect_regime; pair with get_ml_signal (forecast) + get_signals (persisted
cross-source signals). See get_trading_workflow.

Input parameters:

- `asset` (string, required)
- `caller_id` (string)
- `include_series` (boolean)
- `indicators`
- `lookback` (integer)
- `params`
- `timeframe` (string)

### `sr_detect_levels` (~327 tokens)

Multi-timeframe support/resistance zones + liquidity bands (read-only).

Detects S/R zones per timeframe from recent OHLCV (swing highs/lows, floor
pivots, Fibonacci retracement, volume-profile clusters, optional manual
levels), merges them across timeframes with a confluence multiplier, and
weights zone strength by overlapping candle-volume liquidity-band depth.
asset is a token mint; timeframes default ["1h","4h","1d"]; lookback
candles per timeframe (capped at 500); sources subset of swing / pivot /
fibonacci / volume_profile / price_impact / manual; sensitivity 0-1 (higher
\= more zones); zone_width_bps sets the band half-width; manual_levels adds
caller-supplied override prices. Returns zones (supports / resistances /
pivots with price, band, strength, touches, sources, timeframes) plus
liquidity_bands. Computed reference levels only -- not financial advice,
not a trade instruction (DYOR). No wallet, no fee, no on-chain action.

Workflow: INTELLIGENCE step -- the level picture behind sr_backtest +
sr_configure_strategy; pair with get_indicators + detect_regime. See
get_trading_workflow.

Input parameters:

- `asset` (string, required)
- `caller_id` (string)
- `lookback` (integer)
- `manual_levels`
- `sensitivity` (number)
- `sources`
- `timeframes`
- `zone_width_bps` (integer)

### `sr_configure_strategy` (~219 tokens)

Attach an S/R config block to YOUR OWN strategy (ownership-checked).

Persists an `sr` param block (SRConfig knobs: sensitivity, sources,
lookback, swing_window, zone_width_bps, merge_tolerance_bps, min_touches,
min_strength, max_zones_per_side, manual_levels, liquidity_weight_k) onto
the caller's own strategy params. The strategy must belong to
wallet_address -- configuring someone else's strategy is refused.
Strategies without an `sr` block behave exactly as before (back-compat).
User/agent-owned configuration only: you own and control the strategy; the
platform never exercises discretion (DYOR). No key handling, no fee.

Workflow: DECIDE step -- after sr_detect_levels + sr_backtest confirm the
level picture, store the tuned config on the strategy. See
get_trading_workflow.

Input parameters:

- `caller_id` (string)
- `sr_config` (object, required)
- `strategy_id` (integer, required)
- `wallet_address` (string, required)

### `sr_backtest` (~298 tokens)

Backtest a strategy with an S/R config block (read-only simulation).

Runs the existing backtest engine with strategy_type (default
"support_resistance": bounce-long off detected support, exit on a support
break or resistance-fail; on spot a SHORT signal is exit-to-flat) and
merges the validated sr_config into params["sr"]. asset is a token mint;
timeframe one of 1m/5m/15m/1h/4h/1d; start_date/end_date ISO-8601. Returns
the standard performance metrics plus persisted SUPPORT_RESISTANCE signals
carrying zone metadata. Read-only simulation -- no fee, no on-chain action,
not financial advice (DYOR).

Workflow: SIMULATE step -- validate an S/R setup on history before risking
capital; feeds get_risk_assessment -> sr_configure_strategy. See
get_trading_workflow.

Input parameters:

- `asset` (string, required)
- `caller_id` (string)
- `end_date` (string, required)
- `fee_bps` (integer)
- `initial_capital` (number)
- `params`
- `slippage_bps` (integer)
- `slippage_model` (string)
- `sr_config`
- `start_date` (string, required)
- `strategy_type` (string)
- `timeframe` (string, required)
- `wallet_address` (string)

### `asset_classification` (~162 tokens)

Classify a token: crypto / equity / wrapped_major / lst / stablecoin.

Provide token_address (mint) or a known symbol. Tokenized securities
(xStocks, Ondo) classify as 'equity', which subjects strategies to the SEC
framework guardrails (neutral tools, per-execution confirmation for
discretionary types). Registry-authoritative with a static + symbol
fallback. Factual classification only -- not a recommendation.

Workflow: RISK/COMPLIANCE step -- classify before executing; 'equity' forces
geo-gating + per-execution confirm. Pairs with get_disclaimers. See
get_trading_workflow.

Input parameters:

- `caller_id` (string)
- `symbol`
- `token_address`

### `get_disclaimers` (~98 tokens)

Compliance disclaimers for an asset class (SEC framework).

Pass asset_classification (crypto/equity/wrapped_major/lst/stablecoin), or a
token_address/symbol to classify first. Equity adds a securities-specific
non-registration / not-advice notice. Full text: crank.ing/disclosures.

Input parameters:

- `asset_classification`
- `caller_id` (string)
- `symbol`
- `token_address`

### `perp_open_long` (~248 tokens)

Open a leveraged LONG perp position on Drift (non-custodial).

Returns an UNSIGNED base64 transaction for your wallet to sign + broadcast,
plus entry/liquidation/margin estimates. market e.g. SOL-PERP. size_usd is
notional USD; leverage up to the market max. TP/SL are advisory in the
build — place them as trigger orders after the position opens. The fee is
charged on size_usd notional past the daily free tier (x402 payment_header).

\``idempotency_key`` (ENG-7ded4fb8, optional): a client-generated UUID.
Retrying with the same key + same args replays the original result instead
of re-opening the position.

Input parameters:

- `allow_unverified` (boolean)
- `caller_id` (string)
- `idempotency_key` (string)
- `leverage` (number, required)
- `market` (string, required)
- `pay_in_crank` (boolean)
- `payment_header` (string)
- `size_usd` (number, required)
- `stop_loss_price`
- `take_profit_price`
- `wallet_address` (string, required)

### `perp_open_short` (~147 tokens)

Open a leveraged SHORT perp position on Drift (non-custodial).

Same envelope as perp_open_long, opposite direction. ``idempotency_key``
(ENG-7ded4fb8, optional): see perp_open_long.

Input parameters:

- `allow_unverified` (boolean)
- `caller_id` (string)
- `idempotency_key` (string)
- `leverage` (number, required)
- `market` (string, required)
- `pay_in_crank` (boolean)
- `payment_header` (string)
- `size_usd` (number, required)
- `stop_loss_price`
- `take_profit_price`
- `wallet_address` (string, required)

### `perp_close` (~181 tokens)

Close a perp position, full or partial (non-custodial).

close_pct in (0, 100]. Returns an UNSIGNED base64 tx to sign + broadcast,
plus exit price + realized P&L estimate (incl funding). Past the daily free
tier an x402 payment_header is required.

\``idempotency_key`` (ENG-7ded4fb8, optional): a client-generated UUID.
Retrying with the same key + same args replays the original result instead
of re-closing the position.

Input parameters:

- `caller_id` (string)
- `close_pct` (number)
- `idempotency_key` (string)
- `market` (string, required)
- `pay_in_crank` (boolean)
- `payment_header` (string)
- `position_id`
- `wallet_address` (string, required)

### `perp_modify` (~203 tokens)

Modify an existing open Drift ORDER by order_id (non-custodial).

Adjusts trigger price (TP/SL). new_leverage / add_collateral require a
separate collateral deposit/withdraw and are recorded for tracking. Returns
an UNSIGNED base64 tx to sign + broadcast. Past the daily free tier an x402
payment_header is required.

\``idempotency_key`` (ENG-ac7961aa, optional): a client-generated UUID.
Retrying with the same key + same args replays the original result instead
of re-modifying the order.

Input parameters:

- `add_collateral`
- `caller_id` (string)
- `idempotency_key` (string)
- `new_leverage`
- `new_sl`
- `new_tp`
- `order_id` (integer, required)
- `pay_in_crank` (boolean)
- `payment_header` (string)
- `wallet_address` (string, required)

### `perp_positions` (~64 tokens)

List open perp positions for a wallet with live P&L.

Each: market, side, size, entry/mark price, unrealized P&L (incl funding),
liquidation price.

Input parameters:

- `caller_id` (string)
- `wallet_address` (string, required)

### `perp_markets` (~32 tokens)

Available Drift perp markets with price, open interest, funding, max leverage.

Input parameters:

- `caller_id` (string)

### `perp_funding_rates` (~68 tokens)

Current funding for a perp market (rate, period, last funding timestamp).

market e.g. SOL-PERP. period is informational (1h/8h/24h).

Input parameters:

- `caller_id` (string)
- `market` (string, required)
- `period` (string)

### `place_perp_order` (~364 tokens)

Open a leveraged perp position on the best/selected venue (non-custodial).

side is "long" | "short". market e.g. SOL-PERP; size_usd is notional USD.
venue optional -- defaults to the configured primary (Jupiter Perps), with
health failover to the fallback for new orders. Returns an UNSIGNED tx
(Tier A) or a signing payload (Tier B) for your wallet to sign + broadcast,
plus venue_name / custody_tier / settlement_token. Tier B (venue-custodied)
venues require acknowledge_tier_b=true after reviewing custody_disclosure.
Fee charged on size_usd notional past the daily free tier (x402).

Workflow: EXECUTE step (leveraged directional leg) -- after get_venue_health /
get_venue_risk_score clear the venue and get_risk_assessment caps the size.
Monitor via perp_positions. See get_trading_workflow.

\``idempotency_key`` (ENG-7ded4fb8, optional): a client-generated UUID.
Retrying with the same key + same args replays the original result instead
of re-opening the order.

Input parameters:

- `acknowledge_tier_b` (boolean)
- `caller_id` (string)
- `idempotency_key` (string)
- `leverage` (number, required)
- `limit_price`
- `market` (string, required)
- `order_type` (string)
- `pay_in_crank` (boolean)
- `payment_header` (string)
- `side` (string, required)
- `size_usd` (number, required)
- `stop_loss_price`
- `take_profit_price`
- `venue`
- `wallet_address` (string, required)

### `close_perp_position` (~184 tokens)

Close a perp position (full/partial) on its venue (non-custodial).

position_id is venue-native (for Drift it is the market symbol). close_pct in
(0, 100]. Returns an UNSIGNED tx / signing payload to sign + broadcast.

\``idempotency_key`` (ENG-ac7961aa, optional): a client-generated UUID.
Retrying with the same key + same args replays the original result instead
of re-closing the position.

Input parameters:

- `acknowledge_tier_b` (boolean)
- `caller_id` (string)
- `close_pct` (number)
- `idempotency_key` (string)
- `pay_in_crank` (boolean)
- `payment_header` (string)
- `position_id` (string, required)
- `venue`
- `wallet_address` (string, required)

### `cancel_perp_order` (~118 tokens)

Cancel a resting perp order on its venue (non-custodial).

\``idempotency_key`` (ENG-ac7961aa, optional): a client-generated UUID.
Retrying with the same key + same args replays the original result instead
of re-cancelling the order.

Input parameters:

- `acknowledge_tier_b` (boolean)
- `caller_id` (string)
- `idempotency_key` (string)
- `order_id` (string, required)
- `venue`
- `wallet_address` (string, required)

### `perp_positions_all` (~53 tokens)

Open perp positions for a wallet. venue=None aggregates across venues.

Each position carries its venue + custody_tier.

Input parameters:

- `caller_id` (string)
- `venue`
- `wallet_address` (string, required)

### `perp_markets_all` (~37 tokens)

Perp markets across venues (venue=None aggregates all routable venues).

Input parameters:

- `caller_id` (string)
- `venue`

### `perp_funding_rates_all` (~42 tokens)

Normalized funding/borrow rates across venues (venue=None aggregates).

Input parameters:

- `caller_id` (string)
- `market`
- `venue`

### `get_venue_status` (~64 tokens)

Health + capabilities of every perps venue, plus routing config.

Reports primary/fallback venue, which venues are routable, per-venue health
(operational/degraded/down/disabled), and capability flags incl custody tier.

Input parameters:

- `caller_id` (string)

### `go_live_status` (~248 tokens)

Live go-live posture + S1-S6 runbook stage readout (ENG-88a87e5d).

The single documented gated config surface (MB#20378 D2, follow-up to
ENG-b936ca31): renders the ENTIRE go-live flip state -- cluster, RPC host
(bare hostname, never an api key or query string), paper-trading + soft-
launch guards, both technology-service-fee rails (x402 + Jupiter swap fee),
MoonPay environment, and multi-venue perps posture -- read fresh from
config on every call (an admin can flip an env var and the very next call
reflects it, no redeploy needed). ``stages`` is an ordered S1-S6 readout of
the go-live runbook derived purely from that posture, each
\``{stage, label, satisfied, blocking}`` -- the primary verification
instrument for every runbook stage (verify-runtime-behaviour-not-config).

FREE read, never gated (never in x402 PAID_TOOLS): booleans/counts/hosts
only, no secret ever leaves this tool.

Input parameters:

- `caller_id` (string)

### `lend_deposit` (~283 tokens)

Deposit assets to earn yield on Kamino or Marginfi (non-custodial).

Returns an UNSIGNED base64 tx to sign + broadcast, plus supply APY. amount
is in base units of token. protocol: kamino | marginfi. Marginfi needs
marginfi_account (create via the sidecar). Past the daily free tier an x402
payment_header is required. The deposited token is authenticity-verified
first; set allow_unverified=true to supply an unverified token at own risk.

Workflow: EXECUTE step (yield leg) -- supply idle stables/tokens after
comparing get_lending_rates; monitor with get_health_factor. See
get_trading_workflow.

\``idempotency_key`` (ENG-7ded4fb8, optional): a client-generated UUID.
Retrying with the same key + same args replays the original result instead
of re-depositing.

Input parameters:

- `allow_unverified` (boolean)
- `amount` (integer, required)
- `caller_id` (string)
- `idempotency_key` (string)
- `marginfi_account`
- `market`
- `pay_in_crank` (boolean)
- `payment_header` (string)
- `protocol` (string, required)
- `token` (string, required)
- `wallet_address` (string, required)

### `lend_borrow` (~231 tokens)

Borrow against deposited collateral (non-custodial).

Returns an UNSIGNED base64 tx + current health factor (pre-borrow estimate).
amount in base units of borrow_token. Deposit collateral first. Past the
daily free tier an x402 payment_header is required. The borrowed token is
authenticity-verified first; set allow_unverified=true to borrow an unverified
token at your own risk.

\``idempotency_key`` (ENG-7ded4fb8, optional): a client-generated UUID.
Retrying with the same key + same args replays the original result instead
of re-borrowing.

Input parameters:

- `allow_unverified` (boolean)
- `amount` (integer, required)
- `borrow_token` (string, required)
- `caller_id` (string)
- `collateral_token` (string, required)
- `idempotency_key` (string)
- `marginfi_account`
- `market`
- `pay_in_crank` (boolean)
- `payment_header` (string)
- `protocol` (string, required)
- `wallet_address` (string, required)

### `lend_repay` (~174 tokens)

Repay borrowed amount (non-custodial). Returns an UNSIGNED base64 tx +
current health factor. amount in base units of token. Past the daily free
tier an x402 payment_header is required.

\``idempotency_key`` (ENG-7ded4fb8, optional): a client-generated UUID.
Retrying with the same key + same args replays the original result instead
of re-repaying.

Input parameters:

- `amount` (integer, required)
- `caller_id` (string)
- `idempotency_key` (string)
- `marginfi_account`
- `market`
- `pay_in_crank` (boolean)
- `payment_header` (string)
- `protocol` (string, required)
- `token` (string, required)
- `wallet_address` (string, required)

### `get_lending_rates` (~96 tokens)

Compare supply/borrow rates across Kamino + Marginfi.

Each row: protocol, token mint, symbol, supply/borrow APY %, TVL USD,
utilization.

Workflow: YIELDS step -- the passive-return option for idle/low-conviction
capital (lending USDC removes price exposure). Pairs with get_lst_yields.
See get_trading_workflow.

Input parameters:

- `caller_id` (string)

### `get_health_factor` (~83 tokens)

Liquidation-risk monitor for a lending position.

Returns health_factor (>1 safe, <1 liquidatable), collateral value, debt
value, liquidation threshold. protocol: kamino | marginfi.

Input parameters:

- `caller_id` (string)
- `marginfi_account`
- `market`
- `protocol` (string, required)
- `wallet_address` (string, required)

### `set_liquidation_alert` (~183 tokens)

Arm a liquidation alert: notify when a lending obligation's health factor
falls to or below threshold.

protocol: kamino | marginfi (marginfi_account required for marginfi).
threshold is the HF level (e.g. 1.2 warns before the <1.0 liquidation
point). Evaluated every 30s by Celery beat; webhook_url is POSTed on trip.

Workflow: MONITOR step -- arm after opening a leveraged/borrow position so a
deteriorating obligation loops you back to repay/de-risk. Pairs with
get_health_factor. See get_trading_workflow.

Input parameters:

- `caller_id` (string)
- `marginfi_account`
- `market`
- `protocol` (string, required)
- `threshold` (number, required)
- `wallet_address` (string, required)
- `webhook_url`

### `flash_loan` (~228 tokens)

Marginfi flash loan for arbitrage (non-custodial, atomic).

instructions are JSON ix executed between borrow + repay legs. Returns a
single UNSIGNED base64 tx that reverts unless repaid in-transaction. The
borrowed token is authenticity-verified first; set allow_unverified=true to
borrow an unverified mint at your own risk. Past the daily free tier an x402
payment_header is required.

\``idempotency_key`` (ENG-7ded4fb8, optional): a client-generated UUID.
Retrying with the same key + same args replays the original result instead
of re-issuing the flash loan tx.

Input parameters:

- `allow_unverified` (boolean)
- `amount` (integer, required)
- `caller_id` (string)
- `idempotency_key` (string)
- `instructions` (array, required)
- `marginfi_account` (string, required)
- `pay_in_crank` (boolean)
- `payment_header` (string)
- `token` (string, required)
- `wallet_address` (string, required)

### `liquid_stake` (~246 tokens)

Stake SOL for a liquid-staking token (non-custodial).

amount in lamports. protocol: marinade | jito | blaze. Returns an UNSIGNED
base64 tx + the LST received + current APY. The technology service fee is
charged on the staked-SOL notional past the daily free tier (x402
payment_header; set pay_in_crank for the $CRANK discount).

Workflow: EXECUTE step (yield leg) -- stake the idle slice after comparing
get_lst_yields. Non-custodial. Monitor via portfolio_snapshot. See
get_trading_workflow.

\``idempotency_key`` (ENG-7ded4fb8, optional): a client-generated UUID.
Retrying with the same key + same args replays the original result instead
of re-staking.

Input parameters:

- `allow_unverified` (boolean)
- `amount` (integer, required)
- `caller_id` (string)
- `idempotency_key` (string)
- `pay_in_crank` (boolean)
- `payment_header` (string)
- `protocol` (string, required)
- `wallet_address` (string, required)

### `unstake_lst` (~195 tokens)

Unstake an LST back to SOL (non-custodial).

lst_token is a mint (mSOL/jitoSOL/bSOL); amount in base units. mSOL routes
via Marinade, others via the Sanctum router. Returns an UNSIGNED base64 tx.
The technology service fee is charged on the unstaked-LST notional past the
daily free tier (x402 payment_header).

\``idempotency_key`` (ENG-7ded4fb8, optional): a client-generated UUID.
Retrying with the same key + same args replays the original result instead
of re-unstaking.

Input parameters:

- `amount` (integer, required)
- `caller_id` (string)
- `idempotency_key` (string)
- `lst_token` (string, required)
- `pay_in_crank` (boolean)
- `payment_header` (string)
- `wallet_address` (string, required)

### `get_lst_yields` (~95 tokens)

Compare APY across LST providers (Marinade/Jito/Blaze) with MEV-boost +
validator-count descriptors.

Workflow: YIELDS step -- staking keeps SOL exposure + earns yield (vs lending,
which removes price exposure). Best APY becomes the 'park it' leg of the
allocation; execute via liquid_stake. See get_trading_workflow.

Input parameters:

- `caller_id` (string)

### `lst_swap` (~228 tokens)

Swap between two LSTs via the Sanctum router (non-custodial).

from_lst/to_lst are mints; amount in base units. Returns an UNSIGNED base64
tx + output amount. The technology service fee is charged on the input-LST
notional past the daily free tier (x402 payment_header). The acquired LST
(to_lst) is authenticity-verified first; set allow_unverified=true to swap
into an unverified LST at your own risk.

\``idempotency_key`` (ENG-7ded4fb8, optional): a client-generated UUID.
Retrying with the same key + same args replays the original result instead
of re-swapping.

Input parameters:

- `allow_unverified` (boolean)
- `amount` (integer, required)
- `caller_id` (string)
- `from_lst` (string, required)
- `idempotency_key` (string)
- `pay_in_crank` (boolean)
- `payment_header` (string)
- `to_lst` (string, required)
- `wallet_address` (string, required)

### `short_open` (~264 tokens)

Open a lending-based short: deposit collateral -> borrow token -> sell.

Returns an ORDERED STEP PLAN of UNSIGNED base64 txs to sign + broadcast in
sequence, plus entry price + health factor + a short_id for tracking. All
amounts in base units. The shorted token is authenticity-verified first; set
allow_unverified=true to short an unverified mint at your own risk. Past the
daily free tier an x402 payment_header is required.

\``idempotency_key`` (ENG-7ded4fb8, optional): a client-generated UUID.
Retrying with the same key + same args replays the original result instead
of re-opening the short.

Input parameters:

- `allow_unverified` (boolean)
- `borrow_amount` (integer, required)
- `caller_id` (string)
- `collateral_amount` (integer, required)
- `collateral_token` (string, required)
- `idempotency_key` (string)
- `marginfi_account`
- `market`
- `pay_in_crank` (boolean)
- `payment_header` (string)
- `protocol` (string)
- `slippage_bps` (integer)
- `token_to_short` (string, required)
- `wallet_address` (string, required)

### `short_close` (~178 tokens)

Close a tracked short: buy token -> repay loan -> withdraw collateral.

Returns an ORDERED STEP PLAN + exit price. short_id from short_open. Past
the daily free tier an x402 payment_header is required.

\``idempotency_key`` (ENG-7ded4fb8, optional): a client-generated UUID.
Retrying with the same key + same args replays the original result instead
of re-closing the short.

Input parameters:

- `buy_with_amount`
- `caller_id` (string)
- `idempotency_key` (string)
- `marginfi_account`
- `market`
- `pay_in_crank` (boolean)
- `payment_header` (string)
- `short_id` (integer, required)
- `slippage_bps` (integer)
- `wallet_address` (string, required)

### `short_status` (~37 tokens)

List open shorts for a wallet with entry price + health factor.

Input parameters:

- `caller_id` (string)
- `wallet_address` (string, required)

### `leverage_long` (~260 tokens)

Open a lending-based leveraged long by looping deposit -> borrow stable
\-> buy more -> redeposit.

Returns an ORDERED STEP PLAN of UNSIGNED base64 txs, effective leverage, loop
count, health factor, and a position_id. amount in base units. The levered
token is authenticity-verified first; set allow_unverified=true to lever an
unverified mint at your own risk. Past the daily free tier an x402
payment_header is required.

\``idempotency_key`` (ENG-7ded4fb8, optional): a client-generated UUID.
Retrying with the same key + same args replays the original result instead
of re-opening the leveraged position.

Input parameters:

- `allow_unverified` (boolean)
- `amount` (integer, required)
- `caller_id` (string)
- `idempotency_key` (string)
- `marginfi_account`
- `market`
- `pay_in_crank` (boolean)
- `payment_header` (string)
- `protocol` (string)
- `slippage_bps` (integer)
- `stable_token`
- `target_leverage` (number, required)
- `token` (string, required)
- `wallet_address` (string, required)

### `leverage_close` (~169 tokens)

Unwind a tracked leveraged position: sell -> repay stable -> withdraw.

Returns an ORDERED STEP PLAN. position_id from leverage_long. Past the daily
free tier an x402 payment_header is required.

\``idempotency_key`` (ENG-7ded4fb8, optional): a client-generated UUID.
Retrying with the same key + same args replays the original result instead
of re-unwinding the position.

Input parameters:

- `caller_id` (string)
- `idempotency_key` (string)
- `marginfi_account`
- `market`
- `pay_in_crank` (boolean)
- `payment_header` (string)
- `position_id` (integer, required)
- `slippage_bps` (integer)
- `wallet_address` (string, required)

### `fund_wallet` (~221 tokens)

Fund a wallet with fiat via MoonPay (card/bank/Apple Pay -> USDC).

Returns a hosted checkout_url for the user to complete payment + a
session_id to poll with get_onramp_status. Purchased USDC settles directly
to wallet_address (non-custodial). payment_method: card | bank | apple_pay.
The fee is charged on amount_usd notional past the daily free tier (x402
payment_header).

\``idempotency_key`` (ENG-7ded4fb8, optional): a client-generated UUID.
Retrying with the same key + same args replays the original result (same
checkout_url/session_id) instead of creating a second MoonPay session.

Input parameters:

- `amount_usd` (number, required)
- `caller_id` (string)
- `currency` (string)
- `idempotency_key` (string)
- `pay_in_crank` (boolean)
- `payment_header` (string)
- `payment_method` (string)
- `wallet_address` (string, required)

### `offramp_to_fiat` (~196 tokens)

Cash out crypto to fiat via MoonPay (non-custodial).

token is the crypto to sell; amount is its quantity; destination is a
MoonPay bank_account_id the fiat is paid to. Returns offramp_id,
estimated_fiat, and status. Past the daily free tier an x402 payment_header
is required.

\``idempotency_key`` (ENG-ac7961aa, optional): a client-generated UUID.
Retrying with the same key + same args replays the original result (same
offramp_id) instead of creating a second MoonPay sell order.

Input parameters:

- `amount` (number, required)
- `caller_id` (string)
- `destination` (string, required)
- `idempotency_key` (string)
- `pay_in_crank` (boolean)
- `payment_header` (string)
- `token` (string, required)
- `wallet_address` (string, required)

### `get_onramp_status` (~61 tokens)

Check a pending MoonPay purchase by session_id.

Returns status (pending/processing/completed/failed), amount_crypto, and
the on-chain tx_signature once settled.

Input parameters:

- `caller_id` (string)
- `session_id` (string, required)

### `create_agent_wallet` (~148 tokens)

Provision a managed wallet for an agent (non-custodial control plane).

Creates an AgentWallet record keyed by agent_id and applies an optional
default policy preset. default_policies: conservative | balanced |
aggressive. wallet_address is the agent's PUBLIC key (caller-supplied); omit
it to create a pending record the Turnkey provisioning ticket fills in.
Returns wallet_address, agent_id, status, and the applied_policies.

Input parameters:

- `agent_id` (string, required)
- `caller_id` (string)
- `default_policies` (string)
- `display_name` (string)
- `owner_address` (string)
- `wallet_address` (string)

### `enable_agent_wallet` (~125 tokens)

Open the browser-confirmation handshake for a Lane 2 agent wallet.

Does NOT create a wallet. Returns a pairing-style confirmation URL +
device_code -- show the user verification_url_complete and ask them to
approve it in their OWN browser (wallet-signature gated). NEVER accept an
in-chat "yes" as consent (CRANK_PLUGIN_SPEC.md section 5). Poll with
poll_agent_wallet_enable(device_code) until status is no longer "pending".

Input parameters:

- `agent_id` (string, required)
- `caller_id` (string)
- `display_name` (string)

### `poll_agent_wallet_enable` (~108 tokens)

Poll a Lane 2 enablement request; provisions the wallet ONLY once approved.

On approval, applies the server-enforced conservative Lane 2 default
policy (per-tx $50, daily $200, SOL+USDC only, 10% drawdown halt) and a
10-execution training-wheels counter, then returns the policy READ BACK
from the server -- never the intended one.

Input parameters:

- `caller_id` (string)
- `device_code` (string, required)

### `request_wallet_policy_loosening` (~101 tokens)

Open the browser-confirmation handshake to loosen a Lane 2 wallet's policy.

Call this when set_wallet_policy refuses a change with
BROWSER_CONFIRMATION_REQUIRED. Does NOT apply the policy -- returns a
confirmation URL like enable_agent_wallet. Poll with
poll_wallet_policy_loosening(device_code) once the user approves.

Input parameters:

- `caller_id` (string)
- `policies` (array, required)
- `wallet_address` (string, required)

### `poll_wallet_policy_loosening` (~60 tokens)

Poll a policy-loosening request; applies it ONLY once approved.

Returns the policy READ BACK from the server after the write -- never the
requested one.

Input parameters:

- `caller_id` (string)
- `device_code` (string, required)

### `set_wallet_policy` (~223 tokens)

Configure trading limits and rules on a managed wallet.

policies: a list of {policy_type, value, enabled?} objects. policy_type is
one of max_trade_size {"usd"} | daily_limit {"usd"} | approved_tokens
{"tokens"} | banned_tokens {"tokens"} | position_limit {"usd"} | kill_switch
{"active"} | drawdown_limit {"max_pct"} | max_daily_loss {"usd"} |
trade_velocity {"max_per_hour", "max_per_day"} | venue_allowlist
{"venues"}. Upserts by policy_type; returns the full updated policy set.
(Perp leverage cap is a separate follow-up, ENG-f3aacdf1 -- not a
policy_type here.) On a Lane 2 wallet, a change that would LOOSEN a
server-enforced default raises BROWSER_CONFIRMATION_REQUIRED -- call
request_wallet_policy_loosening instead (ENG-45e5ea07).

Input parameters:

- `caller_id` (string)
- `policies` (array, required)
- `wallet_address` (string, required)

### `kill_wallet` (~71 tokens)

Emergency freeze a managed wallet.

Sets status=killed so the policy gate refuses every subsequent value-bearing
action. Returns confirmation + a frozen-positions count. (Turnkey scoped-key
revocation is handled by the deferred provisioning ticket.)

Input parameters:

- `caller_id` (string)
- `wallet_address` (string, required)

### `wallet_status` (~39 tokens)

Current state, policy summary, recent activity, total volume, and tier.

Input parameters:

- `caller_id` (string)
- `wallet_address` (string, required)

### `set_permission_mode` (~173 tokens)

Change a managed wallet's session permission mode (non-custodial control plane).

Ports Claude Code's plan/acceptEdits/bypassPermissions ladder to a wallet
with signing power. mode: observe (deny every mutating tool outright,
PERMISSION_MODE_BLOCKED) | propose (mutating tools return a PROPOSAL
envelope -- proposal_id + params + summary -- instead of executing;
approve within the TTL via approve_proposal) | auto_within_policy (execute
immediately, still capped by every configured WalletPolicy -- the pre-R9
default). Also settable inline via set_wallet_policy's permission_mode
param. The transition is logged as an AgentTransaction audit row.

Input parameters:

- `caller_id` (string)
- `mode` (string, required)
- `wallet_address` (string, required)

### `approve_proposal` (~91 tokens)

Approve a pending PROPOSAL within its TTL (non-custodial control plane).

Flips a propose-mode proposal (see set_permission_mode) from pending to
approved, making it executable. Bookkeeping only -- it does not itself
re-dispatch the original tool call.

Input parameters:

- `approved_by` (string)
- `caller_id` (string)
- `proposal_id` (string, required)

### `authorize_session_signer` (~196 tokens)

Authorize a delegated session signer for a managed wallet (non-custodial).

signer_pubkey is a keypair the USER creates and holds -- ONLY its PUBLIC
key ever crosses this call (hard rule 1). Once authorized, calls that
carry this signer_pubkey are trade-only: the gate rejects any transfer/
withdraw/close-account/authority-change instruction targeting a
destination outside the wallet's own accounts (docs/
SESSION_SIGNER_DESIGN.md). capabilities: subset of swap|perp|lend|stake,
empty/omitted = full default set. expires_at: optional ISO 8601 hard
expiry. Effective on the very next call using this signer_pubkey.

Input parameters:

- `caller_id` (string)
- `capabilities`
- `expires_at` (string)
- `label` (string)
- `signer_pubkey` (string, required)
- `wallet_address` (string, required)

### `revoke_session_signer` (~90 tokens)

Instantly revoke a delegated session signer (non-custodial control plane).

Single atomic DB UPDATE -- the gate resolves the row fresh on every call
with no cache, so this is enforced on the very next call using
signer_pubkey. No TTL/cache window (ENG-39ec13bf).

Input parameters:

- `caller_id` (string)
- `signer_pubkey` (string, required)

### `list_session_signers` (~41 tokens)

List all delegated session signers (active + revoked) for a wallet.

Input parameters:

- `caller_id` (string)
- `wallet_address` (string, required)

### `crank_dependency_status` (~125 tokens)

Protocol dependency compatibility matrix — are we compatible right now?

Read-only. Returns per-protocol RED/AMBER/GREEN status (drift, jupiter,
kamino, marginfi, marinade, sanctum, raydium), our SDK pin vs latest, last
health-probe result, on-chain program slot, next recommended action, and any
auto-filed Engaij ticket — plus an overall headline. Maintained by the
backend dependency response engine; callable from the morning briefing,
dispatch, or ad-hoc.

Input parameters:

- `caller_id` (string)

### `crank_prompt_health` (~113 tokens)

Dev Process Health — recurring CC friction this week vs resolved.

Read-only. Returns the latest weekly close-report review snapshot
(ENG-dc453c0d): a ``Prompt health: N recurring issues, M resolved this week``
headline plus per-issue week-over-week trend (``trending_down_after_fix``)
for a dashboard widget. Surfaced in the Monday morning briefing under "Dev
Process Health". ``available=False`` until the first weekly review runs.

Input parameters:

- `caller_id` (string)

### `register_integrator` (~112 tokens)

Register an agent integrator by its payout wallet -- lands PENDING.

The Jupiter-integrator self-serve onboarding step. The profile earns NOTHING
until an admin approves it via ``set_integrator_share`` (anti-gaming
whitelist). Idempotent on ``wallet_address``. Returns the integrator stats.

Input parameters:

- `agent_id` (string)
- `caller_id` (string)
- `contact_email` (string)
- `name` (string)
- `wallet_address` (string, required)

### `register_referrer` (~80 tokens)

First-touch bind an onboarded agent wallet to an approved integrator.

First-touch wins: a wallet already attributed to any integrator keeps that
binding. Requires the integrator be approved; rejects a self-referral.

Input parameters:

- `caller_id` (string)
- `integrator_wallet_address` (string, required)
- `referred_wallet_address` (string, required)

### `set_integrator_share` (~157 tokens)

ADMIN-GATED: approve an integrator and set its fee-share (0-20%).

Validates ``share_bps`` against the per-leg ceiling (integrator_max_share_bps)
AND the combined stacking guard (referral + clone + integrator <=
max_total_share_bps, so Crank keeps >=40% of every net fee). A breach is
REJECTED, never silently clamped. Setting a share on a PENDING integrator also
approves it. Requires a valid ``admin_secret`` (CRANK_ADMIN_SECRET).

Input parameters:

- `admin_secret` (string)
- `caller_id` (string)
- `integrator_wallet_address` (string, required)
- `share_bps` (integer, required)

### `get_integrator_stats` (~78 tokens)

Integrator dashboard: status, share, onboarded count, earnings breakdown.

Read-only. Every figure is fee-share USD (technology service fees the
onboarded agents paid), never PnL -- a fee-share, never a performance-share.

Input parameters:

- `caller_id` (string)
- `integrator_wallet_address` (string, required)

### `get_integrator_earnings` (~53 tokens)

Per-action + per-month integrator earnings (onboarding API). Read-only.

Input parameters:

- `caller_id` (string)
- `integrator_wallet_address` (string, required)
- `limit` (integer)

### `list_support_tickets` (~131 tokens)

List/filter Crank support tickets (newest first). Read-only.

Filters (all optional): status (open|in_progress|waiting_on_user|resolved|
closed), priority (low|normal|high|urgent), category (billing|technical|
feature_request|general), search (matches ticket number/subject/requester
email+name/wallet). Returns {count, tickets[]}.

Input parameters:

- `caller_id` (string)
- `category` (string)
- `limit` (integer)
- `priority` (string)
- `search` (string)
- `status` (string)

### `get_support_ticket` (~59 tokens)

Full support-ticket detail with the conversation thread. Read-only.

ticket_id: numeric id or human ticket number (e.g. CRK-AB2K9P).

Input parameters:

- `caller_id` (string)
- `ticket_id` (string, required)

### `reply_to_ticket` (~114 tokens)

Reply to a support ticket — emails the requester (SendGrid) + threads it.

Records the outbound message and advances status (open/waiting ->
in_progress, or waiting_on_user when set_waiting). The message is persisted
even if email delivery fails; the returned ``email_sent`` reflects the
delivery attempt.

Input parameters:

- `caller_id` (string)
- `message` (string, required)
- `sender_name` (string)
- `set_waiting` (boolean)
- `ticket_id` (string, required)

### `note_create` (~111 tokens)

Append an internal-only note to a support ticket (ENG-69d5785b).

Agent-side context: records an internal SupportMessage (is_internal_note=True)
that is NEVER emailed to the requester, and leaves the ticket status
unchanged. ticket_id: numeric id or human ticket number (e.g. CRK-AB2K9P).

Input parameters:

- `body` (string, required)
- `caller_id` (string)
- `sender_name` (string)
- `ticket_id` (string, required)

### `set_ticket_priority` (~67 tokens)

Set a support ticket's priority (ENG-69d5785b).

priority: low|normal|high|urgent. Metadata-only -- no email, no status change.

Input parameters:

- `caller_id` (string)
- `priority` (string, required)
- `ticket_id` (string, required)

### `update_ticket_status` (~71 tokens)

Set a support ticket's status.

status: open|in_progress|waiting_on_user|resolved|closed. Stamps resolved_at
on transition into resolved/closed and clears it on reopen.

Input parameters:

- `caller_id` (string)
- `status` (string, required)
- `ticket_id` (string, required)

### `assign_ticket` (~50 tokens)

Assign a support ticket to a staff user (username or id). Empty -> unassign.

Input parameters:

- `assigned_to` (string)
- `caller_id` (string)
- `ticket_id` (string, required)

### `get_support_dashboard` (~78 tokens)

Support desk metrics: open count, avg response/resolution time, breakdowns.

Read-only. Returns totals, open/resolved/unassigned counts, resolution rate,
avg first-response + resolution seconds, by-status/category/priority maps,
and a 14-day created-ticket trend. Mirrors the backoffice dashboard.

Input parameters:

- `caller_id` (string)

### `get_venue_health` (~154 tokens)

Live safety/health read for one trading venue (read-only, non-custodial).

Returns operational status (live/degraded/suspended), last monitoring
heartbeat, on-chain program deploy slot, SDK compatibility headline, TVL +
perps 24h volume (DeFiLlama, cached 5 min). venue is a slug e.g. "drift",
"jupiter", "pacifica". Use BEFORE routing capital to a venue.

Workflow: RISK step (venue-safety gate) -- run before any perps/lending leg;
degraded/down reroutes or blocks the order. See get_trading_workflow.

Input parameters:

- `caller_id` (string)
- `venue` (string, required)

### `get_venue_risk_score` (~112 tokens)

Composite venue risk score 0-100 (higher = safer), with breakdown.

Read-only. Folds custody tier (A self-custodial / B venue-custodied),
multisig threshold, timelock, audit status, exploit history, TVL trend and
program age into a transparent weighted score (score_breakdown returned so
the number is auditable). Factual assessment, not financial advice.

Input parameters:

- `caller_id` (string)
- `venue` (string, required)

### `get_all_venues_status` (~68 tokens)

Dashboard overview of all configured venues for routing decisions.

Read-only. One health record per active venue (status, deploy slot, TVL,
24h volume, composite safety score) so an agent can pick a venue in a
single call.

Input parameters:

- `caller_id` (string)

### `venue_risk_comparison` (~87 tokens)

Side-by-side risk comparison of two venues for a routing decision.

Read-only. Returns each venue's full risk record, the safer venue, and the
composite-score delta. e.g. compare "jupiter" vs "pacifica" before routing.

Input parameters:

- `caller_id` (string)
- `venue_a` (string, required)
- `venue_b` (string, required)

### `trade_equity` (~416 tokens)

Spot-trade a tokenized equity (xStocks / Ondo) via Jupiter, non-custodial.

side: buy | sell. amount is in base units of the INPUT token (USDC 6dp for a
buy, the equity token for a sell). These are tokenized SECURITIES: the call
is geo-gated (Reg S = no US persons; declare jurisdiction once via the
jurisdiction arg) and OFAC-screened, and requires per-execution confirmation
\-- WITHOUT confirm=true it returns a quote + disclaimer and does NOT execute
(no autonomous equity execution). With confirm=true it returns an UNSIGNED
base64 tx to sign + broadcast; pass signed_transaction to broadcast a
caller-signed tx. Value-bearing: past the daily free tier an x402
payment_header is required. ip = caller origin IP for the Reg S geo gate
(US IP -> refused even with an attestation; an agent's Railway Singapore
egress resolves to SG and passes). ``venue_hint`` (ENG-fc290438/ENG-00ebde90,
MB#18215) is ADVISORY, never required -- equity routes via the issuer
registry (one surface today); an unknown hint raises.

\``idempotency_key`` (ENG-7ded4fb8, optional): see jupiter_swap -- same
replay-on-retry semantics, same key reused across build + broadcast.

Input parameters:

- `allow_unverified` (boolean)
- `amount` (integer, required)
- `caller_id` (string)
- `confirm` (boolean)
- `idempotency_key` (string)
- `ip` (string)
- `jurisdiction`
- `pay_in_crank` (boolean)
- `payment_header` (string)
- `side` (string, required)
- `signed_transaction`
- `slippage_bps` (integer)
- `symbol` (string, required)
- `venue_hint`
- `wallet_address` (string, required)

### `equity_markets` (~89 tokens)

List available tokenized equities with issuer, regime, price, market hours.

Read-only. Source: the admin-editable TokenRegistry. Each row carries issuer
(xStocks/Ondo), regulatory_framework, geo_restrictions, and best-effort
price/volume/market-cap, plus NYSE status + the 24/7-on-Solana flag.

Input parameters:

- `caller_id` (string)

### `equity_quote` (~145 tokens)

Read-only Jupiter quote for a tokenized-equity trade (no execution).

amount is in base units of the INPUT token (USDC for buy, the equity for
sell). Returns expected output, price impact, effective fee, slippage, and
the SEC disclaimer. ``venue_hint`` (ENG-fc290438/ENG-00ebde90, MB#18215) is
ADVISORY, never required -- see trade_equity.

Input parameters:

- `amount` (integer, required)
- `caller_id` (string)
- `side` (string)
- `slippage_bps` (integer)
- `symbol` (string, required)
- `venue_hint`

### `equity_positions` (~85 tokens)

Tokenized-equity holdings for a wallet with live prices + market hours.

Read-only. Filters balances to registered equity mints; each: symbol,
quantity, current_price, current_value_usd, issuer, regulatory_framework
(avg_cost / unrealized P&L null until cost-basis tracking lands).

Input parameters:

- `caller_id` (string)
- `wallet_address` (string, required)

### `equity_corporate_events` (~87 tokens)

Earnings / dividend / split calendar for a tokenized equity.

Read-only. The after-hours-agent feature: events an overnight strategy reacts
to while the underlying trades 24/7 on Solana. Provider-backed; returns an
honest empty payload + SEC EDGAR link when no feed is configured.

Input parameters:

- `caller_id` (string)
- `symbol` (string, required)

### `equity_market_hours` (~81 tokens)

NYSE session status + the 24/7-on-Solana availability flag.

Read-only. status: closed | pre_market | open | after_hours, with next
open/close. Highlights the structural advantage: tokenized equities trade
24/7 on-chain regardless of NYSE hours.

Input parameters:

- `caller_id` (string)
- `symbol`

### `get_token_classification` (~166 tokens)

Standardised tokenized-stock classification for a mint or symbol (ENG-b34b5493).

Read-only. Returns every classification dimension -- backing_status
(fully/treasury backed, synthetic, unknown), liquidity_tier (tier_1/2/3 /
illiquid, from Jupiter price impact), issuer_verified (Metaplex authority
match), market_data_quality (live/stale/none) -- plus the derived composite
risk (low/medium/high/blocked) and last_verified_at. FAIL-SAFE: a registered
but unscored token, an inactive token, or an unregistered token reports
tradeable=false. trade_equity enforces this same composite risk.

Input parameters:

- `caller_id` (string)
- `mint_or_symbol` (string, required)

### `register_agent` (~183 tokens)

Register/refresh an agent's discovery profile in the Crank registry.

capabilities is a subset of swap|perps|lending|staking|strategies|signals|
equity|onramp; supported_protocols e.g. ["mcp","a2a","x402"]. Idempotent on
wallet_address (a PUBLIC key -- non-custodial). This is how other agents find
you via the A2A Agent Card + Solana Agent Registry.

Input parameters:

- `a2a_card_url` (string)
- `caller_id` (string)
- `capabilities`
- `contact` (string)
- `description` (string)
- `display_name` (string)
- `mcp_endpoint` (string)
- `supported_protocols`
- `version` (string)
- `wallet_address` (string, required)

### `discover_agents` (~82 tokens)

Find registered agents, optionally filtered to one capability.

capability one of swap|perps|lending|staking|strategies|signals|equity|onramp
(empty = all). Ranked by reputation then recency. Read-only, free.

Input parameters:

- `caller_id` (string)
- `capability` (string)
- `limit` (integer)

### `get_agent_profile` (~41 tokens)

Read an agent's published profile + its referral stats (read-only, free).

Input parameters:

- `caller_id` (string)
- `wallet_address` (string, required)

### `update_agent_profile` (~60 tokens)

Patch an agent profile's metadata (display_name, capabilities, endpoints).

metadata is a dict of writable fields; capabilities are validated if present.

Input parameters:

- `caller_id` (string)
- `metadata` (object, required)
- `wallet_address` (string, required)

### `publish_strategy` (~170 tokens)

Publish a cloneable strategy config to the marketplace (the flywheel).

config_template is the parameter set others clone. anonymous=true omits the
author. performance_summary is a factual metrics blob -- no return promises
are stored or surfaced (hard rule 8). backtest_run_id attaches a verified
backtest (on-chain attestation hash + leaderboard ranking). Equity
(tokenized-security) strategies are excluded (MB#13761). Read/control-plane,
free.

Input parameters:

- `anonymous` (boolean)
- `author_wallet_address` (string)
- `backtest_run_id`
- `caller_id` (string)
- `config_template` (object, required)
- `description` (string)
- `name` (string, required)
- `performance_summary`
- `strategy_type` (string, required)

### `discover_strategies` (~98 tokens)

Browse published strategies (read-only, free). Crypto-only (MB#13761).

strategy_type filters to one of the 16 Crank strategy types (empty = all).
sort ranks by clones|sharpe|return|sortino|win_rate|drawdown (default clones).

Input parameters:

- `caller_id` (string)
- `limit` (integer)
- `sort` (string)
- `strategy_type` (string)

### `get_leaderboard` (~112 tokens)

Top published strategies ranked by a verified backtest metric (free).

Crypto-only -- equity templates excluded (MB#13761). sort in sharpe|return|
sortino|win_rate|drawdown|clones (default sharpe). Each entry carries factual
backtest metrics + the on-chain attestation hash; no return promises (rule 8).

Input parameters:

- `caller_id` (string)
- `limit` (integer)
- `sort` (string)
- `strategy_type` (string)

### `clone_strategy` (~93 tokens)

Clone a published strategy config to a wallet (records attribution).

Returns the config_template to deploy via the strategy create tools. The
clone is attributed to the template author for the clone-creator fee share
(15% of the tech fee on clone actions, MB#13669). Free to clone.

Input parameters:

- `caller_id` (string)
- `template_id` (integer, required)
- `wallet_address` (string, required)

### `send_token_social` (~309 tokens)

Send tokens to an X handle via a claimable crank.ing link (non-custodial).

Locks ``amount`` (base units) of ``token`` (mint) from ``sender_wallet`` into
the on-chain claim escrow against a fresh claim code, and returns an UNSIGNED
base64 transaction for the sender to sign + broadcast, plus the
crank.ing/{code} claim link and the claim_code (the bearer secret to embed in
the announcement tweet). Whoever presents the code claims the tokens and
binds ``referral`` on their first claim. ``expiry_days`` (optional, default 7,
range 1-90) sets the claim window; unclaimed tokens are returned to the sender
after expiry. Anti-abuse gated: sender account age, verified wallet,
per-sender daily limit. platform: x.

\``idempotency_key`` (ENG-7ded4fb8, optional): a client-generated UUID.
Retrying with the same key + same args replays the original result (same
claim_code/link) instead of locking a second escrow.

Input parameters:

- `allow_unverified` (boolean)
- `amount` (integer, required)
- `caller_id` (string)
- `expiry_days`
- `idempotency_key` (string)
- `platform` (string)
- `recipient_handle` (string, required)
- `referral` (string)
- `sender_wallet` (string, required)
- `token` (string, required)

### `bulk_send_social` (~305 tokens)

Distribute one token to many X handles in one call (non-custodial, ENG-bfeacb2c).

\``recipients`` is a list of ``{recipient_handle, amount, message?}`` dicts
(``recipient`` accepted as an alias; ``amount`` in base units; ``message`` an
optional per-recipient note). Locks each amount of ``token`` (mint) from
\``sender_wallet`` into a fresh claim escrow and returns the ``create_claim``
instructions batched into as few UNSIGNED transactions as fit -- the sender
signs + broadcasts every returned tx. Each send carries its crank.ing claim
link, the bearer ``claim_code`` (returned once, embed per tweet), and the
\``transaction_index`` of the tx that funds it. Anti-abuse gated (account age,
verified wallet, per-sender daily limit counting the whole batch). platform: x.

\``idempotency_key`` (ENG-ac7961aa, optional): a client-generated UUID.
Retrying with the same key + same args replays the original result (same
claim_codes/links) instead of locking a second batch of escrows.

Input parameters:

- `caller_id` (string)
- `idempotency_key` (string)
- `platform` (string)
- `recipients` (array, required)
- `referral` (string)
- `sender_wallet` (string, required)
- `token` (string, required)

### `get_social_sends` (~42 tokens)

A wallet's social token sends (newest first; no claim-code secrets).

Input parameters:

- `caller_id` (string)
- `wallet_address` (string, required)

### `claim_status` (~41 tokens)

Public status of a crank.ing claim code (status, amount, claimable, expiry).

Input parameters:

- `caller_id` (string)
- `code` (string, required)

### `get_crank_score` (~155 tokens)

A wallet's Crank Score reputation breakdown (FREE read, ENG-95f335be).

Returns total_score, per-activity components (trade / staking / strategy /
social / claim), sybil_flagged + penalty_bps, and the score-gated perks it
unlocks under ``gates``: fee_discount_bps (additional technology service fee
discount), daily_send_limit (higher social-send cap), priority_access, and
the gate tier (0-3). Score accrues from on-platform activity; circular
funding between wallets is flagged + penalised. Well-formed zeros for an
unscored wallet.

Input parameters:

- `caller_id` (string)
- `wallet_address` (string, required)

### `get_score` (~162 tokens)

User-facing Crank Score: rank, multiplier, metrics + quests (FREE, ENG-b0150c40).

The campaign-layer view on top of ``get_crank_score``. Returns total_score,
leaderboard rank + percentile, the applied multiplier_bps (streak /
early-adopter / strategy-creator), the wallet's costly-action ``metrics``
(fee_volume_usd, strategies_published, clones_spawned, referrals_activated,
active_days), and its live ``quests`` with progress. Points come ONLY from
costly actions (anti-farm). ``disclaimer``: score MAY inform a future token
distribution -- no fixed conversion ratio, no entitlement.

Input parameters:

- `caller_id` (string)
- `wallet_address` (string, required)

### `get_score_leaderboard` (~121 tokens)

Top-N Crank Score leaderboard (FREE read, ENG-b0150c40).

Ranked descending by total_score. ``limit`` caps at the admin-configured
leaderboard_size. Each entry: rank, wallet_address, total_score, the
base/action/quest components, multiplier_bps, streak_days, percentile. Also
returns total_participants and the pre-token ``disclaimer``. (Distinct from
\``get_leaderboard``, which ranks strategy templates.)

Input parameters:

- `caller_id` (string)
- `limit`

### `get_quests` (~116 tokens)

Live Crank Score quests + a wallet's progress (FREE read, ENG-b0150c40).

Time-bounded, admin-configured campaigns (e.g. "Trade $1000 this week = 500
pts"). Each quest carries its tracked costly metric, target_value,
reward_points, the active window, and -- when ``wallet_address`` is given --
the wallet's progress_value + completion state. Carries the ``disclaimer``.

Input parameters:

- `caller_id` (string)
- `wallet_address` (string)

### `check_claim_status` (~152 tokens)

Sender-facing claim status of a social send (FREE read, ENG-bfeacb2c).

Look up by ``claim_id`` (the send id) OR ``recipient`` (X handle); optionally
scope a recipient lookup to one ``sender_wallet``. Returns ``{"sends": [...]}``
each with status (pending/claimed/expired/returned), claim_date, returned_at,
recipient_wallet, amount, claim_link, expiry_ts, and expires_in_seconds (a live
countdown, 0 once expired). Never exposes the claim-code secret.

Input parameters:

- `caller_id` (string)
- `claim_id`
- `recipient` (string)
- `sender_wallet` (string)

### `get_usage_report` (~86 tokens)

An agent's own premium-feature spend report (FREE read).

Returns per-feature {calls, spend_usd, cost_usd} plus totals from the
FeatureUsage ledger. period: today | 7d | 30d | all (default 30d).

Input parameters:

- `caller_id` (string)
- `period` (string)
- `wallet_address` (string, required)

### `get_market_briefing` (~304 tokens)

Crypto market briefing synthesised from free public sources (tiered).

Returns a market briefing aggregated from free crypto data sources (Coin Bureau,
DeFiLlama, the alternative.me Fear & Greed index) plus classified sentiment
signals: market summary, top movers / most-discussed assets, sentiment regime,
the Fear & Greed reading, and source attribution. assets is an optional list of
tickers (e.g. ["BTC","SOL"]); for paid tiers it declares the agent's holdings and
focuses the synthesis. detail_level: "free" returns the pre-generated daily Free
briefing (metered at $0, quota'd per day); "pro" ($0.25) and "platinum" ($0.50)
return real-time Sonnet/Opus synthesis personalised to the wallet's portfolio +
active strategies. Paid tiers are covered by an active $CRANK-staker subscription
or require a verified x402 payment_header (PAYMENT_REQUIRED otherwise). The billing
outcome is in the response ``billing`` field. Not financial advice.

Workflow: INTELLIGENCE step (usually first) -- macro/sentiment context that
frames detect_regime + the allocation. See get_trading_workflow.

Input parameters:

- `assets`
- `caller_id` (string)
- `detail_level` (string)
- `payment_header` (string)
- `timeframe` (string)
- `wallet_address` (string)

### `get_source_accuracy` (~247 tokens)

Historical directional hit-rate of each intelligence source (free read).

Returns per-source accuracy stats for the intelligence signal sources (Coin
Bureau / YouTube, RSS, Fear & Greed API, on-chain), so an agent can weight a
source's calls by how often its bullish/bearish reads have played out. Each
source carries a ``windows`` map over rolling 7d/30d/90d periods, each with
total resolved calls, correct/incorrect counts, and accuracy_pct; sources with
no resolved calls yet are omitted, and results are ranked by longest-window
accuracy. windows optionally narrows the periods (subset of [7,30,90]);
source_type optionally filters by source kind (youtube, rss, api, on_chain).
Accuracy = the directional call vs the realised Birdeye price over the
prediction window. Past accuracy is not a guarantee. Not financial advice.

Workflow: INTELLIGENCE step -- pair with get_market_briefing to discount or
trust a signal by its source's track record before sizing a position.

Input parameters:

- `caller_id` (string)
- `source_type` (string)
- `windows`

### `get_regulatory_updates` (~275 tokens)

Recent regulatory statements affecting Crank's scope (free read, ENG-43ba5e83).

Returns SEC / CFTC / FinCEN press releases and rule proposals from a scheduled daily
scan, LLM-classified for relevance to Crank: DeFi, crypto perps, tokenized equities,
autonomous agent trading, and non-custodial custody. Each update carries the issuing
\``agency``, title, url, ``relevance`` (high/medium/low) + score, matched ``topics``,
and a one-line factual ``summary``; results are ranked by relevance then recency.
window_hours bounds the lookback (default 168 = 7 days, capped at 720 = 30 days);
min_relevance filters by floor (high/medium/low); agency optionally narrows to one
body (SEC, CFTC, FinCEN). Relevance is a compliance-triage signal, not legal advice.
Not financial advice.

Workflow: INTELLIGENCE / COMPLIANCE step -- check the current regulatory posture
around perps, tokenized equities, or agent trading before acting on a strategy.

Input parameters:

- `agency` (string)
- `caller_id` (string)
- `min_relevance` (string)
- `window_hours` (integer)

### `get_technology_updates` (~318 tokens)

Recent technology / tooling developments relevant to Crank + Engaij (free read, ENG-565c74a9).

Returns items from a scheduled scan of technology feeds (Anthropic, OpenAI, Coinbase
Developer, Solana Foundation, Hacker News filtered, GitHub trending) plus flagged
YouTube tech channels (full transcript ingested), LLM-classified for relevance to both
Crank (Solana trading infra + DeFi frontend) and Engaij (the parent automation
platform). Each update carries ``category`` (sdk_release / api_change / competitor /
regulatory / research / tooling), ``relevance_to_crank`` and ``relevance_to_engaij``
(high/medium/low/none), a concrete ``application_recommendation`` (what to do about
it), title, url, and a one-line ``summary``; results are ranked by relevance then
recency. window_hours bounds the lookback (default 168 = 7 days, capped at 720 = 30
days); min_relevance filters by floor (high/medium/low); category optionally narrows
to one kind. A triage signal, not advice. Not financial advice.

Workflow: INTELLIGENCE step -- scan for SDK / API releases, competitor moves, or
tooling worth adopting before planning integration or strategy work.

Input parameters:

- `caller_id` (string)
- `category` (string)
- `min_relevance` (string)
- `window_hours` (integer)

### `get_consensus` (~272 tokens)

Multi-source consensus + contrarian read for one asset (PLATINUM premium).

Cross-references the classified intelligence signals for ``asset`` over the last
\``window_hours`` (default 24): how many independent sources agree on direction
(consensus_score 0-1), the source breakdown (bullish/bearish/neutral), and the
accuracy-weighted directional score (-1..+1) that blends each source's call by its
historical hit-rate (get_source_accuracy). High agreement (>80%) is flagged as a
crowded, potentially contrarian condition; low agreement (<30%) as uncertain. This
is a PLATINUM-tier feature: covered by a Platinum $CRANK-staker subscription, or
pay the per-call x402 fee with payment_header (PAYMENT_REQUIRED otherwise); the
billing outcome is in the response ``billing`` field. Descriptive signal only, not
a recommendation. Not financial advice.

Workflow: INTELLIGENCE step -- pair with get_market_briefing + get_source_accuracy
to gauge how crowded a directional read is before sizing.

Input parameters:

- `asset` (string, required)
- `caller_id` (string)
- `payment_header` (string)
- `wallet_address` (string)
- `window_hours` (integer)

### `get_contrarian_signals` (~224 tokens)

Contrarian (crowded) + uncertain assets across the window (PLATINUM premium).

Scans the classified intelligence signals over the last ``window_hours`` and returns
assets where source agreement is very high -- a one-sided, crowded positioning
flagged as a potential contrarian condition (with the side a contrarian would take)
\-- and assets where agreement is very low (uncertain). With ``asset`` set, returns
just that asset's assessment. PLATINUM-tier: covered by a Platinum $CRANK-staker
subscription or a verified x402 payment_header (PAYMENT_REQUIRED otherwise); the
billing outcome is in ``billing``. Descriptive signal only, not a recommendation.
Not financial advice.

Workflow: INTELLIGENCE step -- surface crowded trades to fade or uncertain assets to
avoid before committing to a regime/allocation.

Input parameters:

- `asset` (string)
- `caller_id` (string)
- `payment_header` (string)
- `wallet_address` (string)
- `window_hours` (integer)

### `get_signals` (~242 tokens)

Filtered, most-recent-first feed of structured market signals (free read).

The observed-signal data spine: squeeze / flow / technical / microstructure /
behavioral / liquidity / safety / whale / regime / macro / oracle / event /
composite signals persisted by the collectors. ``subject`` matches a token
symbol/market or its stable ref (mint / market address); ``signal_type`` /
\``tier`` (a|b|c) / ``risk_level`` (none..critical) / ``min_score`` narrow the
feed. Unknown filter values are dropped, not errored. Descriptive observed
data only -- never a trade instruction. Not financial advice.

Workflow: INTELLIGENCE step -- pair with get_market_briefing (macro) and
get_token_risk_assessment (per-token safety roll-up) before sizing.

Input parameters:

- `caller_id` (string)
- `include_expired` (boolean)
- `limit` (integer)
- `min_score`
- `risk_level` (string)
- `signal_type` (string)
- `subject` (string)
- `tier` (string)

### `get_token_risk_assessment` (~179 tokens)

Per-token risk roll-up over recently observed safety signals (free read).

Folds every non-expired signal for ``subject`` (symbol or mint) in the window
into the worst risk level seen, a 0..1 risk score, a per-level count
breakdown, and the contributing signals (worst-first). Complements -- does
not replace -- ``get_risk_assessment`` (regime + position-size guards for
deploying a strategy). Descriptive observed data only. Not financial advice.

Workflow: INTELLIGENCE / RISK step -- run before quoting or sizing an
unfamiliar token; a critical safety signal is a hard skip condition.

Input parameters:

- `caller_id` (string)
- `limit` (integer)
- `subject` (string, required)
- `window_hours` (integer)

### `get_market_regime` (~132 tokens)

Market-wide regime from the persisted regime/macro signal feed (free read).

Returns the dominant regime, its confidence, a distribution across observed
regimes, and the contributing signals. For a live per-asset regime computed
from OHLCV, use ``detect_regime`` instead. Descriptive observed data only.
Not financial advice.

Workflow: INTELLIGENCE step -- market-wide posture check before choosing a
strategy type or direction_mode; pair with detect_regime for the asset leg.

Input parameters:

- `caller_id` (string)
- `limit` (integer)
- `window_hours` (integer)

### `list_signal_catalog` (~176 tokens)

Catalog of every available signal stream (free read; ENG-5029a312).

One entry per signal source across all tiers -- on-chain collectors, free
API sources, derived analyzers and external provider adapters -- with tier,
cost-gate state (paid Tier-D gates are fail-closed and disabled by
default), coverage window (earliest/latest persisted signal -- the honest
backtest window), effectiveness stats (graded evaluation count + correct
rate) and a gameability class (social streams rank high -- they carry
anti-gaming caps). Descriptive historical data only. Not financial advice.

Workflow: COMPOSE step -- enumerate streams before authoring a composite
strategy definition; pair with get_signals to inspect a stream's feed.

Input parameters:

- `caller_id` (string)
- `include_inactive` (boolean)

### `get_source_weights` (~143 tokens)

Source-effectiveness weight table (free read; ENG-bfb7ace4).

Per (source, signal_type, regime): graded evaluation counts, the smoothed
effectiveness weight (social sources hold a low prior until sufficiently
graded -- the anti-gaming cold start), the fleet Layer-2 multiplier from
released k-anonymous insights, and the combined weighted value the
composite effectiveness_weighted transform consumes. Historical grading
statistics only -- descriptive, never advice. Not financial advice.

Workflow: COMPOSE step -- read alongside list_signal_catalog to pick
streams with a real graded track record before authoring a definition.

Input parameters:

- `caller_id` (string)

### `get_cross_exchange` (~175 tokens)

Cross-venue snapshot for one asset (free read).

Per-venue price/bid/ask/movement (5m/1h/24h change), the pairwise spread
matrix (bps), the widest current spread, and -- for wrapped-asset legs
(BTC/ETH) only -- the Solana-DEX wrapped-asset premium vs the
CEX-consensus reference price. Observed data, decision-support only --
spreads ignore fees, slippage, and cross-venue/bridge transfer latency;
never an execution instruction. Not financial advice.

Workflow: INTELLIGENCE step -- pair with get_arb_discrepancies for the
persisted, already-debounced episode history.

Input parameters:

- `asset` (string, required)
- `caller_id` (string)
- `window_minutes` (integer)

### `get_arb_discrepancies` (~180 tokens)

Persisted cross-venue discrepancy episodes (free read).

Already-debounced ``cross_exchange`` signals (each required >= N
consecutive polls above the discrepancy threshold to exist at all),
filtered to ``spread_bps >= min_spread_bps`` and optionally to ``assets``,
within ``window_hours``. One entry per episode: venue pair, spread,
first/last seen, persistence, reference price. Observed data,
decision-support only -- ignores fees, slippage, and transfer latency;
never an execution instruction. Not financial advice.

Workflow: INTELLIGENCE step -- pair with get_cross_exchange for the
current live-ish read on a specific asset.

Input parameters:

- `assets`
- `caller_id` (string)
- `min_spread_bps` (number)
- `window_hours` (integer)

### `get_strategy_suggestions` (~204 tokens)

Signal-to-action suggestions from the synthesis engine (free read, G4).

Per-asset directional observations aggregated hourly from the accuracy-
weighted intelligence consensus (get_consensus math) plus the Fear & Greed
context, each carrying a ready-to-use strategy config. PROPOSE flow: this
tool never executes anything -- act on a suggestion by creating the strategy
through the normal strategy tools (your wallet policy and the engine's risk
/ conflict / guardrail gates still apply), or approve it in the app.
\``status`` filters proposed|approved|dismissed|executed|expired|all.
Informational descriptions of observed data only. Not financial advice.

Workflow: INTELLIGENCE -> DECIDE step -- review suggestions, then pair with
backtest_strategy + get_risk_assessment before any create call.

Input parameters:

- `asset` (string)
- `caller_id` (string)
- `limit` (integer)
- `status` (string)

### `get_ilo_adoption_status` (~239 tokens)

The ILO adoption gate -- one machine-checkable readiness read (free).

Andrew's decision (MB#20076, ENG-5de0ede9): the ILO proceeds only once
Crank has 1,000 active users, where an active user has at least 5 executed
Crank transactions inside a rolling 7-day window. Signups do not count.
Returns gate_met (active_users >= 1000), active_users, near_active_users,
users_with_any_tx and the pinned transaction definition. A transaction is
an EXECUTED trade only -- a recorded swap (broadcast signature required),
a perp open, or a user-initiated perp close; reads, quotes, unexecuted
intents, paper trades, liquidations and devnet activity never count.
\``cluster=devnet`` exposes the same metric for pre-launch observability;
the gate itself is the mainnet number. Aggregate counts only, no
per-wallet data. Informational readiness metric; not a promise of any
launch, outcome or timeline.

Input parameters:

- `caller_id` (string)
- `cluster` (string)

### `strategy_dca_create` (~320 tokens)

Create a dollar-cost-average strategy buying ``usd_per_buy`` of target each interval.

\``risk`` (optional) overrides the safe-default risk limits (ENG-b2c60329):
\``max_position_pct`` / ``max_portfolio_exposure_pct`` / ``max_single_loss_pct``
/ ``max_drawdown_pct`` / ``max_daily_loss_pct`` (percent; <=0 disables a guard).

Direction (ENG-bd44b1b7, optional, all advisory -- DYOR): ``direction_mode``
(auto | long_only | short_only | manual; default auto = follow the market
regime, reducing exposure in a bear instead of accumulating), ``allow_short``
(enable real shorts via the Drift perps venue), ``regime_override`` (force
bull | bear | range | volatile instead of trusting detection).

Workflow: EXECUTE step -- stand up a recurring strategy after backtest_strategy
validates it and get_risk_assessment sets the guards; track via strategy_status.
A managed wallet without a Turnkey signer = paper-trade (unsigned tx per tick).
See get_trading_workflow.

Input parameters:

- `allow_short`
- `direction_mode`
- `interval_seconds` (integer)
- `regime_override`
- `risk`
- `slippage_bps` (integer)
- `smart` (boolean)
- `source_token` (string)
- `target_token` (string, required)
- `usd_per_buy` (number, required)
- `wallet_address` (string, required)

### `strategy_equity_dca_create` (~251 tokens)

Create an equity dollar-cost-average strategy (tokenized equities / xStocks).

Shares the DCA executor -- identical mechanics/config to
\``strategy_dca_create`` -- tagged ``equity_dca`` because ``target_token`` is
expected to be a tokenized-equity mint. SEC posture (ENG-6f4d3513): DCA is a
MECHANICAL, user-configured strategy (not discretionary), so it stays
autonomous even on a security target -- the per-execution confirmation gate
only applies to the discretionary types (momentum / sentiment). Equity
classification still drives geo-gating + disclaimers at execution; call
asset_classification / get_disclaimers first.

\``risk`` / direction params: see ``strategy_dca_create``.

Input parameters:

- `allow_short`
- `direction_mode`
- `interval_seconds` (integer)
- `regime_override`
- `risk`
- `slippage_bps` (integer)
- `smart` (boolean)
- `source_token` (string)
- `target_token` (string, required)
- `usd_per_buy` (number, required)
- `wallet_address` (string, required)

### `strategy_stoploss_create` (~229 tokens)

Create a stop-loss / take-profit / trailing-stop monitor on a held position.

\``position_amount`` is base units of ``target_token`` to liquidate on
trigger. At least one of ``stop_loss_pct`` / ``take_profit_pct`` / a trailing
config should be set (fractions, e.g. 0.15 == 15%).

Direction (ENG-bd44b1b7, optional, advisory): ``direction_mode`` /
\``allow_short`` / ``regime_override`` -- see ``strategy_dca_create``.

Input parameters:

- `allow_short`
- `direction_mode`
- `entry_price`
- `interval_seconds` (integer)
- `position_amount` (integer, required)
- `regime_override`
- `risk`
- `slippage_bps` (integer)
- `source_token` (string)
- `stop_loss_pct`
- `take_profit_pct`
- `target_token` (string, required)
- `trailing` (boolean)
- `trailing_distance_pct`
- `wallet_address` (string, required)

### `strategy_protect_create` (~179 tokens)

Create a downside-protection monitor on a held position.

Shares the stop-loss executor -- identical config/mechanics to
\``strategy_stoploss_create`` -- framed as a pure downside guard. At least
one of ``stop_loss_pct`` / ``take_profit_pct`` / ``trailing`` must be set.

Input parameters:

- `allow_short`
- `direction_mode`
- `entry_price`
- `interval_seconds` (integer)
- `position_amount` (integer, required)
- `regime_override`
- `risk`
- `slippage_bps` (integer)
- `source_token` (string)
- `stop_loss_pct`
- `take_profit_pct`
- `target_token` (string, required)
- `trailing` (boolean)
- `trailing_distance_pct`
- `wallet_address` (string, required)

### `strategy_hedge_create` (~219 tokens)

Create a hedge strategy -- an exit trigger that unwinds a held position.

Shares the stop-loss executor -- identical config/mechanics to
\``strategy_stoploss_create`` -- framed as an active risk-offset trigger: set
\``stop_loss_pct`` / ``trailing`` to shed exposure on an adverse move, or
\``take_profit_pct`` to lock in a favourable one. At least one of
\``stop_loss_pct`` / ``take_profit_pct`` / ``trailing`` must be set.

Input parameters:

- `allow_short`
- `direction_mode`
- `entry_price`
- `interval_seconds` (integer)
- `position_amount` (integer, required)
- `regime_override`
- `risk`
- `slippage_bps` (integer)
- `source_token` (string)
- `stop_loss_pct`
- `take_profit_pct`
- `target_token` (string, required)
- `trailing` (boolean)
- `trailing_distance_pct`
- `wallet_address` (string, required)

### `strategy_rebalance_create` (~133 tokens)

Create a portfolio-rebalance strategy toward ``target_allocation`` (mint->weight).

Direction (ENG-bd44b1b7, optional, advisory): ``direction_mode`` /
\``allow_short`` / ``regime_override`` -- see ``strategy_dca_create``.

Input parameters:

- `allow_short`
- `direction_mode`
- `drift_threshold_pct` (number)
- `interval_seconds` (integer)
- `regime_override`
- `risk`
- `slippage_bps` (integer)
- `target_allocation` (object, required)
- `wallet_address` (string, required)

### `strategy_vault_create` (~213 tokens)

Create a vault strategy -- a target-allocation basket held via rebalancing.

Shares the rebalance executor -- identical config/mechanics to
\``strategy_rebalance_create`` (``target_allocation`` mint->weight,
\``drift_threshold_pct``) -- framed as a passive basket rather than an active
rebalance loop. No external vault/LP deposit (hard rule 1): the
non-custodial swap pipeline only rotates spot holdings toward the target
weights.

Direction (ENG-bd44b1b7, optional, advisory): ``direction_mode`` /
\``allow_short`` / ``regime_override`` -- see ``strategy_dca_create``.

Input parameters:

- `allow_short`
- `direction_mode`
- `drift_threshold_pct` (number)
- `interval_seconds` (integer)
- `regime_override`
- `risk`
- `slippage_bps` (integer)
- `target_allocation` (object, required)
- `wallet_address` (string, required)

### `strategy_snipe_create` (~249 tokens)

Create a snipe/scalping strategy -- dip-buy with a fast take-profit/stop exit.

Flat: buys ``usd_per_buy`` when price is ``entry_dip_pct`` below the close
\``lookback`` ticks ago. Holding: exits on a tight ``take_profit_pct`` OR
\``stop_loss_pct`` -- many small round-trips. Runs on a short interval
(default 60s) since it reads a per-tick rolling price window that must
accumulate ``lookback`` + 1 observations before it can enter.

\``risk`` / direction params: see ``strategy_dca_create``.

Input parameters:

- `allow_short`
- `direction_mode`
- `entry_dip_pct` (number)
- `interval_seconds` (integer)
- `lookback` (integer)
- `regime_override`
- `risk`
- `slippage_bps` (integer)
- `source_token` (string)
- `stop_loss_pct` (number)
- `take_profit_pct` (number)
- `target_token` (string, required)
- `usd_per_buy` (number, required)
- `wallet_address` (string, required)

### `strategy_momentum_create` (~227 tokens)

Create a momentum strategy -- fast/slow SMA crossover entry/exit.

Buys on a bullish cross (fast SMA > slow SMA), sells on a bearish cross.
DISCRETIONARY (SEC framework, ENG-6f4d3513): the model interprets a signal
and converts it to a trade, so targeting a tokenized SECURITY forces
per-execution user confirmation before the scheduled dispatcher will run a
tick (``strategies.tasks.execute_strategy`` requires ``user_confirmed=True``;
crypto targets stay fully autonomous). Call asset_classification first.

\``risk`` / direction params: see ``strategy_dca_create``.

Input parameters:

- `allow_short`
- `direction_mode`
- `fast` (integer)
- `interval_seconds` (integer)
- `regime_override`
- `risk`
- `slippage_bps` (integer)
- `slow` (integer)
- `source_token` (string)
- `target_token` (string, required)
- `usd_per_buy` (number, required)
- `wallet_address` (string, required)

### `strategy_sentiment_create` (~234 tokens)

Create a sentiment strategy -- trades an aggregate sentiment score.

Buys when the score is >= ``bull_threshold`` (flat), sells when it is
\<= ``bear_threshold`` (holding); the neutral band holds. The score is
sourced live from market intelligence each tick, or pinned via
\``sentiment_score``. DISCRETIONARY (SEC framework, ENG-6f4d3513): targeting
a tokenized SECURITY forces per-execution ``user_confirmed`` at execution
(crypto stays fully autonomous). Call asset_classification first.

\``risk`` / direction params: see ``strategy_dca_create``.

Input parameters:

- `allow_short`
- `bear_threshold` (number)
- `bull_threshold` (number)
- `direction_mode`
- `interval_seconds` (integer)
- `regime_override`
- `risk`
- `sentiment_score`
- `slippage_bps` (integer)
- `source_token` (string)
- `target_token` (string, required)
- `usd_per_buy` (number, required)
- `wallet_address` (string, required)

### `strategy_yield_farm_create` (~212 tokens)

Create a yield-farm strategy -- maintains a target basket allocation.

Shares the rebalance executor (config identical to
\``strategy_rebalance_create``): depositing into an external yield protocol
/ LP position has no faithful swap-pipeline analogue, so this models a
yield farm as keeping a target allocation across the basket via converging
rebalance swaps (hard rule 1: the non-custodial pipeline only rotates spot
holdings, never deposits externally).

Direction (ENG-bd44b1b7, optional, advisory): ``direction_mode`` /
\``allow_short`` / ``regime_override`` -- see ``strategy_dca_create``.

Input parameters:

- `allow_short`
- `direction_mode`
- `drift_threshold_pct` (number)
- `interval_seconds` (integer)
- `regime_override`
- `risk`
- `slippage_bps` (integer)
- `target_allocation` (object, required)
- `wallet_address` (string, required)

### `strategy_copy_wallet_create` (~202 tokens)

Create a copy-wallet strategy -- mirrors a tracked wallet's entries/exits.

\``tracked_wallet`` is the Solana address to mirror (its confirmed on-chain
buy/sell actions are sourced each tick); ``usd_per_buy`` is the default
mirror size (scaled by ``size_multiplier``) applied when the tracked wallet
buys. APPROXIMATE: no full per-fill replication (every execution is flagged
\``approximate``).

\``risk`` / direction params: see ``strategy_dca_create``.

Input parameters:

- `allow_short`
- `direction_mode`
- `interval_seconds` (integer)
- `regime_override`
- `risk`
- `size_multiplier` (number)
- `slippage_bps` (integer)
- `source_token` (string)
- `target_token` (string, required)
- `tracked_wallet`
- `usd_per_buy` (number, required)
- `wallet_address` (string, required)

### `strategy_market_make_create` (~241 tokens)

Create a market-make strategy -- two-sided spread capture (APPROXIMATE).

No live order book -- SYNTHESISES a spread from realised volatility around
a rolling mid: a "filled bid" (price a half-spread below mid) buys, a
"filled ask" (above mid) sells (up to held inventory). Market-neutral:
PAUSES in a trending (bull/bear) regime instead of adapting direction (a
maker gets run over by a directional move) -- read directly inside the
executor, so no direction params are exposed here.

\``risk``: see ``strategy_dca_create``.

Input parameters:

- `base_spread_pct` (number)
- `interval_seconds` (integer)
- `max_levels` (integer)
- `mid_period` (integer)
- `risk`
- `slippage_bps` (integer)
- `source_token` (string)
- `spread_lookback` (integer)
- `target_token` (string, required)
- `usd_per_quote` (number, required)
- `vol_spread_mult` (number)
- `wallet_address` (string, required)

### `strategy_arb_create` (~237 tokens)

Create an arb strategy -- cross-venue price-discrepancy convergence (APPROXIMATE).

Reads a live cross-venue spread each tick (task-sourced from the Jupiter
quote corpus vs on-chain price) or falls back to a transparent PROXY
(deviation below a short EMA) when unavailable. Enters when the spread
clears ``entry_spread_pct`` and flat; exits when it reverts to
\``exit_spread_pct``. The simultaneous two-venue fill is collapsed to one
leg (flagged ``approximate``). Market-neutral: no direction params exposed
(regime is read directly, not adapted).

\``risk``: see ``strategy_dca_create``.

Input parameters:

- `ema_period` (integer)
- `entry_spread_pct` (number)
- `exit_spread_pct` (number)
- `interval_seconds` (integer)
- `risk`
- `slippage_bps` (integer)
- `source_token` (string)
- `target_token` (string, required)
- `usd_per_trade` (number, required)
- `wallet_address` (string, required)

### `strategy_perp_grid_create` (~341 tokens)

Create a perp-grid strategy -- a ladder of perp LONGS accumulated on dips.

Routes through the multi-venue perps VENUE ADAPTER (hard rule 2; Jupiter
Perps primary). Around a rolling center price (SMA, or an explicit
\``center_price``), each ``grid_spacing_pct`` move below center is one rung;
crossing a deeper rung opens a perp long sized ``usd_per_level`` at
\``leverage``. PAUSES new rungs in a trending (bull/bear) regime and closes
the ladder in a bear (stop the bleed); tightens spacing in range, widens
when volatile. Only an asset with a mapped perp market (currently SOL) can
open -- see get_venue_status for routable markets. ``venue`` optional
(defaults to the configured primary); a Tier B (custodied) venue needs
\``acknowledge_tier_b=true`` after reviewing its ``custody_disclosure``.

\``risk``: see ``strategy_dca_create``.

Input parameters:

- `acknowledge_tier_b` (boolean)
- `center_period` (integer)
- `center_price`
- `grid_levels` (integer)
- `grid_spacing_pct` (number)
- `interval_seconds` (integer)
- `leverage` (number)
- `range_tighten` (number)
- `risk`
- `slippage_bps` (integer)
- `target_token` (string, required)
- `usd_per_level` (number, required)
- `venue`
- `volatile_widen` (number)
- `wallet_address` (string, required)

### `strategy_basis_trade_create` (~303 tokens)

Create a basis-trade strategy -- funding-harvest perp SHORT leg (APPROXIMATE).

Routes the perp leg through the multi-venue VENUE ADAPTER (hard rule 2). A
live delta-neutral basis trade is long spot + short perp harvesting
funding; this executor opens/manages only the perp SHORT leg (the spot
long that makes the book delta-neutral is held separately by the caller)
\-- flagged ``approximate`` + ``funding_not_modeled`` (funding PnL itself is
not simulated live). While funding is favourable (> ``min_funding``) and
flat, opens the short sized ``usd_per_trade`` at ``leverage``; closes when
funding decays to <= ``min_funding``. Only an asset with a mapped perp
market (currently SOL) can open. A Tier B (custodied) venue needs
\``acknowledge_tier_b=true``.

\``risk``: see ``strategy_dca_create``.

Input parameters:

- `acknowledge_tier_b` (boolean)
- `funding_lookback` (integer)
- `interval_seconds` (integer)
- `leverage` (number)
- `min_funding` (number)
- `risk`
- `slippage_bps` (integer)
- `target_token` (string, required)
- `usd_per_trade` (number, required)
- `venue`
- `wallet_address` (string, required)

### `strategy_status` (~40 tokens)

Status + last execution of one strategy (scoped to the caller's wallet).

Input parameters:

- `strategy_id` (integer, required)
- `wallet_address` (string, required)

### `strategy_modify` (~598 tokens)

Edit a running strategy's parameters IN PLACE -- no cancel + recreate.

React to a fresh signal by retuning the strategy you already own: the
execution history, cost-basis ledger and position state all survive, and
there is no window where the strategy is gone. The live executor picks the
new config up on its NEXT tick; a tick already in flight finishes against
the config it loaded (it writes only runtime state, never config, so the
two can never clobber each other).

Scoped to the caller's own wallet (hard rule 1 -- non-custodial: this edits
a row the owner already controls; nothing here holds keys, signs or moves
funds).

Args (all optional -- supply at least one):
  \``config_updates``: strategy-config keys to set, merged over the existing
    config (e.g. ``{"usd_per_buy": 25, "stop_loss_pct": 0.08}``).
  \``remove_keys``: config keys to drop back to the executor's default.
  \``risk``: retune the risk limits -- ``max_position_pct`` /
    ``max_portfolio_exposure_pct`` / ``max_single_loss_pct`` /
    ``max_drawdown_pct`` / ``max_daily_loss_pct`` (percent; <=0 disables a
    single guard).
  \``direction_mode`` / ``allow_short`` / ``regime_override``: the direction
    controls from the create tools (advisory -- DYOR).
  \``target_allocation``: new mint->weight basket (rebalance / vault /
    yield_farm).
  \``interval_seconds``: new tick interval, used from the next tick on.
  \``reason``: free text recorded on the strategy's audit log.

REFUSED (returns ``immutable_config_key``): ``target_token`` /
\``source_token`` / ``tracked_wallet`` / ``venue`` / composite
\``definition``. These define WHAT the strategy trades -- editing them in
place would desync the executor's position bookkeeping or strand an open
perp leg on the venue it was opened against. Cancel and create a new
strategy for those. A STOPPED strategy is final and cannot be modified;
a paused one can (the edit does not resume it -- use strategy_resume).

The merged config is dry-run through the strategy's exec…

Input parameters:

- `allow_short`
- `config_updates`
- `direction_mode`
- `interval_seconds`
- `reason` (string)
- `regime_override`
- `remove_keys`
- `risk`
- `strategy_id` (integer, required)
- `target_allocation`
- `wallet_address` (string, required)

### `strategy_cancel` (~41 tokens)

Stop a strategy (sets status=stopped; it will not be dispatched again).

Input parameters:

- `strategy_id` (integer, required)
- `wallet_address` (string, required)

### `strategy_pause` (~38 tokens)

Manually pause a strategy (status=paused_manual; stops dispatch).

Input parameters:

- `strategy_id` (integer, required)
- `wallet_address` (string, required)

### `strategy_resume` (~89 tokens)

Re-enable a paused strategy (manual re-enable after a drawdown pause).

The drawdown kill switch (ENG-b2c60329) latches a strategy to
\``paused_drawdown`` and requires this explicit owner action to resume; the
equity high-water mark is reset so it does not immediately re-trip.

Input parameters:

- `strategy_id` (integer, required)
- `wallet_address` (string, required)

### `strategy_list` (~28 tokens)

List a wallet's strategies (newest first, capped).

Input parameters:

- `wallet_address` (string, required)

### `get_trading_workflow` (~280 tokens)

Map of how Crank's tools fit into one end-to-end trading flow (read this first).

Read-only, free. Returns an ordered, machine-readable workflow: orient ->
intelligence -> yields -> simulate (backtest) -> risk-size -> execute
(non-custodial) -> monitor -> journal. Each step names the concrete
tool(s) to call, their purpose, key inputs, how to use the output
downstream, and the decision points that branch the flow -- so an agent
that discovered Crank via tools/list can sequence the ~70 tools instead
of guessing. Advisory only (DYOR); only execute-phase tools are
value-bearing.

wallet_address (optional, PUBLIC key only -- non-custodial): when
given, appends ``human_activity`` -- count + most-recent manual
override on this shared account in the last 72h (decision_type, asset,
rationale summary, timestamp) plus an instruction to reconcile with it
before acting. Human and agents act on ONE account: every human action
is journaled (see journal_query source="human") so it is never invisible
to you. Absent/clean (``{"count": 0}``) when there is no override.

Input parameters:

- `caller_id` (string)
- `wallet_address` (string)

### `journal_append` (~285 tokens)

Record a decision in your private, wallet-scoped journal (free write).

Your durable memory on Crank: rationale, intended action, and optional
expectations (e.g. {"direction": "up", "horizon": "24h"}) are stored as
one opaque body only you can read back; the system later attributes
realised P&L from on-chain-verified fills and marks prices at
1h/24h/7d/30d horizons. idempotency_key makes replays safe (offline
queues / batch agents). Link evidence via signal_ids / suggestion_id /
strategy_id (your own strategies only). Autonomous strategy executions
are journaled for you automatically -- use this to add the
agent-authored layer on top.

Workflow: DECIDE step -- journal before (or as) you act; query it back
with journal_query / get_my_performance.

Input parameters:

- `asset` (string)
- `caller_id` (string)
- `client_platform` (string)
- `decision_type` (string, required)
- `expectations`
- `idempotency_key` (string)
- `intended_action` (string)
- `rationale` (string, required)
- `session_id` (string)
- `signal_ids`
- `strategy_id`
- `suggestion_id`
- `wallet_address` (string, required)

### `journal_query` (~267 tokens)

Read your own decision journal, most recent first (free read).

Wallet-scoped: only decisions journaled for wallet_address are ever
returned. Filters: window_hours (0 = all), decision_type, strategy_type,
asset (mint/symbol as journaled), outcome_sign
(positive|negative|zero on realised P&L), source (agent|system|human --
pass source="human" to see only a manual override on this shared
account: human and agents act on ONE account, and every human action is
journaled so agents can see and reconcile with it). Every returned row
carries its source. detail=concise returns id/type/timestamp/pnl rows
(token-budget friendly); detail=full adds bodies, evidence refs, and
full outcome marks.

Workflow: ORIENT step -- recall what you decided (and what a human may
have overridden) before deciding again.

Input parameters:

- `asset` (string)
- `caller_id` (string)
- `decision_type` (string)
- `detail` (string)
- `limit` (integer)
- `outcome_sign` (string)
- `source` (string)
- `strategy_type` (string)
- `wallet_address` (string, required)
- `window_hours` (integer)

### `get_my_performance` (~152 tokens)

Your own realised performance, grouped (free read).

Aggregates your journaled non-paper outcomes: win rate, total/average
realised P&L (USD), and technology-service-fee drag, grouped by
strategy_type | asset | decision_type | hour_of_day over window_hours.
Includes a calibration score (your stated expectations vs the realised
24h move) when you journal expectations. Historical performance data
about your own decisions -- descriptive only, not a recommendation.

Workflow: ORIENT step -- read this before sizing or creating strategies.

Input parameters:

- `caller_id` (string)
- `group_by` (string)
- `wallet_address` (string, required)
- `window_hours` (integer)

### `suggest_parameter_adjustment` (~148 tokens)

Historical parameter observations for one of YOUR strategies (free read).

Compares the strategy's realised outcomes against your other strategies
of the same type that ran different parameter values, and returns the
observed differences ranked by realised P&L -- historical performance
data only, never advice, and nothing is changed by this call (PROPOSE
flow: acting on an observation is your call via the strategy tools,
where every policy/risk gate still applies).

Workflow: ORIENT -> DECIDE step -- review observations, then adjust via
strategy tools if YOU decide to.

Input parameters:

- `caller_id` (string)
- `strategy_id` (integer, required)
- `wallet_address` (string, required)

### `get_portfolio_charter` (~178 tokens)

Read the wallet's active portfolio charter -- the CRANK.md-equivalent mandate (free read).

A user-authored document declaring objectives, risk_band, banned
tokens, target_allocations, max_position_pct, rebalance cadence, and
an escalation webhook -- loaded once per session instead of forgotten
between calls (competitors return raw JSON per call and forget
everything). has_charter is False when the wallet has not set one yet
\-- call set_portfolio_charter to create it. Advisory framing only
("objectives"/"parameters", never return targets, hard rules 5-8).

Workflow: ORIENT step 0 -- read this FIRST, before get_balances /
portfolio_snapshot, so every downstream decision is framed by it.

Input parameters:

- `caller_id` (string)
- `wallet_address` (string, required)

### `set_portfolio_charter` (~293 tokens)

Write a new version of the wallet's portfolio charter (free control-plane write).

Creates a new active version -- the prior version stays in history,
never deleted (versioned mandate, not an in-place overwrite).
risk_band is one of conservative|balanced|aggressive. banned_tokens
merge into AgentWallet.evaluate_trade as an ADDITIONAL deny source
alongside WalletPolicy.banned_tokens -- an active WalletPolicy always
wins when it is the stricter rule; a charter can never loosen an
existing policy, and a conflict comes back in the response's
\`warnings` (logged server-side, never silently dropped).
target_allocations is {token: percent}, must sum to <=100.
objectives/cadence are free-form parameters -- never phrase them as
return promises (hard rules 5-8).

Workflow: ORIENT step 0 -- set once at the start of a relationship
with an agent/wallet; strategies read it on every execute_strategy
tick (see get_trading_workflow).

Input parameters:

- `banned_tokens`
- `body_markdown` (string)
- `cadence` (string)
- `caller_id` (string)
- `escalation_webhook` (string)
- `max_position_pct`
- `objectives` (string)
- `risk_band` (string)
- `target_allocations`
- `wallet_address` (string, required)

### `register_webhook` (~215 tokens)

Register (or reactivate) a lifecycle-event webhook for a wallet (free control-plane write).

event_types is a non-empty subset of: pre_trade (advisory only, never
blocks a trade), post_trade, policy_violation, drawdown_warning,
strategy_executed. url is your https(s) receiving endpoint. secret is
YOUR OWN HMAC-SHA256 signing secret (8-128 chars) -- Crank never sends
or stores platform key material here (hard rule 1); you use it to
verify the `X-Crank-Signature` header on every delivered event (see
docs/WEBHOOKS.md). Re-registering the same (wallet_address, url) pair
updates its event_types/secret and reactivates it if it was
auto-disabled after repeated delivery failures.

Input parameters:

- `caller_id` (string)
- `event_types` (array, required)
- `secret` (string, required)
- `url` (string, required)
- `wallet_address` (string, required)

### `list_webhooks` (~40 tokens)

List a wallet's webhook subscriptions (free read; secrets are never returned).

Input parameters:

- `caller_id` (string)
- `wallet_address` (string, required)

### `delete_webhook` (~47 tokens)

Delete one of a wallet's webhook subscriptions (free control-plane write).

Input parameters:

- `caller_id` (string)
- `wallet_address` (string, required)
- `webhook_id` (integer, required)

### `get_collective_insights` (~251 tokens)

Fleet-wide collective insights, historical performance data (free read).

Filters: asset (mint/symbol), strategy_type, insight_type (one of
param_performance/signal_effectiveness/timing/venue_quality/crowding/
regime_conditional). Only ACTIVE, non-suppressed/non-expired insights
are ever returned. Each insight carries n (contributing agents),
effect_size, a confidence interval, k and epsilon_spent (privacy
metadata -- weigh a low-k or high-epsilon insight more cautiously),
crowding_index, and staleness (age vs half-life). detail=concise adds
a rendered human-readable statement; detail=full adds the raw
statement_template/params/signal_keys. Every response is historical
collective performance data aggregated across the Crank agent fleet --
descriptive only, never a recommendation or a promise of results.

Workflow: INTELLIGENCE step -- fleet-wide context alongside
get_market_briefing / get_consensus before sizing or creating strategies.

Input parameters:

- `asset` (string)
- `caller_id` (string)
- `detail` (string)
- `insight_type` (string)
- `strategy_type` (string)

### `get_strategy_leaderboard` (~176 tokens)

Anonymized fleet strategy-parameter leaderboard (free read).

Ranks param_performance collective insights by effect_size within
window (24h|7d|30d|90d|all). NEVER identifies a wallet or cohort --
rankings are anonymized param-bucket aggregates only, and any bucket
with fewer than 25 contributing cohorts (the k-anonymity granular
floor) is dropped before it ever reaches this response. Historical
collective performance data -- descriptive only, never a
recommendation or a promise of results.

Workflow: INTELLIGENCE step -- compare a strategy_type's own parameter
choices against fleet-wide observed outcomes before adjusting via
suggest_parameter_adjustment / the strategy tools.

Input parameters:

- `caller_id` (string)
- `strategy_type` (string)
- `window` (string)

### `get_signal_effectiveness` (~187 tokens)

Fleet action-conditioned signal effectiveness (free read).

Filters: source_type (e.g. youtube/rss/api/on_chain), signal_type,
window (24h|7d|30d|90d|all). Returns, per matching signal_effectiveness
collective insight, the fleet action taken, effect_size, confidence
interval, contributing-agent count n, k, crowding_index, and
staleness. Historical collective performance data aggregated across
the fleet -- descriptive only, never a recommendation or a promise of
results.

Workflow: INTELLIGENCE step -- weigh a signal by how the FLEET's
actions on it have historically resolved, alongside your own
get_source_accuracy / get_my_performance track record.

Input parameters:

- `caller_id` (string)
- `signal_type` (string)
- `source_type` (string)
- `window` (string)

### `propose_allocation` (~205 tokens)

Ranked allocation plan: intent + balances + regime + yields + ML signals (free read).

One call composes the read-only surfaces an agent would otherwise
orchestrate by hand -- lending supply APYs, LST staking yields, the
per-asset market regime, and the ML ensemble signal -- into a ranked,
intent-shaped plan (conservative | balanced | aggressive). Each
directional entry names the exact backtest_strategy args to validate
it BEFORE deploying, plus the follow-up tool that would act on it.
Descriptive analytics only -- never advice, never a promise of
results; nothing is executed.

Workflow: INTELLIGENCE/ANALYSIS step -- call after get_market_briefing
and before backtest_strategy / get_risk_assessment / strategy_*_create.

Input parameters:

- `assets`
- `caller_id` (string)
- `intent` (string)
- `timeframe` (string)
- `wallet_address` (string)

### `compose_strategy` (~87 tokens)

Validate a composite definition -- returns the normalised definition +
validation report. No persist; read = FREE per the fee schedule.

Checks: schema, stream existence against the signal catalog, rule-tree
depth/size limits, required risk caps, and the anti-gaming rule (a social
sentiment/trend_social stream may never be the sole entry trigger).

Input parameters:

- `definition` (object, required)

### `strategy_composite_create` (~151 tokens)

Create a composite strategy from a validated definition.

Same non-custodial create path as the other 16 strategy types: the wallet
holds its own keys; a wallet without a Turnkey signer receives an unsigned
transaction per tick for the owner to sign. ``mode`` defaults to LIVE
(recorded on the config; a paper mode annotation is advisory until the
managed-signing epic lands). Recommended: run compose_strategy +
backtest_strategy on the definition FIRST -- historical results are not
predictive; DYOR.

Input parameters:

- `definition` (object, required)
- `interval_seconds` (integer)
- `mode` (string)
- `risk`
- `wallet_address` (string, required)

### `create_execution_intent` (~209 tokens)

Create a propose-only execution intent; returns an approval URL to hand to the user.

Lane 1 (non-custodial default): builds the unsigned swap transaction
server-side, persists it as an intent, and returns
{intent_id, approval_url}. NOTHING executes until the user opens the
approval URL in their browser and signs with their own wallet. This
tool never signs and never sees a key. amount is in input-token base
units. The quote includes the technology service fee. After the user
approves, poll get_intent_status and report ONLY the persisted
on-chain state (CONFIRMED before any success claim).

Input parameters:

- `allow_unverified` (boolean)
- `amount` (integer, required)
- `caller_id` (string)
- `idempotency_key` (string)
- `input_token` (string, required)
- `output_token` (string, required)
- `slippage_bps` (integer)
- `wallet_address` (string, required)

### `get_intent_status` (~124 tokens)

Read the persisted lifecycle state of an execution intent (free read).

Returns the server-persisted state only -- CREATED, APPROVED,
SUBMITTED, UNKNOWN, CONFIRMED, FAILED, or EXPIRED -- plus the
simulation summary and the on-chain signature once submitted. Never
infers: UNKNOWN means an unresolved send (may have landed); only
CONFIRMED is a verified on-chain success (fail-closed reporting,
docs/CRANK_PLUGIN_SPEC.md section 6).

Input parameters:

- `caller_id` (string)
- `intent_id` (string, required)

## Diagnostics

Captured diagnostic sections: TLS, DNSSEC, Authorisation, Transports. The full working is on the page: https://verifymcp.io/servers/ing-crank-crank/mcp#diagnostics

## Score history

- 2026-08-03: 62
- 2026-08-02: 62
- 2026-08-01: 61
- 2026-07-31: 58
- 2026-07-30: 57
- 2026-07-29: 57
- 2026-07-28: 56
- 2026-07-27: 58

## Links

- Remote endpoint: https://mcp.crank.ing/mcp
- Repository: https://github.com/engaij/crank
- Website: https://crank.ing/
- Changelog RSS feed: https://verifymcp.io/servers/ing-crank-crank/mcp/changelog.xml
- Changelog JSON feed: https://verifymcp.io/servers/ing-crank-crank/mcp/changelog.json
- HTML version of this page: https://verifymcp.io/servers/ing-crank-crank/mcp
