MCP Server (Local)
Run the Nava MCP server as a local stdio process. Any MCP-compatible client (Claude Desktop, Cursor, etc.) can connect to it.
Run Directly
# Option A: pre-provisioned API key
export NAVA_API_KEY=nava_live_...
export WALLET_ADDRESS=0x...
npx nava-mcp
# Option B: headless wallet bootstrap (no pre-provisioned key)
export NAVA_WALLET_PRIVATE_KEY=0x...
export NAVA_SIWE_DOMAIN=testnet.navalabs.dev
export NAVA_SIWE_URI=https://internal.navalabs.dev/api
npx nava-mcp
For Option B, install viem:
npm install viem
Programmatic Usage
import { NavaClient } from '@navalabs/sdk';
import { createMCPServer } from '@navalabs/sdk/mcp';
const nava = new NavaClient({ apiKey: '...', walletAddress: '0x...' });
const server = createMCPServer(nava);
createMCPServer accepts any object that implements the NavaBackend interface (exported from @navalabs/sdk/mcp). NavaClient satisfies it out of the box. For server-side integrations that call internal services directly instead of going through HTTP, implement NavaBackend with your own backend:
import { createMCPServer, type NavaBackend } from '@navalabs/sdk/mcp';
const backend: NavaBackend = {
async requestVerification(params) { /* call internal service */ },
async checkVerificationStatus(hash) { /* call internal service */ },
getWalletAddress() { return '0x...'; },
};
const server = createMCPServer(backend);
MCP Client Configuration
Add to your MCP client config (e.g. Claude Desktop, Cursor):
{
"mcpServers": {
"nava": {
"command": "npx",
"args": ["nava-mcp"],
"env": {
"NAVA_API_KEY": "nava_live_...",
"WALLET_ADDRESS": "0x..."
}
}
}
}
Or bootstrap from wallet at startup (no pre-provisioned NAVA_API_KEY):
{
"mcpServers": {
"nava": {
"command": "npx",
"args": ["nava-mcp"],
"env": {
"NAVA_WALLET_PRIVATE_KEY": "0x...",
"NAVA_SIWE_DOMAIN": "testnet.navalabs.dev",
"NAVA_SIWE_URI": "https://internal.navalabs.dev/api",
"NAVA_API_KEY_NAME": "agent-session"
}
}
}
}
Exposed Tools
Once connected, the agent has access to four tools:
requestVerification: Submit a transaction for arbiter review.
| Parameter | Type | Required | Description |
|---|---|---|---|
to | string | Yes | Target contract or recipient address (0x...) |
data | string | Yes | Encoded transaction calldata (hex) |
value | string | No | Value in Wei (default "0") |
description | string | Yes | Human-readable description for the arbiter |
protocol | string | No | Protocol identifier (e.g. "uniswap_v3", "cow", "compound_v2"). Skips arbiter protocol detection. |
decodedTx | object | No | Pre-decoded transaction fields. Skips arbiter TX normalization. |
checkVerificationStatus: Poll for the arbiter’s decision.
| Parameter | Type | Required | Description |
|---|---|---|---|
requestHash | string | Yes | The requestHash returned from requestVerification |
Returns status (APPROVED, REJECTED, UNDECIDED, PENDING, NONE), arbiter confidence, analysis, and on rejection: executionTrace, failedNodes, and primaryFailure.
requestAndAwaitVerification: Submit a transaction and block until the arbiter reaches a terminal status. Takes the same parameters as requestVerification.
getUserAddress: Returns the wallet address configured for the current session. No parameters.
Environment Variables
| Variable | Required | Default | Description |
|---|---|---|---|
NAVA_API_KEY | Conditionally | None | Pre-provisioned Nava API key (direct API-key mode) |
WALLET_ADDRESS | Conditionally | None | Wallet address (required with NAVA_API_KEY) |
NAVA_BASE_URL | No | https://internal.navalabs.dev/api | API base URL |
CHAIN_ID | No | 11155111 | Target chain (Sepolia) |
NAVA_WALLET_PRIVATE_KEY | Conditionally | None | Private key for local MCP bootstrap mode (requires viem) |
NAVA_SIWE_DOMAIN | No | testnet.navalabs.dev | SIWE domain for bootstrap mode |
NAVA_SIWE_URI | No | NAVA_BASE_URL | SIWE URI for bootstrap mode |
NAVA_SIWE_STATEMENT | No | SDK default statement | SIWE statement override |
NAVA_API_KEY_NAME | No | server default | Name for generated API key |
NAVA_API_KEY_EXPIRES_AT | No | no expiration | ISO timestamp for generated API key expiration |