MetaLend
Server Details
Browse, deposit, withdraw & rebalance stablecoins on Aave, Morpho & Euler across major EVM chains.
- Status
- Healthy
- Last Tested
- Transport
- Streamable HTTP
- URL
- Repository
- rabeles11/metalend-mcp
- GitHub Stars
- 0
- Server Listing
- MetaLend
Available Tools
19 toolsget_auth_challengeGet SIWE auth challengeAInspect
Get a Sign-In-With-Ethereum challenge message for a wallet, required before any deposit/withdrawal/config-update tool. The returned message must be signed with personal_sign (EIP-191) by the wallet's own signer, then passed to submit_auth_verify. Does NOT itself authenticate anything — it only issues the message to sign. Repeated calls for the same walletAddress within a short window (a few minutes) return the SAME message rather than a fresh one — the backend only keeps one pending challenge per wallet at a time, and generating a new one would invalidate whatever an earlier caller is about to sign, so this is deliberate, not a caching bug. chain does not affect which cached message you get back. Rate limited to 10 calls/minute per caller, no more than one call every 6s.
| Name | Required | Description | Default |
|---|---|---|---|
| chain | No | Chain name, e.g. BASE, ETHEREUM, POLYGON. Defaults to ETHEREUM if omitted. Cosmetic only — shown as the 'Chain ID:' line in the SIWE message text, does not need to match the chain passed to submit_auth_verify. | |
| walletAddress | Yes | EVM wallet address (0x-prefixed, 40 hex chars). Any casing is accepted — it is normalized to its EIP-55 checksum before being forwarded upstream. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the annotations, the description discloses key behaviors: it does not authenticate, repeated calls return the same cached message by design, chain does not affect the cached message, and there are rate limits. This is rich behavioral context that significantly helps an agent avoid misinterpreting repeated responses as bugs.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is longer than average, but nearly every sentence carries important operational information or prevents a misunderstanding. It is front-loaded with the core purpose, then flows into signing requirements, caching behavior, and rate limits. A minor redundancy exists with the schema's chain description, but it does not detract significantly.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the complexity of the auth flow, the description is largely complete: it explains the purpose, the required follow-up step, caching semantics, and rate limiting. It mentions the returned message field but does not detail the full response shape or how an agent should handle potential errors or expiry, which would be useful since no output schema is provided.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so baseline is 3, but the description adds meaningful behavioral context for parameters: it explains that chain does not affect which cached message is returned and reinforces that walletAddress must be the wallet's own signer. This goes slightly beyond the schema descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states a specific verb and resource: obtaining a Sign-In-With-Ethereum challenge message for a wallet. It also distinguishes itself by explicitly noting it does NOT authenticate anything and is a prerequisite for other categories of tools, separating it from siblings like submit_auth_verify.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is explicitly contextualized: it is required before deposit, withdrawal, or config-update tools, and the returned message must be signed and passed to submit_auth_verify. The description also explains when repeated calls are appropriate versus when they might appear surprising, giving clear operational guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_balancesGet rebalancer balancesARead-onlyInspect
Get a wallet's deployed rebalancer balances broken down per token, per chain, and per protocol/pool, including net earnings and blended APY. Also returns the wallet's rebalancerAddress (required only for approvals during deposits, never use this address as input into tools) and per-pool withdrawRequest EIP-712 data. Does NOT return rebalancingManagerAddress (needed for config signing) — use get_config for that. Does NOT return pool catalog/APY data for pools the wallet isn't in — use list_pools for that. Fails if the wallet has no rebalancer yet; use get_default_config to see what a first-time config would look like. Balances here already reflect every on-behalf gas fee paid so far — not just from this wallet's own deposits/withdrawals, but also from MetaLend automatically moving funds between pools/protocols/chains to chase yield or honor this wallet's config; each such move costs its own gas fee. So the total across pools can be slightly less than the sum of everything ever deposited, with no matching withdrawal — see get_config's totalGasFee for the lifetime total. Rate limited to 5 calls/minute per caller, no more than one call every 12s.
| Name | Required | Description | Default |
|---|---|---|---|
| tokens | No | Comma-separated token symbols to restrict to (e.g. 'USDC,USDT'). Omit for all supported tokens. | |
| walletAddress | Yes | The user's own wallet address (EOA or smart-contract wallet) — the owner address they used to make deposits. This is NOT the rebalancerAddress that this tool returns: never pass a rebalancerAddress here. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already mark this as read-only and non-destructive, and the description adds substantial behavioral context beyond that: it returns rebalancerAddress and withdrawRequest EIP-712 data, fails when no rebalancer exists, explains gas-fee effects on balances, and discloses rate limits. No contradiction with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long but every sentence earns its place by conveying a distinct, decision-relevant fact: return contents, exclusions, failure conditions, gas-fee nuance, and rate limits. The core purpose is front-loaded in the first sentence.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Despite having no output schema, the description enumerates the main return components (balances, net earnings, APY, rebalancerAddress, withdrawRequest data), handles edge cases (no rebalancer, missing pools), and explains why totals may differ from deposits. An agent has enough context to call this correctly and interpret results.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the schema already documents both tokens and walletAddress. The description reinforces the critical distinction that walletAddress is the user's own address and must never be a rebalancerAddress, adding practical semantic value for invocation correctness.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb, resource, and scope: 'Get a wallet's deployed rebalancer balances broken down per token, per chain, and per protocol/pool'. It also explicitly differentiates from siblings by naming what it does NOT return (rebalancingManagerAddress, pool catalog) and pointing to the correct alternative tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides explicit when-to-use and when-not-to-use guidance: use get_config for rebalancingManagerAddress, list_pools for pool catalog/APY data, and get_default_config for wallets without a rebalancer yet. It also states failure behavior and rate limits, leaving little to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_bridge_balancesGet bridge balancesARead-onlyInspect
Get a wallet's in-transit USDC bridge balances (funds moving cross-chain toward a destination pool), including estimated completion time. Does NOT include already-settled rebalancer balances — use get_balances for those. Only applies to USDC. Other tokens do not support bridging. Each entry's sourcePool is null for a cross-chain deposit in transit, or a populated pool for an internal rebalance moving funds between pools; isForSpending: true marks a funding-cap refill specifically. There is NO trackingId on these entries — they cannot be correlated back to a specific submit_deposit call; use get_deposit_status with the trackingId from that call instead to track one particular deposit. Rate limited to 20 calls/minute per caller, no more than one call every 3s.
| Name | Required | Description | Default |
|---|---|---|---|
| walletAddress | Yes | EVM wallet address (0x-prefixed, 40 hex chars). Any casing is accepted — it is normalized to its EIP-55 checksum before being forwarded upstream. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already mark the tool read-only and non-destructive, and the description adds meaningful behavior beyond that: entries lack a trackingId and cannot be correlated to submit_deposit calls, rate limits are 20 calls/minute with a 3s minimum gap, and sourcePool/isForSpending semantics are disclosed. No contradiction with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The main action is front-loaded, followed by exclusions, data semantics, correlation caveats, and rate limits in logical order. Every sentence adds distinct information relevant to correct selection or invocation, with no filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's moderate complexity, full schema coverage, and annotations that establish read-only safety, the description is complete enough for an agent to know what this tool returns, what it excludes, how to distinguish entry types, why it cannot be used for tracking specific deposits, and how often it can be called.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema has 100% coverage and already fully documents walletAddress, including the 0x-prefix requirement, 40-hex-char length, and EIP-55 normalization. The description adds no additional parameter-level meaning, so the baseline of 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb and resource: 'Get a wallet's in-transit USDC bridge balances.' It clearly scopes the tool by contrasting it with get_balances for already-settled balances and explicitly states it only applies to USDC, so an agent can distinguish it from siblings even before reading schemas.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explicitly tells the agent when not to use this tool ('Does NOT include already-settled rebalancer balances — use get_balances for those'), what token scope applies, and which alternative to use for tracking a specific deposit ('use get_deposit_status with the trackingId from that call instead'). This is direct, actionable routing guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_configGet rebalancer configARead-onlyInspect
Get a wallet's current rebalancer configuration per token: which protocols/pools/chains are enabled, rebalance frequency, lifetime deposits/withdrawals/fees, and spending cap. spendingCapRaw/spendingCapFormatted (USDC only, null/"0" for every other token) is NOT a spending/deposit/withdrawal limit despite the name. When set (nonzero), it's the target balance MetaLend automatically keeps topped up in the wallet's OWN address (not the rebalancer contract) as Aave aUSDC + native USDC on Linea combined — funding a card tied to this wallet that spends directly from that Linea balance. Refills happen automatically on a weekly cycle and after fresh USDC deposits, not instantly. null/"0" means this auto-funding is off, not "uncapped" (there is no general spending ceiling to remove) — see prepare_config's own spendingCapRaw field description for the full mechanics. Also returns rebalancerAddress and rebalancingManagerAddress. Does NOT return live balances — use get_balances for that. rebalancerExists: false means the wallet has never configured a rebalancer; use get_default_config to see recommended starting values. Each configuration's totalGasFee is the lifetime sum of on-behalf gas fees this wallet has paid for this token — not just from deposits/withdrawals it explicitly requested. MetaLend periodically moves a wallet's funds between pools/protocols/chains on its own (chasing better yield, honoring requiredTvl/requiredLiquidityMultiplier/collateralExposure), and each such move is its own on-chain transaction with its own gas fee, deducted the same way a deposit/withdrawal fee is. So a wallet's balance can drift down slightly between get_balances polls with no deposit/withdrawal in between — that's this, not a bug or lost funds. IMPORTANT: configurations always includes a default/template entry for every supported token, whether or not the wallet ever signed one — a matching entry existing does NOT mean the wallet has a real config. Check that entry's hasSignedConfig to know if it's real. Rate limited to 20 calls/minute per caller, no more than one call every 3s.
| Name | Required | Description | Default |
|---|---|---|---|
| walletAddress | Yes | EVM wallet address (0x-prefixed, 40 hex chars). Any casing is accepted — it is normalized to its EIP-55 checksum before being forwarded upstream. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the readOnlyHint annotation, the description thoroughly discloses the subtle semantics: spendingCapRaw is a target balance, not a limit; refills happen automatically on a weekly cycle and after deposits; gas fees are deduced on the wallet; balance can drift due to rebalancing moves; and rate limits are specified. This is far richer than the annotation alone.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is very dense and long, but every sentence adds essential context—semantics, exceptions, rate limits, and sibling relationships. It is not redundant or padded; the verbosity is justified by the tool's complex behavior. Still, it could be slightly trimmed without losing meaning, so a 4 is appropriate.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity (default entries, spending cap semantics, rebalancing side effects, rate limits) and the absence of an output schema, the description covers all needed aspects: what is returned, what is not returned (live balances, use get_balances), how to interpret edge cases (hasSignedConfig, rebalancerExists), and operational constraints (rate limit). Nothing important is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Although the parameter schema already covers 100% of the single input (walletAddress), the description adds crucial semantic detail beyond the schema: it explains that the address is normalized to an EIP-55 checksum before being forwarded upstream. This is non-obvious and not present in the schema, so the description meaningfully enhances understanding.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb ('get'), resource ('rebalancer configuration'), and scope ('per token') in the first sentence, clearly distinguishing it from siblings like get_default_config and get_balances. It also clarifies that the result includes enabled protocols/pools/chains, frequency, lifetime fees, and spending cap, leaving no ambiguity.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly directs the agent to use get_balances for live balances, get_default_config for recommended values when rebalancerExists is false, and prepare_config for the spending cap's full mechanics. It also warns that a default/template entry always exists and instructs checking hasSignedConfig, making it unmistakable when to call this tool versus its siblings.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_default_configGet default rebalancer config for a tokenARead-onlyInspect
Get MetaLend's recommended default rebalancer configuration for a given token symbol (e.g. 'USDC'): rebalancingManagerAddress plus recommended protocolIds/poolAddresses/domainIds. Intended for wallets with no existing config yet — for an existing wallet's current config use get_config instead. Rate limited to 20 calls/minute per caller, no more than one call every 3s.
| Name | Required | Description | Default |
|---|---|---|---|
| token | Yes | Token symbol, e.g. USDC, USDT, MUSD, RLUSD, USDG, USDE, PYUSD. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and destructiveHint=false, and the description adds meaningful behavioral context: the rate limit of 20 calls/minute and a minimum 3s interval between calls. It also clarifies that the returned values are recommendations from MetaLend, which is useful beyond the structured fields.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences carry all necessary information: what the tool does, what it returns, when to use it versus the alternative, and rate limits. There is no filler or repetition, and the core purpose is front-loaded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a single-parameter read-only tool, the description is fully sufficient: it names the input, describes the output fields, states the usage context, gives the alternative, and discloses rate limits. No critical information is missing for an agent to select and invoke it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, and the schema already explains that 'token' is a token symbol with examples. The description repeats the token-symbol framing and adds the e.g. 'USDC' example, but it does not meaningfully extend the parameter semantics beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb ('Get'), a clear resource ('MetaLend's recommended default rebalancer configuration'), the target input ('a given token symbol'), and enumerates the returned fields. It also distinguishes itself from get_config, making the tool's purpose unmistakable.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly says this tool is for wallets with no existing config yet and points to get_config as the alternative for an existing wallet's current config. This gives the agent a clear decision rule rather than leaving usage to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_deposit_statusGet deposit statusARead-onlyInspect
Poll the status of a deposit by trackingId (returned by submit_deposit). status is one of: PROCESSING — still confirming on-chain, keep polling; BRIDGING — deposit accepted, funds are now crossing chains via CCTP to the target pool (typically 20-30 minutes, up to several hours from Linea) — treat this as done, do NOT keep polling waiting for the bridge to finish; SUCCESS — terminal, deposit fully completed (reached directly for a same-chain deposit, or later for a bridged one once funds land — you do not need to wait for it after BRIDGING); FAILED — terminal, deposit did not go through; EMERGENCY_WITHDRAW — terminal but NOT success: after the bridge completed and funds reached the destination chain, the destination pool could not accept the deposit (e.g. it was at capacity), so funds were automatically sent back directly to your OWN wallet address — not to the rebalancer, not lost or stuck. This resolution (bridge completion plus destination-side processing) can itself take 30+ minutes after BRIDGING is first observed, so don't expect it right away. Rate limited to 20 calls/minute per caller, no more than one call every 3s.
| Name | Required | Description | Default |
|---|---|---|---|
| trackingId | Yes | trackingId returned by submit_deposit. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only declare readOnlyHint=true and destructiveHint=false; the description carries the real behavioral burden and delivers. It discloses the rate limit (20 calls/min, max 1 per 3s), the non-blocking BRIDGING semantics, and the subtle EMERGENCY_WITHDRAW resolution where funds return to the caller's own wallet rather than the rebalancer. No contradiction with the read-only annotation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the core purpose before branching into the five status semantics and rate limit. Every sentence earns its place for a polling tool with complex terminal states; slightly dense but justified. The rate limit is appended at the end rather than prioritized, a minor structural nit.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
There is no output schema, so the description must explain return semantics — it does, exhaustively, via the five status values with actionable interpretations. One parameter at 100% coverage, rate limits, and timing expectations all present. Nothing an agent needs to poll correctly or interpret results is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% — trackingId is already documented as 'returned by submit_deposit' in the schema. The description repeats that linkage but adds no syntax or format detail beyond the schema. Baseline 3 is appropriate since the schema carries the parameter documentation.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource (poll deposit status) and the key input (trackingId), and ties it to its producer (submit_deposit), which cleanly separates it from sibling get_withdrawal_status. The purpose is unambiguous and distinct.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides explicit when-to-poll and when-not-to-poll guidance: keep polling on PROCESSING, treat BRIDGING as done and do NOT keep polling, and no need to wait for SUCCESS after BRIDGING. It also sets timing expectations (20-30 min bridge, 30+ min for EMERGENCY_WITHDRAW resolution). The polling contract is fully specified.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_rewardsGet rebalancer rewardsARead-onlyInspect
Get a wallet's aggregated rewards/earnings across all reward sources (e.g. Merkle), including claimed/available USD totals. Does NOT include base rebalancer yield/APY earnings — those are in get_balances' netEarning field. There is NO backend endpoint to submit a claim — this server cannot claim rewards for you. Each rewards[].rewardItems[] entry with an available balance carries an optional claimTransaction (chain-specific, per RewardItem.chain) with everything needed to broadcast the claim directly: to (send the transaction here — this is MetaLend's RebalancingManager contract, NOT the same item's own distributorAddress, which is only an input parameter, not the call target), abi, and pre-encoded calldata. Your own wallet must sign and broadcast this on-chain (this server has no RPC access and cannot do it for you) — if claimTransaction is absent on an item, treat it as nothing currently claimable there (e.g. still vesting) rather than assuming one should exist. Rate limited to 20 calls/minute per caller, no more than one call every 3s.
| Name | Required | Description | Default |
|---|---|---|---|
| reloadChain | No | Chain name to force a fresh reload for (e.g. 'BASE'). Omit to use cached data. | |
| walletAddress | Yes | EVM wallet address (0x-prefixed, 40 hex chars). Any casing is accepted — it is normalized to its EIP-55 checksum before being forwarded upstream. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the readOnlyHint/openWorldHint annotations, the description adds crucial behavior: the server has no RPC access, cannot sign/broadcast claims, is rate limited to 20 calls/minute with min 3s spacing, and claimTransaction absence means nothing is currently claimable. This materially changes how an agent should act.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is dense and front-loaded with the main purpose, but it has some redundancy: 'this server cannot claim rewards for you' and later 'cannot do it for you'. Almost every sentence earns its place, but a bit of tightening would make it fully concise.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given there is no output schema, the description supplies critical output/behavioral context: rewards[].rewardItems[], claimTransaction fields, the distinction between `to` and distributorAddress, and rate limits. An agent has enough information to invoke the tool correctly and understand what the result means.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3. The description does not add parameter-level meaning beyond the schema; walletAddress and reloadChain are already fully described in the input schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb+resource: 'Get a wallet's aggregated rewards/earnings across all reward sources'. It clearly scopes what is included (Merkle, claimed/available USD totals) and explicitly differentiates from get_balances by excluding base rebalancer yield/APY earnings.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives explicit when-not guidance: base rebalancer yield is not included and lives in get_balances' netEarning field. It also warns there is no backend claim endpoint, preventing an agent from attempting to use this tool for claiming rewards.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_token_infoGet token infoARead-onlyInspect
Get a token's on-chain metadata (display name, decimals, EIP-712 version) for a given chain. Needed when building an EIP-3009 deposit signature's tokenName/tokenVersion fields. Rate limited to 6 calls/minute per caller, no more than one call every 10s.
| Name | Required | Description | Default |
|---|---|---|---|
| chain | Yes | Chain name, e.g. BASE, ETHEREUM, POLYGON. | |
| token | Yes | Token symbol, e.g. USDC, USDT, MUSD, RLUSD, USDG, USDE, PYUSD. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already flag this as a read-only, non-destructive call; the description adds rate limiting (6 calls/min, 10s spacing) and the precise data fields returned. This is useful behavioral context beyond annotations, though it omits error handling and any authentication requirements.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences with no fluff: purpose comes first, followed by use-case and rate limit. Every sentence earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 2-parameter read-only lookup with full schema coverage, the description provides the target metadata fields, the exact use-case, and call constraints. Nothing essential for selecting or invoking the tool correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, with both token and chain parameters described and exemplified, so the description does not need to repeat them. The description adds context about how the returned values feed into tokenName/tokenVersion fields, but it provides no parameter-format details beyond what the schema already gives.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and direct object: 'Get a token's on-chain metadata (display name, decimals, EIP-712 version) for a given chain.' This names the exact data returned and the chain dimension, clearly separating it from balance, status, and config sibling tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explicitly says 'Needed when building an EIP-3009 deposit signature's tokenName/tokenVersion fields,' giving a concrete trigger for use. It does not name alternative tools or state when not to use it, so it falls just short of full when/when-not guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_transaction_costsGet transaction costsARead-onlyInspect
Get constant on-behalf deposit/withdraw gas costs and minimum deposit/withdraw amounts for a token, broken down per supported chain. Use before a deposit to check the amount meets the chain's minimum. Rate limited to 20 calls/minute per caller, no more than one call every 3s.
| Name | Required | Description | Default |
|---|---|---|---|
| token | Yes | Token symbol, e.g. USDC, USDT, MUSD, RLUSD, USDG, USDE, PYUSD. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and destructiveHint=false. The description adds a valuable rate limit (20 calls/min, no more than one call per 3s) and clarifies the returned values are constant per chain, which goes beyond annotation coverage.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences front-load the core purpose, then provide usage context and the rate limit. Every sentence earns its place with no redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a one-parameter read-only query tool, the description adequately covers purpose, output breakdown per chain, and rate limiting. No output schema exists, but the return values are sufficiently described.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% and the token parameter already includes a descriptive list of examples. The tool description adds no extra parameter meaning, so the baseline of 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names a distinct resource — constant on-behalf deposit/withdraw gas costs and minimum amounts per chain — with a clear verb 'Get'. This differentiates it from siblings like get_balances or get_token_info without needing to inspect their schemas.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explicitly says to use the tool before a deposit to verify the amount meets the chain's minimum, giving a concrete decision context. It does not name alternative tools, but the timing guidance is clear and actionable.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_withdrawal_statusGet withdrawal statusARead-onlyInspect
Poll the status of a withdrawal by trackingId (returned by submit_withdrawal). status is one of: PROCESSING — still in progress, keep polling (withdrawals have no cross-chain bridging leg, unlike deposits); SUCCESS — terminal, withdrawal completed; FAILED — terminal, withdrawal did not go through. Rate limited to 20 calls/minute per caller, no more than one call every 3s.
| Name | Required | Description | Default |
|---|---|---|---|
| trackingId | Yes | trackingId returned by submit_withdrawal. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already mark readOnlyHint=true and destructiveHint=false. The description adds substantial behavioral detail beyond that: the meaning of each status value, polling expectations (keep polling during PROCESSING), terminal states, and a specific rate limit of 20 calls/minute with a 3-second minimum interval.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three tightly scoped sentences with no filler. The core purpose and parameter provenance come first, followed by status semantics and rate limits — each sentence earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Despite no output schema, the description fully explains the meaningful return values (status enum), what the caller should do for non-terminal statuses, and the rate limiting constraints. This is complete information for a polling tool of this simplicity.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% for the single trackingId parameter, so the baseline is 3. The description reiterates that trackingId comes from submit_withdrawal, which matches the schema and adds no new information beyond it.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Description states a clear action ('Poll the status of a withdrawal') and the exact resource identifier ('trackingId returned by submit_withdrawal'). It distinguishes itself from deposit-related tools by explicitly noting withdrawals have no cross-chain bridging leg, unlike deposits.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides clear context on when to use the tool: when polling a withdrawal's status, with explicit handling guidance for PROCESSING versus terminal states. It doesn't explicitly name an alternative tool for deposits, but the contrast with deposits and the sibling get_deposit_status makes the intended usage clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_withdrawal_versionGet withdrawal contract versionARead-onlyInspect
Get the contract signing version string required for the EIP-712 domain data used when signing a withdrawal. Rarely changes; safe to cache client-side. Rate limited to 10 calls/minute per caller, no more than one call every 6s.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the readOnlyHint and destructiveHint annotations, the description adds valuable behavioral context: the value rarely changes, is safe to cache client-side, and is rate limited to 10 calls/minute per caller with a 6-second minimum interval. This is exactly the kind of operational nuance an agent needs.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences and front-loaded with purpose before behavior. Every clause earns its place: what it returns, why it's needed, caching guidance, and rate limits—no filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a zero-parameter, read-only, no-output-schema tool, this description is complete. It tells the agent what the value is for, how often it changes, how to cache it, and what rate limit to expect.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool takes zero parameters, so the description has no parameter semantics to add. With no parameters and 100% schema coverage, the baseline of 4 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb ('Get'), a precise resource ('contract signing version string'), and its role in EIP-712 domain data for signing withdrawals. This clearly differentiates it from siblings like get_withdrawal_status, which covers status rather than signing versions.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It provides clear context: the version string is required when signing a withdrawal, and the caching guidance implies this is a low-frequency lookup. It does not explicitly name when-not-to-use or alternative tools, so it stops short of a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_poolsList rebalancer poolsARead-onlyInspect
List all pools MetaLend's rebalancer can deposit into: protocol (Aave, Morpho, Euler), chain, APY breakdown (native/rewards/total/net-of-fee), TVL, liquidity, and the signData (protocolId, poolAddress, domainId) needed to build a rebalancer config. Does NOT return a wallet's current balances or configuration — use get_balances / get_config for that. Callers should filter out pools where blacklisted is true. poolTvl/poolLiquidity can read "0" either because the pool is genuinely empty or because upstream data is momentarily missing — the two are not distinguishable here. There is no pool-level paused/capacity/deposit-or-withdraw-enabled flag: deposits can be paused globally, and withdrawals from specific pools can be temporarily blocked per-wallet (e.g. during a funding-cap refill) — neither shows up in this list, only as an error from submit_deposit/submit_withdrawal itself. Rate limited to 20 calls/minute per caller, no more than one call every 3s.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already mark this as read-only and non-destructive, and the description adds substantial behavioral context beyond that: it explains that poolTvl/poolLiquidity may read '0' for two indistinguishable reasons, that blacklisted pools must be filtered, that there is no pool-level paused/capacity flag, and that deposit/withdrawal blocking is invisible here. No contradiction with annotations exists.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Every sentence earns its place: the core purpose is front-loaded, the sibling distinction is explicit, the caveats address realistic misinterpretations, and the rate limit is actionable. Though the description is longer than a one-liner, the tool's data ambiguities and absence of pool-level flags genuinely require this much detail. It remains well-structured and not redundant.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description carries the full burden of explaining the return semantics, and it does so thoroughly: it names the returned fields, clarifies the meaning of zero TVL/liquidity, identifies what is intentionally not returned, and explains how paused/blocked states manifest elsewhere. Nothing essential is missing for an agent to call this tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has zero parameters, so the input schema carries no burden and the description need not explain parameter meaning. The description instead focuses on what the returned list contains, which is appropriate. Since there are no parameters, a baseline score of 4 is warranted, and the description adds no misleading parameter-related claims.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: 'List all pools MetaLend's rebalancer can deposit into.' It then enumerates the exact returned fields (protocol, chain, APY breakdown, TVL, liquidity, signData). It also explicitly distinguishes itself from get_balances and get_config, so an agent can immediately tell it apart from siblings.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives explicit when-to-use and when-not-to-use guidance: it says the tool does NOT return wallet balances or configuration and directs callers to get_balances/get_config. It also instructs callers to filter out blacklisted pools and warns that paused/capacity conditions will only surface as submit_deposit/submit_withdrawal errors, not in this list. Rate limits are also stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
prepare_configPrepare a rebalancer config updateARead-onlyInspect
Build the signing hash for updating a wallet's rebalancer configuration (which pools/protocols/chains it's allowed to move funds into), without signing anything. Computes keccak256(abi.encode(managerAddress, protocolIds, poolAddresses, domainIds, spendingCapRaw)) server-side — sign the returned hashToSign with personal_sign over its raw 32 bytes (not the UTF-8 text of the hex string) and pass the signature to submit_config. Refuses to build a config that would drop a pool you still hold a nonzero balance in — withdraw from it first (prepare_withdrawal) and retry. Also refuses an invalid spendingCapRaw (see its own field description for the exact rules), a non-null collateralExposure with no Aave pool included, containing an untracked symbol, or where no requested Aave pool's live TVL meets requiredTvl, any (domainId, protocolId, poolAddress) tuple that doesn't match a real pool in the current catalog for this token (see list_pools), or a config where every requested pool is blacklisted (see list_pools' blacklisted field) — a deposit under such a config would have no eligible destination and fail later, well after signing — rather than building a hash for it. For a smart-contract wallet: there is no single chain for this signature — the backend derives candidate chains straight from domainIds and requires the SAME signature to independently pass ERC-1271/ERC-6492 verification on EVERY chain named in domainIds, not just one; if the wallet doesn't have (deployed, or via ERC-6492 counterfactual deployment) a valid signer on all of them, the whole update is rejected. That signature must also be cross-chain transferable — supporting ERC-6492 counterfactual deployment does not by itself guarantee that. Some ERC-6492-compliant wallets intentionally bind their signature to a single network domain and are not cross-chain transferable — e.g. Coinbase's Smart Wallet (Base Smart Wallet) supports ERC-6492 but scopes its signature to one chain, so it does not support cross-chain signatures. For a wallet like that, keep domainIds restricted to that single chain (see domainIds' own field description) and sign on that exact chain, rather than mixing pools across chains. An EOA is unaffected (one ECDSA signature covers every chain). Even with a valid signature, submit_config can still be rejected with a 409 if a rebalance or deposit is currently in progress for this wallet+token, or (USDC only) a funding-cap refill is in progress — there is no read-only endpoint to check that ahead of time, so it is NOT pre-validated here; treat a 409 there as temporary and retry later (the error body includes a retryAfterSeconds hint), not as a problem with the signature itself. Rate limited to 5 calls/minute per caller, no more than one call every 12s.
| Name | Required | Description | Default |
|---|---|---|---|
| token | Yes | Token symbol this config applies to, e.g. USDC, USDT, MUSD, RLUSD, USDG, USDE, PYUSD. | |
| domainIds | Yes | Chain domain IDs, one per poolAddresses entry, from list_pools' signData.domainId. Max 200 entries. For a smart-contract wallet, every distinct chain named here must independently verify the SAME signature — the standards supported for smart-wallet signature verification are ERC-1271 and ERC-6492 (counterfactual deployment). Supporting ERC-6492 is not the same as producing a cross-chain-transferable signature: some ERC-6492-compliant wallets intentionally bind their signature to a single network domain, so the same signature will never verify on a second chain regardless of 6492 support. Coinbase's Smart Wallet (Base Smart Wallet) is an example — it does support ERC-6492, but its signatures are domain-bound by design, so it does not support cross-chain signatures. For a wallet like that, keep domainIds single-chain — e.g. all Base, or all Ethereum, matching whichever chain the wallet's signature is scoped to — and sign the hashToSign with that wallet's signer on that exact chain; do not mix pools from other chains into the same config, that combination will always fail verification. | |
| protocolIds | Yes | 0=Aave, 1=Morpho, 2=Euler — one entry per poolAddresses/domainIds entry, from list_pools' signData.protocolId. Pass only the exact set of (domainId, protocolId, poolAddress) pools you intend to allow, with no duplicate entries. Max 200 entries. | |
| requiredTvl | No | Minimum pool TVL in USD required for a pool to be eligible as a rebalance target — pools below this are skipped when the rebalancer picks where to move funds. 0 (default if omitted) disables the filter. Max 500000000. Accepts a number or a numeric string, and is always returned/forwarded as a string to preserve exact decimal precision (the backend stores this as an unrestricted-precision decimal, and get_config's own response already serializes it as a string for the same reason — pass that value straight through, it is never converted through a JS number here, which would silently round a high-precision value). When reconfiguring an existing signed config, copy this wallet's current value from get_config rather than omitting it, or you'll silently reset it to 0 (no floor). | |
| poolAddresses | Yes | Pool contract addresses to allow, from list_pools' signData.poolAddress. Max 200 entries. | |
| walletAddress | Yes | EVM wallet address (0x-prefixed, 40 hex chars). Any casing is accepted — it is normalized to its EIP-55 checksum before being forwarded upstream. | |
| spendingCapRaw | No | Raw units, USDC only (must be "0"/null/omitted for every other token). "0" means this feature is off (the default if omitted or null — get_config's own response serializes it as null, pass that straight through). A nonzero value turns it on and is the TARGET BALANCE MetaLend automatically keeps topped up in the wallet's OWN address (not the rebalancer contract) as Aave aUSDC + native USDC on Linea combined — it funds a card (e.g. MetaMask card) tied to this wallet that spends directly from that Linea balance. It is not a spending/deposit/withdrawal ceiling and does not limit how much can be deposited or withdrawn elsewhere. MetaLend tops the wallet back up toward this target automatically (pulling from the rebalancer's own positions, bridging cross-chain if needed) on a weekly cycle and whenever the wallet makes a fresh USDC deposit — not instantly on every call. It also biases a USDC deposit whose source chain is Linea itself to land in the Linea Aave pool first (the cheapest source for that top-up) while the wallet's own Linea balance is still under this target. Must match exactly between prepare_config and submit_config. If set nonzero, must be at least 1000000 (1 USDC) and the config must include the Aave pool on Linea. | |
| includeRewardsApy | No | Whether reward-token (e.g. Merkle) APY counts toward the total-APY comparison used to pick the best pool to rebalance into — false restricts the comparison to native lending APY only. Defaults to true if omitted. When reconfiguring an existing signed config, copy this wallet's current value from get_config rather than omitting it, or you'll silently reset it. | |
| collateralExposure | No | Whitelist of collateral asset symbols — applies only to Morpho vault selection; a vault is excluded from rebalancing if its own tracked collateral exposure includes any symbol not in this list. Each symbol must be one MetaLend actually tracks exposure for on at least one Morpho vault (see list_pools' collateralExposure values) — rejected here, before signing, otherwise. null (default if omitted) disables the filter entirely — an empty array is rejected, use null instead. Setting this to a non-null list also requires the config to include at least one Aave pool (rejected here, before signing, if none is present) whose live TVL (see list_pools' poolTvl) also meets requiredTvl — also rejected here, before signing, if none of the requested Aave pools currently qualify. When reconfiguring an existing signed config, copy this wallet's current value from get_config rather than omitting it, or you'll silently disable this filter. | |
| requiredLiquidityMultiplier | No | Requires a candidate pool's available liquidity to be at least this multiplier times the deposit amount (USD) before it's eligible as a rebalance target — a liquidity safety margin, not a percentage. 0 (default if omitted) disables the check. Max 1000. Accepts a number or a numeric string, and is always returned/forwarded as a string to preserve exact decimal precision (the backend stores this as an unrestricted-precision decimal, and get_config's own response already serializes it as a string for the same reason — pass that value straight through, it is never converted through a JS number here, which would silently round a high-precision value). When reconfiguring an existing signed config, copy this wallet's current value from get_config rather than omitting it, or you'll silently reset it to 0 (no margin required). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the readOnlyHint/destructiveHint annotations, the description discloses extensive behavioral traits: it computes the hash server-side and signs nothing, refuses to build configs under many enumerated conditions, enforces a rate limit (5 calls/minute, no more than one per 12s), and explains that later 409s at submit_config are temporary. It also details smart-contract wallet ERC-1271/ERC-6492 cross-chain verification nuance, which is far beyond what annotations state.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with its core purpose and is information-dense, but it is a single enormous run-on paragraph; the long enumeration of refusal conditions and the smart-wallet discussion are difficult to scan and partly duplicate guidance already present in field descriptions. Every sentence adds some value, but the lack of bullets or clear segmentation makes it less concise and structured than it should be for this complexity.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given there is no output schema, the description clearly identifies the key return value ('the returned hashToSign') and explains how to consume it (personal_sign over raw 32 bytes, not UTF-8 hex text). It covers preconditions, refusal conditions, rate limiting, error semantics, cross-chain verification behavior, and the follow-up 409 handling at submit_config, leaving essentially nothing an agent needs in order to call the tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3; the description itself does not restate each field but adds cross-parameter behavioral meaning: spendingCapRaw must match between prepare and submit, collateralExposure requires an Aave pool whose live TVL meets requiredTvl, and (domainId, protocolId, poolAddress) tuples must match real catalog entries. This adds tool-level semantics beyond individual schema field descriptions, though some gaps remain because the schema already carries the per-parameter detail.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: 'Build the signing hash for updating a wallet's rebalancer configuration', then clarifies it does this 'without signing anything'. It explicitly names the cryptographic hash (keccak256(abi.encode(...))), the intended consumer (submit_config), and distinguishes itself from signing/submission tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides explicit workflow routing: sign the returned hashToSign and pass it to submit_config; use prepare_withdrawal first if a pool would be dropped; copy current values from get_config when reconfiguring; consult list_pools for valid pools. It also gives when-not-to-use signals, such as refusals for blacklisted pools and the 409-at-submit warning, and warns that a cross-chain-incompatible smart wallet must keep domainIds single-chain.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
prepare_depositPrepare a depositARead-onlyInspect
Build everything needed to deposit into MetaLend's rebalancer, without signing anything. For gasless tokens (USDC, MUSD, PYUSD) returns an EIP-712 ReceiveWithAuthorization typed-data payload — sign it with your own wallet and pass the signature to submit_deposit. For approval-only tokens (USDT, RLUSD, USDG, USDE) returns on-chain approve() parameters instead — your wallet must broadcast that approval itself (this server has no RPC access and cannot do it for you), then call submit_deposit with no signature. The signature flow only accepts a raw 65-byte EOA-style ECDSA signature — smart-contract wallets (including via ERC-6492 counterfactual deployment) are rejected regardless of validity, even for gasless-eligible tokens. A smart-contract wallet should instead pass method: "approval" explicitly here (works for any token, needs no signature at all) — but chain must then be one that wallet can actually transact on (see chain's own field description); this server cannot validate that. Requires a signed rebalancer config for this token already (use prepare_config/submit_config first if get_config shows none) — and validates the amount against the chain's minimum deposit — before returning anything, so a doomed request never reaches signing. A fixed on-behalf gas fee (see fee in the response, also available standalone via get_transaction_costs) is deducted from amount before the rebalancer credits it — the response's expectedCreditedAmountRaw is what will actually show up in get_balances after the deposit lands, not the full amount you send. Rate limited to 6 calls/minute per caller, no more than one call every 10s.
| Name | Required | Description | Default |
|---|---|---|---|
| chain | Yes | Chain name, e.g. BASE, ETHEREUM, POLYGON — the originating chain of this deposit: where the approve() call is broadcast, or for the signature flow, the chain the EIP-712 signature must validate on. Not where the rebalancer later invests the funds — deposits are naturally cross-chain in that sense, and this server only checks that the token has a signed config at all (hasSignedConfig), independent of which chains that config's domainIds allow. For an EOA, this originating chain is supported unconditionally: a raw ECDSA signature has no chain-specific verification step of its own, so any chain works. But when it comes to deposits done on a chain the wallet doesn't have configuration for, the deposit might fail if it's a smart-contract wallet that doesn't support cross-chain signatures (e.g. Coinbase's Smart Wallet / Base Smart Wallet) | |
| token | Yes | Token symbol, e.g. USDC, USDT, MUSD, RLUSD, USDG, USDE, PYUSD. | |
| amount | Yes | Raw token amount as a decimal-digit string (smallest denomination). Use get_token_info for decimals. | |
| method | No | Force a specific flow. Defaults to 'signature' for gasless-eligible tokens, else 'approval'. | |
| walletAddress | Yes | EVM wallet address (0x-prefixed, 40 hex chars). Any casing is accepted — it is normalized to its EIP-55 checksum before being forwarded upstream. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the readOnlyHint annotation, the description discloses major behavioral constraints: the server never signs, has no RPC access, rejects smart-contract wallet signatures, enforces a 6-calls/minute rate limit, validates minimum deposits, and reduces credited amounts by a fee. It also warns about unvalidatable assumptions around cross-chain smart-contract wallet support.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long, but nearly every sentence carries operational information: flow selection, server limitations, prerequisites, validation, fees, and rate limits. It is not tightly structured into sections, but it is front-loaded with the core purpose and contains no filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with no output schema, the description does a good job of explaining what comes back conceptually (EIP-712 typed-data vs approve parameters), the fee field, expectedCreditedAmountRaw, and the later get_balances impact. It could add a concrete response shape, but the workflow, prerequisites, validation, and failure modes are covered well enough for an agent to proceed.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema already covers all parameters with 100% coverage, so the baseline is 3. The description adds real semantic value by explaining the gasless vs approval classification, the smart-contract wallet workaround via method:'approval', and the fee-and-credit relationship for amount. It does not fully replace the schema's detail on chain semantics, but it meaningfully enriches parameter understanding.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb-resource pair ('Build everything needed to deposit into MetaLend's rebalancer') and immediately distinguishes the tool from submit_deposit by stating it does no signing. It clearly partitions gasless tokens and approval-only tokens into two concrete output flows, so an agent can tell exactly what this tool produces.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives explicit when-to-use guidance: use the signature flow for gasless tokens, use approval for others, and force method:'approval' for smart-contract wallets. It names the next-step tool (submit_deposit), the prerequisite flow (prepare_config/submit_config), and the diagnostic tool (get_config), leaving no ambiguity about placement in the workflow.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
prepare_withdrawalPrepare a withdrawalARead-onlyInspect
Build the EIP-712 typed-data payload to sign for withdrawing from a specific pool, without signing anything. Looks up the exact withdrawRequest domain/types/value MetaLend expects from your current balances, fills in amount and a short-lived deadline, and returns it ready to sign with your own wallet. Pass the resulting signature to submit_withdrawal. Omit amount (or pass "MAX") to withdraw the pool's entire balance — this uses the maxUint256 convention rather than the exact current balance, which avoids stale-balance/rounding failures. chain is required: the same pool contract address can exist on multiple chains (e.g. Aave reuses one address across Polygon/Arbitrum/Avalanche/Optimism), so poolContract alone cannot disambiguate a wallet holding balance in that pool on more than one of those chains. Also refuses to build typedData when the pool's live liquidity (see list_pools' poolLiquidity) does not exceed the amount being withdrawn (this also applies to MAX, using the pool's own balance) — the backend would reject the signed request either way, so this catches it before a wallet signs. A fixed on-behalf gas fee (see fee in the response, also available standalone via get_transaction_costs) is deducted from the withdrawn amount before it reaches your wallet — the response's expectedReceivedAmountRaw is what will actually arrive, not the full amount being withdrawn from the pool. Rate limited to 5 calls/minute per caller, no more than one call every 12s.
| Name | Required | Description | Default |
|---|---|---|---|
| chain | Yes | Chain name, e.g. BASE, ETHEREUM, POLYGON. | |
| token | Yes | Token symbol, e.g. USDC, USDT, MUSD, RLUSD, USDG, USDE, PYUSD. Required to disambiguate — some pool addresses serve multiple tokens. | |
| amount | No | Raw amount to withdraw. Omit or pass "MAX" for a full withdrawal (uses maxUint256). | |
| poolContract | Yes | Pool contract address, from get_balances' perPool[].poolAddress. Combined with `chain` to identify the exact balance — the same address can exist on several chains. | |
| walletAddress | Yes | EVM wallet address (0x-prefixed, 40 hex chars). Any casing is accepted — it is normalized to its EIP-55 checksum before being forwarded upstream. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only signal read-only/non-destructive, but the description adds substantial behavior beyond that: it refuses to build when liquidity is insufficient, uses the maxUint256 convention for MAX, deducts an on-behalf fee, returns expectedReceivedAmountRaw, and enforces a 5 calls/minute rate limit. This level of disclosure is well beyond what annotations provide.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Though long, the description is front-loaded with the core purpose and every sentence earns its place: withdrawal mechanics, MAX semantics, chain/token disambiguation, failure pre-checks, fee deduction, and rate limits. Nothing is redundant with the schema or annotations.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description still covers what the response contains (EIP-712 domain/types/value, fee, expectedReceivedAmountRaw) and all preconditions needed to call successfully. Sibling relationships are explicitly named, making the tool's role in the broader workflow clear.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3, but the description adds meaning the schema lacks: amount is optional via omission or the string MAX with a maxUint256 explanation, chain is justified by cross-chain address reuse, and token is explained as a disambiguator for pool addresses serving multiple tokens. This materially improves correct parameter selection.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The first sentence names a specific verb and resource: build an EIP-712 typed-data payload for withdrawing from a specific pool, explicitly noting it signs nothing. It also differentiates from the sibling submit_withdrawal, which consumes the resulting signature, so an agent cannot confuse the two.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives an explicit workflow: call this tool, then pass the signature to submit_withdrawal. It gives conditional usage rules (omit amount or pass MAX for full withdrawal, chain required due to address reuse across chains, refusal when liquidity is insufficient) and references supporting tools such as list_pools and get_transaction_costs.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
submit_auth_verifyVerify SIWE signature and get a JWTAInspect
Exchange a signed SIWE challenge message (from get_auth_challenge) for a JWT scoped to that wallet. The returned jwt must be passed explicitly as the jwt argument to submit_deposit/submit_withdrawal/submit_config for that same wallet — this server does not cache or store it. The JWT is only valid for the walletAddress that produced the signature; using it for a different wallet's write call will be rejected upstream. Reuse the same jwt for subsequent write calls to this wallet instead of re-authenticating every time — the response's expiresAt (decoded from the JWT's own exp claim) says how long it's good for. Rate limited to 5 calls/minute per caller, no more than one call every 12s.
| Name | Required | Description | Default |
|---|---|---|---|
| chain | No | Chain name, e.g. BASE, ETHEREUM, POLYGON. Defaults to ETHEREUM if omitted. For an EOA wallet this is irrelevant (signature recovery is chain-agnostic). For a smart-contract wallet, this MUST be the chain it has (or, if undeployed, would have via ERC-6492 counterfactual deployment) a valid signer on for this signature — it determines which chain's RPC is queried to validate it (ERC-1271/6492), and does not need to match the chain passed to get_auth_challenge. | |
| signature | Yes | personal_sign signature of the SIWE message from get_auth_challenge. | |
| walletAddress | Yes | EVM wallet address (0x-prefixed, 40 hex chars). Any casing is accepted — it is normalized to its EIP-55 checksum before being forwarded upstream. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only say the call is not read-only and not destructive; the description carries the real behavioral burden and does so thoroughly: no server-side caching/storage of the JWT, strict per-wallet validity with upstream rejection for mismatched wallets, expiration via decoded exp, and a precise rate limit.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long but genuinely dense, with the key exchange purpose first and operational constraints following. A little repetitiveness around 'same wallet' exists, but each sentence contributes non-obvious information needed to use the tool safely.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Despite the lack of an output schema, the description names the two response fields that matter for subsequent behavior (jwt and expiresAt) and covers the preconditions, downstream requirements, and rate limiting. There is no apparent gap that would prevent a competent agent from calling it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Though the schema already documents all three parameters (100% coverage), the description adds critical semantics: signature type is personal_sign, chain is irrelevant for EOAs but determines RPC validation for smart-contract wallets via ERC-1271/6492, and walletAddress is normalized to EIP-55 checksum. This materially improves correct invocation.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb-resource pairing: exchange a signed SIWE challenge message for a JWT scoped to a wallet. It names the related get_auth_challenge and submit_* siblings, making the tool's position in the auth/write flow unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explicitly ties this to get_auth_challenge as the source of the signed message and spells out that the JWT must be forwarded to submit_deposit/submit_withdrawal/submit_config. It also advises reusing the JWT instead of re-authenticating, and gives rate-limit constraints—clear operational guidance for when to call it.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
submit_configSubmit a rebalancer config updateADestructiveInspect
Submit a signed rebalancer configuration update. Requires a jwt from submit_auth_verify for this walletAddress and a signature over prepare_config's hashToSign. Always call prepare_config first — this tool does not compute the signing hash or check the balance invariant itself. Can return a 409 if a rebalance or deposit is currently in progress for this wallet+token, or (USDC only) a funding-cap refill is in progress — this is unrelated to the signature and not something prepare_config could have caught; wait and retry (the error body includes a retryAfterSeconds hint). This call can also time out on its own if the backend accepted the update but its response took too long to arrive — if that happens, check get_config afterward rather than assuming it didn't happen. Rate limited to 10 calls/minute per caller, no more than one call every 6s.
| Name | Required | Description | Default |
|---|---|---|---|
| jwt | Yes | JWT from submit_auth_verify for this walletAddress. | |
| token | Yes | Token symbol this config applies to, e.g. USDC, USDT, MUSD, RLUSD, USDG, USDE, PYUSD. | |
| domainIds | Yes | Chain domain IDs, one per poolAddresses entry, from list_pools' signData.domainId. Max 200 entries. For a smart-contract wallet, every distinct chain named here must independently verify the SAME signature — the standards supported for smart-wallet signature verification are ERC-1271 and ERC-6492 (counterfactual deployment). Supporting ERC-6492 is not the same as producing a cross-chain-transferable signature: some ERC-6492-compliant wallets intentionally bind their signature to a single network domain, so the same signature will never verify on a second chain regardless of 6492 support. Coinbase's Smart Wallet (Base Smart Wallet) is an example — it does support ERC-6492, but its signatures are domain-bound by design, so it does not support cross-chain signatures. For a wallet like that, keep domainIds single-chain — e.g. all Base, or all Ethereum, matching whichever chain the wallet's signature is scoped to — and sign the hashToSign with that wallet's signer on that exact chain; do not mix pools from other chains into the same config, that combination will always fail verification. | |
| signature | Yes | Signature over prepare_config's hashToSign. | |
| protocolIds | Yes | 0=Aave, 1=Morpho, 2=Euler — one entry per poolAddresses/domainIds entry, from list_pools' signData.protocolId. Pass only the exact set of (domainId, protocolId, poolAddress) pools you intend to allow, with no duplicate entries. Max 200 entries. | |
| requiredTvl | No | Minimum pool TVL in USD required for a pool to be eligible as a rebalance target — pools below this are skipped when the rebalancer picks where to move funds. 0 (default if omitted) disables the filter. Max 500000000. Accepts a number or a numeric string, and is always returned/forwarded as a string to preserve exact decimal precision (the backend stores this as an unrestricted-precision decimal, and get_config's own response already serializes it as a string for the same reason — pass that value straight through, it is never converted through a JS number here, which would silently round a high-precision value). When reconfiguring an existing signed config, copy this wallet's current value from get_config rather than omitting it, or you'll silently reset it to 0 (no floor). | |
| poolAddresses | Yes | Pool contract addresses to allow, from list_pools' signData.poolAddress. Max 200 entries. | |
| walletAddress | Yes | EVM wallet address (0x-prefixed, 40 hex chars). Any casing is accepted — it is normalized to its EIP-55 checksum before being forwarded upstream. | |
| spendingCapRaw | No | Raw units, USDC only (must be "0"/null/omitted for every other token). "0" means this feature is off (the default if omitted or null — get_config's own response serializes it as null, pass that straight through). A nonzero value turns it on and is the TARGET BALANCE MetaLend automatically keeps topped up in the wallet's OWN address (not the rebalancer contract) as Aave aUSDC + native USDC on Linea combined — it funds a card (e.g. MetaMask card) tied to this wallet that spends directly from that Linea balance. It is not a spending/deposit/withdrawal ceiling and does not limit how much can be deposited or withdrawn elsewhere. MetaLend tops the wallet back up toward this target automatically (pulling from the rebalancer's own positions, bridging cross-chain if needed) on a weekly cycle and whenever the wallet makes a fresh USDC deposit — not instantly on every call. It also biases a USDC deposit whose source chain is Linea itself to land in the Linea Aave pool first (the cheapest source for that top-up) while the wallet's own Linea balance is still under this target. Must match exactly between prepare_config and submit_config. If set nonzero, must be at least 1000000 (1 USDC) and the config must include the Aave pool on Linea. | |
| includeRewardsApy | No | Whether reward-token (e.g. Merkle) APY counts toward the total-APY comparison used to pick the best pool to rebalance into — false restricts the comparison to native lending APY only. Defaults to true if omitted. When reconfiguring an existing signed config, copy this wallet's current value from get_config rather than omitting it, or you'll silently reset it. | |
| collateralExposure | No | Whitelist of collateral asset symbols — applies only to Morpho vault selection; a vault is excluded from rebalancing if its own tracked collateral exposure includes any symbol not in this list. Each symbol must be one MetaLend actually tracks exposure for on at least one Morpho vault (see list_pools' collateralExposure values) — rejected here, before signing, otherwise. null (default if omitted) disables the filter entirely — an empty array is rejected, use null instead. Setting this to a non-null list also requires the config to include at least one Aave pool (rejected here, before signing, if none is present) whose live TVL (see list_pools' poolTvl) also meets requiredTvl — also rejected here, before signing, if none of the requested Aave pools currently qualify. When reconfiguring an existing signed config, copy this wallet's current value from get_config rather than omitting it, or you'll silently disable this filter. | |
| requiredLiquidityMultiplier | No | Requires a candidate pool's available liquidity to be at least this multiplier times the deposit amount (USD) before it's eligible as a rebalance target — a liquidity safety margin, not a percentage. 0 (default if omitted) disables the check. Max 1000. Accepts a number or a numeric string, and is always returned/forwarded as a string to preserve exact decimal precision (the backend stores this as an unrestricted-precision decimal, and get_config's own response already serializes it as a string for the same reason — pass that value straight through, it is never converted through a JS number here, which would silently round a high-precision value). When reconfiguring an existing signed config, copy this wallet's current value from get_config rather than omitting it, or you'll silently reset it to 0 (no margin required). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Even though annotations already mark destructiveHint=true and readOnlyHint=false, the description adds substantial operational traits: 409 collisions with ongoing rebalance/deposit/funding-cap refill, the ambiguous timeout behavior where the backend may have accepted the update, and a rate limit of 10 calls/minute with at least 6s between calls. These failure modes and side-effect risks go well beyond what the annotation bits convey.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a dense, front-loaded paragraph that opens with the operation and prerequisites, then packs only high-value operational caveats into the remaining sentences. There is no filler or repeated schema content, and the length is justified by the number of real edge cases it covers.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given 12 parameters, 7 required, no output schema, and rich input-schema descriptions, the description covers all the non-obvious context an agent needs: required call sequence, 409/retry semantics, ambiguous timeout result, and rate limiting. The success response is not explicitly described, but the explicit 'check get_config afterward' guidance makes that omission non-critical.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% and every parameter has its own detailed description, so the baseline is 3. The tool description reiterates the jwt/signature provenance and the prepare_config ordering, but does not add new parameter-level meaning beyond what the schema already provides.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names an exact action ('Submit a signed rebalancer configuration update') and immediately ties it to required artifacts (jwt from submit_auth_verify, signature over prepare_config's hashToSign). It also explicitly separates itself from prepare_config by noting it does not compute the signing hash or check the balance invariant, so an agent can correctly distinguish this tool from its siblings.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives an explicit order: 'Always call prepare_config first' and states that this tool does not compute the signing hash or check the balance invariant itself. It also tells the agent what to do on a 409 (wait and retry, with a retryAfterSeconds hint) and on timeout (check get_config afterward rather than assuming it didn't happen), which is clear, actionable usage guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
submit_depositSubmit a depositADestructiveInspect
Submit a deposit to MetaLend's rebalancer — moves funds. Requires a jwt from submit_auth_verify for this walletAddress, and either a signature (from prepare_deposit's signature-method output) or, for approval-based tokens, no signature at all once your wallet has already broadcast the approve() transaction on-chain. Always call prepare_deposit first — this tool does not validate amounts or resolve addresses itself (it does reject a partial set of validAfter/validBefore/nonce/signature/tokenName/tokenVersion — provide all six, or none). This call can time out on its own if the backend accepted the deposit but its response took too long to arrive. For a signature-based deposit, the trackingId needed for get_deposit_status is still recoverable then: retry with the exact same signature/nonce — it cannot double-spend (a real duplicate is rejected with a 409 signature-already-used error, which itself confirms the original deposit went through), and that error's message now includes the original trackingId, so read it from there and call get_deposit_status directly rather than escalating to support. If that error's message doesn't include a trackingId (it's only included when the conflicting deposit belongs to this same wallet), treat the timeout as inconclusive rather than a failure and escalate to support with the wallet address and approximate time instead. For an approval-based deposit (no signature), retrying after an uncertain outcome is safe in the ordinary case without needing to check status first: this tool's own amount is only used by the backend to check against your current on-chain allowance before anything is broadcast — the on-chain deposit transaction itself takes no amount parameter, it just pulls and consumes your entire then-current allowance atomically. So if the original attempt already landed, a retry finds a zero allowance and is rejected outright with a 400 ApprovalValidationError from that same pre-flight check, before anything is broadcast on-chain, rather than moving funds again. The one exception: if you separately call token.approve() again for this token/spender while an earlier submit_deposit for it is still outstanding, a retry (or the original call, if it was merely delayed rather than failed) could then consume that new allowance as a second real deposit — avoid re-approving until you've confirmed via get_deposit_status that any earlier attempt for the same token has reached a terminal state. Can also fail with a 403 if the jwt wasn't issued for this walletAddress, or a 503 if deposits are temporarily paused platform-wide. The signature must be a raw 65-byte ECDSA signature (132 hex chars, 0x-prefixed) — anything else, including an ERC-6492-wrapped or other smart-contract-wallet signature, is rejected outright regardless of validity; there is no counterfactual/smart-wallet support for deposit signatures (unlike withdrawal/config signatures). Use the approval method instead for a smart-contract wallet. Rate limited to 10 calls/minute per caller, no more than one call every 6s.
| Name | Required | Description | Default |
|---|---|---|---|
| jwt | Yes | JWT from submit_auth_verify for this walletAddress. | |
| chain | Yes | Chain name, e.g. BASE, ETHEREUM, POLYGON — the originating chain of this deposit: where the approve() call is broadcast, or for the signature flow, the chain the EIP-712 signature must validate on. Not where the rebalancer later invests the funds — deposits are naturally cross-chain in that sense, and this server only checks that the token has a signed config at all (hasSignedConfig), independent of which chains that config's domainIds allow. For an EOA, this originating chain is supported unconditionally: a raw ECDSA signature has no chain-specific verification step of its own, so any chain works. But when it comes to deposits done on a chain the wallet doesn't have configuration for, the deposit might fail if it's a smart-contract wallet that doesn't support cross-chain signatures (e.g. Coinbase's Smart Wallet / Base Smart Wallet) | |
| nonce | No | From prepare_deposit's signature-method output. | |
| token | Yes | Token symbol, e.g. USDC, USDT, MUSD, RLUSD, USDG, USDE, PYUSD. | |
| amount | Yes | Raw token amount as a decimal-digit string (smallest denomination). Use get_token_info for decimals. | |
| signature | No | Signature over prepare_deposit's typedData. Omit for approval-based deposits. | |
| tokenName | No | From prepare_deposit's signature-method output. | |
| validAfter | No | From prepare_deposit's signature-method output. | |
| validBefore | No | From prepare_deposit's signature-method output. | |
| tokenVersion | No | From prepare_deposit's signature-method output. | |
| walletAddress | Yes | EVM wallet address (0x-prefixed, 40 hex chars). Any casing is accepted — it is normalized to its EIP-55 checksum before being forwarded upstream. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Goes far beyond the false readOnly and true destructive annotations by disclosing timeout behavior, retry semantics, double-spend protection via a 409 error, approval-allocation consumption, rate limits, and specific failure modes (400/403/503). This is rich behavioral context that lets an agent predict side effects and handle uncertainty.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a dense, multi-paragraph wall of prose with many nested conditionals; while every sentence is informative, the sheer length and lack of bullet structure reduce scannability. It is front-loaded with purpose and prerequisites, but not concise.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a destructive, time-sensitive deposit tool with no output schema, the description covers auth prerequisites, prepare_deposit dependency, error recovery, retry safety, token approval nuances, rate limits, and cross-chain behavior. An agent can correctly decide how and when to call this tool, including handling ambiguous timeout outcomes.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Even though schema coverage is 100%, the description adds crucial semantics: the 'amount' is only an allowance preflight check, 'signature' must be raw 65-byte ECDSA (not ERC-6492), 'chain' refers to the originating chain, and the optional six fields must be all-or-none. This materially clarifies how to fill the parameters.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Submit a deposit to MetaLend's rebalancer — moves funds') and clearly identifies the operation as a fund-moving deposit. It does not explicitly contrast itself with sibling tools such as submit_withdrawal, but the deposit scope and prerequisite references to prepare_deposit make the purpose unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides explicit when-to-use guidance: 'Always call prepare_deposit first', distinguishes signature-based vs approval-based flows, and directs smart-contract wallets to the approval method. It also spells out the condition to escalate to support instead of retrying, giving clear routing.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
submit_withdrawalSubmit a withdrawalADestructiveInspect
Submit a withdrawal from MetaLend's rebalancer — moves funds. Requires a jwt from submit_auth_verify for this walletAddress and a signature over prepare_withdrawal's typedData. Always call prepare_withdrawal first — this tool does not look up pool data or validate amounts. The signature's EIP-712 domain is scoped to this one chain — for a smart-contract wallet, it must have (or, if undeployed, would have via ERC-6492 counterfactual deployment) a valid signer on that exact chain (an EOA is chain-agnostic and unaffected). This call can time out on its own if the backend accepted the withdrawal but its response took too long to arrive — the trackingId needed for get_withdrawal_status is still recoverable then: retry with the exact same signature — it cannot double-spend (a real duplicate is rejected with a 409 signature-already-used error, which itself confirms the original withdrawal went through), and that error's message now includes the original trackingId, so read it from there and call get_withdrawal_status directly rather than escalating to support. If that error's message doesn't include a trackingId (it's only included when the conflicting withdrawal belongs to this same wallet), treat the timeout as inconclusive rather than a failure and escalate to support with the wallet address and approximate time instead. Can also fail with a 403 if the jwt wasn't issued for this walletAddress, or a 409 if withdrawing from the Linea Aave USDC pool specifically while a funding-cap refill for that wallet is in progress there (temporary; not visible ahead of time from list_pools or get_balances) — wait and retry. Rate limited to 20 calls/minute per caller, no more than one call every 3s.
| Name | Required | Description | Default |
|---|---|---|---|
| jwt | Yes | JWT from submit_auth_verify for this walletAddress. | |
| chain | Yes | From prepare_withdrawal's output. | |
| token | Yes | Token symbol, e.g. USDC, USDT, MUSD, RLUSD, USDG, USDE, PYUSD. | |
| amount | Yes | From prepare_withdrawal's output. | |
| deadline | Yes | From prepare_withdrawal's output. | |
| signature | Yes | Signature over prepare_withdrawal's typedData. | |
| poolContract | Yes | ||
| walletAddress | Yes | EVM wallet address (0x-prefixed, 40 hex chars). Any casing is accepted — it is normalized to its EIP-55 checksum before being forwarded upstream. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Despite annotations already indicating destructive behavior, the description adds extensive runtime behavior: timeout ambiguity, retry idempotence, 409 duplicate semantics, 403 failures, funding-cap conflicts, and rate limits. It even explains the exact recovery path for a timed-out call.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long but every sentence earns its place: prerequisites, failure modes, retry behavior, and rate limits are all operationally critical. It is front-loaded with the core action and call order before moving to edge cases.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a destructive, multi-parameter submission tool with no output schema, the description covers everything an agent needs: required prior calls, signature dependencies, timeout handling, error recovery, and constraints. No material gap remains.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is high (88%), so the baseline is already elevated. The description adds crucial parameter-level nuance beyond the schema: the signature must be over prepare_withdrawal's typedData, the EIP-712 domain is chain-scoped, smart-contract wallet signer requirements, and that amounts are not validated. This materially helps correct invocation.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names a specific verb-resource pair ('Submit a withdrawal from MetaLend's rebalancer') and immediately clarifies the side effect: 'moves funds.' It also distinguishes this tool from prepare_withdrawal by stating that it does not look up pool data or validate amounts.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives explicit prerequisites: a jwt from submit_auth_verify and a signature over prepare_withdrawal's typedData. It says 'Always call prepare_withdrawal first,' and it explicitly routes the agent to get_withdrawal_status using the recovered trackingId instead of escalating. This is strong when/why/alternative guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections. Dates show when Glama detected each change.
19 tool updates
- First observed
get_auth_challenge - First observed
get_balances - First observed
get_bridge_balances - First observed
get_config - First observed
get_default_config - First observed
get_deposit_status - First observed
get_rewards - First observed
get_token_info - First observed
get_transaction_costs - First observed
get_withdrawal_status - First observed
get_withdrawal_version - First observed
list_pools - First observed
prepare_config - First observed
prepare_deposit - First observed
prepare_withdrawal - First observed
submit_auth_verify - First observed
submit_config - First observed
submit_deposit - First observed
submit_withdrawal
Frequently Asked Questions
Claiming proves that you control a remote MCP connector. It does not move, proxy, or interrupt the server.
Open the connector listing, choose Claim ownership, and sign in to Glama.
Complete one verification method:
GitHub identity — fastest for official registry listings. For a namespace such as
io.github.alice/server, link the matching GitHub user, then choose Claim with GitHub. An organization namespace such asio.github.acme/serveralso needs that organization to have installed the Glama AI GitHub App and approved its permissions, because GitHub discloses organization membership only to apps it has installed. Use HTTP or DNS when it has not.HTTP challenge — works when you can deploy a public file. Generate a token, publish the exact JSON Glama shows at
/.well-known/glama.jsonon the same origin as the connector, then choose Check HTTP challenge.DNS challenge — works when you control DNS but cannot change the server. Generate a token, create the exact TXT record Glama shows, wait for it to propagate, then choose Check DNS challenge.
After verification, Glama sends a confirmation email and gives you access to listing details, thumbnails, health checks, and analytics. Keep the HTTP file or DNS record in place: Glama periodically checks it and ownership remains verified while the token is discoverable.
The HTTP ownership file has this structure:
{
"$schema": "https://glama.ai/mcp/schemas/connector.json",
"claim": "glama_claim_..."
}Claim tokens are opaque, stable, and bound to the signed-in Glama account. They contain no email address or other personal information. If Glama can no longer discover a verified HTTP or DNS token, it starts a seven-day grace period before removing claim-based access. Restore the same token during that period to keep ownership verified. Never publish an email address, Glama session token, GitHub token, or connector credential as ownership proof.
If verification fails, confirm that you copied the current token exactly. The HTTP file must be public, return valid JSON with a successful HTTP response, and stay on the connector's origin. DNS changes may need more time to propagate. A claim cannot transfer to a different origin or hostname: if the connector target changes, Glama starts the grace period and the new target must be claimed separately after the previous claim is released.
For a connector linked to the official MCP Registry, registry updates continue to replace its name, description, and URL by default. After claiming, open Manage connector and enable Use Glama listing details as the source of truth if edits made on Glama should be preserved. Categories and thumbnails are always managed on Glama; registry linkage and technical connection settings continue to sync.
Control your server's listing on Glama, including description and metadata
Access analytics and receive server usage reports
Get monitoring and health status updates for your server
Feature your server to boost visibility and reach more users
To improve your MCP server's ranking:
Claim ownership of the server listing
Complete the server profile with an accurate description and thumbnail
Provide a test profile so Glama can connect to and evaluate the server
Keep tool definitions clear and complete to earn a high Tool Definition Quality Score (TDQS)
Route real usage through the Glama Gateway; more recorded successful server uses also improve the ranking
For users:
Full audit trail – every tool call is logged with inputs and outputs for compliance and debugging
Granular tool control – enable or disable individual tools per connector to limit what your AI agents can do
Centralized credential management – store and rotate API keys and OAuth tokens in one place
Change alerts – get notified when a connector changes its schema, adds or removes tools, or updates tool definitions, so nothing breaks silently
For server owners:
Proven adoption – public usage metrics on your listing show real-world traction and build trust with prospective users
Tool-level analytics – see which tools are being used most, helping you prioritize development and documentation
Direct user feedback – users can report issues and suggest improvements through the listing, giving you a channel you would not have otherwise
The connector status is unhealthy when Glama is unable to successfully connect to the server. This can happen for several reasons:
The server is experiencing an outage
The URL of the server is wrong
Credentials required to access the server are missing or invalid
If you are the owner of this MCP connector and would like to make modifications to the listing, including providing test credentials for accessing the server, please contact support@glama.ai.
Discussions
No comments yet. Be the first to start the discussion!
Related MCP Connectors
Leveraged-yield router on Morpho. List strategies, simulate, and build UNSIGNED txs.
Search 700+ DeFi vaults, compare risk scores, analyze protocols. No API key needed.
Crypto yield data for AI agents: lending, savings, staking, borrowing & stablecoin rates. 18 tools.
Barker's real-time stablecoin yield index + AI advisor + non-custodial deposit/redeem (x402 paid).
Related MCP Servers
- FlicenseAqualityDmaintenanceComplete DeFi intelligence — Yield, Staking, Restaking, RWA, Perps, Gas Optimization & Contract Security. One answer, not raw data.17-
- AlicenseAqualityAmaintenanceSelf-custodial crypto portfolio and DeFi MCP server. Read balances and positions (Aave, Compound, Morpho, Uniswap V3, Lido, EigenLayer) across Ethereum, Arbitrum, Polygon, and Base, and prepare transactions for approval on a Ledger via WalletConnect.100914Business Source 1.1
- AlicenseNot gradedqualityBmaintenancePhosphor is a local stablecoin portfolio manager that exposes an MCP server, enabling AI agents to read balances, composition, and costs, and propose actions like consolidation or policy changes, with all execution gated by explicit human approval in the app window.7581MIT
- FlicenseAqualityFmaintenanceDeFi execution and agent-to-agent economy tools for AI agents — swaps, yield, transfers, policy enforcement, trust scoring, A2A jobs, and P\&L across Ethereum, Base, Arbitrum, and Polygon.311-
Glama MCP Gateway
Add one secure layer between your agents and this server.
TDQS
Every tool targets a distinct operation: auth challenge/verify, config read/build/submit, deposit/withdrawal prepare/submit/status, balances, rewards, pools, and small utility lookups. Descriptions explicitly cross-reference one another (e.g., get_balances vs get_bridge_balances vs get_rewards), making accidental misselection very unlikely.
Tool names follow a consistent snake_case verb_noun pattern: get_* for reads, prepare_* for signing-payload construction, submit_* for signed writes, and list_pools for the catalog. The verb families map cleanly onto the tool's lifecycle stages, so the naming is predictable and scannable.
19 tools is on the higher end, but the count is justified by the domain: authentication, config lifecycle, deposit/withdrawal prepare-and-submit flows, status polling, balances, and reward reading each need dedicated surface area. A few utilities (get_token_info, get_transaction_costs, get_withdrawal_version) feel slightly granular, but none are redundant.
The tool set covers the core lifecycle well: auth, config creation/update, deposit, withdrawal, status tracking, balance/reward queries, and pool discovery. Minor gaps exist (no reward claim endpoint, no deposit/withdrawal history listing, no explicit rebalancer deletion), but the descriptions provide workarounds and clearly scope what is intentionally unsupported.