今回は今話題のMCPサーバーの作成に取り組んでみたので、作成過程について共有します。まだ、発展途中で特に今回取り上げるresourceについては特に情報も少ないので、皆様のお役に立てば嬉しいです。
最近話題のMCP(Message Content Protocol)
MCPとは、Message Content Protocolの略で、AIアシスタントの能力を拡張するための標準化されたプロトコルです。このプロトコルを利用することで、AIアシスタントに外部ツールやリソースへのアクセス権を与え、より多くのタスクを実行できるようにします。例えば、ウェブ検索、コード実行、データベース操作、ファイル管理などの機能をAIに提供できます。
今回はドキュメントをコンテキストとして提供可能なMCPサーバーを作成してみました。 今回作成するMCPはclaude desktopアプリ上での利用を目標としました。 作成に関してはfastMCPと言うフレームワークを使用し、fastMCPのドキュメントと、MCP自体のドキュメントをAIに渡し、AIと共同で開発しました。 また、ドキュメント参照ということでmcpのconceptのうちresourceの機能を使おうと考え、実装を始めました。
そもそもMCPとは
MCPは、2023年後半から注目を集め始めた比較的新しいプロトコルです。AI開発の急速な進化に伴い、AIの能力を拡張する標準的な方法が必要とされ、その解決策として登場しました。
MCPの主な構成要素は以下の3つです:
- Tools(ツール) – AIが外部システムで実行できるアクション。例えば、計算の実行、データベースのクエリ、APIの呼び出しなど。
- Resources(リソース) – AIがアクセスできる静的または動的なデータソース。例えば、ドキュメント、データベース、ファイルなど。
- Artifacts(アーティファクト) – AIとユーザーの間で共有される、会話の過程で生成・編集されるオブジェクト。
今回は特に「Resources」機能に注目し、AIが必要に応じて参照できるドキュメントリポジトリをMCPサーバーとして実装しました。
また、fastMCPとはMCPの実装を大幅に簡素化し、開発者がAIモデルと構造化データを効率的に統合できるようにするPythonフレームワークです。低レベルの通信プロトコルを管理する代わりに、AI機能の拡張に集中できるようになります。AIとの対話を強化するための柔軟性とスケーラビリティを提供し、AIアプリケーション開発における強力なツールとなっています。
開発を始めてみて
想像以上にresourceについての記事が少なく、事例が少ない印象。どちらかというとtoolの機能の方が人気ではないか。実際、MCPの多くの実装例ではツール機能が主に紹介されており、リソース機能の具体的な活用事例はまだ限られています。
実装方法
まず、resourceが参照するドキュメントが必要だったためAPIドキュメントのウェブサイトをクローリングし、jsonにまとめるプログラムを作成した。本ブログではその実装方法については省略するが、url, title, contentを要素として持つようにしました。
AIを使った開発のためなんとなくの形になるのは早かったが、問題が生じた。resourceはユニークなURIを使って実行されます(ex: @mcp.resource(“docs://list”))。そして、ドキュメント長が膨大な場合もあるため該当URLの箇所のみの情報の取得が必要でした。しかし、claude desktopにおいては動的なURIの使用ができませんでした(ex:@mcp.resource(“api-doc://{url}”))。claude desktopにてresourceは以下のように現れます。しかし、ここには動的なURIを持つものは表示されない。ネット上でも同じ問題に直面している人がいるので、まだ実装されていないということだろうと思います。

そこで考えた現時点での解決策は、toolの機能も使う方法。resourceはドキュメントのリスト(目次)を取得するために使用し、必要な該当箇所をtoolの機能を使って取得するという方法です。toolであれば該当箇所のURLを動的に指定することが可能になります。
まず、ドキュメントの一覧を取得するために以下のコードを使います。
@mcp.resource("docs://list")
async def list_all_documents() -> dict:
"""すべての内容一覧を返します"""
if not docs_repository.docs_data:
return {
"mimeType": "text/plain",
"text": "ドキュメントデータが読み込まれていません。"
}
doc_list = []
for i, doc in enumerate(docs_repository.docs_data, 1):
doc_list.append(f"{i}. {doc.get('title', 'タイトルなし')} - {doc.get('url', 'URLなし')}")
return {
"mimeType": "text/plain",
"text": "\n".join(doc_list)
}
ここで、各内容のURLを取得できるので、次のtoolのコードが該当URLを指定できるようになります。
@mcp.tool("getDocument_gemini")
async def get_document_by_url(url: str) -> dict:
"""
指定されたURLに基づいてドキュメントを取得します。
Args:
url: ドキュメントのURL
Returns:
ドキュメントの内容
"""
if not docs_repository.docs_data:
return {
"success": False,
"message": "ドキュメントデータが読み込まれていません。"
}
doc = docs_repository.get_by_url(url)
if not doc:
return {
"success": False,
"message": f"指定されたURL '{url}' のドキュメントは見つかりませんでした。"
}
# レスポンスの作成
return {
"success": True,
"document": {
"title": doc.get('title', 'タイトルなし'),
"url": url,
"content": doc.get('content', 'コンテンツなし')
}
}
今回の実装は一つの大きなドキュメントを参照するものです。list機能で取得したのも一つのドキュメント内にあるものだが、そうではなく、ローカルの特定のディレクトリにあるドキュメントをリストとして返すこともできます。この場合は、必要なドキュメントのURIを取得し、動的URIで指定することで内容を取得することになります。
Claude Desktopでの利用
実装したMCPサーバーをClaude Desktopで利用するためには、Claudeの設定画面からMCPの設定を行う必要があります。
設定>開発者>構成を編集
と進むと、claude_desktop_config.jsonというファイルが見つかります。このファイルをテキストエディタで開き、以下のように作成したmcpと繋げます。
{
"mcpServers": {
"gemini_docs_resource": {
"command": "uv",
"args": [
"--directory",
"/Users/ディレクトリへのパス",
"run",
"gemini_docs.py"
]
}
}
}
claude desktopを再起動すると、
MCPサーバーが接続されていることが確認できます。
ここで完成したMCPサーバーの挙動を確認してみます。
まず、リストを渡してみるとドキュメントに何が記載されているのかがわかります。
続いて、特定の内容についての言及を求めてみます。
この出力はドキュメントの詳細までは確認できていなかったため、URIへのアクセスを明確に指示してみます。
結果、内容を詳しく確認し、ドキュメントにまとめてくれました。
まとめ
MCPはまだ発展途上のプロトコルですが、AIアシスタントの能力を拡張するための重要な手段となっています。また、今回はresourceの機能がメインとなっていましたが、MCPのメイン機能としてはtoolsの方という印象を受けています。
resourceはプログラム作成の記事自体が少ないのと、claude desktopでは動的URIが現時点で使用できないのにも関わらず、MCPサーバーと繋げれば使えると記載している記事も見受けられました。
MCPはAIエージェントが広まっていく今後において重要な技術となると思うので、今後もアップデートや情報を追っていきたいと思います。