Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 0 additions & 9 deletions .changeset/bound-execute-result-size.md

This file was deleted.

11 changes: 0 additions & 11 deletions .changeset/nft-per-chain-fanout.md

This file was deleted.

20 changes: 20 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,25 @@
# @iqai/mcp-debank

## 2.2.0

### Minor Changes

- 304039f: Fetch whale NFT holdings by fanning out per-chain instead of the slow server-side aggregate.

`getUserAllNftList` previously called DeBank's `/user/all_nft_list`, which aggregates across every chain server-side and takes 10–20 s for active wallets — routinely timing out to nothing for whales (e.g. vitalik.eth). It now discovers the wallet's used chains (`used_chain_list`) and fans out the fast per-chain `/user/nft_list` calls in parallel with bounded concurrency (8), so wall-clock is ≈ (chains / 8) × ~1.5 s.

The method also degrades gracefully instead of failing all-or-nothing: a chain that errors or is too slow is dropped and reported, and the method enforces its own soft deadline (~75% of the call's timeout budget) so it returns the chains that landed _before_ the client's hard abort fires — partial-on-timeout, mirroring the result-size-budget philosophy.

**Return-shape change (guest-facing):** `getUserAllNftList` now resolves to `{ nfts, chains, partial, chains_skipped }` instead of a bare `UserNFT[]`. Read `result.nfts` for the holdings (each NFT is stamped with its `chain`); `partial: true` with `chains_skipped` names the chains to retry (narrow via `chain_ids`, or use `getUserNftList` per chain). The tool description, cookbook, and instructions are updated accordingly.

### Patch Changes

- ca6d059: Bound the `execute` result size so whale-wallet queries can't overflow the consuming model's context window.

The `execute` tool serialized the guest `run()` return value with no size limit and returned it verbatim to the MCP client. For large wallets (e.g. vitalik.eth), whole-portfolio queries — "all token holdings across all chains", "all NFT holdings", "all approvals on Ethereum" — produced payloads of ~500k tokens, which overflowed the consuming agent's context window before the summarizing model call could even run.

There is now a generic size budget enforced at the result boundary (`DEBANK_MCP_EXECUTE_RESULT_BUDGET_CHARS`, default 200,000 chars ≈ 50k tokens). When a result exceeds it, the envelope metadata (`ok` / `error` / `log_lines` / `err_lines`) is kept intact and the bulk `result` is truncated — arrays keep the first N elements, objects trim their largest arrays, strings keep a prefix — with a structured `_truncated: { shown, total, reason, hint }` signal attached so the consumer can answer "showing top N of M — refine to see more" instead of crashing. Results under budget are returned byte-for-byte unchanged.

## 2.1.1

### Patch Changes
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@iqai/mcp-debank",
"version": "2.1.1",
"version": "2.2.0",
"description": "Standalone MCP server for DeBank data access",
"main": "dist/index.js",
"type": "module",
Expand Down
Loading