get_portfolio_tokens
Retrieve token holdings with balances, prices, and metadata for wallet addresses to analyze DeFi portfolios across multiple blockchain networks.
Instructions
Get tokens with balances, prices, and metadata for wallet addresses (uses USER_ADDRESS from env if addresses not provided)
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| addresses | No | Array of address and networks pairs (max 3 addresses, max 20 networks each). Optional - uses USER_ADDRESS from env if not provided | |
| networks | No | Network identifiers to use with USER_ADDRESS (e.g., 'eth-mainnet', 'base-mainnet'). Only used when addresses not provided. Defaults to ['eth-mainnet', 'base-mainnet'] | |
| withMetadata | No | Include token metadata (optional, default: true) | |
| withPrices | No | Include token prices (optional, default: true) | |
| includeNativeTokens | No | Include native tokens like ETH (optional, default: false) |
Implementation Reference
- src/toolService.js:598-648 (handler)Main handler function in ToolService that processes input parameters for get_portfolio_tokens, defaults to user address if not provided, calls AgService, and returns formatted response with summary.async getPortfolioTokens(params) { const { addresses, withMetadata, withPrices, includeNativeTokens, networks, } = params; // Use provided addresses or default to USER_ADDRESS with specified networks let targetAddresses; if (addresses && Array.isArray(addresses)) { targetAddresses = addresses; } else if (this.userAddress) { // Default to USER_ADDRESS with provided networks or common networks const defaultNetworks = networks || ["eth-mainnet", "base-mainnet"]; targetAddresses = [ { address: this.userAddress, networks: defaultNetworks, }, ]; } else { throw new Error( "Either addresses parameter or USER_ADDRESS environment variable is required" ); } const result = await this.agg.getPortfolioTokens(targetAddresses, { withMetadata, withPrices, includeNativeTokens, }); return { message: "Portfolio tokens retrieved successfully", data: result, summary: `Retrieved tokens for ${ targetAddresses.length } address(es) across ${targetAddresses.reduce( (total, addr) => total + addr.networks.length, 0 )} network(s)`, addressUsed: targetAddresses[0].address, options: { withMetadata: withMetadata !== false, withPrices: withPrices !== false, includeNativeTokens: includeNativeTokens || false, }, }; }
- src/index.js:770-822 (schema)Input schema definition and description for the get_portfolio_tokens tool in the MCP tools list.name: TOOL_NAMES.GET_PORTFOLIO_TOKENS, description: "Get tokens with balances, prices, and metadata for wallet addresses (uses USER_ADDRESS from env if addresses not provided)", inputSchema: { type: "object", properties: { addresses: { type: "array", description: "Array of address and networks pairs (max 3 addresses, max 20 networks each). Optional - uses USER_ADDRESS from env if not provided", items: { type: "object", properties: { address: { type: "string", description: "Wallet address", }, networks: { type: "array", items: { type: "string", }, description: "Network identifiers (e.g., 'eth-mainnet', 'base-mainnet')", }, }, required: ["address", "networks"], }, }, networks: { type: "array", items: { type: "string", }, description: "Network identifiers to use with USER_ADDRESS (e.g., 'eth-mainnet', 'base-mainnet'). Only used when addresses not provided. Defaults to ['eth-mainnet', 'base-mainnet']", }, withMetadata: { type: "boolean", description: "Include token metadata (optional, default: true)", }, withPrices: { type: "boolean", description: "Include token prices (optional, default: true)", }, includeNativeTokens: { type: "boolean", description: "Include native tokens like ETH (optional, default: false)", }, }, required: [], },
- src/index.js:1162-1164 (registration)Registration/dispatch in the main switch statement that routes calls to toolService.getPortfolioTokens.case TOOL_NAMES.GET_PORTFOLIO_TOKENS: result = await toolService.getPortfolioTokens(args); break;
- src/services/agService.js:247-278 (helper)Supporting function in AgService that makes the actual API call to the aggregator's /api/portfolio/tokens endpoint.async getPortfolioTokens(addresses, options = {}) { try { const requestBody = { addresses, withMetadata: options.withMetadata, withPrices: options.withPrices, includeNativeTokens: options.includeNativeTokens }; const response = await fetch(`${this.baseUrl}/api/portfolio/tokens`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(requestBody) }); if (!response.ok) { throw new Error(`HTTP ${response.status}: ${response.statusText}`); } const data = await response.json(); if (!data.success) { throw new Error(data.error || 'Portfolio tokens request failed'); } return data.data; } catch (error) { throw new Error(`Failed to get portfolio tokens: ${error.message}`); } }
- src/constants.js:39-39 (registration)Constant definition mapping the tool name for use in registration and dispatch.GET_PORTFOLIO_TOKENS: "get_portfolio_tokens",