Developers · Guide

Orientim in the Vercel AI SDK

Give an agent built with the Vercel AI SDK protected Solana swaps. It gets the four tools of the Orientim MCP server, your limits hold, and nothing is signed until you say yes.

What you need

  • Node 20 or later.
  • A wallet for the agent alone, as a keypair file, holding only what it may trade and 0.01 SOL. The server gets its own API key with it.
  • Your own Solana RPC, and a key for your model (here Claude, through ANTHROPIC_API_KEY).
npm install ai @ai-sdk/mcp @ai-sdk/anthropic tsx

1. Write your limits

A policy file the agent cannot edit. Here: at most 5 USDC a swap, and only SOL to buy. Every limit is in theguide.

{
  "maxAmountIn": { "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v": "5000000" },
  "allowedOutputMints": ["So11111111111111111111111111111111111111112"]
}

2. The agent

In agent.ts: the server starts with the agent and stops with it. Before the first swap of each quote it asks you, in your terminal; only a typed yes makes the swap.

import { createInterface } from 'node:readline/promises';
import { anthropic } from '@ai-sdk/anthropic';
import { createMCPClient, ElicitationRequestSchema } from '@ai-sdk/mcp';
import { Experimental_StdioMCPTransport as StdioMCPTransport } from '@ai-sdk/mcp/mcp-stdio';
import { generateText, isStepCount } from 'ai';

const orientim = await createMCPClient({
  transport: new StdioMCPTransport({
    command: 'npx',
    args: ['-y', '@orientimhq/swap@2.1.0', 'mcp'],
    env: {
      SOLANA_RPC_URL: process.env.SOLANA_RPC_URL!,
      ORIENTIM_WALLET_KEYPAIR: '/home/agent/agent-wallet.json',
      ORIENTIM_POLICY: '/home/agent/orientim-policy.json',
    },
  }),
  // Tells the server it may ask you before a swap.
  capabilities: { elicitation: {} },
});

// The server's question, before the first swap of each quote: only a typed "yes" makes it.
const terminal = createInterface({ input: process.stdin, output: process.stdout });
orientim.onElicitationRequest(ElicitationRequestSchema, async ({ params }) => {
  const answer = await terminal.question(`\n${params.message}\nSwap? (yes/no) `);
  return answer.trim().toLowerCase() === 'yes' ? { action: 'accept', content: { confirm: true } } : { action: 'decline' };
});

try {
  const { text } = await generateText({
    model: anthropic('claude-sonnet-5-5'),
    tools: await orientim.tools(),
    stopWhen: isStepCount(10),
    prompt: process.argv[2] ?? 'Show my wallet, then quote 1 USDC to SOL.',
  });
  console.log(text);
} finally {
  await orientim.close();
  terminal.close();
}

capabilities: { elicitation: {} } tells the server that your app can ask you, and onElicitationRequest is where you do. Any model the AI SDK supports works the same way.

3. Run it

First a quote: Orientim prices the swap and verifies it on your RPC. Nothing is signed.

export SOLANA_RPC_URL=<your own RPC>
export ANTHROPIC_API_KEY=...
npx tsx agent.ts "Show my wallet, then quote 1 USDC to SOL."

Then a swap. The server asks you first, with the amounts; answer yes, and the agent tells you what the swap did. Your policy enforces your limits before anything is signed.

npx tsx agent.ts "Swap 1 USDC to SOL."

Without a person at the keyboard

A bot that runs alone has no one to ask. Leave out the question, and the server swaps on the agent's word: then the policy file is all that stops it. Keep the file where the agent cannot change it, at /etc/orientim/policy.json, which is used whatever the environment says. The agent may ask for at most 3% slippage and 5% price impact; only you raise them.

Where it runs

The server is a process beside your agent, with the wallet's key, on a machine or container you control. It keeps a record of each order in ORIENTIM_STATE_DIR, on a disk that outlives a restart. A serverless function, such as Vercel Functions, has neither. The assistant never sees the key, only the wallet's address and what each swap did.

More: the MCP server, its four tools and its settings, and what the check before signing does.