Skip to main content
Glama

SVM-MCP: SOON モデルコンテキストプロトコルサーバー

Claude AIをSOONおよびその他のSVMベースのブロックチェーンと統合するモデルコンテキストプロトコル(MCP)サーバー。このサーバーは、SOONのテストネットとメインネット上のアカウント残高、取引、トークン保有状況の確認、残高確認、最近のトランザクションの取得、トークン保有状況の表示を行うツールを提供します。

概要

この MCP サーバーは、Claude を SOON エコシステムに接続し、次のことを可能にするように設計されています。

  • テストネットとメインネットのウォレット残高を照会する

  • アドレスの最新の取引を取得する

  • 任意のアカウントのトークン保有状況を確認する

現在の実装では SOON の RPC エンドポイントを使用していますが、Solana 互換のブロックチェーンやカスタム SVM 実装で動作するように簡単に変更できます。

Related MCP server: Solana Agent Kit MCP Server

特徴

  • 残高を取得: SOONテストネットまたはメインネット上の任意のアドレスのネイティブトークン残高を取得します

  • 最後のトランザクションを取得: アドレスの最新のトランザクションを取得します

  • トークンアカウントの取得: アドレスが所有するすべてのトークンアカウントを一覧表示します

前提条件

  • Node.js (v16+)

  • NPM または Bun パッケージ マネージャー

  • Claude Desktop(ローカルテスト用)

インストール

  1. リポジトリをクローンします。

git clone https://github.com/rkmonarch/svm-mcp
cd svm-mcp
  1. 依存関係をインストールします:

npm install
# or
bun install
  1. プロジェクトをビルドします。

npm run build
# or
bun run build

プロジェクト構造

メインサーバーの実装はsrc/index.tsにあります。

import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { Connection, PublicKey } from "@solana/web3.js";
import { z } from "zod";

const connectionTestnet = new Connection("https://rpc.testnet.soo.network/rpc");
const connectionMainnet = new Connection("https://rpc.mainnet.soo.network/rpc");

const server = new McpServer({
  name: "svm-mcp",
  version: "0.0.1",
  capabilities: [
    "get-soon-testnet-balance",
    "get-soon-testnet-last-transaction",
    "get-soon-testnet-account-tokens",
    "get-soon-mainnet-balance",
    "get-soon-mainnet-last-transaction",
    "get-soon-mainnet-account-tokens",
  ],
});

ツールの実装

バランスを取る

server.tool(
  "get-soon-testnet-balance",
  "Get the balance of a address on the Soon testnet",
  {
    address: z.string().describe("The Solana address to get the balance of"),
  },
  async ({ address }) => {
    try {
      const balance = await connectionTestnet.getBalance(new PublicKey(address));
      return {
        content: [
          {
            type: "text",
            text: `Balance: ${balance}`,
          },
        ],
      };
    } catch (error) {
      return {
        content: [
          {
            type: "text",
            text: `Error getting balance: ${error instanceof Error ? error.message : String(error)}`,
          },
        ],
      };
    }
  }
);

最後の取引を取得

server.tool(
  "get-soon-testnet-last-transaction",
  "Get the last transaction of an address on the Soon testnet",
  {
    address: z
      .string()
      .describe("The Solana address to get the last transaction for"),
  },
  async ({ address }) => {
    try {
      // Fetch the most recent transaction signatures for the address
      const signatures = await connectionTestnet.getSignaturesForAddress(
        new PublicKey(address),
        { limit: 1 } // Limit to just the most recent transaction
      );

      if (signatures.length === 0) {
        return {
          content: [
            {
              type: "text",
              text: "No transactions found for this address",
            },
          ],
        };
      }

      // Get the most recent transaction using its signature
      const latestSignature = signatures[0].signature;
      const transaction = await connectionTestnet.getConfirmedTransaction(
        latestSignature
      );

      return {
        content: [
          {
            type: "text",
            text: JSON.stringify(transaction),
          },
        ],
      };
    } catch (error) {
      return {
        content: [
          {
            type: "text",
            text: `Error getting transaction: ${error instanceof Error ? error.message : String(error)}`,
          },
        ],
      };
    }
  }
);

トークンアカウントを取得する

server.tool(
  "get-soon-testnet-account-tokens",
  "Get the tokens of a address on the Soon testnet",
  {
    address: z.string().describe("The Solana address to get the tokens of"),
  },
  async ({ address }) => {
    try {
      const tokens = await connectionTestnet.getTokenAccountsByOwner(
        new PublicKey(address),
        {
          programId: new PublicKey("TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA"),
        }
      );
      return {
        content: [
          {
            type: "text",
            text: JSON.stringify(tokens),
          },
        ],
      };
    } catch (error) {
      return {
        content: [
          {
            type: "text",
            text: `Error getting tokens: ${error instanceof Error ? error.message : String(error)}`,
          },
        ],
      };
    }
  }
);

サーバーの初期化

async function main() {
  try {
    console.error("Starting MCP server...");
    const transport = new StdioServerTransport();
    console.error("Transport initialized, connecting to server...");
    await server.connect(transport);
    console.error("Server connection established successfully");
    // The server will keep running in this state
  } catch (error) {
    console.error("There was an error connecting to the server:", error);
    process.exit(1);
  }
}

main().catch((err) => {
  console.error("There was an error starting the server:", err);
  process.exit(1);
});

構成

クロードデスクトップ構成

この MCP サーバーを Claude Desktop で使用するには、 claude_desktop_config.jsonファイルに次のコードを追加します。

{
  "mcpServers": {
    "svm-mcp": {
      "command": "bun",
      "args": ["/path/to/svm-mcp/build/index.js"]
    }
  }
}

RPCエンドポイントのカスタマイズ

異なるRPCエンドポイントを使用したり、異なるSolana互換ブロックチェーンに接続したりするには、 src/index.tsの接続URLを編集します。

const connectionTestnet = new Connection("YOUR_TESTNET_RPC_URL");
const connectionMainnet = new Connection("YOUR_MAINNET_RPC_URL");

クロードとの使用

MCP サーバーが実行中になり、Claude に接続されたら、次のコマンドを使用できます。

アドレス残高の確認

Can you check the balance of this SOON testnet address: <address>

最近の取引を取得しています

What is the last transaction made by <address> on SOON testnet?

トークン保有の取得

What tokens does <address> hold on SOON mainnet?

謝辞

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/rkmonarch/svm-mcp'

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