LangChain Integration
Use WDK MCP tools in LangChain agents with zero-config server startup
You can use the WDK MCP Toolkit as a tool provider for LangChain agents in both Python and TypeScript. LangChain's MultiServerMCPClient spawns the MCP server as a subprocess and converts WDK tools into LangChain-compatible tools, giving your agent access to wallet operations, pricing, swaps, bridges, lending, and more.
This integration uses the serve CLI command, which starts a fully configured MCP server on stdio with no server script required.
This approach uses LangChain's MCP adapters to connect to the WDK MCP server. WDK does not ship a native LangChain integration, it leverages the standard MCP protocol that LangChain already supports.
Want more control? The serve command is the fastest way to get running, but you can also write your own MCP server with the programmatic API for full control over wallets, tools, and protocols. Then point LangChain's MultiServerMCPClient at it using node your-server.js instead of the serve command.
The serve Command
Complete the pinned source setup first. From that checkout, serve starts the MCP server without a custom server script:
node bin/index.js serveConfigure a trusted secret-manager command to enable wallet operations. Replace the placeholder with your own executable that prints only the mnemonic to stdout, and authenticate the secret manager before starting the agent. The command must work without interactive input. See seed sources, precedence, and startup behavior.
# With wallet operations
WDK_SEED_COMMAND="/absolute/path/to/trusted-seed-loader" node bin/index.js serve
# Pricing-only mode (no seed sources configured)
unset WDK_SEED WDK_SEED_COMMAND WDK_SEED_FILE
node bin/index.js serveDefault Chains
By default, serve enables three chains: Ethereum, Arbitrum, and Bitcoin. For each enabled chain it dynamically imports the required wallet package and skips any that aren't installed. You can change the enabled set with the WDK_CHAINS environment variable.
Built-in Registry
The command has built-in definitions for 13 chains and 4 protocol modules. When a chain is enabled and its configured package is installed, the wallet is registered automatically. Protocol modules are also auto-registered when their packages are installed and at least one of their target chains is enabled.
| Module | Registers | Default |
|---|---|---|
@tetherto/wdk-wallet-evm | Configured built-in EVM chains | Ethereum + Arbitrum enabled |
@tetherto/wdk-wallet-btc | Bitcoin | Enabled |
@tetherto/wdk-wallet-solana | Solana | Requires a module override; not enabled by default |
@tetherto/wdk-wallet-ton | TON | Not enabled by default |
@tetherto/wdk-wallet-tron | Tron | Not enabled by default |
@tetherto/wdk-protocol-swap-velora-evm | Swap tools (Ethereum, Arbitrum) | -- |
@tetherto/wdk-protocol-bridge-usdt0-evm | Bridge tools (Ethereum, Arbitrum) | -- |
@tetherto/wdk-protocol-lending-aave-evm | Lending tools (Ethereum) | -- |
@tetherto/wdk-protocol-fiat-moonpay | Fiat tools (Ethereum) | Requires MOONPAY_API_KEY plus a non-sensitive MOONPAY_SECRET_KEY=unused sentinel in the pinned source CLI; URLs remain unsigned |
Use the package's CHAINS export as the complete accepted-identifier registry for the source checkout; see Built-in Chain Identifiers.
The pinned serve source imports @tetherto/wdk-wallet-sol for Solana. To use the installed @tetherto/wdk-wallet-solana package, set chains.solana.module to "@tetherto/wdk-wallet-solana" in a custom config file, supply its wallet configuration, and enable solana through enabledChains (or WDK_CHAINS when enabledChains is omitted).
Unavailable wallet packages are skipped with a startup warning. Install the packages named by the registry or your config. For chains or protocols not in the built-in registry, use a custom config file.
Quick Start
Replace /absolute/path/wdk-mcp-toolkit in both examples with your source checkout path and /absolute/path/to/trusted-seed-loader with your secret-manager executable. WDK does not provide the loader. Authenticate it first, ensure it runs without interactive input in the server's environment, and unset any inherited WDK_SEED so it cannot override the command source.
The examples below set WDK_MCP_ELICITATION="false", which automatically accepts confirmation requests. With a seed configured, serve exposes write tools as well as read tools; asking only for a balance or price does not restrict what the agent can call. Use a dedicated development wallet with limited funds. For read-only access, register only read tools in a custom server; for writes, provide authorization outside the agent's control. See confirmation and agent access.
Install dependencies
pip install langchain-mcp-adapters langgraph langchain-openaiCreate your agent
import asyncio
from langchain_mcp_adapters.client import MultiServerMCPClient
from langgraph.prebuilt import create_react_agent
from langchain_openai import ChatOpenAI
async def main():
client = MultiServerMCPClient({
"wdk": {
"transport": "stdio",
"command": "node",
"args": ["/absolute/path/wdk-mcp-toolkit/bin/index.js", "serve"],
"env": {
"WDK_SEED_COMMAND": "/absolute/path/to/trusted-seed-loader",
"WDK_MCP_ELICITATION": "false",
},
}
})
tools = await client.get_tools()
agent = create_react_agent(ChatOpenAI(model="gpt-4o"), tools)
result = await agent.ainvoke({
"messages": [{"role": "user", "content": "What is my Ethereum address?"}]
})
print(result["messages"][-1].content)
await client.close()
asyncio.run(main())Run it
export OPENAI_API_KEY="sk-..."
python agent.pyConfiguration
Environment Variables
Control serve behavior through environment variables. The three seed sources are optional individually and are checked in the order shown. A nonempty resolved seed is required for wallet tools; see seed resolution and failure behavior.
| Variable | Required | Default | Description |
|---|---|---|---|
WDK_SEED | No | -- | Direct mnemonic; takes precedence over the command and file sources |
WDK_SEED_COMMAND | No | -- | Trusted command whose stdout contains the mnemonic; used when WDK_SEED is unset or empty |
WDK_SEED_FILE | No | -- | UTF-8 mnemonic file; used when both preceding variables are unset or empty |
WDK_CHAINS | No | ethereum,arbitrum,bitcoin | Comma-separated identifiers from the package's CHAINS export |
WDK_MCP_ELICITATION | No | true | The exact string "false" disables elicitation and automatically accepts confirmation requests; it does not enforce spending limits |
WDK_RPC_\<CHAIN\> | No | Built-in defaults | Override an existing provider field for a configured chain (e.g. WDK_RPC_ETHEREUM=https://my-rpc.com) |
WDK_CONFIG | No | -- | Path to a wdk.config.json file for custom chains and protocols |
WDK_INDEXER_API_KEY | No | -- | Enables indexer tools for balance and transfer history queries |
MOONPAY_API_KEY | No | -- | With the sentinel below, passes the pinned serve source's MoonPay registration gate |
MOONPAY_SECRET_KEY | No | -- | Set to a non-sensitive sentinel such as unused only to satisfy the pinned source CLI gate; never provide the real MoonPay signing secret |
The pinned serve source checks for both MoonPay variables but passes a configuration field that MoonPay beta.3 does not use. Its generated widget URLs therefore remain unsigned. Never give serve the real signing secret. For signed MoonPay flows, use programmatic registration with the signUrl configuration and keep the signing secret in an authenticated backend.
Custom Config File
For chains or protocols not in the built-in defaults, create a wdk.config.json and pass its path via WDK_CONFIG:
WDK_CONFIG=./wdk.config.json WDK_SEED_COMMAND="/absolute/path/to/trusted-seed-loader" node bin/index.js serve{
"chains": {
"zksync": {
"module": "@myorg/wdk-wallet-zksync",
"config": { "provider": "https://mainnet.era.zksync.io" }
},
"ethereum": {
"config": { "provider": "https://my-private-rpc.com" }
}
},
"protocols": [
{
"module": "@myorg/wdk-protocol-swap-custom",
"label": "custom-swap",
"type": "swap",
"chains": ["zksync"]
}
],
"enabledChains": ["ethereum", "zksync", "bitcoin"]
}| Field | Description |
|---|---|
chains | Add new chains or override config for built-in ones. New chains require a module field; overrides for existing chains can omit it |
protocols | Add custom protocols. Each entry requires module, label, and chains. The type field (swap, bridge, lending, fiat) maps to the corresponding built-in tool set |
enabledChains | Overrides WDK_CHAINS env var. If omitted, WDK_CHAINS is used |
LLM Provider Support
Both the Python and TypeScript examples support OpenAI and Anthropic. Set the corresponding environment variable and install the matching package:
| Provider | Environment Variable | Python Package | TypeScript Package |
|---|---|---|---|
| OpenAI | OPENAI_API_KEY | langchain-openai | @langchain/openai |
| Anthropic | ANTHROPIC_API_KEY | langchain-anthropic | @langchain/anthropic |
The examples auto-detect which provider to use based on which API key is set. If both are set, OpenAI takes priority.
Full examples -- See the complete interactive agent examples with conversation loops on GitHub: mcp-toolkit/langchain/python/ and mcp-toolkit/langchain/typescript/.