T-CREATOR

MCP サーバー セットアップ完全ガイド:インストール・環境変数・ポート/証明書設定の最短手順

MCP サーバー セットアップ完全ガイド:インストール・環境変数・ポート/証明書設定の最短手順

AI アシスタントとデータソースをシームレスに連携させるための新しい標準プロトコル、Model Context Protocol(MCP)。その中核を担う MCP サーバーのセットアップは、現代の AI 開発において避けては通れない重要なステップです。

しかし、初めて MCP サーバーを構築しようとすると、インストール方法、環境変数の管理、トランスポートの選択、証明書の設定など、多くの設定項目に直面します。公式ドキュメントは充実していますが、情報が分散しており、全体像を掴みにくいという課題があるでしょう。

本記事では、MCP サーバーのセットアップに必要な全ての手順を、インストールから環境変数設定、ポート/トランスポート設定、証明書設定まで、一つひとつ段階的に解説します。この記事を読み終える頃には、あなたも自信を持って MCP サーバーを構築できるようになっているはずです。

背景

Model Context Protocol(MCP)の概要

Model Context Protocol(MCP)は、Anthropic が提唱する、AI アシスタントと外部システムを接続するためのオープンプロトコルです。従来、AI アシスタントが外部データにアクセスするには、個別のカスタム統合を構築する必要がありました。

MCP はこの課題を解決し、標準化された方法で AI アシスタントとデータソースを接続可能にします。これにより、Google Drive、Slack、GitHub、データベースなど、さまざまなシステムとの統合が容易になります。

MCP アーキテクチャの 3 つのコンポーネント

MCP のアーキテクチャは、以下の 3 つの主要コンポーネントで構成されています。

以下の図で、MCP の全体構造を確認しましょう。

mermaidflowchart TB
    subgraph host["MCP ホスト"]
        client["MCP クライアント"]
    end

    subgraph servers["MCP サーバー群"]
        server1["MCP サーバー A<br/>(例: GitHub)"]
        server2["MCP サーバー B<br/>(例: Slack)"]
        server3["MCP サーバー C<br/>(例: Database)"]
    end

    subgraph resources["外部リソース"]
        github[("GitHub<br/>リポジトリ")]
        slack[("Slack<br/>メッセージ")]
        db[("PostgreSQL<br/>データベース")]
    end

    client <-->|"プロトコル通信"| server1
    client <-->|"プロトコル通信"| server2
    client <-->|"プロトコル通信"| server3

    server1 <-->|"API/接続"| github
    server2 <-->|"API/接続"| slack
    server3 <-->|"API/接続"| db

この図から以下のことがわかります。

  • MCP ホスト: Claude Desktop や VS Code などの AI アプリケーションが該当します
  • MCP クライアント: ホスト内で動作し、サーバーとの通信を管理します
  • MCP サーバー: 外部システムへの接続とデータ提供を担当します

MCP サーバーの役割と重要性

MCP サーバーは、AI アシスタントと実際のデータソースの間に立つ橋渡し役です。具体的には、以下の 3 つの主要機能を提供します。

#機能名説明具体例
1プロンプトLLM とのやり取りを導くテンプレート定型質問フォーマット
2リソースモデルに追加コンテキストを提供ファイル内容、DB レコード
3ツールモデルがアクションを実行可能にするファイル作成、API 呼び出し

これらの機能により、AI アシスタントは単なる会話だけでなく、実際のシステムとやり取りし、タスクを実行できるようになります。

セットアップの必要性

MCP サーバーを適切にセットアップすることで、以下のメリットが得られます。

まず、AI アシスタントの能力が大幅に拡張されます。ファイルシステムへのアクセス、データベース操作、API 呼び出しなど、さまざまな操作が可能になるでしょう。

次に、標準化されたプロトコルにより、一度構築した MCP サーバーは複数の AI アプリケーションで再利用できます。

さらに、セキュリティ面でも、適切な環境変数管理と証明書設定により、安全な通信が保証されます。

課題

セットアップ時の一般的な問題点

MCP サーバーのセットアップには、いくつかの典型的な課題があります。初めて取り組む開発者が直面する問題を理解しておくことで、スムーズな構築が可能になるでしょう。

以下の図で、セットアップ時に遭遇する主な課題の流れを確認しましょう。

mermaidflowchart TD
    start["MCP サーバー<br/>セットアップ開始"] --> choice1{"インストール<br/>方法の選択"}

    choice1 -->|"Python"| python_issues["Python 環境の問題<br/>- バージョン不一致<br/>- 依存関係の競合"]
    choice1 -->|"Node.js"| node_issues["Node.js 環境の問題<br/>- パッケージエラー<br/>- npx の実行失敗"]

    python_issues --> env_config["環境変数設定"]
    node_issues --> env_config

    env_config --> env_issues{"環境変数の<br/>管理方法"}
    env_issues -->|"直接記述"| security_risk["セキュリティリスク<br/>- API キー漏洩<br/>- 認証情報の露出"]
    env_issues -->|".env ファイル"| path_issues["パス解決の問題<br/>- 相対パスエラー<br/>- ファイル読み込み失敗"]

    security_risk --> transport_choice["トランスポート選択"]
    path_issues --> transport_choice

    transport_choice --> transport_issues{"通信方式の<br/>複雑さ"}
    transport_issues -->|"STDIO"| stdio_limit["STDIO の制限<br/>- ローカルのみ対応<br/>- デバッグ困難"]
    transport_issues -->|"HTTP/SSE"| port_issues["ポート設定の問題<br/>- ポート競合<br/>- ファイアウォール"]

    stdio_limit --> cert_config["証明書設定"]
    port_issues --> cert_config

    cert_config --> cert_issues["証明書の課題<br/>- 自己署名証明書エラー<br/>- HTTPS 必須要件<br/>- リバースプロキシ設定"]

    cert_issues --> task_end["トラブル<br/>シューティングが必要"]

この図から、セットアップには複数の段階があり、各段階で固有の課題が発生することがわかります。

環境変数管理の難しさ

API キーやアクセストークンなど、機密情報の管理は特に注意が必要です。

よくある失敗例として、設定ファイルに直接 API キーを記述してしまい、誤ってリポジトリにコミットしてしまうケースがあります。また、環境変数のパス解決が正しく行われず、サーバーが起動時に必要な認証情報を読み込めないこともあるでしょう。

さらに、開発環境と本番環境で異なる環境変数を管理する必要があり、その切り替えが煩雑になりがちです。

トランスポート選択の複雑さ

MCP は複数のトランスポート方式をサポートしていますが、それぞれに特性と制約があります。

STDIO(標準入出力)は最もシンプルですが、ローカル環境でのみ動作します。リモート接続が必要な場合は、SSE(Server-Sent Events)か Streamable HTTP を選択する必要がありますが、これらはポート設定やネットワーク設定が必要になります。

どのトランスポートを選ぶべきか、そしてそれぞれの設定方法を理解することが、セットアップの重要なステップとなるでしょう。

証明書設定とセキュリティの課題

リモート接続を行う MCP サーバーでは、HTTPS による安全な通信が必須です。

しかし、ローカル開発環境で自己署名証明書を使用すると、SSL 証明書検証エラーが発生します。本番環境では信頼できる証明書を使用する必要がありますが、その取得と設定には手間がかかります。

さらに、Docker コンテナ内で MCP サーバーを実行する場合、リバースプロキシ(NGINX など)の設定が不可欠になるケースも多いでしょう。

解決策

インストール手順

MCP サーバーのインストールは、使用する言語環境によって手順が異なります。ここでは、Python と Node.js の両方の環境について、段階的に解説します。

前提条件の確認

まず、システムに必要なツールがインストールされているか確認しましょう。

Python 環境の場合

Python 3.10 以上が必要です。バージョンを確認するには、以下のコマンドを実行します。

bashpython3 --version

Node.js 環境の場合

Node.js 16 以上が推奨されます。バージョンを確認するには、以下のコマンドを実行します。

bashnode --version

Python 環境でのインストール

Python で MCP サーバーを構築する場合、uv または pip を使用します。

uv を使用する方法(推奨)

uv は高速な Python パッケージマネージャーです。macOS では Homebrew でインストールできます。

bashbrew install uv

インストール後、バージョンを確認します。

bashuv --version

MCP サーバーのインストールは、以下のコマンドで実行します。

bash# プロジェクトディレクトリに移動
cd your-mcp-server-project

# 依存関係をインストール
uv pip install mcp httpx fastapi uvicorn

pip を使用する方法

従来の pip を使用する場合は、仮想環境を作成してからインストールします。

bash# 仮想環境を作成
python3 -m venv venv

# 仮想環境を有効化(macOS/Linux)
source venv/bin/activate

# 仮想環境を有効化(Windows)
venv\Scripts\activate

仮想環境を有効化したら、必要なパッケージをインストールします。

bashpip install mcp httpx fastapi uvicorn

Node.js 環境でのインストール

Node.js で MCP サーバーを構築する場合、Yarn または npm を使用します。

Yarn を使用する方法(推奨)

Yarn がインストールされていない場合は、まずインストールします。

bashnpm install -g yarn

MCP サーバーの依存関係をインストールします。

bash# プロジェクトディレクトリに移動
cd your-mcp-server-project

# 依存関係をインストール
yarn add @modelcontextprotocol/sdk

npm を使用する方法

npm を使用する場合は、以下のコマンドでインストールします。

bashnpm install @modelcontextprotocol/sdk

設定ファイルの配置

MCP サーバーを使用するには、設定ファイルを適切な場所に配置する必要があります。設定ファイルの場所は、使用するアプリケーションと OS によって異なります。

Claude Desktop の場合

Claude Desktop の設定ファイル名は claude_desktop_config.json です。

#OS設定ファイルのパス
1macOS~​/​Library​/​Application Support​/​Claude​/​claude_desktop_config.json
2Windows%APPDATA%\Claude\claude_desktop_config.json
3Linux~​/​.config​/​Claude​/​claude_desktop_config.json

Claude Code(VS Code 拡張機能)の場合

Claude Code では、プロジェクトルートまたはユーザーディレクトリに設定ファイルを配置します。

#スコープ設定ファイルのパス
1プロジェクト.claude​/​mcp.json
2ユーザー~​/​.claude​/​mcp.json

設定ファイルの基本構造は、以下のようになります。

json{
  "mcpServers": {
    "server-name": {
      "command": "node",
      "args": ["path/to/server.js"]
    }
  }
}

この基本構造に、環境変数やトランスポート設定を追加していきます。

環境変数設定

環境変数は、API キーやデータベース接続情報など、機密情報を安全に管理するために不可欠です。MCP サーバーでは、複数の方法で環境変数を設定できます。

env フィールドでの直接指定

最もシンプルな方法は、設定ファイルの env フィールドに直接環境変数を指定することです。

設定ファイル(claude_desktop_config.json または .claude​/​mcp.json)に、以下のように記述します。

json{
  "mcpServers": {
    "github-server": {
      "command": "node",
      "args": ["path/to/github-server.js"],
      "env": {
        "GITHUB_TOKEN": "ghp_your_token_here",
        "DEBUG": "true",
        "LOG_LEVEL": "info"
      }
    }
  }
}

この方法のメリットは、設定が一箇所にまとまり、わかりやすいことです。ただし、設定ファイルを Git にコミットする場合は、機密情報が含まれないよう注意が必要です。

envfile プロパティの使用

より安全な方法として、.env ファイルを別途作成し、envfile プロパティで参照する方法があります。

まず、プロジェクトディレクトリに .env ファイルを作成します。

bash# .env ファイル
GITHUB_TOKEN=ghp_your_token_here
SLACK_TOKEN=xoxb-your-slack-token
DATABASE_URL=postgresql://user:pass@localhost:5432/dbname
DEBUG=true

次に、設定ファイルで .env ファイルのパスを指定します。

json{
  "mcpServers": {
    "github-server": {
      "command": "node",
      "args": ["path/to/github-server.js"],
      "envfile": "${workspaceFolder}/.env"
    }
  }
}

.env ファイルは .gitignore に追加することで、Git リポジトリにコミットされるのを防げます。

bash# .gitignore に追加
.env
.env.local
.env.*.local

環境変数の展開構文

Claude Code は、柔軟な環境変数展開構文をサポートしています。これにより、デフォルト値の設定や、システム環境変数の参照が可能になります。

デフォルト値の設定

環境変数が設定されていない場合のデフォルト値を指定できます。

json{
  "mcpServers": {
    "api-server": {
      "command": "node",
      "args": ["server.js"],
      "env": {
        "API_PORT": "${API_PORT:-8080}",
        "LOG_LEVEL": "${LOG_LEVEL:-info}",
        "NODE_ENV": "${NODE_ENV:-development}"
      }
    }
  }
}

この例では、API_PORT が設定されていない場合は 8080 が、LOG_LEVEL が設定されていない場合は info が使用されます。

システム環境変数の参照

システムに既に設定されている環境変数を参照することもできます。

json{
  "mcpServers": {
    "home-server": {
      "command": "python3",
      "args": ["${HOME}/mcp-servers/server.py"],
      "env": {
        "USER_HOME": "${HOME}",
        "PATH": "${PATH}"
      }
    }
  }
}

環境別の設定管理

開発環境、ステージング環境、本番環境で異なる環境変数を使用する場合の管理方法です。

環境ごとに .env ファイルを作成します。

bash# 開発環境
.env.development

# ステージング環境
.env.staging

# 本番環境
.env.production

設定ファイルでは、環境変数 NODE_ENV に基づいて適切なファイルを読み込むように設定します。

json{
  "mcpServers": {
    "api-server": {
      "command": "node",
      "args": ["server.js"],
      "envfile": "${workspaceFolder}/.env.${NODE_ENV:-development}"
    }
  }
}

Python での環境変数の取得

Python で MCP サーバーを実装する場合、環境変数を取得する方法は以下の通りです。

pythonimport os

# 環境変数を取得(存在しない場合は None)
github_token = os.getenv("GITHUB_TOKEN")

# デフォルト値を指定して取得
api_port = os.getenv("API_PORT", "8080")
log_level = os.getenv("LOG_LEVEL", "info")

python-dotenv ライブラリを使用すると、.env ファイルの読み込みが簡単になります。

pythonfrom dotenv import load_dotenv
import os

# .env ファイルを読み込む
load_dotenv()

# 環境変数を取得
github_token = os.getenv("GITHUB_TOKEN")
database_url = os.getenv("DATABASE_URL")

Node.js/TypeScript での環境変数の取得

Node.js または TypeScript で MCP サーバーを実装する場合、環境変数は process.env でアクセスします。

typescript// 環境変数を取得
const githubToken = process.env.GITHUB_TOKEN;
const apiPort = process.env.API_PORT || '8080';
const logLevel = process.env.LOG_LEVEL || 'info';

dotenv パッケージを使用すると、.env ファイルを読み込めます。

typescriptimport dotenv from 'dotenv';

// .env ファイルを読み込む
dotenv.config();

// 環境変数を取得
const githubToken = process.env.GITHUB_TOKEN;
const slackToken = process.env.SLACK_TOKEN;

Deno での環境変数の取得

Deno で MCP サーバーを実装する場合は、Deno.env.get() を使用します。

typescript// 環境変数を取得
const githubToken = Deno.env.get('GITHUB_TOKEN');
const apiPort = Deno.env.get('API_PORT') || '8080';

Deno は、実行時に --allow-env フラグが必要です。

bashdeno run --allow-env server.ts

ポート設定とトランスポートの選択

MCP サーバーは、複数のトランスポート方式をサポートしています。それぞれの特性を理解し、用途に応じて適切なものを選択することが重要です。

以下の表で、各トランスポートの特徴を比較しましょう。

#トランスポート通信方式ポート用途メリットデメリット
1STDIO標準入出力不要ローカル開発設定が簡単、デバッグしやすいリモート接続不可
2SSEHTTP + SSE必要(デフォルト: 8080)リモート接続(レガシー)一方向ストリーミングHTTP POST との組み合わせが必要
3Streamable HTTPHTTP ストリーミング必要本番環境双方向ストリーミング、効率的設定がやや複雑

STDIO トランスポート

STDIO(Standard Input/Output)は、最もシンプルなトランスポート方式です。ローカルで動作するプロセス間通信に使用されます。

Python での STDIO サーバーの実装

FastMCP を使用した STDIO サーバーの基本的な実装です。

pythonfrom fastmcp import FastMCP

# MCP サーバーのインスタンスを作成
mcp = FastMCP("My MCP Server")

# ツールを定義
@mcp.tool()
def hello(name: str) -> str:
    """ユーザーに挨拶します"""
    return f"こんにちは、{name}さん!"

サーバーのメイン処理を記述します。デフォルトでは STDIO トランスポートが使用されます。

pythonif __name__ == "__main__":
    # STDIO トランスポートで実行(デフォルト)
    mcp.run()

Node.js/TypeScript での STDIO サーバーの実装

MCP SDK を使用した STDIO サーバーの実装です。

typescriptimport { Server } from '@modelcontextprotocol/sdk/server/index.js';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';

// サーバーインスタンスを作成
const server = new Server(
  {
    name: 'my-mcp-server',
    version: '1.0.0',
  },
  {
    capabilities: {
      tools: {},
    },
  }
);

ツールハンドラーを登録し、トランスポートを初期化します。

typescript// ツールハンドラーを登録
server.setRequestHandler('tools/call', async (request) => {
  // ツールの実装
});

// STDIO トランスポートで起動
const transport = new StdioServerTransport();
await server.connect(transport);

STDIO サーバーの設定

Claude Desktop または Claude Code の設定ファイルで STDIO サーバーを登録します。

json{
  "mcpServers": {
    "my-stdio-server": {
      "command": "python3",
      "args": ["/path/to/server.py"]
    }
  }
}

Node.js サーバーの場合は、以下のように設定します。

json{
  "mcpServers": {
    "my-stdio-server": {
      "command": "node",
      "args": ["/path/to/server.js"]
    }
  }
}

Windows 環境で npx を使用する場合は、cmd ​/​c ラッパーが必要です。

json{
  "mcpServers": {
    "my-stdio-server": {
      "command": "cmd",
      "args": ["/c", "npx", "-y", "@some/mcp-package"]
    }
  }
}

SSE(Server-Sent Events)トランスポート

SSE トランスポートは、HTTP ベースのリモート接続を可能にします。サーバーからクライアントへは SSE、クライアントからサーバーへは HTTP POST を使用します。

Python での SSE サーバーの実装

FastMCP で SSE トランスポートを使用する場合、run() メソッドにパラメータを指定します。

pythonfrom fastmcp import FastMCP

mcp = FastMCP("My SSE Server")

@mcp.tool()
def get_data(query: str) -> dict:
    """データを取得します"""
    return {"result": f"Query: {query}"}

SSE トランスポートで起動するには、ホストとポートを指定します。

pythonif __name__ == "__main__":
    # SSE トランスポートで起動
    mcp.run(
        transport="sse",
        host="127.0.0.1",
        port=8000
    )

カスタムエンドポイントパスを指定することもできます。

pythonif __name__ == "__main__":
    mcp.run(
        transport="sse",
        host="0.0.0.0",
        port=8080,
        sse_path="/sse",
        message_path="/messages"
    )

SSE サーバーの設定

Claude Code で SSE サーバーを登録するには、claude mcp add コマンドを使用します。

bashclaude mcp add --transport sse my-sse-server http://localhost:8000

設定ファイルに直接記述する場合は、以下のようになります。

json{
  "mcpServers": {
    "my-sse-server": {
      "transport": "sse",
      "url": "http://localhost:8000/sse"
    }
  }
}

Streamable HTTP トランスポート

Streamable HTTP は、本番環境での使用に推奨される、最も効率的なトランスポート方式です。双方向ストリーミングをサポートします。

HTTP サーバーの設定

Claude Code で HTTP サーバーを登録します。

bashclaude mcp add --transport http my-http-server https://api.example.com/mcp

認証ヘッダーを含める場合は、以下のように設定します。

json{
  "mcpServers": {
    "my-http-server": {
      "transport": "http",
      "url": "https://api.example.com/mcp",
      "headers": {
        "Authorization": "Bearer ${API_TOKEN}",
        "X-API-Key": "${API_KEY}"
      }
    }
  }
}

ポート競合の解決

複数の MCP サーバーを同時に実行する場合、ポート競合が発生する可能性があります。

使用中のポートを確認するには、以下のコマンドを使用します。

bash# macOS/Linux
lsof -i :8080

# Windows
netstat -ano | findstr :8080

各サーバーに異なるポートを割り当てることで、競合を回避できます。

json{
  "mcpServers": {
    "server-a": {
      "transport": "sse",
      "url": "http://localhost:8000/sse"
    },
    "server-b": {
      "transport": "sse",
      "url": "http://localhost:8001/sse"
    },
    "server-c": {
      "transport": "sse",
      "url": "http://localhost:8002/sse"
    }
  }
}

STDIO サーバーを SSE として公開する

ローカルの STDIO サーバーをリモートから利用可能にするため、mcp-proxy ツールを使用できます。

mcp-proxy をインストールします。

bashyarn global add mcp-proxy

STDIO サーバーを SSE エンドポイントとして公開します。

bashmcp-proxy --port=8080 uvx mcp-server-fetch

これにより、ローカルの STDIO サーバーが http:​/​​/​localhost:8080 で SSE サーバーとして利用可能になります。

証明書設定とセキュリティ

リモート接続を行う MCP サーバー(SSE や Streamable HTTP)では、HTTPS による安全な通信が必須です。適切な証明書設定により、データの盗聴や改ざんを防ぐことができます。

以下の図で、証明書設定の全体フローを確認しましょう。

mermaidflowchart TD
    start["証明書設定開始"] --> env_check{"環境の確認"}

    env_check -->|"ローカル開発"| local_dev["ローカル開発環境"]
    env_check -->|"本番環境"| production["本番環境"]

    local_dev --> mkcert_check{"mkcert を<br/>使用可能?"}
    mkcert_check -->|"はい"| mkcert_install["mkcert のインストール"]
    mkcert_check -->|"いいえ"| self_signed["自己署名証明書を作成"]

    mkcert_install --> mkcert_cert["信頼された<br/>ローカル証明書を生成"]
    self_signed --> trust_cert["証明書を信頼リストに追加"]

    mkcert_cert --> local_config["サーバー設定に<br/>証明書パスを追加"]
    trust_cert --> local_config

    production --> cert_source{"証明書の取得元"}
    cert_source -->|"Let's Encrypt"| letsencrypt["certbot で<br/>無料証明書を取得"]
    cert_source -->|"商用 CA"| commercial_ca["CA から証明書を購入"]
    cert_source -->|"クラウドサービス"| cloud_cert["AWS ACM/GCP<br/>証明書マネージャー"]

    letsencrypt --> reverse_proxy["リバースプロキシ設定"]
    commercial_ca --> reverse_proxy
    cloud_cert --> reverse_proxy

    reverse_proxy --> nginx_config["NGINX で<br/>TLS ターミネーション"]
    nginx_config --> security_headers["セキュリティヘッダー設定"]

    local_config --> test_connection["HTTPS 接続テスト"]
    security_headers --> test_connection

    test_connection --> task_end["証明書設定完了"]

この図から、ローカル開発と本番環境で異なるアプローチが必要であることがわかります。

ローカル開発環境での証明書設定

ローカル開発では、mkcert を使用することで、信頼された証明書を簡単に生成できます。

mkcert のインストール

macOS では Homebrew でインストールできます。

bashbrew install mkcert

Linux では、以下のコマンドでインストールします。

bash# Ubuntu/Debian
sudo apt install mkcert

# Arch Linux
sudo pacman -S mkcert

Windows では、Chocolatey または Scoop を使用します。

bash# Chocolatey
choco install mkcert

# Scoop
scoop install mkcert

ローカル CA のインストール

mkcert のルート証明書をシステムにインストールします。

bashmkcert -install

このコマンドにより、mkcert が生成する証明書が自動的に信頼されるようになります。

証明書の生成

ローカルホスト用の証明書を生成します。

bash# localhost 用の証明書を生成
mkcert localhost 127.0.0.1 ::1

このコマンドにより、localhost.pem(証明書)と localhost-key.pem(秘密鍵)が生成されます。

複数のドメイン名に対応する証明書も生成できます。

bashmkcert localhost 127.0.0.1 myapp.local "*.myapp.local"

Python サーバーでの証明書使用

FastMCP で HTTPS を有効にするには、証明書と秘密鍵のパスを指定します。

pythonfrom fastmcp import FastMCP

mcp = FastMCP("My Secure Server")

@mcp.tool()
def secure_operation(data: str) -> dict:
    """セキュアな操作を実行"""
    return {"status": "success", "data": data}

SSE トランスポートで HTTPS を有効にして起動します。

pythonif __name__ == "__main__":
    mcp.run(
        transport="sse",
        host="127.0.0.1",
        port=8443,
        ssl_certfile="./localhost.pem",
        ssl_keyfile="./localhost-key.pem"
    )

Node.js サーバーでの証明書使用

Node.js の https モジュールで証明書を使用します。

typescriptimport https from 'https';
import fs from 'fs';
import express from 'express';

const app = express();

// HTTPS サーバーオプション
const httpsOptions = {
  cert: fs.readFileSync('./localhost.pem'),
  key: fs.readFileSync('./localhost-key.pem'),
};

HTTPS サーバーを起動します。

typescript// HTTPS サーバーを作成
const server = https.createServer(httpsOptions, app);

server.listen(8443, () => {
  console.log(
    'HTTPS サーバーが起動しました: https://localhost:8443'
  );
});

自己署名証明書の作成と使用

mkcert を使用できない環境では、OpenSSL で自己署名証明書を作成できます。

OpenSSL による証明書生成

秘密鍵と証明書を一度に生成します。

bashopenssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem \
  -days 365 -nodes \
  -subj "/C=JP/ST=Tokyo/L=Tokyo/O=MyOrg/CN=localhost"

このコマンドで、key.pem(秘密鍵)と cert.pem(証明書)が生成されます。

自己署名証明書の信頼設定

macOS で自己署名証明書を信頼リストに追加します。

bashsudo security add-trusted-cert -d -r trustRoot \
  -k /Library/Keychains/System.keychain cert.pem

自己署名証明書使用時の注意点

自己署名証明書を使用する場合、クライアント側で証明書検証エラーが発生します。開発環境では、検証を無効にするオプションがある場合がありますが、本番環境では絶対に使用しないでください。

本番環境での証明書設定

本番環境では、信頼できる認証局(CA)から取得した証明書を使用する必要があります。

Let's Encrypt を使用した無料証明書の取得

Let's Encrypt は、無料で信頼された SSL/TLS 証明書を提供するサービスです。

certbot をインストールします。

bash# Ubuntu/Debian
sudo apt install certbot

# macOS
brew install certbot

証明書を取得します(standalone モード)。

bashsudo certbot certonly --standalone -d yourdomain.com

証明書は ​/​etc​/​letsencrypt​/​live​/​yourdomain.com​/​ に保存されます。

証明書の自動更新設定

Let's Encrypt の証明書は 90 日間有効です。自動更新を設定しておきましょう。

bash# 更新のテスト
sudo certbot renew --dry-run

# 自動更新の設定(cron)
sudo crontab -e

cron に以下を追加します。

bash0 0 * * * certbot renew --quiet

リバースプロキシ(NGINX)の設定

本番環境、特に Docker コンテナで MCP サーバーを実行する場合、NGINX をリバースプロキシとして使用することが推奨されます。

NGINX のインストール

bash# Ubuntu/Debian
sudo apt install nginx

# macOS
brew install nginx

NGINX 設定ファイルの作成

​/​etc​/​nginx​/​sites-available​/​mcp-server に設定ファイルを作成します。

nginxserver {
    listen 443 ssl http2;
    server_name yourdomain.com;

    # SSL 証明書の設定
    ssl_certificate /etc/letsencrypt/live/yourdomain.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/yourdomain.com/privkey.pem;

    # SSL プロトコルと暗号スイートの設定
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers HIGH:!aNULL:!MD5;
    ssl_prefer_server_ciphers on;

プロキシ設定とセキュリティヘッダーを追加します。

nginx    # MCP サーバーへのプロキシ設定
    location /mcp {
        proxy_pass http://localhost:8080;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }

SSE エンドポイント用の特別な設定を追加します。

nginx    # SSE エンドポイント用設定(圧縮を無効化)
    location /sse {
        proxy_pass http://localhost:8080/sse;
        proxy_http_version 1.1;
        proxy_set_header Connection "";
        proxy_buffering off;
        proxy_cache off;
        chunked_transfer_encoding off;
    }

セキュリティヘッダーを設定します。

nginx    # セキュリティヘッダー
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
    add_header X-Frame-Options "DENY" always;
    add_header X-Content-Type-Options "nosniff" always;
    add_header X-XSS-Protection "1; mode=block" always;
}

HTTP から HTTPS へのリダイレクト設定を追加します。

nginx# HTTP を HTTPS にリダイレクト
server {
    listen 80;
    server_name yourdomain.com;
    return 301 https://$server_name$request_uri;
}

NGINX 設定の有効化と再起動

設定ファイルをシンボリックリンクで有効化します。

bashsudo ln -s /etc/nginx/sites-available/mcp-server /etc/nginx/sites-enabled/

設定ファイルの構文をチェックします。

bashsudo nginx -t

NGINX を再起動します。

bashsudo systemctl restart nginx

Docker 環境での証明書設定

Docker コンテナで MCP サーバーを実行する場合、docker-compose を使用して NGINX と連携させます。

docker-compose.yml の例

yamlversion: '3.8'

services:
  mcp-server:
    build: ./mcp-server
    ports:
      - '8080:8080'
    environment:
      - NODE_ENV=production
    networks:
      - mcp-network

  nginx:
    image: nginx:alpine
    ports:
      - '443:443'
      - '80:80'
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf:ro
      - /etc/letsencrypt:/etc/letsencrypt:ro
    depends_on:
      - mcp-server
    networks:
      - mcp-network

networks:
  mcp-network:
    driver: bridge

この設定により、NGINX が TLS ターミネーションを担当し、バックエンドの MCP サーバーは HTTP で通信します。

証明書のトラブルシューティング

証明書設定でよく発生する問題と解決方法です。

SSL 証明書検証エラー

エラーメッセージ: SSL certificate verification failed

原因は、自己署名証明書を使用している、または証明書チェーンが不完全であることが考えられます。

解決方法として、Let's Encrypt の fullchain.pem を使用するか、中間証明書を含める必要があります。

bash# 証明書チェーンの確認
openssl s_client -connect yourdomain.com:443 -showcerts

証明書の期限切れ

Let's Encrypt の証明書は 90 日で期限切れになります。自動更新が正しく設定されているか確認しましょう。

bash# 証明書の有効期限を確認
sudo certbot certificates

ポート 443 へのアクセス不可

ファイアウォールで HTTPS ポート(443)が開いているか確認します。

bash# Ubuntu/Debian
sudo ufw allow 443/tcp

# CentOS/RHEL
sudo firewall-cmd --permanent --add-service=https
sudo firewall-cmd --reload

具体例

ここまでの解説を踏まえて、実際の MCP サーバーセットアップの完全な実装例を示します。Claude Desktop と Claude Code の両方で使用できる、実用的な構成です。

全体のセットアップワークフロー

まず、セットアップ全体の流れを図で確認しましょう。

mermaidflowchart TD
    start["セットアップ開始"] --> install["環境のインストール"];
    install --> lang_choice{"言語環境の選択"};
    lang_choice --|Python|--> python_setup["Python + uv<br/>のセットアップ"];
    lang_choice --|Node.js|--> node_setup["Node.js + Yarn<br/>のセットアップ"];

    python_setup --> create_server["MCP サーバーの実装"];
    node_setup --> create_server;

    create_server --> env_setup["環境変数の設定"];
    env_setup --> env_file["&#96;.env&#96; ファイルの作成"];
    env_file --> config_file["設定ファイルの作成"];

    config_file --> transport_choice{"トランスポートの選択"};
    transport_choice --|ローカル開発|--> stdio_config["STDIO 設定"];
    transport_choice --|リモート接続|--> remote_config["SSE/HTTP 設定"];

    stdio_config --> test_local["ローカルテスト"];
    remote_config --> cert_setup["証明書設定"];

    cert_setup --> dev_cert{"開発環境?"};
    dev_cert --|はい|--> mkcert_setup["mkcert で証明書生成"];
    dev_cert --|いいえ|--> prod_cert["Let's Encrypt 証明書"];

    mkcert_setup --> https_config["HTTPS サーバー起動"];
    prod_cert --> nginx_setup["NGINX リバースプロキシ"];

    nginx_setup --> https_config;
    https_config --> test_remote["リモートテスト"];

    test_local --> verify["動作確認"];
    test_remote --> verify;

    verify --> task_end["セットアップ完了"];


この図から、セットアップが段階的に進むことがわかります。では、具体的な実装を見ていきましょう。

実装例 1: GitHub 連携 MCP サーバー(Python)

GitHub API と連携する MCP サーバーの完全な実装例です。

プロジェクト構造

bashgithub-mcp-server/
├── server.py
├── .env
├── .env.example
├── .gitignore
└── requirements.txt

requirements.txt

必要なパッケージを記述します。

shellmcp>=1.0.0
httpx>=0.25.0
fastapi>=0.104.0
uvicorn>=0.24.0
python-dotenv>=1.0.0

.env.example(テンプレート)

環境変数のテンプレートファイルを作成します。

bash# GitHub API トークン
GITHUB_TOKEN=your_github_token_here

# サーバー設定
PORT=8000
LOG_LEVEL=info

.env(実際の設定)

実際の API キーを記述します(Git には含めない)。

bashGITHUB_TOKEN=ghp_xxxxxxxxxxxxxxxxxxxx
PORT=8000
LOG_LEVEL=info

.gitignore

機密情報を含むファイルを Git から除外します。

bash.env
__pycache__/
*.pyc
.DS_Store

server.py(パート 1: インポートと初期化)

必要なモジュールをインポートします。

pythonfrom fastmcp import FastMCP
from dotenv import load_dotenv
import os
import httpx
from typing import Optional

# 環境変数を読み込む
load_dotenv()

# MCP サーバーのインスタンスを作成
mcp = FastMCP("GitHub MCP Server")

server.py(パート 2: GitHub API クライアント)

GitHub API との通信を担当するクラスを定義します。

pythonclass GitHubClient:
    """GitHub API クライアント"""

    def __init__(self, token: str):
        self.token = token
        self.base_url = "https://api.github.com"
        self.headers = {
            "Authorization": f"Bearer {token}",
            "Accept": "application/vnd.github.v3+json"
        }

    async def get_repo_info(self, owner: str, repo: str) -> dict:
        """リポジトリ情報を取得"""
        async with httpx.AsyncClient() as client:
            response = await client.get(
                f"{self.base_url}/repos/{owner}/{repo}",
                headers=self.headers
            )
            response.raise_for_status()
            return response.json()

server.py(パート 3: MCP ツールの定義)

MCP サーバーが提供するツールを定義します。

python# GitHub クライアントのインスタンスを作成
github_token = os.getenv("GITHUB_TOKEN")
if not github_token:
    raise ValueError("GITHUB_TOKEN が設定されていません")

github_client = GitHubClient(github_token)

@mcp.tool()
async def get_repository(owner: str, repo: str) -> dict:
    """
    GitHub リポジトリの情報を取得します

    Args:
        owner: リポジトリのオーナー名
        repo: リポジトリ名

    Returns:
        リポジトリの詳細情報
    """
    try:
        repo_info = await github_client.get_repo_info(owner, repo)
        return {
            "name": repo_info["name"],
            "description": repo_info["description"],
            "stars": repo_info["stargazers_count"],
            "forks": repo_info["forks_count"],
            "language": repo_info["language"],
            "url": repo_info["html_url"]
        }
    except Exception as e:
        return {"error": str(e)}

server.py(パート 4: サーバー起動)

環境変数から設定を読み込み、サーバーを起動します。

pythonif __name__ == "__main__":
    # 環境変数から設定を取得
    port = int(os.getenv("PORT", "8000"))
    log_level = os.getenv("LOG_LEVEL", "info")

    # 開発環境では STDIO、本番環境では SSE を使用
    if os.getenv("NODE_ENV") == "production":
        mcp.run(
            transport="sse",
            host="127.0.0.1",
            port=port
        )
    else:
        # デフォルトは STDIO
        mcp.run()

Claude Desktop 用設定(claude_desktop_config.json

macOS の場合、~​/​Library​/​Application Support​/​Claude​/​claude_desktop_config.json を編集します。

json{
  "mcpServers": {
    "github-server": {
      "command": "python3",
      "args": [
        "/absolute/path/to/github-mcp-server/server.py"
      ],
      "envfile": "/absolute/path/to/github-mcp-server/.env"
    }
  }
}

Claude Code 用設定(.claude​/​mcp.json

プロジェクトルートの .claude​/​mcp.json を作成します。

json{
  "mcpServers": {
    "github-server": {
      "command": "python3",
      "args": [
        "${workspaceFolder}/github-mcp-server/server.py"
      ],
      "envfile": "${workspaceFolder}/github-mcp-server/.env"
    }
  }
}

実装例 2: Slack 連携 MCP サーバー(Node.js/TypeScript)

Slack API と連携する MCP サーバーの実装例です。

プロジェクト構造

bashslack-mcp-server/
├── src/
│   └── index.ts
├── .env
├── .env.example
├── .gitignore
├── package.json
└── tsconfig.json

package.json

依存パッケージを定義します。

json{
  "name": "slack-mcp-server",
  "version": "1.0.0",
  "type": "module",
  "scripts": {
    "build": "tsc",
    "dev": "tsx src/index.ts",
    "start": "node dist/index.js"
  },
  "dependencies": {
    "@modelcontextprotocol/sdk": "^1.0.0",
    "@slack/web-api": "^6.9.0",
    "dotenv": "^16.3.1"
  },
  "devDependencies": {
    "@types/node": "^20.10.0",
    "tsx": "^4.7.0",
    "typescript": "^5.3.0"
  }
}

tsconfig.json

TypeScript の設定を記述します。

json{
  "compilerOptions": {
    "target": "ES2022",
    "module": "ES2022",
    "moduleResolution": "node",
    "outDir": "./dist",
    "rootDir": "./src",
    "strict": true,
    "esModuleInterop": true,
    "skipLibCheck": true,
    "forceConsistentCasingInFileNames": true
  },
  "include": ["src/**/*"],
  "exclude": ["node_modules"]
}

.env.example

環境変数のテンプレートです。

bashSLACK_TOKEN=xoxb-your-slack-bot-token
PORT=8000
NODE_ENV=development

src​/​index.ts(パート 1: インポートと初期化)

必要なモジュールをインポートし、初期化します。

typescriptimport { Server } from '@modelcontextprotocol/sdk/server/index.js';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
import { WebClient } from '@slack/web-api';
import dotenv from 'dotenv';

// 環境変数を読み込む
dotenv.config();

// Slack クライアントの初期化
const slackToken = process.env.SLACK_TOKEN;
if (!slackToken) {
  throw new Error('SLACK_TOKEN が設定されていません');
}

const slackClient = new WebClient(slackToken);

src​/​index.ts(パート 2: MCP サーバーの作成)

MCP サーバーのインスタンスを作成し、機能を定義します。

typescript// MCP サーバーのインスタンスを作成
const server = new Server(
  {
    name: 'slack-mcp-server',
    version: '1.0.0',
  },
  {
    capabilities: {
      tools: {},
    },
  }
);

src​/​index.ts(パート 3: ツールハンドラーの実装)

Slack メッセージ送信ツールを実装します。

typescript// ツールハンドラーを登録
server.setRequestHandler('tools/call', async (request) => {
  const { name, arguments: args } = request.params;

  if (name === 'send_message') {
    try {
      // Slack にメッセージを送信
      const result = await slackClient.chat.postMessage({
        channel: args.channel,
        text: args.text,
      });

      return {
        content: [
          {
            type: 'text',
            text: JSON.stringify({
              success: true,
              timestamp: result.ts,
              channel: result.channel,
            }),
          },
        ],
      };
    } catch (error) {
      return {
        content: [
          {
            type: 'text',
            text: JSON.stringify({
              success: false,
              error: error.message,
            }),
          },
        ],
        isError: true,
      };
    }
  }

  throw new Error(`未知のツール: ${name}`);
});

src​/​index.ts(パート 4: サーバー起動)

トランスポートを初期化し、サーバーを起動します。

typescript// STDIO トランスポートで起動
async function main() {
  const transport = new StdioServerTransport();
  await server.connect(transport);

  console.error('Slack MCP Server が起動しました');
}

main().catch((error) => {
  console.error('サーバー起動エラー:', error);
  process.exit(1);
});

Claude Code 用設定(claude mcp add コマンド)

Claude Code CLI を使用して MCP サーバーを登録します。

bash# STDIO トランスポートで登録
claude mcp add --transport stdio slack-server \
  --env SLACK_TOKEN="${SLACK_TOKEN}" \
  -- yarn tsx src/index.ts

実装例 3: HTTPS 対応リモート MCP サーバー

リモートアクセス可能な、HTTPS で保護された MCP サーバーの実装例です。

mkcert による証明書生成

ローカル開発用の証明書を生成します。

bash# mkcert のインストール(macOS)
brew install mkcert

# ルート CA をインストール
mkcert -install

# localhost 用の証明書を生成
mkcert localhost 127.0.0.1

これにより、localhost.pemlocalhost-key.pem が生成されます。

HTTPS 対応 Python サーバー

先ほどの GitHub MCP サーバーを HTTPS 対応にします。

python# server.py の最後の部分を以下に変更

if __name__ == "__main__":
    port = int(os.getenv("PORT", "8443"))

    # HTTPS で SSE サーバーを起動
    mcp.run(
        transport="sse",
        host="0.0.0.0",
        port=port,
        ssl_certfile="./localhost.pem",
        ssl_keyfile="./localhost-key.pem"
    )

Claude Code での HTTPS サーバー登録

HTTPS エンドポイントとして登録します。

bashclaude mcp add --transport sse github-https \
  https://localhost:8443/sse

トラブルシューティング

実際の運用で発生しやすい問題と解決方法をまとめます。

問題 1: サーバーが起動しない

エラーコード: ModuleNotFoundError: No module named 'mcp'

原因として、必要なパッケージがインストールされていないことが考えられます。

解決方法は、依存パッケージを再インストールすることです。

bash# Python の場合
pip install -r requirements.txt

# Node.js の場合
yarn install

問題 2: 環境変数が読み込まれない

エラーメッセージ: GITHUB_TOKEN が設定されていません

原因は、.env ファイルのパスが正しくない、または環境変数の名前が間違っていることです。

解決方法として、まず .env ファイルが存在するか確認します。

bashls -la .env

次に、設定ファイルのパスが絶対パスになっているか確認します。

json{
  "envfile": "/absolute/path/to/.env"
}

問題 3: ポート競合

エラーコード: Error: Address already in use (errno: 98)

原因は、指定したポートが既に使用されていることです。

使用中のポートを確認します。

bashlsof -i :8000

別のポートを使用するか、競合しているプロセスを停止します。

bash# プロセスを停止(PID を確認してから)
kill -9 <PID>

問題 4: SSL 証明書エラー

エラーメッセージ: SSL certificate verification failed

原因は、自己署名証明書が信頼されていない、または証明書の有効期限が切れていることです。

mkcert を使用している場合、ルート CA が正しくインストールされているか確認します。

bashmkcert -install

証明書の有効期限を確認します。

bashopenssl x509 -in localhost.pem -text -noout | grep "Not After"

まとめ

MCP サーバーのセットアップは、複数の段階を経て完成します。本記事で解説した手順をまとめます。

セットアップの 5 つの重要ステップ

#ステップ重要ポイント推奨ツール
1インストールPython 3.10+ または Node.js 16+ が必要uv, Yarn
2環境変数設定.env ファイルで機密情報を管理dotenv, envfile
3トランスポート選択ローカルは STDIO、リモートは Streamable HTTP-
4証明書設定開発環境は mkcert、本番環境は Let's Encryptmkcert, certbot
5セキュリティ対策NGINX でリバースプロキシと TLS ターミネーションNGINX

ベストプラクティス

適切な MCP サーバー運用のために、以下のベストプラクティスを守りましょう。

まず、環境変数管理についてです。API キーやトークンは必ず .env ファイルで管理し、.gitignore に追加してリポジトリに含めないようにします。環境ごと(開発・ステージング・本番)に異なる .env ファイルを用意することも重要です。

次に、トランスポートの選択です。ローカル開発では STDIO を使用し、シンプルに保ちます。リモートアクセスが必要な本番環境では、Streamable HTTP を選択し、効率的な通信を実現しましょう。

証明書管理では、ローカル開発に mkcert を使用することで、信頼された証明書を簡単に生成できます。本番環境では Let's Encrypt で無料の信頼された証明書を取得し、自動更新を設定しておくことが大切です。

セキュリティ対策として、本番環境では NGINX をリバースプロキシとして使用し、TLS ターミネーションを行います。適切なセキュリティヘッダー(HSTS、X-Frame-Options など)を設定することも忘れないようにしましょう。

セキュリティ上の注意事項

MCP サーバーのセキュリティは、以下の点に特に注意が必要です。

機密情報の取り扱いでは、API キーやトークンを設定ファイルに直接記述しないこと、チャット履歴に機密情報を含めないことが重要です。

通信の保護では、リモート接続では必ず HTTPS を使用し、自己署名証明書は開発環境のみで使用することを徹底しましょう。

アクセス制御として、MCP サーバーには必要最小限の権限のみを付与し、本番環境では適切なファイアウォール設定を行うことが求められます。

次のステップ

MCP サーバーの基本的なセットアップができたら、以下のステップに進むことができます。

カスタム MCP サーバーの開発では、独自のビジネスロジックを組み込んだ MCP サーバーを構築できます。複数のツールやリソースを組み合わせた高度な機能も実装可能です。

スケーラビリティの向上では、Docker コンテナ化により複数インスタンスの管理が容易になります。Kubernetes でのオーケストレーションも検討できるでしょう。

モニタリングと監視では、ログ集約システム(ELK スタックなど)の導入や、メトリクス収集(Prometheus、Grafana など)により、サーバーの健全性を監視できます。

本記事で解説した手順に従えば、初心者でも確実に MCP サーバーをセットアップできます。ぜひ、実際に手を動かして、AI アシスタントと外部システムを連携させる素晴らしい体験を味わってください。

関連リンク

公式ドキュメント

SDK とツール

セキュリティと証明書

参考記事