3
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

FastMCPでローカルMCPサーバーを用意してClaude Codeから呼び出してみた

3
Posted at

Supershipの名畑です。ついに完結したアニメ版のグノーシアはすべてにおいて非常に高い期待値を大きく飛び越えてくれました。脚本や作画、音楽、さらには声優の演技。特にSQ役の鬼頭明里さんとラキオ役の七海ひろきさんが良すぎました。七海さんは舞台を何度か観劇させていただいたことがありますが、声優としても素晴らしすぎます。

はじめに

Claude Code は agentic coding ツールで、コードベースを読み取り、ファイルを編集し、コマンドを実行し、開発ツールと統合します。ターミナル、IDE、デスクトップアプリ、ブラウザで利用できます。

参考:Claude Code の概要 - Claude Code Docs

もはやその名前を聞かない日がないほどに普及しているClaude Codeですが、今回はその拡張としてMCP(Model Context Protocol) サーバーを用意してみます。

MCPサーバーによってClaude Codeを外部のデータやAPIと連携させることが可能です。

今回は、PythonでMCPサーバーを手間少なく構築できるフレームワーク FastMCP で用意した自前のMCPサーバーをClaude Codeから呼び出すところまでを記録に残します。
毎度のごとくまったく目新しさのない情報ではありますが、Claude Codeが爆発的に普及しているこのタイミングで改めて備忘として残しておきます。

本記事ではClaude Code自体のセッティングについては触れませんので、まだの方はクイックスタートをご覧ください。

MCPとは

MCP (Model Context Protocol) is an open-source standard for connecting AI applications to external systems.

Using MCP, AI applications like Claude or ChatGPT can connect to data sources (e.g. local files, databases), tools (e.g. search engines, calculators) and workflows (e.g. specialized prompts)—enabling them to access key information and perform tasks.

Think of MCP like a USB-C port for AI applications. Just as USB-C provides a standardized way to connect electronic devices, MCP provides a standardized way to connect AI applications to external systems.

参考:What is the Model Context Protocol (MCP)? - Model Context Protocol

日本語訳すると以下です。

MCP(Model Context Protocol)は、AIアプリケーションを外部システムに接続するためのオープンソースの標準規格です。

MCPを使用することで、ClaudeやChatGPTなどのAIアプリケーションは、データソース(ローカルファイル、データベースなど)、ツール(検索エンジン、電卓など)、ワークフロー(特化型プロンプトなど)に接続でき、重要な情報へのアクセスやタスクの実行が可能になります。

MCPは、AIアプリケーションにとってのUSB-Cポートのようなものです。USB-Cが電子機器を接続するための標準規格であるように、MCPはAIアプリケーションを外部システムに接続するための標準規格を提供します。

Claude CodeにおけるMCP

Claude Code は、AI ツール統合のためのオープンソース標準である Model Context Protocol (MCP) を通じて、数百の外部ツールとデータソースに接続できます。MCP サーバーは Claude Code にツール、データベース、API へのアクセスを提供します。

参考:MCP を使用して Claude Code をツールに接続する - Claude Code Docs

MCPサーバーは様々なサードパーティーが公開しています。CanvaNotionFigmaSlackAtlassianなどなど。

Claude Codeでの人気MCPサーバーの一覧はこちらです。

以下注記の通り、Anthropicの公式というわけではないことを認識の上で利用ください。

サードパーティの MCP サーバーは自己責任で使用してください。Anthropic はこれらすべてのサーバーの正確性またはセキュリティを検証していません。 インストールする MCP サーバーを信頼していることを確認してください。 信頼できないコンテンツを取得する可能性のある MCP サーバーを使用する場合は特に注意してください。これらはプロンプトインジェクションのリスクにさらされる可能性があります。

参考:人気のある MCP サーバー

FastMCPとは

FastMCP is the standard framework for building MCP applications. The Model Context Protocol (MCP) connects LLMs to tools and data. FastMCP gives you everything you need to go from prototype to production — build servers that expose capabilities, connect clients to any MCP service, and give your tools interactive UIs

参考:Welcome to FastMCP - FastMCP

日本語訳すると以下です。

FastMCPは、MCPアプリケーションを構築するための標準フレームワークです。Model Context Protocol(MCP)はLLMをツールやデータに接続します。FastMCPは、プロトタイプから本番環境まで必要なすべてを提供します。機能を公開するサーバーの構築、任意のMCPサービスへのクライアント接続、そしてツールにインタラクティブなUIを持たせることが可能です。

さらに読み進めていくと、FastMCP 1.0は2024年にMCP公式Python SDKに組み込まれ、現在、独立プロジェクトとして積極的にメンテナンスされているということ、また、1日に100万回ダウンロードされ、全言語を通じてMCPサーバーの70%が何らかのバージョンのFastMCPを利用しているともあります。

FastMCPの柱は以下の3つです。

  • Servers:ツール、リソース、プロンプトをLLMに公開する
  • Clients:任意のMCPサーバーに接続する
  • Apps:会話内にインタラクティブなUIを提供する

では、実際にFastMCPを使ってローカルのMCPサーバーを試してみようと思います。

環境

MacBookです。

Pythonをインストール済みです。

% python --version
Python 3.14.3

Claude Codeもインストール済みです。

% claude --version                              
2.1.80 (Claude Code)

FastMCPのインストール

まず pip install fastmcp でFastMCPをインストールします。

% pip install fastmcp
Collecting fastmcp
  Using cached fastmcp-3.1.1-py3-none-any.whl.metadata (8.1 kB)
Collecting authlib>=1.6.5 (from fastmcp)
  Using cached authlib-1.6.9-py2.py3-none-any.whl.metadata (9.8 kB)

以下略

バージョンを確認しておきます。

% fastmcp version
FastMCP version:3.1.1
MCP version:1.26.0
Python version:3.14.3
Platform:macOS-26.2-arm64-arm-64bit-Mach-O
FastMCP root path:略

MCPサーバーの作成

Quickstartを参考にして「0〜9の各数字をカウントするMCPサーバー」を用意することとします。
AIは計算をしていないのでカウントが苦手」というのはよく言われますので、その補完を想定します。

以下のコードを digit_counter.py として保存します。

from fastmcp import FastMCP

mcp = FastMCP("Digit Counter")


@mcp.tool
def count_digits(text: str) -> dict[str, int]:
    """文字列に含まれる0〜9の各数字の出現回数をカウントします。"""
    return {str(d): text.count(str(d)) for d in range(10)}


if __name__ == "__main__":
    mcp.run()

@mcp.tool デコレータをつけるだけで関数がMCPツールとして扱われます。
また docstring として書いた内容("""で挟まれた部分)がMCPのツール説明として用いられます。

count_digits という関数に文字列を渡すと0から9の出現回数を返すという非常にシンプルなコードです。

MCPサーバーの動作確認

FastMCPにはCLIが用意されており、サーバーの動作を確認できます。

以下の通り fastmcp run を呼び出すと、スクリーンショットの通り、起動したことが示されます。

% fastmcp run /path/to/digit_counter.py:mcp

/path/to/digit_counter.py は実際のdigit_counter.pyまでのファイルパスに置き換えてください。

fastmcp_1.png

起動が確認できたなら、Ctrl + C で停止します。

Claude CodeへのMCPサーバーの登録

Claude CodeにMCPサーバーを登録します。

claude mcp add コマンドを使います。

% claude mcp add digit-counter -- python /path/to/digit_counter.py

登録されたか確認してみます。

% claude mcp list

以下の通り、接続が確認できました。

digit-counter: python /path/to/digit_counter.py - ✓ Connected

Claude Codeからの呼び出し

では実際にClaude上で呼び出してみます。
文字列に登場する0の数をカウントしてもらいます。

「00000000000000000000000000000000000100000000000000000000000000000000000100000000000000000000000000000000000」0はいくつありますか?

正解は105です。

以下の通りの確認が表示されましたので、digit-counterがきっちり使われているようです。

 Tool use                                                                                                                                                                           
                  
   digit-counter - count_digits(text: "00000000000000000000000000000000000100000000000000000000000000000000000100000000000000000000000000000000000") (MCP)                          
   文字列に含まれる0〜9の各数字の出現回数をカウントします。

 Do you want to proceed?

Yesを選ぶと、以下が出力されました。成功です。

0は 105個 です。(ちなみに1が2個、合計107文字の文字列です)   

応用編 URLを渡すと内容を取得するMCPサーバーを用意する

せっかくなのでもう少し応用してみます。

通常、Claude CodeはURLの読み込み時には組み込みのWeb fetch toolを用いますが、今回はそれをMCP経由で行うようにしてみます。

データの取得はMCPサーバーが行い、その加工をClaude Codeで行う、その一例となれば幸いです。

MCPサーバーの作成

まず、以下のコードを web_reader.py として保存します。渡されたurlからhtmlを取得し、scriptとstyleとnoscriptを取り除きます。

from html.parser import HTMLParser

import httpx
from fastmcp import FastMCP

mcp = FastMCP("Web Reader")


class _TextExtractor(HTMLParser):
    """HTMLからscript/style/noscript以外のテキストを抽出する。"""

    def __init__(self):
        super().__init__()
        self._parts: list[str] = []
        self._skip = False

    def handle_starttag(self, tag, attrs):
        self._skip = tag in ("script", "style", "noscript")

    def handle_endtag(self, tag):
        if tag in ("script", "style", "noscript"):
            self._skip = False

    def handle_data(self, data):
        if not self._skip:
            self._parts.append(data)

    def get_text(self) -> str:
        return "".join(self._parts)


@mcp.tool
def fetch_page(url: str) -> str:
    """URLのページを取得し、本文テキストを返します。"""
    
    resp = httpx.get(url, follow_redirects=True, timeout=15)
    resp.raise_for_status()
    parser = _TextExtractor()
    parser.feed(resp.text)
    return parser.get_text()


if __name__ == "__main__":
    mcp.run()

簡易な実装ですが、MCPサーバーとしての動作確認には十分かと思います。

Claude CodeへのMCPサーバーの登録

続いてClaude Codeに登録します。

% claude mcp add web-reader -- python /path/to/web_reader.py

/path/to/web_reader.py は実際のファイルパスに変更してください。

登録されたか確認してみます。

% claude mcp list

以下の通り、無事に登録されていました。

web-reader: python /path/to/web_reader.py - ✓ Connected

Claude Codeからの呼び出し

では、実際にWebページの読み込みを行ってみます。

今回は私の過去記事である「エンジニア採用担当者である私の目から見たAtCoder(競技プログラミング)の印象」を対象としてみます。

MCP経由で以下の内容を取得し、要約してください。
https://qiita.com/nabata/items/b1da32104ce39662b11d 

Web fetch toolの呼び出しを避けるためにMCP経由と明示しています。
CLAUDE.mdに「特定のURLはMCP経由で取得する」などと記載する方が適切かとは思います。

以下の通りの確認が表示されましたので、意図通りに挙動していそうです。

 Tool use                                                                                                                                                                           
                                                                                                                                                                                    
   web-reader - fetch_page(url: "https://qiita.com/nabata/items/b1da32104ce39662b11d") (MCP)                                                                                        
   URLのページを取得し、本文テキストを返します。                                                                                                                                    
                                                                                                                                                                                  
 Do you want to proceed?

結果は以下です。成功です。

⏺ 記事の要約                                                                                                                                                                        
                                                                                                                                                                                    
  タイトル: 「エンジニア採用担当者である私の目から見たAtCoder(競技プログラミング)の印象」                                                                                           
                                                                                                                                                                                    
  著者: nabataさん(Supership CTO)/ 2023年12月25日投稿                                                                                                                             
                                                                                                                                                                                    
  主なポイント                                                                                                                                                                      
                                                                                                                                                                                  
  1. きっかけ — 採用活動で応募者の競プロ経験を正しく評価するため、2020年頃に自らAtCoderを始め、約1年で緑ランクに到達。                                                              
  2. やってみて変わった印象 — 茶(上位46%)や緑(上位25%)になるのも想像以上に難しい。自由意志で参加する人たちの中でのランキングなので、簡単なわけがない。
  3. 成長実感 —                                                                                                                                                                     
  コードの読み書きが以前よりスムーズになった。秒単位を意識してコードを書く経験が基礎力を底上げし、思考にリソースを回せるようになった。スキルの可視化による「自信」も得られた。      
  4. 実務への有用性 — 「役立つ」と断言。競プロ的な問題が実務で頻出するわけではないが、基礎力の向上を通じて間接的に実務に効く。                                                      
  5. 他人に薦めるか — 強く薦めたことはない。エンジニアリングは幅広く、競プロだけが成長の最短ルートではない。自身が続けた理由は「面白いから」。                                      
  6. 色への印象 —                                                                                                                                                                   
  水色以上は「すごい」(数学的思考・継続力・頭の回転・コーディング速度)。緑・茶でも継続力があり、灰でも続ければ伸びると思う。上位ほど「プログラミングが好きなんだろうな」と感じる。
  7. 就活への効果 — 一定の効果はある。特にコーディング試験やAtCoderJobs経由では有利。ただし一般的なWeb系新卒採用では、自作アプリやインターン経験なども同等以上に重要。アピールするな
  ら色の意味を説明する「肉付け」が必要。                                                                                                                                            
  8. 競プロを始めて変わったこと — 「プログラミング自体が目的」という世界に居心地の良さを感じ、自分がプログラミングを好きだと再認識した。競プロ仲間との交流も増えた。

最後に

MCPサーバーはデータの取得や計算を担い、判断や加工といった知的作業はClaude Codeが担うという役割分担が手軽に実現できて面白いです。

宣伝

SupershipのQiita Organizationを合わせてご覧いただけますと嬉しいです。他のメンバーの記事も多数あります。

Supershipではプロダクト開発やサービス開発に関わる方を絶賛募集しております。
興味がある方はSupership株式会社 採用サイトよりご確認ください。

3
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?