使用说明
DefiLama MCP服务器
概述
DefiLama MCP服务器使AI代理能够与 DefiLlama,一个全面的DeFi数据聚合器。该服务器提供对8个服务组和4个上游主机的TVL指标、DEX量、协议统计、稳定币数据、代币价格、收益养殖池、期权数据等的访问。
通过实现模型上下文协议(MCP),该服务器允许大型语言模型(LLM)通过 代码模式 surface:代理编写在沙盒中运行的小型JavaScript程序,而不是每个端点一个工具 isolated-vm 预布线环境 defillama.* 客户。四种选择加入动态工具可用于结构化端点发现和调度。
演示
克劳德正在使用的服务器。代理人使用 search_docs 为了找到正确的方法,为 execute 沙盒,只将答案投射到边界之外。
“哪种方案的TVL 7天变化最大?” --代理加载工具,调用 search_docs 要了解如何读取变化指标,请编写 execute 程序。它注意到原始领导者是一个数据工件(一个TVL从接近零的水平跃升,读数为万亿%的协议),并给出了有意义答案的原因:
然后,它将字面答案(3Jane Lending)与有意义的答案(STRATO,在具有足够TVL的协议中排名第一,使百分比可信)区分开来:
“具有高TVL和30天APY的游泳池” --一个 execute 调用获取收益池,按TVL对其进行排名,并格式化 apyMean30d 在一张桌子上:
需求
- Node.js>=22(需要
isolated-vm6.x代表execute沙盒)。 - 已发布的二进制文件的shebang已经通过
--no-node-snapshot到节点。如果你调用node dist/index.js直接通过--no-node-snapshot你自己:node --no-node-snapshot dist/index.js. isolated-vm在声明中optionalDependencies,所以pnpm install将在没有预构建插件或编译器工具链的平台上成功。服务器仍在启动search_docs仍然有效;仅execute将报告加载失败错误,直到您运行pnpm rebuild isolated-vm.pnpm(用于包装管理和pnpm dlx调用)。
安装
使用pnpm-dlx(推荐)
要使用此服务器而不全局安装,请执行以下操作:
pnpm dlx @iqai/defillama-mcp
从源代码构建
git clone https://github.com/IQAIcom/mcp-defillama.git
cd mcp-defillama
pnpm install
pnpm run build
使用MCP客户端运行
将以下配置添加到MCP客户端设置中(例如。, claude_desktop_config.json).
最小配置
{
"mcpServers": {
"defillama": {
"command": "pnpm",
"args": ["dlx", "@iqai/defillama-mcp"],
"env": {}
}
}
}
高级配置(带IQ网关)
{
"mcpServers": {
"defillama": {
"command": "pnpm",
"args": ["dlx", "@iqai/defillama-mcp"],
"env": {
"IQ_GATEWAY_URL": "your_iq_gateway_url",
"IQ_GATEWAY_KEY": "your_iq_gateway_key"
}
}
}
}
启用动态工具
从开始 --tools=dynamic (或设置 DEFILLAMA_MCP_TOOLS=dynamic)还要注册四个端点调度工具:
{
"mcpServers": {
"defillama": {
"command": "pnpm",
"args": ["dlx", "@iqai/defillama-mcp", "--tools=dynamic"],
"env": {}
}
}
}
注意(克劳德桌面/旧版MCP客户端): Claude Desktop可能会解决
pnpm/node从一个 旧节点 在你的PATH,服务器拒绝(需要节点>=22)。如果启动失败并出现节点版本错误,请参阅 故障排除 在......下面
配置(环境变量)
所有环境变量都是可选的。DefiLlama的公共API未经认证;API密钥和网关设置适用于付费访问或想要缓存的用户。
| 变量 | 必填 | 描述 | 默认值 |
|---|---|---|---|
DEFILLAMA_API_KEY |
否 | DefiLlama API密钥;发送为 x-api-key 直接通话。 |
— |
IQ_GATEWAY_URL |
否 | IQ网关基本URL。与一起设置时 IQ_GATEWAY_KEY,所有上游调用都通过网关代理(添加缓存)。 |
— |
IQ_GATEWAY_KEY |
无 | IQ网关API密钥;发送为 x-api-key 到网关。 |
— |
DEFILLAMA_MCP_TOOLS |
否 | 设置为 dynamic 在默认的两个端点调度工具旁边注册四个额外的端点调度工具。相当于通过 --tools=dynamic. |
— |
故障排除
requires Node >= 22 / ReferenceError: File is not defined
服务器需要 节点>=22 (the execute 沙盒使用 isolated-vm 6.x)。通过启动时 pnpm dlx/npx,该方案的shebang解决了任何问题 node 来 第一 在MCP客户端中 PATH --像Claude Desktop这样的客户端通常会继承 PATH 其中旧节点(例如来自 nvm)是第一。在旧节点下,服务器现在立即退出:
[defillama-mcp] @iqai/defillama-mcp requires Node >= 22 (running v18.17.1).
(旧版本反而以一个神秘的方式崩溃了 ReferenceError: File is not defined 从传递依赖性。)
固定一个绝对节点>=22。 使用Node 22工具链安装包,并将客户端直接指向该Node二进制文件和已安装的条目,绕过 PATH 完全:
# with the Node >= 22 you want to run under:
npm install -g @iqai/defillama-mcp@latest
npm root -g # prints <global>; entry is <global>/@iqai/defillama-mcp/dist/index.js
which node # absolute path to your Node >= 22 binary
{
"mcpServers": {
"defillama": {
"command": "/absolute/path/to/node22/bin/node",
"args": [
"--no-node-snapshot",
"/absolute/path/to/global/node_modules/@iqai/defillama-mcp/dist/index.js"
],
"env": {}
}
}
}
添加 "--tools=dynamic" 作为第三个条目 args 以启用动态工具。
或者,保持 pnpm dlx 但将大于等于22的节点强制施加到 PATH 通过服务器 env:
{
"mcpServers": {
"defillama": {
"command": "/absolute/path/to/node22/bin/pnpm",
"args": ["dlx", "@iqai/defillama-mcp@latest"],
"env": { "PATH": "/absolute/path/to/node22/bin:/usr/local/bin:/usr/bin:/bin" }
}
}
}
开 视窗,使用 ; 路径分隔符和Windows样式的路径 PATH 覆盖(例如。 "PATH": "C:\\Program Files\\nodejs;C:\\Windows\\System32"),和点 command 在 node.exe / pnpm.cmd.
建议使用绝对路径方法——它还避免了每次发射 dlx 取回。
建筑
┌────────────────────────────────────────────────────────────────────────────┐
│ Claude Desktop / Cursor / any MCP client │
└─────────────────────────────────┬──────────────────────────────────────────┘
│ stdio (JSON-RPC)
▼
┌────────────────────────────────────────────────────────────────────────────┐
│ defillama-mcp server │
│ ┌──────────────────────────────────────────────────────────────────────┐ │
│ │ Default tools │ Dynamic tools (opt-in via --tools=…) │ │
│ │ ────────────────────── │ ────────────────────────────────── │ │
│ │ execute │ defillama_resolve │ │
│ │ search_docs │ list_endpoints │ │
│ │ │ get_endpoint_schema │ │
│ │ │ invoke_endpoint (with jq_filter) │ │
│ └──────────────────────────────────────────────────────────────────────┘ │
│ │ │ │
│ ┌─────────▼──────────────┐ ┌──────────▼──────────────┐ │
│ │ isolated-vm sandbox │ │ direct dispatch │ │
│ │ • 128 MiB cap │ │ • zod schema validate │ │
│ │ • 30 s wall clock │ │ • 5 s / 6 s timeouts │ │
│ │ • scope budget+slots │ │ • jq projection │ │
│ └────────────────────────┘ └─────────────────────────┘ │
│ └──────────────┬──────────────────┘ │
└───────────────────────────┼────────────────────────────────────────────────┘
│ HTTPS (optional API key or IQ Gateway)
▼
┌──────────────────────────────────────────────┐
│ DefiLlama upstream (4 hosts) │
│ api.llama.fi coins.llama.fi │
│ stablecoins.llama.fi yields.llama.fi │
└──────────────────────────────────────────────┘
如何 execute 作品(一次通话的生命周期)
sequenceDiagram
participant Agent
participant Tool as execute (tool.ts)
participant Sandbox as runInSandbox (sandbox.ts)
participant Guest as Guest JS<br/>(V8 isolate)
participant Bridge as installServiceCall<br/>(client.ts)
participant DefiLlama as DefiLlama API
Agent->>Tool: tools/call execute {code}
Tool->>Tool: createExecutionScope()<br/>(budget=100, concurrency=10)
Tool->>Sandbox: runInSandbox(code, installClient)
Sandbox->>Sandbox: new Isolate({memoryLimit:128MB})
Sandbox->>Bridge: installDefillamaClient(ctx, scope)
Bridge-->>Guest: install defillama.protocol.*, defillama.price.*, resolveChain, ...
Sandbox->>Guest: script.run({timeout:30s})
Guest->>Bridge: await defillama.protocol.getChains({})
Bridge->>Bridge: tryReserveBudget<br/>acquireSlot<br/>safeParse(args)
Bridge->>DefiLlama: HTTPS (5s abort + 6s axios timeout)
DefiLlama-->>Bridge: JSON
Bridge-->>Guest: envelope {ok:true, data}
Guest-->>Sandbox: return projected result
Sandbox-->>Tool: {ok, result, log_lines, err_lines}
Tool->>Tool: cancelScope() in finally
Tool-->>Agent: MCP envelope
关键见解: 只有投影返回值穿过V8边界代理编写循环、连接和过滤的JS;主机看到一个返回值,而不是N个中间响应。
代码模式
从AI代理查询DefiLama的首选方式是 execute + search_docs 一对。这两个工具通过代理编写的JavaScript处理完整的工作流程——发现、投影、多步骤组合。
默认刀具表面
默认情况下,服务器只注册两个工具:
| 工具 | 目的 |
|---|---|
execute |
在安全的环境中运行代理编写的JavaScript isolated-vm 在完全配置的DefiLama客户端上使用沙盒。处理多步骤工作流、循环、连接、条件逻辑和自定义投影。 |
search_docs |
在所有DefiLlama API方法和食谱条目上搜索嵌入式MiniSearch索引。 |
--tools=dynamic 模式
使用启动服务器 --tools=dynamic (或设置 DEFILLAMA_MCP_TOOLS=dynamic)注册四个附加工具:
| 工具 | 目的 |
|---|---|
defillama_resolve |
将人类可读的名称(“BSC”、“Lido”、“USDC”)解析为其DefiLama标识符。 |
list_endpoints |
列出所有可用的端点限定名称及其说明。 |
get_endpoint_schema |
检查特定端点的参数和响应形状。 |
invoke_endpoint |
使用可选的限定名调用单个端点 jq_filter 用于主机侧投影。 |
使用动态工具配置MCP客户端:
{
"mcpServers": {
"defillama": {
"command": "pnpm",
"args": ["dlx", "@iqai/defillama-mcp", "--tools=dynamic"],
"env": {}
}
}
}
或者通过环境变量:
{
"mcpServers": {
"defillama": {
"command": "pnpm",
"args": ["dlx", "@iqai/defillama-mcp"],
"env": {
"DEFILLAMA_MCP_TOOLS": "dynamic"
}
}
}
}
execute --沙盒JavaScript
在安全环境中运行任意JavaScript isolated-vm 沙箱。沙盒接收一个完全配置的DefiLama客户端,作为 defillama。所有八个服务组都可用。
定义 async function run(defillama) { ... };JSON可序列化返回值(加号 console.log 输出)被发回。
示例——TVL的前5个协议:
async function run(defillama) {
const protocols = await defillama.protocol.getProtocols();
return protocols
.sort((a, b) => (b.tvl ?? 0) - (a.tvl ?? 0))
.slice(0, 5)
.map(p => ({ name: p.name, tvl: p.tvl, chain: p.chain }));
}
示例——ETH和USDT的当前价格:
async function run(defillama) {
return await defillama.price.getCurrentPrices({
coins: 'coingecko:ethereum,ethereum:0xdac17f958d2ee523a2206206994597c13d831ec7'
});
}
defillama.* 客户群
这 defillama 客户端内部 execute 分为八组,反映上游服务架构:
| 组 | 方法 | 上游主机 |
|---|---|---|
defillama.protocol |
getChains, getProtocols, getProtocol, getHistoricalChainTvl |
api.llama.fi |
defillama.dex |
getDexSummary, getDexsOverview |
api.llama.fi |
defillama.fees |
getFeesSummary, getFeesOverview |
api.llama.fi |
defillama.options |
getOptionsSummary, getOptionsOverview |
api.llama.fi |
defillama.stablecoin |
getStablecoins, getStablecoinChains, getStablecoinCharts, getStablecoinPrices |
stablecoins.calla.fi |
defillama.price |
getCurrentPrices, getFirstPrices, getBatchHistorical, getHistoricalPrices, getPercentageChange, getPriceChart |
coins.lama.fi |
defillama.yield |
getLatestPools, getHistoricalPoolData |
yields.llama.fi |
defillama.blockchain |
getBlockAtTimestamp |
coins.lama.fi |
解析器
内部有三个解析器助手 execute:
resolveChain(input)--将人名解析为{ name, slug }.使用.name为了api.llama.fi组(协议、dex、费用、选项)和.slug为了coins.llama.fi电话(价格、区块链)。resolveProtocol(input)--将协议名称解析为其DefiLama字符串(例如。"lido").resolveStablecoin(input)--将稳定币名称或符号解析为其数字DefiLama ID字符串(例如。"1"对于USDT)。
例子:
async function run(defillama) {
const chain = await defillama.resolveChain('BSC');
// chain = { name: 'BSC', slug: 'bsc' }
const overview = await defillama.dex.getDexsOverview({ chain: chain.name });
return overview.protocols?.slice(0, 5).map(p => ({ name: p.name, volume: p.total24h }));
}
链名与段塞约定
DefiLama根据主机使用两个链式拼写:
- api.lama.fi集团 (
protocol,dex,fees,options)使用链条 显示名称 --例如。"Ethereum","BSC". - coins.lama.fi的电话 (
price,blockchain)使用小写字母 蛞蝓 --例如。"ethereum","bsc".
resolveChain(x) 回报 { name, slug }。始终使用 .name 对于api组参数和 .slug 用于硬币组参数。
价格硬币格式-- chain:address
这 price 组将令牌标识为 chain:address,使用小写链段塞:
ethereum:0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2--以太坊上的WETHcoingecko:ethereum--通过CoinGecko ID获取原生ETH(无需合约地址)bsc:0x55d398326f99059ff775485246999027b3197955--BSC上的USDT
多个标记以逗号分隔:
await defillama.price.getCurrentPrices({
coins: 'coingecko:ethereum,ethereum:0xdac17f958d2ee523a2206206994597c13d831ec7'
})
search_docs --本地文档搜索
在所有DefiLlama API方法和食谱条目上搜索嵌入式MiniSearch索引。当你不确定你需要哪种方法或参数,或者找到一个有效的配方时,先使用它。
查询示例: top protocols tvl
安全限制
这 execute 沙盒强制执行五个边界。默认值已调整为合法值 Promise.all-风格工作。
| 限制 | 默认 | 覆盖 | 命中时的行为 |
|---|---|---|---|
| 隔离内存 | 128MiB | 硬编码 | 隔离终止;错误表现为脚本超时(V8在某些路径中将OOM与超时混为一谈) |
| 脚本挂钟 | 30秒 | 内部(仅测试) | 返回 "Execute timed out after 30s." |
通话次数 execute |
100 | 内部(仅限测试) | 后续客人来电返回预算超出错误 |
| 并发调用 | 10 | 内部(仅限测试) | 信号量上的调用队列;没有错误,只是背压 |
| 上游每次调用 | 5秒中止+6s轴 | 硬编码 | 返回 "DefiLlama call timed out after 5s: <method>" |
这些限制保护了DefiLama的公共速率限制,这些限制与任何用户凭据无关。
沙盒还会阻止源代码级标识符 process., require(, import(,以及 eval( 在提交时作为深度防御检查。
模式验证在每个客户机调用上强制执行:在到达上游服务之前,根据方法的已发布模式对参数进行zod解析。无效的参数返回一个明确的错误消息,而不是传播到API。
invoke_endpoint 随着 jq_filter
invoke_endpoint (in --tools=dynamic 模式)接受可选 jq_filter 预测反应 在它回到代理之前 --减少响应大小并跳过客户端解析。
{
"name": "defillama.protocol.getChains",
"params": {},
"jq_filter": "[.[] | {name, tvl}] | sort_by(-.tvl) | .[0:5]"
}
常见模式:
| 目标 | jq过滤器 |
|---|---|
| 项目一现场 | .name |
| 从每个项目中挑选 | .[] | {name, tvl} |
| 过滤然后投影 | [.[] | select(.tvl > 1000000) | .name] |
| 聚合 | [.[] | .tvl] | add |
过滤器贯穿 间隙可调式球团圆辊筛 (纯JS,无原生 jq 二进制),因此它适用于每个平台。
错误信封
每个工具都返回MCP标准 { content: [{ type, text }], isError } 信封。这 text JSON包含以下之一:
| 形状 | 你什么时候能看到 |
|---|---|
{"ok": true, "result": ..., "log_lines": [], "err_lines": []} |
execute 成功; result 不管怎样 run(defillama) 返回 |
{"ok": false, "error": "...", "log_lines": [], "err_lines": [...]} |
execute 失败;上述安全限制中列出的规范消息 |
{"results": [...]} |
search_docs 点击数 |
{"resolved": {"name","slug"}} (链式)/ {"resolved": "<slug-or-id>"} (协议/稳定币)或 {"resolved": null, "error": "..."} |
defillama_resolve |
{"endpoints": [...]} |
list_endpoints |
{"qualified", "description", "params", "response", "exampleCall"} |
get_endpoint_schema |
| 原始方法JSON(或jq投影) | invoke_endpoint 成功 |
{"error": "..."} |
invoke_endpoint 失败 |
错误永远不会跨越VM边界——每一个客户机端故障都会表现为 { ok: false, error } 信封。
从早期版本迁移
约19个特定终点 defillama_* 工具是 移除.使用 execute 对于多步骤工作流,或从 --tools=dynamic 对于每端点调度三元组:
list_endpoints--发现可用端点及其限定名称。get_endpoint_schema--检查特定端点的参数和响应形状。invoke_endpoint--使用可选参数调用单个端点jq_filter用于主机侧投影。
这 OPENROUTER_API_KEY, LLM_MODEL,以及 GOOGLE_GENERATIVE_AI_API_KEY env变量不再被识别。
ADK使用
@iqai/defillama-mcp 导出与ADK兼容的辅助程序:
import { getDefillamaTools } from "@iqai/defillama-mcp/dist/adk/index.js";
// Default surface (execute + search_docs) — 2 tools
const tools = getDefillamaTools();
// With dynamic tools enabled — 6 tools
const allTools = getDefillamaTools({ dynamic: true });
getDefillamaTools() 回报 BaseTool[] 从 @iqai/adk这些封装了相同的MCP工具实现,可以放入任何ADK代理中。
发展
生成项目
pnpm run build
开发模式(观看)
pnpm run watch
装订和格式化
pnpm run lint
pnpm run format
测试
pnpm test
发布管理
pnpm changeset # Create a release note
pnpm version-packages # Apply pending changesets
pnpm publish-packages # Build and publish
项目结构
src/
├── index.ts # Server entry point (FastMCP registration)
├── env.ts # Env validation (dotenv + zod)
├── config.ts # Per-group cache TTLs
├── types.ts # Shared TypeScript types
├── adk/index.ts # getDefillamaTools() ADK adapter
├── services/ # DefiLlama API client (one *.service.ts per domain)
│ └── base.service.ts # RequestOptions, IQ-Gateway + direct fetch
├── lib/
│ ├── entity-resolver.ts # resolveChain / resolveProtocol / resolveStablecoin
│ └── utils/ # logger, error-handler
├── mcp/
│ ├── tools.ts # defillama_resolve (dynamic mode)
│ ├── execute/ # Code Mode: sandbox + client + scope + tool
│ ├── search-docs/ # MiniSearch index + tool + cookbook recipes
│ ├── endpoints/ # list_endpoints / get_endpoint_schema / invoke_endpoint
│ ├── instructions/ # instructions.md → instructions.generated.ts
│ └── catalog/ # tool-metadata + response-schemas (shared)
└── enums/chains.ts # Bundled chain catalog (fallback when live fetch fails)
scripts/
├── build-docs-index.ts # Pre-build: tool-metadata + cookbook → embedded-index.ts
└── build-instructions.ts # Pre-build: instructions.md → instructions.generated.ts
tests/integration/ # End-to-end tests (spawn the built server)
资源
免责声明
该项目是一个非官方工具,与DefiLama没有直接关联。它通过DefiLlama的公共API与DeFi协议数据交互。用户应谨慎行事,独立验证所有数据。DeFi涉及风险。
