@embarkai/mcp
v0.2.1
Published
MCP server exposing EmbarkAI SDK capabilities as tools for AI agents
Maintainers
Readme
@embarkai/mcp
MCP (Model Context Protocol) server that exposes EmbarkAI SDK capabilities as tools for AI agents.
Features
- ✅ 7 blockchain tools - Wallet info, balances, transfers, contract reads, transaction status, chain management
- ✅ Multi-chain support - Switch between Lumia, Ethereum Sepolia, BSC Testnet, Arbitrum Sepolia, Base Sepolia
- ✅ Auto wallet creation - Wallet is created automatically on first use via MPC/TSS protocol
- ✅ ERC20 support - Native and token balances/transfers out of the box
- ✅ Stdio transport - Works with Claude Code, Claude Desktop, and any MCP-compatible client
- ✅ Programmatic API - Use as a library in your own Node.js applications
Installation
pnpm add @embarkai/mcp viem dkls23-wasm
# or
npm install @embarkai/mcp viem dkls23-wasmQuick Start
With Claude Code (CLI)
claude mcp add --transport stdio \
-e EMBARK_API_KEY=lp_your_api_key \
-e EMBARK_WALLET_ID=my-agent-wallet \
-e EMBARK_CHAIN_ID=2030232745 \
embarkai -- npx @embarkai/mcpThen ask Claude: "What's my wallet address?" or "Send 0.1 LUMIA to 0x..."
Verify it's registered:
claude mcp listWith Claude Code (JSON config)
Add to your project .mcp.json:
{
"mcpServers": {
"embarkai": {
"command": "npx",
"args": ["@embarkai/mcp"],
"env": {
"EMBARK_API_KEY": "lp_your_api_key",
"EMBARK_WALLET_ID": "my-agent-wallet",
"EMBARK_CHAIN_ID": "2030232745"
}
}
}
}With Claude Desktop
Add to ~/Library/Application Support/Claude/claude_desktop_config.json (macOS):
{
"mcpServers": {
"embarkai": {
"command": "npx",
"args": ["@embarkai/mcp"],
"env": {
"EMBARK_API_KEY": "lp_your_api_key",
"EMBARK_WALLET_ID": "my-agent-wallet"
}
}
}
}Programmatic Usage
import { createMcpServer, startMcpServer, resolveConfig } from '@embarkai/mcp';
// Option 1: Start with stdio transport (for MCP clients)
await startMcpServer();
// Option 2: Create server with custom config
const server = await createMcpServer({
apiKey: 'lp_...',
walletId: 'my-wallet',
chainId: 2030232745,
keyshareDir: './data/keyshares',
debug: false,
});Configuration
All configuration is via environment variables:
| Variable | Required | Default | Description |
|----------|----------|---------|-------------|
| EMBARK_API_KEY | Yes | - | Project API key (lp_...) from dashboard.lumiapassport.com |
| EMBARK_WALLET_ID | Yes | - | Unique identifier for the server wallet |
| EMBARK_CHAIN_ID | No | 2030232745 | Default chain (Lumia Beam testnet) |
| EMBARK_KEYSHARE_DIR | No | ./data/keyshares | Directory for encrypted keyshare storage |
| EMBARK_KEYSHARE_PASSWORD | No | - | Encryption password. If omitted, uses in-memory storage (keyshares lost on restart) |
| EMBARK_WALLET_BACKUP_PASSWORD | No | - | Password for ShareVault backup. If set, auto-restores keyshare from vault when missing locally |
| EMBARK_DEBUG | No | false | Enable debug logging to stderr |
Note: For production use, always set
EMBARK_KEYSHARE_PASSWORDto persist keyshares to disk. Without it, the wallet will need to re-run the DKG protocol on every restart.
Tools
get_wallet_info
Get wallet addresses and active chain info.
Input: (none)
Output: { walletId, smartAccountAddress, ownerAddress, chain: { id, name, nativeCurrency, blockExplorerUrl } }get_balance
Check native or ERC20 token balance.
Input: { address?: string, tokenAddress?: string }
Output: { address, balance, formatted, symbol, decimals, chain }- Omit
addressto use the wallet's smart account - Omit
tokenAddressfor native balance, provide it for ERC20
transfer
Send native tokens or ERC20 tokens. Waits for on-chain confirmation.
Input: { to: string, amount: string, tokenAddress?: string }
Output: { userOpHash, transactionHash, blockNumber, success, gasUsed, chain }amountis human-readable (e.g."1.5", not wei)- Omit
tokenAddressfor native transfer
read_contract
Call any view/pure function on a smart contract.
Input: { address: string, abi: AbiItem[], functionName: string, args?: any[] }
Output: { result, chain }get_transaction_status
Check the status of a previously submitted user operation.
Input: { userOpHash: string }
Output: { status: 'confirmed'|'pending'|'failed', transactionHash?, blockNumber?, success?, gasUsed? }list_supported_chains
List all supported blockchain networks.
Input: (none)
Output: { chains: [{ id, name, nativeCurrency, blockExplorerUrl, isActive }], activeChainId }switch_chain
Switch the active blockchain network for subsequent operations.
Input: { chainId: number }
Output: { previousChainId, activeChain: { id, name, nativeCurrency, blockExplorerUrl } }Supported Chains
| Chain | ID | Type |
|-------|----|------|
| Lumia Prism | 994873017 | Mainnet |
| Lumia Beam | 2030232745 | Testnet (default) |
| Ethereum Sepolia | 11155111 | Testnet |
| BSC Testnet | 97 | Testnet |
| Arbitrum Sepolia | 421614 | Testnet |
| Base Sepolia | 84532 | Testnet |
Testing
With MCP Inspector
The MCP Inspector is the official GUI tool for testing MCP servers:
npx @modelcontextprotocol/inspector node packages/mcp/dist/bin.jsSet the environment variables in the inspector UI, then call tools interactively.
Smoke Test
Run the built-in smoke test to verify tools are registered correctly:
node packages/mcp/test/smoke.mjsArchitecture
Agent (Claude Code / Claude Desktop)
│ stdio (JSON-RPC)
▼
MCP Server (this package)
│
├── ChainManager (lazy pool)
│ ├── ServerWalletManager per chain
│ ├── PublicReadClient per chain
│ └── Shared KeyshareStorage
│
└── Tools
├── get_wallet_info
├── get_balance
├── transfer
├── read_contract
├── get_transaction_status
├── list_supported_chains
└── switch_chainLicense
MIT
