Skip to main content
Glama
akc2267

Solana MCP Server

by akc2267

transfer

Send SOL tokens securely from one wallet to another using your secret key, destination address, and specified amount on the Solana MCP Server.

Instructions

Transfer SOL from your keypair to another address

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
amountYesAmount of SOL to send
secretKeyYesYour keypair's secret key (as comma-separated numbers or JSON array)
toAddressYesDestination wallet address

Implementation Reference

  • The handler function that implements the transfer logic: parses secretKey to Keypair, creates SystemProgram.transfer instruction, sends and confirms the transaction, returns success with signature or error.
      async ({ secretKey, toAddress, amount }) => {
        try {
          // Parse the secret key and create keypair
          let fromKeypair: Keypair;
          try {
            // First try parsing as comma-separated string
            const decoded = Uint8Array.from(secretKey.split(',').map(num => parseInt(num.trim())));
            fromKeypair = Keypair.fromSecretKey(decoded);
          } catch {
            // If that fails, try as a JSON array string
            fromKeypair = Keypair.fromSecretKey(Uint8Array.from(JSON.parse(secretKey)));
          }
    
          // Convert SOL amount to lamports
          const lamports = amount * LAMPORTS_PER_SOL;
    
          // Create transfer instruction
          const transaction = new Transaction().add(
            SystemProgram.transfer({
              fromPubkey: fromKeypair.publicKey,
              toPubkey: new PublicKey(toAddress),
              lamports,
            })
          );
    
          // Send and confirm transaction
          const signature = await sendAndConfirmTransaction(
            connection,
            transaction,
            [fromKeypair]
          );
    
          return {
            content: [
              {
                type: "text",
                text: `Transfer successful!
    From: ${fromKeypair.publicKey.toBase58()}
    To: ${toAddress}
    Amount: ${amount} SOL
    Transaction signature: ${signature}
    Explorer URL: https://explorer.solana.com/tx/${signature}`,
              },
            ],
          };
        } catch (err) {
          const error = err as Error;
          return {
            content: [
              {
                type: "text",
                text: `Failed to transfer SOL: ${error.message}`,
              },
            ],
          };
        }
      }
  • Zod schema for 'transfer' tool inputs: secretKey (string), toAddress (string), amount (positive number).
    {
      secretKey: z.string().describe("Your keypair's secret key (as comma-separated numbers or JSON array)"),
      toAddress: z.string().describe("Destination wallet address"),
      amount: z.number().positive().describe("Amount of SOL to send"),
    },
  • src/index.ts:207-272 (registration)
    Registration of the 'transfer' tool via server.tool() call, including name, description, input schema, and handler reference.
    server.tool(
      "transfer",
      "Transfer SOL from your keypair to another address",
      {
        secretKey: z.string().describe("Your keypair's secret key (as comma-separated numbers or JSON array)"),
        toAddress: z.string().describe("Destination wallet address"),
        amount: z.number().positive().describe("Amount of SOL to send"),
      },
      async ({ secretKey, toAddress, amount }) => {
        try {
          // Parse the secret key and create keypair
          let fromKeypair: Keypair;
          try {
            // First try parsing as comma-separated string
            const decoded = Uint8Array.from(secretKey.split(',').map(num => parseInt(num.trim())));
            fromKeypair = Keypair.fromSecretKey(decoded);
          } catch {
            // If that fails, try as a JSON array string
            fromKeypair = Keypair.fromSecretKey(Uint8Array.from(JSON.parse(secretKey)));
          }
    
          // Convert SOL amount to lamports
          const lamports = amount * LAMPORTS_PER_SOL;
    
          // Create transfer instruction
          const transaction = new Transaction().add(
            SystemProgram.transfer({
              fromPubkey: fromKeypair.publicKey,
              toPubkey: new PublicKey(toAddress),
              lamports,
            })
          );
    
          // Send and confirm transaction
          const signature = await sendAndConfirmTransaction(
            connection,
            transaction,
            [fromKeypair]
          );
    
          return {
            content: [
              {
                type: "text",
                text: `Transfer successful!
    From: ${fromKeypair.publicKey.toBase58()}
    To: ${toAddress}
    Amount: ${amount} SOL
    Transaction signature: ${signature}
    Explorer URL: https://explorer.solana.com/tx/${signature}`,
              },
            ],
          };
        } catch (err) {
          const error = err as Error;
          return {
            content: [
              {
                type: "text",
                text: `Failed to transfer SOL: ${error.message}`,
              },
            ],
          };
        }
      }
    );
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full burden of behavioral disclosure. It states the action ('Transfer SOL') which implies a write/mutation operation, but doesn't disclose critical traits like authentication needs (handled via secretKey), potential for irreversible loss of funds, network fees, or rate limits. This is a significant gap for a financial transaction tool.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, efficient sentence that directly states the tool's purpose without any fluff or redundancy. It's appropriately sized and front-loaded, making it easy to parse quickly.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the complexity of a financial transfer tool with no annotations and no output schema, the description is insufficient. It doesn't explain what happens on success/failure, return values, error conditions, or security implications, leaving critical gaps for agent understanding.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema description coverage is 100%, with all parameters well-documented in the input schema (amount, secretKey, toAddress). The description adds no additional parameter semantics beyond what's already in the schema, so it meets the baseline for adequate but unremarkable coverage.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the action ('Transfer SOL') and the resource ('from your keypair to another address'), making the purpose immediately understandable. However, it doesn't explicitly differentiate this tool from its siblings (like getBalance or getAccountInfo), which are read-only operations, so it falls short of a perfect score.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides no guidance on when to use this tool versus alternatives. It doesn't mention prerequisites (e.g., needing a funded keypair), exclusions, or comparisons with sibling tools, leaving the agent to infer usage context on its own.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other Tools

Related Tools

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/akc2267/solana-mcp-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server