An extensible TypeScript toolkit for EVM and Solana blockchain interactions. Up to 205 composable tools (191 without optional API credentials) covering on-chain actions, DeFi protocols, market data, and off-chain services — designed for AI agents, MCP clients, and developers.
Requires Node.js 20.18.1 or newer.
CLI (fastest way to try it):
npx @agentek/cli list # browse up to 205 tools
npx @agentek/cli info getBalance # inspect a specific tool
npx @agentek/cli exec getBalance --json '{"chainId":1,"address":"0x0000000000000000000000000000000000000000"}'MCP Server (for Claude Desktop, Cursor, etc.):
pnpx @agentek/mcp-serverTypeScript SDK:
pnpm add @agentek/tools| Package | Description | Version |
|---|---|---|
@agentek/tools |
Core toolkit — up to 205 tools | 0.1.26 |
@agentek/ai-sdk |
Vercel AI SDK integration | 0.1.26 |
@agentek/mcp-server |
Model Context Protocol server | 0.1.26 |
@agentek/cli |
Command-line interface | 0.0.2 |
@agentek/gym |
Agent evaluation on disposable Anvil forks | 0.0.1 |
@agentek/nani |
Private host-integrated Nani bundle | 0.1.0 |
Versions above are workspace manifest versions; they do not establish npm publication status.
- Node.js >= 20.18.1
- pnpm (for development)
- Bun for the private Nani bundle build
- Foundry/Anvil for Gym fork environments and integration tests
# Core tools
pnpm add @agentek/tools viem zod
# Vercel AI SDK integration
pnpm add @agentek/ai-sdk @agentek/tools viem zodimport { allTools } from '@agentek/tools';
import { AgentekToolkit } from '@agentek/ai-sdk';
import { http } from 'viem';
import { mainnet } from 'viem/chains';
const tools = await allTools({
perplexityApiKey: process.env.PERPLEXITY_API_KEY,
zeroxApiKey: process.env.ZEROX_API_KEY,
});
const toolkit = new AgentekToolkit({
accountOrAddress: '0x...',
chains: [mainnet],
transports: [http()],
tools,
});
// Pass to Vercel AI SDK
const aiTools = toolkit.getTools();import { createAgentekClient } from '@agentek/tools/client';
import { allTools } from '@agentek/tools';
import { http } from 'viem';
import { mainnet } from 'viem/chains';
const tools = await allTools({});
const client = createAgentekClient({
accountOrAddress: '0x...',
chains: [mainnet],
transports: [http()],
tools,
});
const result = await client.execute('getBalance', {
address: '0x...',
chainId: 1,
});Add to your claude_desktop_config.json:
{
"mcpServers": {
"agentek": {
"command": "pnpx",
"args": ["@agentek/mcp-server"],
"env": {
"ACCOUNT": "YOUR_ETHEREUM_ADDRESS",
"PERPLEXITY_API_KEY": "...",
"TALLY_API_KEY": "..."
}
}
}
}Use ACCOUNT for address context and unsigned EVM intents. Configure a signer
or PRIVATE_KEY to submit EVM transactions; Solana signing is configured separately.
See the MCP Server README for full configuration details.
# List all available tools
npx @agentek/cli list
# Search for tools by keyword
npx @agentek/cli search "swap"
# Get detailed info about a tool
npx @agentek/cli info intentApprove
# Execute a tool
npx @agentek/cli exec getCryptoPrice --symbol ethereumSee the CLI Guide for complete documentation.
You don't have to use all 205 tools. Import only what you need:
import { rpcTools, erc20Tools, defillamaTools } from '@agentek/tools';
const tools = [
...rpcTools(),
...erc20Tools(),
...defillamaTools(),
];allTools({}) returns 191 tools. Optional service credentials add up to 14
more; availability depends on configuration. Host-integrated Nani tool sets
may expose a different selection. Tool support also varies by chain.
| Module | Tools | Description |
|---|---|---|
| rpc | 11 | getBalance, getBlock, getBlockNumber, getGasPrice, getTransaction, getTransactionReceipt, getCode, getTransactionCount, estimateGas, getFeeHistory, intentSendTransaction |
| erc20 | 8 | getBalanceOf, getAllowance, getTotalSupply, getDecimals, getName, getSymbol, getTokenMetadata, intentApprove |
| transfer | 2 | intentTransfer, intentTransferFrom |
| erc721 | 1 | getNFTMetadata |
| erc6909 | 3 | Token balance, metadata, and transfer intents |
| ens | 2 | resolveENS, lookupENS |
| resolveToken | 1 | resolveToken — token address and metadata resolution |
| contract | 2 | readContract, intentWriteContract — generic contract interaction |
| approvals | 7 | Permission discovery/observations, selected revocation plans, and approval revocation intents |
| wns | 19 | resolveWNS, isAvailableWNS, intentRegisterWNS, and 16 more naming tools |
| Module | Tools | Description |
|---|---|---|
| aave | 7 | Account observations and lending/borrowing: getAaveUserData, getAaveReserveData, deposit, withdraw, borrow, repay intents |
| uniV3 | 11 | Position discovery/observations and liquidity: getUniV3Pool, getUserPositions, getPoolFeeData, mint/increase/decrease/collect/transfer intents |
| swap | 1 | intent0xSwap — token swaps via 0x aggregator |
| weth | 2 | depositWETH, withdrawWETH |
| zamm | 5 | getCoin, getHolders, getAccountPortfolio, getPool, getSwaps |
| zrouter | 2 | getQuote, intentSwap — cross-DEX routing |
| x402 | 3 | x402Fetch, getX402PaymentInfo, x402DiscoverResources — HTTP 402 payments |
| defillama | 6 | getYieldTool, getYieldPoolEvidence, compareYieldTool, getYieldHistoryTool, compareYieldHistoryTool, getTokenChart |
| Module | Tools | Description |
|---|---|---|
| across | 3 | getAcrossRoutes, getAcrossFeeQuote, intentDepositAcross |
| slowTransfer | 12 | Slow-release transfers with guardian controls |
| Module | Tools | Description |
|---|---|---|
| dexscreener | 1 | getLatestTokens — trending token discovery |
| researchCA | 1 | researchCA — aggregate EVM contract, token/NFT, holder, mint-history, privilege, and pool diligence with explicit data-completeness qualifiers |
| cryptoprices | 1 | getCryptoPrice — current prices via CoinGecko |
| coindesk | 1 | getLatestCoindeskNewsTool — crypto news |
| coinmarketcal | 1 | getMarketEvents — upcoming market events |
| feargreed | 1 | getFearAndGreedIndex |
| gasestimator | 3 | estimateGasCost, quoteNaniBatch, quoteNaniNativeMax — gas estimates and unsigned execution quotes |
33 tools covering addresses, transactions, blocks, tokens, smart contracts, and search across supported networks.
| Module | Tools | Description |
|---|---|---|
| tally | 5 | tallyProposals, tallyChains, tallyUserDaos, intentGovernorVote, intentGovernorVoteWithReason |
| nani | 5 | getNaniProposals, intentStakeNani, intentUnstakeNani, intentProposeNani, intentVoteNaniProposal |
| coinchan | 8 | Coin creation, vesting, airdrops |
| Module | Tools | Description |
|---|---|---|
| 5 | searchRecentTweets, getTweetById, getXUserByUsername, getXUserTweets, getHomeTimeline |
|
| web | 3 | scrapeWebContent, webPageExtractor, webPageResult — scraping and host-integrated page observations |
| search | 1 | askPerplexitySearch |
| imagegen | 1 | generateAndPinImage — AI image generation + IPFS pinning |
| Module | Tools | Description |
|---|---|---|
| security | 2 | checkMaliciousAddress, checkMaliciousWebsite |
| btc-rpc | 4 | getBtcAddressInfo, getBtcTxDetails, getBtcBlockTxids, getLatestBtcBlock |
| think | 1 | Reasoning step for multi-step agent workflows |
| Module | Tools | Description |
|---|---|---|
| solana | 21 | getSolBalance, getSolanaAccountInfo, getSolanaTokenBalances, getSolanaTokenBalance, getSolanaTokenSupply, getSolanaTransaction, getSolanaTransactionHistory, getSolanaBlock, getSolanaNetworkStatus, getSolanaPriorityFees, intentTransferSol, intentTransferSplToken, searchSolanaTokens, getSolanaTrendingTokens, getSolanaRecentTokens, getSolanaTokenMarketData, getSolanaLatestProfiles, getSolanaPromotedTokens, getSolanaTokenPairs, getSolanaSwapQuote, intentSwapSolana |
EVM
- Ethereum Mainnet
- Optimism
- Arbitrum
- Polygon
- Base
- Mode
- Sepolia
These are the default CLI/MCP EVM client networks; individual tools declare their own supported chains.
Solana
- Mainnet-beta by default. Tools take a
clusterparameter (mainnet-beta,devnet,testnet) to switch cluster; a private or self-hosted endpoint is configured once viaSOLANA_RPC_URLorsolana.rpcUrlrather than passed per call.
Solana tools sit alongside the EVM ones and share the same client. Reads work
with no configuration at all. Writes need a key, which lives in its own
solana config block because Solana uses ed25519 keys rather than secp256k1:
import { createAgentekClient } from '@agentek/tools/client';
import { allTools } from '@agentek/tools';
import { http } from 'viem';
import { mainnet } from 'viem/chains';
const client = createAgentekClient({
accountOrAddress: '0x...',
chains: [mainnet],
transports: [http()],
tools: await allTools({}),
solana: {
// A base58 secret key (Phantom export), a JSON byte array
// (solana-keygen), or the raw 64 bytes.
privateKey: process.env.SOLANA_PRIVATE_KEY,
rpcUrl: process.env.SOLANA_RPC_URL,
jupiterApiKey: process.env.JUPITER_API_KEY,
},
});
await client.execute('getSolBalance', {
address: '5tzFkiKscXHK5ZXCGbXZxdw7gTjjD1mBwuoFbhUvuAi9',
});SOL and SPL transfer intent tools mirror the EVM ones: with a key configured
they sign and submit, returning the signature and confirmationStatus.
A submitted or unknown outcome is not confirmation; reconcile the signature
before retrying. Without a key, pass
solana.address instead and they return the unsigned transaction as base64
for you to sign elsewhere. intentSwapSolana always returns Jupiter's
untrusted transaction and request ID for an external wallet to decode,
validate, simulate, approve, sign, and execute; agentek never signs or submits
a Jupiter swap intent:
{
"intent": "send 0.25 SOL to 5tzFki...",
"chain": "solana",
"transaction": "AQAAAAAA...",
"signature": "4pF2s...",
"confirmationStatus": "confirmed"
}The public mainnet-beta endpoint is heavily rate limited — set
SOLANA_RPC_URL to your own endpoint for anything beyond casual use.
Most tools work without any API keys. Optional keys unlock additional features.
EVM tools fall back to public RPC endpoints, which are shared and rate limited —
point RPC_URLS (or the per-chain variables) at your own provider for anything
beyond casual use.
| Variable | Required for |
|---|---|
PRIVATE_KEY |
Local EVM transaction signing (unsigned intents work with an address; the CLI can also use its signer daemon) |
ACCOUNT |
EVM address context and unsigned intents (alternative to PRIVATE_KEY) |
SOLANA_PRIVATE_KEY |
Signing Solana transactions (base58 or JSON byte array) |
SOLANA_ACCOUNT |
Read-only Solana address (alternative to SOLANA_PRIVATE_KEY) |
SOLANA_RPC_URL |
Solana JSON-RPC endpoint (defaults to public mainnet-beta) |
RPC_URLS |
EVM endpoints as a chainId=url list, e.g. 1=https://…,8453=https://… |
RPC_URL_<chainId> |
EVM endpoint for one chain, e.g. RPC_URL_1 |
ETHEREUM_RPC_URL and friends |
Per-chain aliases: OPTIMISM_, ARBITRUM_, POLYGON_, BASE_, MODE_, SEPOLIA_ |
JUPITER_API_KEY |
Higher Jupiter Tokens V2 and Swap V2 rate limits and analytics (keyless access is supported) |
OPENROUTER_API_KEY |
Model-powered examples and Gym OpenRouter evaluations |
ANVIL_BINARY |
Optional Anvil executable path for Gym (defaults to anvil on PATH) |
PERPLEXITY_API_KEY |
AI-powered search |
ZEROX_API_KEY |
Token swaps via 0x |
TALLY_API_KEY |
Governance data |
COINDESK_API_KEY |
Crypto news |
COINMARKETCAL_API_KEY |
Market events calendar |
FIREWORKS_API_KEY |
AI image generation |
PINATA_JWT |
IPFS pinning (paired with FIREWORKS_API_KEY) |
X_BEARER_TOKEN |
Twitter/X read-only access |
X_API_KEY + X_API_KEY_SECRET |
Twitter/X OAuth (full access) |
Copy the example to get started:
cp -n .env.example .env@agentek/gym runs agents against disposable, pinned Anvil forks using a
public development account, restricted Agentek tools, and separate correctness,
safety, and cost reports. It supports resumable suites and saved-report
comparisons. Across destination settlement is simulated with an Anvil state
override, rather than a destination bridge fill transaction. The included
smoke fixtures are development tests, not a canonical benchmark.
See the Gym guide for setup and examples.
git clone https://github.com/NaniDAO/agentek.git
cd agentek
pnpm i
pnpm run build
pnpm exec vitest run -c ./test/vitest.config.ts
# The default test script watches; the command above runs once.Some existing tests call public RPCs or external APIs; a full run is not an
offline test suite. A .env file is not automatically loaded by every command;
pass it explicitly where needed, for example node --env-file=.env ....
Interested in contributing? Check out our CONTRIBUTING.md guide.
