読了時間:29分
概要
Model Context Protocol(MCP)を利用すると、外部のデータソースやサービスと連携するカスタムツールを用いて、ClaudeなどのAIアシスタント機能を拡張することができます。 このガイドでは、Claude Desktop(またはCursor)などのツールがSolanaブロックチェーンに直接クエリを実行できるようにするSolana MCPサーバーを構築します。この統合により、Claudeはウォレットの残高確認、トークンアカウントの閲覧、トランザクション詳細の取得、アカウント情報の分析といったタスクを実行できるようになります。その一方で、これらのやり取りに対する制御権はユーザーが保持し続けます。 Goat SDKやSendAI.funなど、AIとSolanaを橋渡しする優れたツールは数多く存在しますが、独自のツールを構築したい方には、このガイドが最適です!このチュートリアルを終える頃には、Claude Desktopに接続可能な、完全に機能するSolana MCPサーバーが完成し、自然言語を通じてシームレスにブロックチェーンとやり取りできるようになります:

主な業務内容
- TypeScriptとMCP SDKを使用してSolana MCPサーバーをセットアップする
- Solana Kitを使用して Solana 独自の機能を実装する
- Claude Desktopでサーバーをテストする
- トークンアカウントの取得や取引明細など、ますます複雑化する機能を追加する
- AIがツールを適切に活用できるよう、役立つプロンプトを作成してください
必要なもの
- TypeScriptの基本的な知識
- Solana BasicsおよびSolana Kitの利用経験
- Node.js
- お使いのコンピューターにインストールされた「Claude Desktop」
- SolanaのRPCエンドポイント(こちらから無料で取得できます)
| 依存関係 | バージョン |
|---|---|
| ノード | >=23.0.0 |
| @modelcontextprotocol/sdk | ^1.9.0 |
| @solana/kit | ^2.1.0 |
| zod | ^3.24.2 |
| TypeScript | ^5.8.3 |
| Claude デスクトップ | 0.9.2 |
MCPの理解
モデルコンテキストプロトコル(MCP)は、AIモデルと外部のデータソースやツールとの間のギャップを埋めるオープンプロトコルです。これは、アプリケーションが大規模言語モデル(LLM)にコンテキストを提供するための標準化された方法を確立し、LLMがリアルタイムの情報にアクセスしたり、学習データを超えたアクションを実行したりできるようにします。MCPは、AIモデルがさまざまなデータソース、API、機能と安全かつ確実に連携できるようにする「万能アダプター」のようなものだと考えてください。 MCPの中核はクライアント・サーバーアーキテクチャに基づいており、ClaudeのようなAIアプリケーションがクライアントとしてMCPサーバーに接続します。これらのサーバーは、主に以下の3つの機能を提供します:
- ツール:AIがアクションを実行するために呼び出すことができる関数(ウォレットの残高確認など)
- リソース:AIが読み取ることができるファイル形式のデータ(ドキュメントなど)
- プロンプト:AIとツールのやり取りを導く、あらかじめ作成されたテンプレート
データ可視化ツール、コードアナライザー、あるいは外部システムとの連携インターフェースのいずれを開発する場合でも、MCPはAI機能を拡張するための構造化された安全なフレームワークを提供します。これは、ブロックチェーンデータへのアクセスを容易にし、その取り扱いを簡素化する上で特に役立ちます。
MCPとソラナ
Model Context Protocol により、AI アシスタントと Quicknode などの外部サービス間の安全な通信が可能となり、Solana(またはその他のブロックチェーン)のデータへのアクセスが可能になります:

今回のSolana MCPでは、主にRPC呼び出しを利用するツールに焦点を当てますが、完全な統合を実演するために、リソースといくつかのプロンプトも実装します。さっそく作ってみましょう!
環境の設定
まずは新しいプロジェクトを作成し、必要な依存関係をインストールしましょう:
mkdir solana-mcp && cd solana-mcp
新しい npm プロジェクトを初期化する
npm init -y
依存関係をインストールする
npm インストール @modelcontextprotocol/sdk @solana/kit zod
npm install --save-dev typescript @types/node
[作成] tsconfig.json 以下の設定が記述されたファイル:
{
"compilerOptions": {
"target": "ES2022",
"module": "NodeNext",
"moduleResolution": "NodeNext",
"esModuleInterop": true,
"strict": true,
"outDir": "./build",
"rootDir": "./",
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true
},
"include": ["*.ts", "src/**/*.ts"],
"exclude": ["node_modules", "build"]
}
これらのスクリプトが package.json:
"scripts": {
"build": "tsc",
"start": "node build/index.js"
}
新しいディレクトリを作成し、 src そして index.ts その中のファイル:
mkdir src && touch src/index.ts
MCPサーバーの構築
まずは、クライアントがウォレットのSOL残高を取得できるようにする単一のツールを実装してみましょう。
依存関係のインポート
開く src/index.ts そして、以下のコードを追加してください:
import {
McpServer,
} from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { z } from "zod";
import {
createSolanaRpc,
address,
isSolanaError,
assertIsAddress,
assertIsSignature,
} from "@solana/kit";
ここでは、MCPサーバーを作成するために必要な依存関係をインポートしています。この @modelcontextprotocol/sdk このパッケージは、MCPサーバーを構築するためのコア機能を提供し、一方、 @solana/kit SolanaのRPC呼び出しを扱うためのユーティリティを提供します。また、以下もインポートします。 zod スキーマ検証のため。これにより、サーバーは入力および出力の妥当性を検証できるようになります。
定数の定義
次に、サーバー用にいくつかの定数を定義する必要があります。これには、RPCエンドポイントやSPLプログラムキーなどが含まれます。以下のコードを src/index.ts:
const CONFIG = {
rpcEndpoint:
process.env.SOLANA_RPC_ENDPOINT || "https://api.mainnet-beta.solana.com",
};
const SPL_PROGRAM_KEYS = {
TOKEN_PROGRAM: address("TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA"),
TOKEN_2022_PROGRAM: address("TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb"),
};
const solanaRpc = createSolanaRpc(CONFIG.rpcEndpoint);
お気づきかもしれませんが、ここでは、次のようなライブラリを使用せずに環境変数を参照しています。 dotenv. MCPサーバーは、クライアントで設定された環境変数を読み込みます(例: claude_desktop_config.json). それについては後で設定します。
MCPサーバーの作成
それでは、MCPサーバーを作成しましょう。このサーバーは、クライアントからのリクエストを受け付け、適切なデータを返します。以下のコードを src/index.ts:
const server = new McpServer({
name: "SolanaMCP",
version: "1.0.0",
});
新しい変数、 サーバー の新しいインスタンスを起動します McpServer クラス。その 名前 そして バージョン プロパティは、サーバーとそのバージョンを識別するために使用されます。あとは、サーバーがクライアントに対して公開するツール、リソース、およびプロンプトを定義するだけです。これは、単に server.tool() メソッド(または .resource() または .prompt() (必要に応じて)。
バランスツールを作成する
最初に作成するツールは、シンプルな残高チェッカーです。このツールは、Solanaのアドレスを入力として受け取り、そのアドレスの残高を返します。以下のコードを src/index.ts:
server.tool(
"getBalance",
{
walletAddress: z
.string()
.describe("Solana wallet address to check the balance for"),
},
async (args: { walletAddress: string }) => {
try {
assertIsAddress(args.walletAddress);
const accountAddress = address(args.walletAddress);
const { value: lamports } = await solanaRpc
.getBalance(accountAddress)
.send();
const solBalance = Number(lamports) / 1_000_000_000;
return {
content: [
{
type: "text" as const,
text: `Balance for ${args.walletAddress}: ${solBalance} SOL (${lamports.toString()} lamports)`,
},
],
};
} catch (error) {
return {
content: [
{
type: "text",
text: `Error while getting balance: ${isSolanaError(error) ? error.message : "Unknown error"}`,
},
],
isError: true,
};
}
},
);
このコードは、 getBalance. このツールは単一の引数を受け取り、 walletAddress、これは残高を確認するSolanaアドレスを表す文字列です。この tool() このメソッドは3つの引数を受け取ります:
- ツールの名前、
- zod 入力スキーマ、および
- ツールが呼び出された際に実行されるコールバック関数。
コールバック関数は、 assertIsAddress 関数 from @solana/kit アドレスの形式を検証します。アドレスが有効な場合、 getBalance Solana RPCクライアントのメソッドを呼び出し、SOLおよびlamports単位の残高を返します。エラーが発生した場合は、エラーメッセージを返します。
サーバーの初期化
素晴らしい!これでサーバーの設定の基本は完了しました。次に、サーバーを初期化し、着信リクエストの受信を開始する必要があります。以下のコードを src/index.ts:
async function runServer() {
const transport = new StdioServerTransport();
await server.connect(transport);
}
runServer().catch((error) => {
console.error("Fatal error:", error);
process.exit(1);
});
受信リクエストの処理には、Standard Input/Output クラスを使用しています(ローカル統合にはこの方法をお勧めします)。このトランスポートを使用すると、サーバーは標準入力および標準出力を介してクライアントと通信できます。この connect() このメソッドはサーバーを起動し、着信リクエストの受信待機を開始します。MCP を使った開発を進めるにつれて、追加のトランスポートオプションが必要になる場合があります。その場合は、 MCP SDK ドキュメント 詳細については。
サーバーの構築
サーバーの設定が完了したので、次にビルドして実行してみましょう。ターミナルで、次のコマンドを実行してください:
npm run build
これにより、TypeScript コードが JavaScript にコンパイルされ、その出力結果が ビルド ディレクトリ。これでサーバーを実行できるようになりましたが、Claude Desktop を使用する場合は、実際に実行する必要はありません。Claude Desktop が自動的にサーバーを初期化してくれるからです。
Claude Desktop のセットアップ
MCPサーバーのコンパイルが完了したので、次はClaudeがそのサーバーを認識でき、それを使用するように設定されていることを確認する必要があります。Claude Desktopがインストールされていることを確認してください。アプリから「Claude」→「設定」の順に選択し、「開発者」をクリックします。「設定の編集」をクリックしてください:

これで、 claude_desktop_config.json ファイル(またはその親ディレクトリ)。ファイルが見つからない場合は、最新の 参考資料 それがどこにあるかを確認するために。
MCPサーバーのJSONオブジェクトが表示されるはずです。これが初めてのMCPの場合は、空になっているはずです。ここで、新しい ソラナ ~に異議を唱える mcpServers オブジェクト。このオブジェクトには、Solana MCP サーバーの設定が含まれます。更新 claude_desktop_config.json 出演:
{
"mcpServers": {
"solana": {
"command": "node",
"args": [
"/absolute/path/to/build/index.js"
],
"env": {
"SOLANA_RPC_ENDPOINT": "https://example.solana-mainnet.quiknode.pro/123456/"
}
}
// other MCP servers that you already have configured...
}
}
以下の点に必ず注意してください:
- 置換
/build/への絶対パス/index.jsの絶対パスを指定してbuild/index.jsファイル。これを見つけるには、次のコマンドを実行します。pwdターミナルで。 - 置換
https://example.solana-mainnet.quiknode.pro/123456/ご自身のSolana RPCエンドポイントを使用してください。お持ちでない場合は、無料で取得できます こちら. 必ずあなたのhttpsエンドポイント。
注:ここが SOLANA_RPC_ENDPOINT 環境変数が定義されています。MCPサーバーにおける環境変数の詳細については、 公式ドキュメント.
ファイルを保存して閉じます。このガイドを進める上で、これ以上このファイルを編集する必要はないはずです。
MCPサーバーのテスト
Claude Config の更新が完了しましたので、Claude Desktop を一度閉じてから再度起動してください。そうすれば、再起動時に Claude Desktop が MCP サーバーを起動するはずです。起動すると、次のような画面が表示されるはずです:

「🔨 ツール」ボタンをクリックすると、使用可能なツールが表示されます(この例では、 getBalance) 👀:

さっそく試してみましょう。クロードに、自分のウォレットの残高を調べてくれるよう頼んでみてください(例:「CebN5WGQ4jvEPvsVU4EoHEpgzq1VV7AbicfhtW4xC9iMの残高はいくらですか?」)。少し考えた後、クロードはMCPツールの使用許可を求めるはずです:

クリックしてツールの使用を許可すると、Claudeがブロックチェーンからデータを取得し、レスポンスとして返してくれるはずです:

おめでとうございます!基本的なSolana MCPサーバーの作成と、Claude Desktopとの連携に成功しました。
MCPサーバーの機能を強化する
基本的な統合が機能するようになったので、サーバーの機能をさらに強化していきましょう。以下を追加します:
- トークンアカウントを取得するためのツール
- ネットワークの状態を確認するためのツール
- トランザクションの詳細を取得するためのツール
- アカウント情報を取得するためのツール
- 簡単なリソースの例
- よくある作業に役立つヒント
これらを追加するのは簡単です。それぞれを1回のメソッド呼び出しで登録するだけで済みます。それぞれについて順に見ていきましょう。必要に応じて、好きな部分だけを選んで実装しても構いません。
トークンアカウントツール
ユーザーのSOL残高を取得するツールはすでにありますが、トークンの残高も取得したい場合はどうすればよいでしょうか。このトークンアカウントツールを使えば、指定されたウォレットアドレスのすべてのトークンアカウントを取得できます。以下のコードを src/index.ts:
server.tool(
"getTokenAccounts",
{
walletAddress: z
.string()
.describe("Solana wallet address to check token accounts for"),
},
async ({ walletAddress }) => {
try {
assertIsAddress(walletAddress);
const accounts = await Promise.all([
solanaRpc
.getTokenAccountsByOwner(
walletAddress,
{ programId: SPL_PROGRAM_KEYS.TOKEN_PROGRAM },
{ encoding: "jsonParsed" },
)
.send(),
solanaRpc
.getTokenAccountsByOwner(
walletAddress,
{ programId: SPL_PROGRAM_KEYS.TOKEN_2022_PROGRAM },
{ encoding: "jsonParsed" },
)
.send(),
]);
const tokenAccounts = accounts.flat();
const tokenAccountDetails = tokenAccounts.flatMap((account) => {
return account.value.map((account) => {
const address = account.pubkey;
const mint = account.account.data.parsed.info.mint;
const amount = account.account.data.parsed.info.tokenAmount.uiAmount;
const decimals =
account.account.data.parsed.info.tokenAmount.decimals;
return { address, mint, amount, decimals };
});
});
// Format data as a markdown table
let markdownTable = "| Token Address | Mint | Amount | Decimals |\n";
markdownTable += "|-------------|------|--------|----------|\n";
tokenAccountDetails
.filter((account) => account.amount !== null)
.filter((account) => account.amount !== 0)
.filter((account) => account.amount !== 1) // removing possible NFTs
.sort((a, b) => b.amount! - a.amount!) // we already removed null and 0 amounts
.forEach((account) => {
markdownTable += `| ${account.address} | ${account.mint} | ${account.amount} | ${account.decimals} |\n`;
});
return {
content: [
{
type: "text",
text: `Found ${tokenAccountDetails.length} token accounts for ${walletAddress}`,
},
{
type: "text",
text: markdownTable,
},
],
};
} catch (error) {
return {
content: [
{
type: "text",
text: `Error while getting balance: ${isSolanaError(error) ? error.message : "Unknown error"}`,
},
],
isError: true,
};
}
},
);
これは構造的に、次のものと非常に似ています。 getBalance ツール。主な違いは、私たちが getTokenAccountsByOwner 指定されたウォレットアドレスのすべてのトークンアカウントを取得するメソッドです。従来のSPLトークンプログラムとToken 2022プログラムの両方に対応しています。レスポンスの量が非常に多くなる可能性があるため、残高が0または1のアカウント(おそらくNFT)を除外し、データの一部をマークダウン形式の表に整形する処理を行っています。 ご自身のユースケースに最適な形式を見つけるため、さまざまなレスポンス構造を自由に試してみてください。
ネットワークステータスツール
次に、ネットワークの状態を確認するためのツールを追加しましょう。このツールは、現在のエポック、ブロック高、スロット番号を返します。以下のコードを src/index.ts:
server.tool("networkStatus", {}, async () => {
try {
await solanaRpc.getHealth().send();
} catch (error) {
return {
content: [
{
type: "text",
text: `Network is down`,
},
],
};
}
try {
const { epoch, blockHeight, absoluteSlot } = await solanaRpc
.getEpochInfo()
.send();
const status = {
health: "okay",
currentEpoch: epoch.toString(),
blockHeight: blockHeight.toString(),
currentSlot: absoluteSlot.toString(),
};
return {
content: [
{
type: "text",
text: JSON.stringify(status, null, 2),
},
],
};
} catch (error) {
return {
content: [
{
type: "text",
text: `Error while getting network status: ${isSolanaError(error) ? error.message : "Unknown error"}`,
},
],
isError: true,
};
}
});
ここでは、実際には2つのRPC呼び出しを行っています。1つ目は、ネットワークが接続されているかどうかを確認するための単純なヘルスチェックです。これがエラーを返した場合は、「ネットワークがダウンしています」という簡単なメッセージを返します。接続されている場合は、 getEpochInfo 現在のエポック、ブロック高、スロット番号を取得します。このデータをJSON形式で返します。なお、 bigint シリアライゼーションの問題を回避するために、値を文字列に変換します。 JSON.stringify.
取引詳細ツール
次に、トランザクションの詳細を取得するツールを追加しましょう。このツールは、トランザクションの署名を入力として受け取り、トランザクションの詳細を返します。以下のコードを src/index.ts:
server.tool(
"getTransaction",
{
signature: z.string().describe("Solana transaction signature to look up"),
},
async ({ signature }) => {
try {
assertIsSignature(signature);
} catch (error) {
return {
content: [
{
type: "text",
text: `not a vaid signature: ${signature}`,
},
],
isError: true,
};
}
try {
const transaction = await solanaRpc
.getTransaction(signature, {
maxSupportedTransactionVersion: 0,
encoding: "json",
})
.send();
if (!transaction) {
return {
content: [
{ type: "text", text: `Transaction ${signature} not found` },
],
isError: true,
};
}
const programIndices = transaction.transaction.message.instructions.map(
(instruction) => instruction.programIdIndex,
);
const programsInvoked = programIndices.map((index) => {
const programId = transaction.transaction.message.accountKeys[index];
return programId.toString();
});
// Format the transaction data for readability
const formattedTx = {
signature,
computeUnits: transaction.meta?.computeUnitsConsumed?.toString(),
logs: transaction.meta?.logMessages,
accountKeys: transaction.transaction.message.accountKeys,
programsInvoked: programsInvoked,
instructions: transaction.transaction.message.instructions,
slot: transaction.slot.toString(),
blockTime: transaction.blockTime
? new Date(Number(transaction.blockTime) * 1000).toISOString()
: null,
fee: transaction.meta?.fee.toString(),
status: transaction.meta?.err ? "Failed" : "Success",
preBalances: transaction.meta?.preBalances.map((balance) =>
balance.toString(),
),
postBalances: transaction.meta?.postBalances.map((balance) =>
balance.toString(),
),
preTokenBalances: transaction.meta?.preTokenBalances,
postTokenBalances: transaction.meta?.postTokenBalances,
};
return {
content: [
{
type: "text",
text: `Transaction ${signature}:\n${JSON.stringify(formattedTx, null, 2)}`,
},
],
};
} catch (error) {
return {
content: [
{
type: "text",
text: `Error while getting balance: ${isSolanaError(error) ? error.message : "Unknown error"}`,
},
],
isError: true,
};
}
},
);
当社の残高チェッカーと同様に、Solana Kitのアサーションを使用してパラメータを検証することができます(この場合は、 assertIsSignature). 次に、 getTransaction トランザクションの詳細を取得する方法です。データを解析し、LLMがトランザクションを分析する際に有用だと判断したデータの一部のみを返しています。 この場合、トランザクション内で呼び出されたプログラムID、トランザクション署名、消費された演算単位、ログ、アカウントキー、呼び出されたプログラム、命令、スロット番号、ブロック時間、手数料、ステータス、事前残高、事後残高、およびトークンの事前・事後残高を抽出しています。前回のツールと同様に、必ず変換を行うようにしています。 bigint シリアライゼーションの問題を回避するために、値を文字列に変換します。
MCPを試してみる際には、IDLを活用して命令データを解析したり、有用と思われるその他のコンテキストやマッピングを追加したりして、応答データを少し充実させてみるのもよいでしょう。
アカウント情報ツール
次に、アカウント情報を取得するツールを追加しましょう。このツールは、アカウントアドレスを入力として受け取り、アカウント情報を返します。以下のコードを src/index.ts:
server.tool(
"getAccountInfo",
{
walletAddress: z
.string()
.describe("Solana wallet address to check account information for"),
},
async ({ walletAddress }) => {
try {
assertIsAddress(walletAddress);
const accountAddress = address(walletAddress);
const { value: accountInfo } = await solanaRpc
.getAccountInfo(accountAddress)
.send();
if (!accountInfo) {
return {
content: [
{
type: "text",
text: `Account ${walletAddress} not found or has no SOL balance`,
},
],
isError: true,
};
}
const info = {
executable: accountInfo.executable,
lamports: accountInfo.lamports.toString(),
owner: accountInfo.owner.toString(),
rentEpoch: accountInfo.rentEpoch.toLocaleString(),
space: accountInfo.data.length,
};
return {
content: [
{
type: "text",
text: JSON.stringify(info, null, 2),
},
],
};
} catch (error) {
console.error("Error fetching account info:", error);
return {
content: [
{
type: "text",
text: `Error while getting account info: ${isSolanaError(error) ? error.message : "Unknown error"}`,
},
],
isError: true,
};
}
},
);
こうしたパターンは、もうお馴染みだと思います。ここでは、 getAccountInfo アカウント情報を取得する方法。
リソースの例
MCPのリソースは、サーバーがLLMによって参照・利用可能な構造化データを公開するための手段を提供します。呼び出されると操作を実行するツールとは異なり、リソースは標準化された形式でデータを公開する「読み取り専用エンドポイント」のようなものです。リソースは、file://やhttps://といったスキーム、あるいはこの例でいうsolana://のようなカスタムスキームに従ったURI(Uniform Resource Identifier)によって識別されます。
ここでは、ドキュメントリソースをサーバーに取り込む方法について、統合された例をご紹介します。これは、Solanaのトランザクション最適化に関するドキュメントの内容を要約したものです:
server.resource(
"transaction-optimization",
"solana://docs/transaction-optimization",
async (uri) => {
const optimizationGuide = {
title: "Solana Transaction Optimization Strategies",
strategies: {
priority_fees: {
description: "Increase transaction priority in validator queues",
implementation:
"Use ComputeBudgetProgram.setComputeUnitPrice({microLamports})",
best_practice:
"Use QN Priority Fee API to determine optimal fee based on network conditions",
},
compute_units: {
description:
"Optimize compute unit usage to prevent transaction drops",
current_limits: {
per_block: "48 million",
per_account_per_block: "12 million",
per_transaction: "1.4 million",
transaction_default: "200,000",
},
implementation:
"Use ComputeBudgetProgram.setComputeUnitLimit({units}) after simulation",
},
transaction_assembly: {
steps: [
"Create transaction with instructions",
"Fetch and add priority fees",
"Simulate transaction to determine compute usage",
"Set compute limit based on simulation",
"Add recent blockhash",
"Sign and send",
],
},
jito_bundles: {
description: "Bundle multiple transactions for atomic execution",
requires: "SOL transfer to Jito Tip Account",
},
confirmation: {
description: "Poll transaction status to ensure it landed",
method: "Use getSignatureStatuses and implement retry logic",
},
},
moreInfo: "https://www.quicknode.com/docs/solana/transactions",
};
return {
contents: [
{
uri: uri.href,
text: JSON.stringify(optimizationGuide, null, 2),
},
],
};
},
);
このリソースは、Solanaにおけるトランザクション最適化戦略について、体系的な概要を提供します。LLMはこのリソースを活用することで、ツールやAPIを呼び出すことなく、トランザクション最適化に関する質問に回答することができます。URIスキーマ(solana://)は、これがカスタムリソースタイプであることを示しており、内容は構造化された形式で返されます。
役立つプロンプト
MCPにおけるプロンプトとは、AIがツールやリソースとやり取りする際の指針となる、あらかじめ定義されたメッセージテンプレートです。コードを実行する「ツール」やデータを提供する「リソース」とは異なり、プロンプトは、LLMが特定のタスクにどのように取り組むべきかを構造化する「レシピ」のようなものです。
LLMが私たちのツールをうまく活用できるよう、役立つプロンプトをいくつか追加しましょう。以下のコードを src/index.ts:
server.prompt(
"analyze-wallet",
{ walletAddress: z.string() },
({ walletAddress }) => ({
description:
"Analyze a Solana wallet address and provide a summary of its balances and activity",
messages: [
{
role: "user",
content: {
type: "text",
text: `Please analyze this Solana wallet address: ${walletAddress}
1. What is the SOL balance of this wallet?
2. What token balances does this wallet hold?
3. Provide a summary of recent activity if possible.`,
},
},
],
}),
);
server.prompt(
"explain-transaction",
{ signature: z.string() },
({ signature }) => ({
description: "Analyze and explain a Solana transaction in simple terms",
messages: [
{
role: "user",
content: {
type: "text",
text: `Please analyze this Solana transaction signature: ${signature}
1. Was this transaction successful?
2. What type of transaction is this? (e.g., token transfer, swap, NFT mint)
3. What accounts were involved?
4. Explain what happened in simple terms.`,
},
},
],
}),
);
各プロンプトは以下の要素で構成されています:
- 一意の名前(「analyze-wallet」など)
- パラメータスキーマ(型検証にZodを使用)
- それらのパラメータに基づいてメッセージの内容を生成する関数
ユーザーがClaude Desktopでプロンプトを選択すると、パラメータを入力するためのフォームが表示されます。送信されると、Claudeはフォーマットされたメッセージテンプレートを受け取り、それに応じて応答します。プロンプトは特に次のような場合に役立ちます:
- 一般的なワークフローの標準化
- クライアントが業務を一貫して遂行できるようにする
- ユーザーが効果的なクエリを作成できるよう支援する
- クライアントがツールを最も効率的な順序で利用できるよう導く
サーバーを再構築する
ツール、リソース、プロンプトをすべて追加したので、サーバーを再構築しましょう:
npm run build
強化されたMCPサーバーをテストする
サーバーの機能を拡張したので、Claude Desktopを使って新機能を試してみましょう。設定変更後は、必ずClaude Desktopを一度閉じてから再起動し、サーバーを再起動してください。Claude Desktopを開くと、ツールメニューに5つのツールがすべて表示されるはずです:

ぜひ少し試してみてください。例えば、次のようなことを試してみてもいいでしょう:
- ソラナ・ネットワークの現状はどうなっていますか?
- このウォレットに含まれるトークンの一覧を作成してください:XYZ...ABC
- XYZ...ABCに関する取引情報を教えてください。
- XYZ…ABCの口座情報を教えてください。
また、🔌「MCPから添付」というボタンがあるはずですので、それをクリックすると、利用可能なリソースとプロンプトが表示されます:

プロンプトのいずれかをクリックすると、パラメータ(ウォレットアドレスやtxidなど)を入力できるフォームが表示されます:

パラメータを入力して「送信」をクリックすると、クロードはそのプロンプトに基づいて(必要なツールを活用しながら)メッセージを生成し、それに応じて返信します。ぜひ試してみてください。
いよいよ、リソースをテストできます。これを行うには、 トランザクションの最適化 プロンプトにそれを入力し、その内容に関連した質問をクロードに投げかけてみてください。ぜひ試してみてください:

よくやった!
まとめ
ブロックチェーン機能によってLLMの能力を強化するSolana MCPサーバーの構築に成功しました。この統合により、ClaudeはSolanaブロックチェーンと直接やり取りできるようになり、残高の確認、トークン情報の取得、トランザクションの確認などが可能になります。 AIアシスタントの自然言語理解能力とMCPサーバーのデータアクセス機能を組み合わせることで、ブロックチェーンとのやり取りを行うための強力なツールを構築しました。開発者、トレーダー、あるいは単にSolanaに興味がある方であっても、この統合により、ブロックチェーンデータへのアクセスが容易になり、理解しやすくなります。 MCPフレームワークは柔軟かつ拡張性が高いため、ニーズの変化に応じてサーバーに追加機能を継続的に強化していくことが可能です。単純なデータクエリから、複雑な分析、トランザクションの構築(適切なセキュリティ対策を施した上で)、エージェントの組み立てに至るまで、その可能性は事実上無限です。 このガイドが、MCPとSolanaの統合を始める上でお役に立てば幸いです。すでに構築したものをさらに拡張したいとお考えですか?継続的な開発に向けたアイデアをいくつかご紹介します:
Solana MCP サーバーの拡張
MCPサーバーが正常に動作するようになったところで、さらなる機能強化のためのアイデアをいくつかご紹介します:
- トークンのメタデータ取得:QuicknodeのDAS APIを使用して、各ソースからNFTやトークンのメタデータを取得し、トークンの残高とともに名称、シンボル、ロゴを表示します。
- 価格情報:Metis Jupiter APIと連携し、SOL および SPL トークンの最新価格を提供します。
- 取引履歴:ウォレットアドレスの直近の取引を取得するツールを実装する。
- プログラムのアカウントおよびトランザクションデータを解析する:このMCPはSolana Kitを使用して構築されているため、Codamaを使用して独自のプログラム用のクライアントを生成し、プログラムのコーデックをMCPサーバーに統合することができます。
- ステークアカウント情報:ステークアカウントやデリゲーションの状態に関する情報を取得するためのツールを追加する(Solana Kit を使用したステークアカウントの取得例)
- Quicknodeのアドオンを統合して機能を拡張する
ぜひ創造力を発揮してください!皆さんがどんなものを作ってくれるのか、楽しみにしています。ご質問やサポートが必要な場合は、Discordや Twitterで遠慮なくご連絡ください。
その他の参考資料
- 本ガイドのコード
- モデルコンテキストプロトコルのドキュメント
- Solana ドキュメント
- Solana Kit ドキュメント
- MCP Inspector- MCPサーバーのデバッグに役立つツール
- MCP のセキュリティに関する注意事項- MCP サーバーを構築する際の重要なセキュリティ上の注意事項
皆様からのフィードバックを心よりお待ちしております!❤️
ご意見や新しいトピックに関するご要望などがありましたら、ぜひお知らせください。皆様からのご連絡を心よりお待ちしております。
