MCP: 手を動かして学んだログ

MCP: 手を動かして学んだログ

Slug
learn-mcp
Tags
Tech
Published
April 12, 2025
AI summary
⚠️
ただ触ってみただけなので、技術的な正しさは保証できません!

目次

概要を知る

まず、MCPについて再度確認するために以下の2つの動画を見た。
安野さんの動画はまず一番最初におすすめしたいくらい的確かつ噛み砕かれた説明だった。
グンタさんのLTは、より詳細な動向や具体的なツールについて技術者向けに説明されている。
Video preview
Video preview
 
また、安野さんの動画でも紹介されている以下の記事は、実際の業務でMCPをCursor経由で使用するイメージを湧かせるのに良かった。
 

何はともあれ総本山へ

それではMCPのことがなんとなく分かった所で、総本山を参拝する。
先ほど動画で概要を理解したお陰で、この図もすんなり理解出来る。
https://modelcontextprotocol.io/introduction#general-architecture

まずはExampleを

ドキュメントの流れに沿ってQuickStartから手を付ける…と思いきや、まずはExampleコードを見ることに。
問題集を解くときに答えから見る派
問題集を解くときに答えから見る派
 
コードを眺めていると、 request.params.name に応じて条件分岐をして、その先でslackClientの関数を実行していることが分かる。つまり、LLMには事前に params.name のリストとその機能内容が共有されており、LLMが実行したい機能の params.name をMCPサーバーに渡すことで処理が行われていると推測できる。
server.setRequestHandler( CallToolRequestSchema, async (request: CallToolRequest) => { console.error("Received CallToolRequest:", request); try { if (!request.params.arguments) { throw new Error("No arguments provided"); } switch (request.params.name) { case "slack_list_channels": { const args = request.params .arguments as unknown as ListChannelsArgs; const response = await slackClient.getChannels( args.limit, args.cursor, ); return { content: [{ type: "text", text: JSON.stringify(response) }], }; }
https://github.com/modelcontextprotocol/servers/blob/2c706e5c51aa6fce0e04de90a51c1f63c0466dd0/src/slack/index.ts#L379-L402
 

MCPサーバーを動かしてみる

次に、QuickStartガイドで手を動かす。新規プロジェクトを立ち上げて、言われた通りにコードをペタペタ貼っていく。
 
すげー!出てきた。
notion image
 
ここで試しに get-forecast という単語がある箇所を調べて、 get-forecaster という文字列に変えてみる。
notion image
npm run build し、Claudeを再起動すると、 get-forecaster になった!ここで、 server.tool() で定義したツールがちゃんと読み込まれていることを実感する。
notion image
 
挙動がおかしくなると嫌なので get-forcast に戻す。
ドキュメントの通りに天気を聞いてみると、ローカルのMCPサーバーへのアクセス許可を求められた。
notion image
 
USの天気しか取れないらしい。無念。
notion image
 
シアトルなら取れた!
notion image
 
ここで情報元の weather.gov にアクセスして確かめてみると…
確かに情報が一致していそう!
https://forecast.weather.gov/MapClick.php?lat=47.6611&lon=-122.3055&unit=0&lg=english&FcstType=graphical
 

分かったこと

最初の推測通り、 server.tool() によって、
LLMには事前に params.name のリストとその機能内容が共有されており、LLMが実行したい機能の params.name をMCPサーバーに渡すことで処理が行われている
ことが分かった。また、それに加えて、paramsも指定されている事がわかる。
server.tool( "get-forecast", "Get weather forecast for a location", { latitude: z.number().min(-90).max(90).describe("Latitude of the location"), longitude: z .number() .min(-180) .max(180) .describe("Longitude of the location"), },
https://github.com/foxytanuki/mcp-sandbox/blob/7b2fc85ef9a6912cc95ad406fb1c4312bb2eedef/src/weather.ts#L136-L146
確かに、Claude Desktop上で latitudelogtitude の入ったオブジェクトを生成して、MCPサーバーに渡しているような場面があった
notion image
 

クライアントについて理解する

Quickstartにはクライアント側のガイドもあるが、自分はクライアントを実装する気はないので、ドキュメントをざっと見るだけにする。
 
MCPの接続をしてから、toolsを取得している箇所がある。
this.mcp.connect(this.transport); const toolsResult = await this.mcp.listTools(); this.tools = toolsResult.tools.map((tool) => { return { name: tool.name, description: tool.description, input_schema: tool.inputSchema, }; });
https://modelcontextprotocol.io/quickstart/client#server-connection-management-2
 
messageの中に tools というkeyがあるのが分かる。
const response = await this.anthropic.messages.create({ model: "claude-3-5-sonnet-20241022", max_tokens: 1000, messages, tools: this.tools, });
https://modelcontextprotocol.io/quickstart/client#query-processing-logic-2
これはClaudeに元々あったfunction callingという機能を使っているっぽい?
 
Claudeに聞いた

Q. Tool CallとFunction CallingとMCPの関係について教えて
A. Tool Call、Function Calling、MCPの関係について説明します。
基本的な関係
  • Function Calling(関数呼び出し)は、AIモデルが外部の関数やAPIを呼び出すための仕組みです。
  • Tool Calling(ツール呼び出し)は、AnthropicがFunction Callingを実装した機能の呼び方です。基本的には同じ概念を指します。
  • MCP (Model Completion Protocol) は、Anthropicが開発した、より広範なプロトコルで、Tool/Function Callingを含むモデルとのやり取りを標準化するフレームワークです。
詳細な説明
  1. Function Calling / Tool Calling
      • これらは本質的に同じ概念です。AIモデルが外部の関数やAPIを呼び出す機能を指します。
      • OpenAIは「Function Calling」、Anthropicは「Tool Calling」という用語を主に使用していますが、機能的には非常に似ています。
      • この機能により、AIモデルは自分の知識や能力を超えたタスク(最新の情報検索、計算、外部システムとの連携など)を実行できます。
  1. MCP (Model Completion Protocol)
      • MCPはAnthropicが開発したより包括的なプロトコルです。
      • Tool Callingはこのプロトコルの一部として実装されています。
      • MCPは単なるツール呼び出しを超えて、モデルとアプリケーション間のやり取りを標準化し、一貫性のある方法でAIの出力をパースして利用できるようにすることを目指しています。
  1. 実装の違い
      • OpenAIのFunction Callingは特定のJSON形式で関数を定義します。
      • AnthropicのTool Callingも同様にJSONスキーマベースですが、MCPの一部として実装されているため、より広範なコンテキストで機能します。

 

実践: gas代を取得するMCPサーバー実装

実装

Ethereum Mainnetのgas代を取得するMCPサーバーを実装してみた。
Update package.json and package-lock.json to include ethers.js and add gas tool implementation in gas.ts for Ethereum gas price retrieval
 
プロンプトは以下。
@weather.ts を参考に、ethereumのgas代を取得するMCPサーバーを実装して。RPCのURLはhttps://ethereum-rpc.publicnode.com とします。
 
claude_desktop_config.json の変更及びClaude Desktopの再起動も忘れずに。
{ "mcpServers": { "weather": { "command": "node", "args": [ "/Users/foxy/mcp-sandbox/build/weather.js" ] }, "gas": { "command": "node", "args": [ "/Users/foxy/mcp-sandbox/build/gas.js" ] } } }
 

いざ実行

get-gas-price というtoolが増えている!
notion image
 
結果は… 0.457 Gwei (一時期に比べたら異次元の安さ…)
notion image
確かに合っていそう!
https://etherscan.io/gastracker
 
https://t.foxytanuki.dev/

まとめ

巷ではMCPはAI向けのUSB-Cだ!なんて言われており、Claudeもそう説明しているようだが、個人的には”AI様に使って頂くために書式を整えたAPIサーバー”という印象を受けた。まだMCPの一部の機能しか使ってないからかも。
これからのWebサーバー開発では、「RESTやgRPC、GraphQLといった従来型のAPI」と「MCP」による二系統のアクセス手段を整備するスタイルが主流になっていくのかも。
ロジックをいかに共通化しつつ、用途に応じてアクセス経路を適切に分離するかが鍵となり、この分野でも今後ベストプラクティスが生まれてきそうだと感じた。
 
[追記] 以下の記事わかりやすかったです!