yield-xyz-agentkit — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited yield-xyz-agentkit (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
A skill for discovering and acting on DeFi yield opportunities via the Yield.xyz MCP server.
This skill is the yield layer — it discovers yields, inspects their schemas, and builds unsigned transactions. It never holds keys, signs, or broadcasts, and it's tied to no wallet or custody product. Drop it into any agent or app that can already sign, and it becomes that agent's expertise for earning yield.
Responsibility splits cleanly on every transaction:
unsignedTransaction (actions_enter / actions_exit / actions_manage).submit_hash with the returned hash, then get_transaction until CONFIRMED.This holds whether signing is human-approved or fully autonomous. Where a human is in the loop, confirm before signing; where the host signs on its own, skip the confirmation and let it run.
Always call tools via the connected MCP server (`https://mcp.yield.xyz/mcp`). Never fall back to curl, bash, or raw HTTP requests.
The MCP server exposes these tools directly — call them like any other tool:
DO NOT modify `unsignedTransaction` returned by any action tool under any circumstances. Not addresses, amounts, fees, encoding — nothing.
Modifying unsignedTransaction will result in permanent loss of funds.
For all display rules, number formatting, badges, tables, and action summaries, see [`references/output-formats.md`](./references/output-formats.md).
Never dump raw JSON or plain comma-separated data. Always follow the formats defined there.
MANDATORY: Before displaying any results, read `references/output-formats.md` using the Read tool. Do not skip this step.
You must follow the guidelines defined in [`references/policies.md`](./references/policies.md) for API usage, data fetching, and efficiency.
yields_get_allList and filter yield opportunities across networks and tokens.
Key parameters:
networks — array of network slugs e.g. ["base"], ["ethereum", "arbitrum"]. For unified search pass all in one array. For fair cross-network comparison ("ethereum vs arbitrum", "which network is better") run one call per network in parallel — see Intelligence Notes. Use networks_get_all to resolve a network name if unsure.token — token symbol e.g. "USDC", "ETH", "WBTC" or a contract address.types — array of yield types. Valid values: staking, restaking, lending, vault, fixed_yield, real_world_asset, concentrated_liquidity_pool, liquidity_pool. These are the only valid types. Map user requests to nearest match (e.g. "liquid staking" → staking, "earn" → vault, "LP" → liquidity_pool) or confirm before calling.sort — server-side sort order. Always pass `rewardRateDesc` by default — do not re-sort client-side. Switch to rewardRateAsc, statusEnterDesc, statusEnterAsc, statusExitDesc, or statusExitAsc per user request.search — free-text search across yield names, token names, provider names, and descriptions.yieldIds — batch fetch up to 100 specific yields by ID.inputTokens — filter to yields whose accepted deposit token is in this list — symbols or contract addresses, e.g. ["USDC"]. This is how you scope discovery to a wallet's holdings. A symbol like USDC can over-match contract variants (native vs bridged); pass the contract address when you need an exact token.providers — filter by provider IDs e.g. ["lido", "aave"]. Use providers_get_all to get valid IDs.hasCooldownPeriod — true to show only yields with a cooldown, false to exclude them.hasWarmupPeriod — true to show only yields with a warmup period.limit / offset — pagination (default 20, max 50)Returns: { total, offset, limit, items[] }. Each item has: id, tokenSymbol, network, type, providerId, rewardRate (number, the APY/APR), tvlUsd, status { enter, exit }, cooldownPeriod, warmupPeriod, lockupPeriod, minEntry, maxEntry, kycRequired, authorizeUrl. Use yields_get for full per-yield detail (fees, validators, full reward breakdown).
Use when: User wants to browse or compare yield options.
*Discovery — fetch relevant yields. When a wallet is in context, scope discovery to what it can deposit: pass the wallet's held tokens as `inputTokens` (and their chains as `networks`) so you return only yields that accept a token the wallet holds*, instead of the whole catalog. (Token match isn't a guarantee of entry — that still depends on holding enough vs minEntry, the yield's status.enter, and any gating like RWA KYC.) The base has no wallet — get holdings from the host's signer/wallet (e.g. a connector's balance read). With no wallet in context, discover by the user's stated token / networks instead.
yields_getFetch full details for a single yield opportunity by its ID.
Key parameters:
yieldId — the id field from yields_get_all resultsReturns: Full YieldDto including state, mechanics, risk, statistics.
Use when: User wants deep detail on a specific yield (fees, lockup, validators, etc.).
yields_get_validatorsList validators for a yield that requires validator selection.
Key parameters:
yieldIdlimit / offset — pagination (default 20, max 50)preferred — pass true to return only curated/recommended validators.name — filter by validator name (partial match).status — filter by status e.g. "active", "jailed".address — filter by exact validator address.provider — filter by provider ID.Returns: { total, offset, limit, items: ValidatorDto[] }
Use when: mechanics.requiresValidatorSelection === true, or user asks to pick a validator.
Display & selection rules:
limit: 20 unless the user asks to see more.preferred: true with a "Curated" label.yields_get_balancesFetch the user's balances across one or more yield positions.
Key parameters:
address — single wallet address (string)network — required, e.g. "base", "ethereum"yieldIds — optional array of yield IDs to filterReturns: { items: YieldBalancesDto[], errors: [{ yieldId, error }] }
Each YieldBalancesDto has yieldId and balances: BalanceDto[]. `pendingActions[]` lives on each `BalanceDto` (path: items[].balances[].pendingActions[]), not on YieldBalancesDto. Each pending action has intent, type, passthrough, optional arguments, and optional amount. To act on one, pass pendingActions[].type as the action parameter and pendingActions[].passthrough as passthrough to actions_manage.
Use when: User asks "what are my positions?", "how much am I earning?", or "show my balances".
actions_enterInitiate entering (depositing into) a yield position.
Key parameters:
yieldIdaddress — user's wallet addressamount — human-readable (e.g. "100", never raw wei)validatorAddress — optional; required when mechanics.requiresValidatorSelectionreceiverAddress, useMaxAllowance — optionalmechanics.arguments.enter — pass them as top-level params (there is no args wrapper), and never invent an inputToken paramReturns: ActionDto with transactions: TransactionDto[]
Use when: User wants to stake, deposit, or enter a position.
actions_exitInitiate exiting (withdrawing from) a yield position.
Key parameters:
yieldId, address, amountvalidatorAddress, receiverAddress, useMaxAmount, useAutoClaim — optionaluseInstantExecution — optional; only when the yield offers it (e.g. some RWA redemptions). true → instant settlement, usually for a fee; false → standard NAV redemption, funds settle in ~1–7 business days. Ask the user which they want; never default it silently.passthrough (that's actions_manage only).Returns: ActionDto
Use when: User wants to unstake, withdraw, or exit. Always check cooldown/lockup first.
actions_managePerform a management action on an existing position (claim rewards, restake, change validator).
Key parameters:
yieldIdaddress — user's wallet addressaction — required, action type from pendingActions[].type (e.g. "CLAIM_REWARDS")passthrough — required, from pendingActions[].passthrough in balances responseamount — optional, human-readable amount for partial claims e.g. "10.5". Omit to claim the full available amount.Returns: ActionDto
Use when: User has pending actions on a balance, or wants to claim rewards.
submit_hashSubmit the on-chain transaction hash after the signer has signed and broadcast a transaction.
This is mandatory after every transaction. Never skip this step.
Key parameters:
transactionId — the transaction UUID from the transactions[] array in the ActionDtohash — the on-chain hash returned after broadcasting e.g. "0x1234…abcdef"Returns: Updated TransactionDto
Use when: The signer has signed and broadcast any transaction from an enter, exit, or manage action.
get_transactionPoll the status of a transaction by its ID.
Key parameters:
transactionId — the transaction UUID from the transactions[] arrayReturns: TransactionDto with status: one of NOT_FOUND | CREATED | BLOCKED | WAITING_FOR_SIGNATURE | SIGNED | BROADCASTED | PENDING | CONFIRMED | FAILED | SKIPPED. Terminal states are CONFIRMED, FAILED, and SKIPPED.
Use when: After calling submit_hash, poll until status is terminal (CONFIRMED, FAILED, or SKIPPED) before proceeding. On CONFIRMED continue; on FAILED stop the sequence and report (don't sign later steps); SKIPPED means that step needs no on-chain tx — proceed to the next.
actions_getGet the current status and transactions of a specific action.
Key parameters:
actionId — the action UUID returned by actions_enter, actions_exit, or actions_manageReturns: Full ActionDto with current status and all transactions.
Use when: Checking whether an action has completed, or tracking an async execution pattern where approval may take time.
actions_get_allList past and pending actions for a wallet address.
Key parameters:
address — wallet address to querystatuses — filter by one or more statuses: "CREATED", "PROCESSING", "WAITING_FOR_NEXT", "SUCCESS", "FAILED", "CANCELED", "STALE"intent — filter by "enter", "exit", or "manage"type — filter by action type e.g. "STAKE", "UNSTAKE", "CLAIM_REWARDS"yieldId — filter by yield IDnetwork — filter by networklimit / offset — pagination (default 20, max 100)Returns: Paginated list of ActionDto
Use when: User asks "show my pending actions", "what did I do recently?", or to find actions waiting for a next step.
networks_get_allList all networks supported by Yield.xyz.
Key parameters:
search — filter by name or ID (min 2 chars) e.g. "eth", "bnb", "base"category — filter by "evm", "cosmos", "substrate", or "misc"Returns: Array of { id, name, category, logoURI }
Use when: Resolving a network name the user mentioned (e.g. user says "Binance Smart Chain" → search "bnb" to get the correct slug), or when listing supported chains.
providers_get_allList all supported protocols and validator providers (e.g. Lido, Aave, Morpho).
Key parameters:
limit / offset — pagination (default 20, max 100)Returns: Paginated list with id, name, description, website, tvlUsd, type
Use when: User asks what protocols Yield.xyz supports, or to get valid provider IDs for yields_get_all filters.
yields_get_reward_rate_historyGet historical APY/reward rate snapshots for a yield over time.
Key parameters:
yieldIdperiod — predefined window: "1d", "7d", "30d", "90d", "1y", "all". Default: "30d". Ignored if from/to are set.from / to — ISO 8601 date range e.g. "2025-01-01T00:00:00Z". Overrides period.interval — sampling resolution: "day", "week", "month". Default: "day".limit / offset — pagination (default 30, max 365)Returns: { yieldId, interval, from, to, items: [{ timestamp, rewardRate }], total }
Important: If items is empty (total: 0), historical reward rate data is not available for this yield. This is expected for many yields — it is not an error.
Use when: User asks "has this APY been stable?", "what was the yield last month?", or wants to see APY trends.
yields_get_tvl_historyGet historical Total Value Locked snapshots for a yield.
Key parameters:
yieldIdperiod — predefined window: "1d", "7d", "30d", "90d", "1y", "all". Default: "30d". Ignored if from/to are set.from / to — ISO 8601 date range. Overrides period.interval — "day", "week", "month". Default: "day".limit / offset — pagination (default 30, max 365)Returns: { yieldId, interval, from, to, items: [{ timestamp, tvlUsd }], total }
Important: If items is empty (total: 0), TVL history is not available for this yield. This is expected for many yields — it is not an error.
Use when: User asks about protocol health, TVL growth/decline, or wants to assess liquidity trends.
yields_get_riskGet detailed risk parameters for a yield — more granular than the risk field in yields_get.
Key parameters:
yieldIdReturns: { updatedAt, exponentialFi: { poolRating, poolScore, ratingDescription, url }, credora: { rating, score, ... } }
Important: If the response contains only updatedAt with no exponentialFi or credora fields, detailed risk data is not available for this yield. This is expected for many yields — it is not an error. Fall back to the risk field in yields_get if present.
Use when: User asks about protocol safety, risk rating, or audit status for a specific yield.
yields_get_kyc_statusCheck a wallet's KYC/eligibility status for a permissioned (RWA) yield.
Key parameters:
yieldId — the RWA yield's IDaddress — the wallet address to checkReturns: { kycStatus, authorizeUrl? }. kycStatus is one of not_required | not_started | pending | approved | rejected. authorizeUrl (when present, for not_started / pending) is the issuer's onboarding link.
Use when: Before building an actions_enter for any permissioned RWA yield (kycRequired === true). Proceed only when `kycStatus` is `approved` (or `not_required`). For not_started / pending, send the user to authorizeUrl and stop; rejected means blocked — see references/kyc-flows.md.
YieldDto — a yield opportunity| Field | Description |
|---|---|
id | Unique yield ID — required for all other calls |
network | Chain name (e.g. "base") |
token | Primary input token |
rewardRate | { total, rateType, components[] } — APY/APR |
status | { enter: boolean, exit: boolean } |
mechanics | Lockup, cooldown, fees, validator requirement, entry limits |
statistics | TVL, unique users |
risk | Staking Rewards / Credora ratings |
metadata | Name, logo, description, documentation URL |
TransactionDto — a transaction to execute| Field | Description |
|---|---|
unsignedTransaction | Raw tx data — never modify |
isMessage | If true, sign as message not tx |
gasEstimate | Estimated gas |
explorerUrl | Block explorer link |
yields_get_all with inputTokens set to the held tokens and networks to their chains — so you fetch only yields that accept a token the wallet holds (final entry still checks the held amount vs minEntry and status.enter). With no wallet in context, discover by the user's stated token / networks. (sort: "rewardRateDesc", limit: 20)yields_get on that ID — show reward breakdown + mechanicsrequiresValidatorSelection, call yields_get_validators, present top 10actions_enter → present structured transaction summarysubmit_hash with the tx hash (mandatory)get_transaction until CONFIRMED before proceeding to the next transactionyields_get_balances with wallet address + yield IDspendingActions with claimable amountsactions_manage with passthrough from pending actionsubmit_hash (mandatory)get_transaction until CONFIRMEDyields_get → confirm status.exit === trueactions_exit → return structured transaction summarysubmit_hash (mandatory)get_transaction until CONFIRMEDyields_get_all with token filter, sort: "rewardRateDesc", limit: 20rewardRate.components)yields_get_reward_rate_history — period: "30d", interval: "day"yields_get_tvl_history — period: "30d", interval: "day"items, note that historical data is not available for this yieldyields_get_risk — get detailed risk dataexponentialFi or credora fields, fall back to risk field from yields_getnetworks_get_all with search set to the user's network name e.g. "bnb", "binance"id slug in subsequent callsrewardRate.components — if driven by incentives, flag as potentially short-lived.risk data is present, always show it — never hide from users.limit: 20 each) so every network gets fair representation. Keywords like "show me yields on ethereum and arbitrum", "find yields across chains" → single call (networks: [...], limit: 50). The API sorts globally — without parallel calls for comparisons, a high-APY network will crowd out all others from the results.entryLimits.minimum or maximum, note it proactively.networks_get_all with a search term before calling any other tool.yields_get_tvl_history shows a consistent downward trend, flag it as a potential risk signal.real_world_asset yields may be permissioned (kycRequired === true). Before building an enter for one, call yields_get_kyc_status(yieldId, address); if the wallet isn't verified/eligible, guide KYC via references/kyc-flows.md instead of building the enter (a deposit from a non-allowlisted wallet can revert on-chain). See references/rwa-overview.md.~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.