Claude Desktop で始める MCP (Model Context Protocol) 入門
1. はじめに
ClaudeやCursor、ClineなどのAI開発支援ツールで注目を集めている「MCP(Model Context Protocol)」。これは、AIにツールを持たせるための標準プロトコルで、いわば"AI用USB-Cポート"のようなもの。これを使えば、AIがファイル操作、API呼び出し、DB問い合わせ、ブラウザ操作など、さまざまな機能を外部ツールとして活用できるようになります。
この記事では、Claude for Desktop(Freeプラン)を使って、MCPを実際に動かしてみた記録と、MCPクライアントの自作方法まで丁寧に紹介していきます。
2. MCPとは?
正式名称:Model Context Protocol(モデル・コンテキスト・プロトコル)
開発元:Anthropic社
MCPは、AIモデルが外部のツールやデータソースに安全かつ標準化された方法でアクセスするためのオープンプロトコルです。USB-Cがデバイス接続の標準であるように、MCPはAIとツールの接続標準となることを目指しています。
利用例(一部)
カテゴリ | 機能例 |
---|---|
ファイル操作 | ローカルファイルの読み書き |
DBアクセス | Postgres, SQLite |
Web操作 | Puppeteerによるスクレイピング |
チャット連携 | Slack, Discord |
クラウド制御 | AWS, Docker, Kubernetes |
3. Claude for Desktop での設定
必要なもの
- Claude for Desktop(WindowsまたはMac)
- Node.js(npxコマンドが使えること)
手順概要
- Claudeの設定画面を開く(Ctrl + ,)
- "Developer > Edit Config"を選択し設定フォルダを開く
-
claude_desktop_config.json
を編集
設定例(Windows)
{
"mcpServers": {
"filesystem": {
"command": "npx",
"args": [
"-y",
"@modelcontextprotocol/server-filesystem",
"C:\\Users\\あなたのユーザー名\\Downloads\\mcp"
]
}
}
}
設定例(macOS)
{
"mcpServers": {
"filesystem": {
"command": "npx",
"args": [
"-y",
"@modelcontextprotocol/server-filesystem",
"/Users/あなたのユーザー名/Downloads/mcp"
]
}
}
}
設定ファイルを保存後、Claudeアプリを再起動すればMCPサーバーが起動されます。
4. MCPを使ってみる
テスト内容
Claudeに次のようなプロンプトを入力:
"Claudeの説明文を書いて、mcpフォルダ内にテキストファイルで保存して"
結果
- ClaudeがMCP経由でローカルの
mcp
フォルダにテキストファイルを生成。 - 中身にはClaudeの機能説明が記載されていた。
ファイル内容の一部:
Claudeは、Anthropic社が開発した高度なAIアシスタントです...
権限確認ダイアログが出る場合もありますが、許可すれば動作します。
5. 自作MCPクライアントの構築(Python)
ここからは「クライアント開発者向け」の情報です。ClaudeなどのLLMとMCPサーバーを連携させるためのチャットボットクライアントをPythonで構築します。
5-1. システム要件
- MacまたはWindows
- 最新のPython
-
uv パッケージマネージャ(
pip install uv
)
5-2. 開発環境のセットアップ
uv init mcp-client
cd mcp-client
uv venv
source .venv/bin/activate # Windows: .venv\Scripts\activate
uv add mcp anthropic python-dotenv
rm main.py
touch client.py
5-3. APIキーの準備
.env
ファイルを作成して以下のように書き込みます:
ANTHROPIC_API_KEY=your-api-key-here
.gitignore
に .env
を追加してセキュリティ確保:
echo ".env" >> .gitignore
5-4. クライアント実装の基本構造
import asyncio
from typing import Optional
from contextlib import AsyncExitStack
from mcp import ClientSession, StdioServerParameters
from mcp.client.stdio import stdio_client
from anthropic import Anthropic
from dotenv import load_dotenv
import sys
load_dotenv()
class MCPClient:
def __init__(self):
self.session: Optional[ClientSession] = None
self.exit_stack = AsyncExitStack()
self.anthropic = Anthropic()
5-5. サーバー接続処理
async def connect_to_server(self, server_script_path: str):
is_python = server_script_path.endswith('.py')
is_js = server_script_path.endswith('.js')
if not (is_python or is_js):
raise ValueError("Server script must be a .py or .js file")
command = "python" if is_python else "node"
server_params = StdioServerParameters(
command=command,
args=[server_script_path],
env=None
)
stdio_transport = await self.exit_stack.enter_async_context(stdio_client(server_params))
self.stdio, self.write = stdio_transport
self.session = await self.exit_stack.enter_async_context(ClientSession(self.stdio, self.write))
await self.session.initialize()
tools = (await self.session.list_tools()).tools
print("Connected to server with tools:", [tool.name for tool in tools])
5-6. クエリ処理とツール呼び出し
async def process_query(self, query: str) -> str:
messages = [{"role": "user", "content": query}]
tools = await self.session.list_tools()
available_tools = [
{"name": t.name, "description": t.description, "input_schema": t.inputSchema}
for t in tools.tools
]
response = self.anthropic.messages.create(
model="claude-3-5-sonnet-20241022",
max_tokens=1000,
messages=messages,
tools=available_tools
)
final_text = []
assistant_message_content = []
for content in response.content:
if content.type == 'text':
final_text.append(content.text)
assistant_message_content.append(content)
elif content.type == 'tool_use':
result = await self.session.call_tool(content.name, content.input)
final_text.append(f"[Calling tool {content.name} with args {content.input}]")
messages += [
{"role": "assistant", "content": assistant_message_content},
{"role": "user", "content": [{"type": "tool_result", "tool_use_id": content.id, "content": result.content}]}
]
response = self.anthropic.messages.create(
model="claude-3-5-sonnet-20241022",
max_tokens=1000,
messages=messages,
tools=available_tools
)
final_text.append(response.content[0].text)
return "\n".join(final_text)
5-7. チャットループとメイン処理
async def chat_loop(self):
print("\nMCP Client Started! Type your queries or 'quit' to exit.")
while True:
query = input("\nQuery: ").strip()
if query.lower() == 'quit': break
try:
print("\n" + await self.process_query(query))
except Exception as e:
print(f"\nError: {str(e)}")
async def cleanup(self):
await self.exit_stack.aclose()
async def main():
if len(sys.argv) < 2:
print("Usage: python client.py <path_to_server_script>")
sys.exit(1)
client = MCPClient()
try:
await client.connect_to_server(sys.argv[1])
await client.chat_loop()
finally:
await client.cleanup()
if __name__ == "__main__":
asyncio.run(main())
5-8. 実行例
uv run client.py ./server/weather.py # Python製MCPサーバーを指定
5-9. よくあるエラーと対処法
-
FileNotFoundError
: サーバースクリプトのパスを確認 -
Connection refused
: サーバーが起動していない可能性 -
Tool execution failed
: ツールの環境変数が不足している場合 -
Timeout
: 初回実行時は最大30秒程度かかることがあります
6. VS Code + MCP連携も可能に!
VS Code Insider版では、設定画面からMCPサーバーを追加でき、GitHub Copilotのagent modeとも連携可能。
参考:
VS Code InsiderでMCPサーバー追加とCopilot agent mode活用 - Qiita
7. まとめ
Claude FreeプランでもMCPを通じて、AIにファイル操作などのツールを与えることが可能です。また、Pythonでクライアントを自作することで、独自のワークフローに合わせたAIチャットエージェントを構築できます。
今後さらに多くのツールがMCP対応していくことが予想され、AI×ツール連携の標準技術としての普及が期待されます。
Discussion