「サーバ - MCP」の版間の差分
| 89行目: | 89行目: | ||
== 開発言語とフレームワークの選択 == | == 開発言語とフレームワークの選択 == | ||
==== Node.js + MCP SDKを使用する場合 ==== | ==== Node.js + MCP SDKを使用する場合 ==== | ||
まず、Node.jsをインストールする。<br> | |||
RHEL / SUSEの場合、Node Version Manager (nvm) を使用することを推奨する。<br> | |||
# nvmのインストール (全ディストリビューション共通) | # nvmのインストール (全ディストリビューション共通) | ||
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v<バージョン 例 : 0.43.0>/install.sh | bash | curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v<バージョン 例 : 0.43.0>/install.sh | bash | ||
# Node.js LTS版のインストール | # Node.js LTS版のインストール | ||
| 99行目: | 98行目: | ||
nvm use --lts | nvm use --lts | ||
<br> | <br> | ||
Banana Pi F3 (RISC-V) | Banana Pi F3 (RISC-V) の場合は、パッケージ管理システムからインストールする。<br> | ||
# Banana Pi F3 (Armbian) | # Banana Pi F3 (Armbian) | ||
sudo apt install nodejs npm | sudo apt install nodejs npm | ||
| 107行目: | 106行目: | ||
npm --version | npm --version | ||
<br> | <br> | ||
もし、公式バイナリが存在しない場合は、ソースコードからビルドを行う。<br> | |||
# ソースからのビルド (RISC-V環境で必要な場合) | # ソースからのビルド (RISC-V環境で必要な場合) | ||
git clone https://github.com/nodejs/node.git | git clone https://github.com/nodejs/node.git | ||
| 120行目: | 119行目: | ||
make install | make install | ||
<br> | <br> | ||
次に、プロジェクトディレクトリを作成して、MCPサーバのプロジェクトを初期化する。<br> | |||
mkdir | mkdir <プロジェクトディレクトリ> | ||
cd | cd <プロジェクトディレクトリ> | ||
npm init -y | npm init -y | ||
| 132行目: | 131行目: | ||
<syntaxhighlight lang="json"> | <syntaxhighlight lang="json"> | ||
{ | { | ||
"name": "mcp-server", | "name": "<任意の名前 例 : mcp-server>", | ||
"version": "1.0.0", | "version": "1.0.0", | ||
"type": "module", | "type": "module", | ||
| 158行目: | 157行目: | ||
<br> | <br> | ||
プロジェクトディレクトリを作成して、Python仮想環境を設定する。<br> | プロジェクトディレクトリを作成して、Python仮想環境を設定する。<br> | ||
mkdir -p | mkdir -p <プロジェクトディレクトリ> | ||
cd | cd <プロジェクトディレクトリ> | ||
python3 -m venv venv | python3 -m venv venv | ||
<br> | <br> | ||
Pythonの仮想環境をアクティベートする。<br> | Pythonの仮想環境をアクティベートする。<br> | ||
# Bash / Zshの場合 | |||
source venv/bin/activate | source venv/bin/activate | ||
# Fishの場合 | |||
source venv/bin/activate.fish | |||
<br> | <br> | ||
必要なPythonライブラリをインストールする。<br> | 必要なPythonライブラリをインストールする。<br> | ||
| 170行目: | 173行目: | ||
<br> | <br> | ||
<u>※注意</u><br> | <u>※注意</u><br> | ||
<u>venv/bin/ | <u>venv/bin/activateスクリプトの設定を~/.profileファイル等に記述することは非推奨である。</u><br> | ||
<br> | |||
<u>activateスクリプトは相対パスで動作するため、フルパスで指定する必要がある。</u><br> | <u>activateスクリプトは相対パスで動作するため、フルパスで指定する必要がある。</u><br> | ||
<u>これは、常に特定の仮想環境がアクティブになってしまうため、他のプロジェクトで異なる仮想環境を使用する場合に問題が発生するためである。</u><br> | |||
<br> | <br> | ||
<u>また、シェルのセッションごとに自動的にアクティベートすると、どの環境で作業しているのか理解し難い。</u> | <u>また、シェルのセッションごとに自動的にアクティベートすると、どの環境で作業しているのか理解し難い。</u> | ||
<br> | <br> | ||
代替案として、以下に示すような方法が推奨される。<br> | 代替案として、以下に示すような方法が推奨される。<br> | ||
これは、必要な時のみ仮想環境をアクティベートすることが可能なため、柔軟な運用が可能になる。<br> | |||
<br> | <br> | ||
特に、複数のプロジェクトを扱う場合は、"方法 2" や "方法 3" が便利である。<br> | |||
<br> | <br> | ||
* エイリアスを設定する方法 | |||
*: ~/.profileファイル等に記述する。 | |||
<syntaxhighlight lang="sh"> | <syntaxhighlight lang="sh"> | ||
# 方法 1 | # 方法 1 | ||
alias activate-mcpserver="source <activateスクリプトのパス>" | alias activate-mcpserver="source <activateスクリプトのパス>" | ||
</syntaxhighlight> | </syntaxhighlight> | ||
<br> | <br> | ||
* プロジェクトディレクトリに入った時のみ自動的にアクティベートする方法 | |||
*: ~/.profileファイル または ~/.zprofileファイル等に記述する。 | |||
<syntaxhighlight lang="sh"> | <syntaxhighlight lang="sh"> | ||
# 方法 2 | # 方法 2 (a) : Bash / Zsh | ||
function cd() | function cd() | ||
| 196行目: | 202行目: | ||
builtin cd "$@" | builtin cd "$@" | ||
# | # 新しいディレクトリに仮想環境が存在するか確認 | ||
if [ -d "venv" ]; then | if [ -d "venv" ]; then | ||
# | # 既に仮想環境がアクティブでない場合のみアクティベート | ||
if [ -z "$VIRTUAL_ENV" ]; then | if [ -z "$VIRTUAL_ENV" ]; then | ||
source venv/bin/activate | |||
# 異なる仮想環境に切り替える場合 | |||
elif [ "$VIRTUAL_ENV" != "$PWD/venv" ]; then | |||
deactivate | |||
source venv/bin/activate | source venv/bin/activate | ||
fi | fi | ||
# venvディレクトリが存在しない場合、アクティブな仮想環境があれば無効化 | |||
elif [ -n "$VIRTUAL_ENV" ]; then | |||
deactivate | |||
fi | fi | ||
} | } | ||
</syntaxhighlight> | </syntaxhighlight> | ||
<br> | <br> | ||
* プロジェクトディレクトリに入った時のみ自動的にアクティベートする方法 | |||
*: ~/.config/fish/config.fishファイルに記述する。 | |||
<syntaxhighlight lang="fish"> | |||
# 方法 2 (b) : Fish | |||
function cd | |||
# 現在アクティブな仮想環境のパスを記録 | |||
set -l prev_venv "$VIRTUAL_ENV" | |||
builtin cd $argv | |||
# 新しいディレクトリに仮想環境が存在するか確認 | |||
if test -d "venv" | |||
# 既に仮想環境がアクティブでない場合のみアクティベート | |||
if test -z "$VIRTUAL_ENV" | |||
source venv/bin/activate.fish | |||
# 異なる仮想環境に切り替える場合 | |||
else if test "$VIRTUAL_ENV" != "$PWD/venv" | |||
deactivate | |||
source venv/bin/activate.fish | |||
end | |||
# venvディレクトリが存在しない場合、アクティブな仮想環境があれば無効化 | |||
else if test -n "$VIRTUAL_ENV" | |||
deactivate | |||
end | |||
end | |||
</syntaxhighlight> | |||
<br> | |||
* direnvのような専用ツールを使用する方法 | |||
*: プロジェクトディレクトリの.envrcファイルに記述する。 | |||
<syntaxhighlight lang="sh"> | <syntaxhighlight lang="sh"> | ||
# 方法 3 | # 方法 3 | ||
layout python3 # Pythonの仮想環境を自動的に管理 | layout python3 # Pythonの仮想環境を自動的に管理 | ||
2026年1月2日 (金) 13:02時点における版
概要
Model Context Protocol (MCP) は、Large Language Model (LLM) とツール、データソースを統一的に接続するための標準プロトコルである。
MCPサーバは、AIアシスタントがアクセス可能なツール、リソース、プロンプトを提供するインターフェースとして機能する。
MCPサーバの実装において、Linuxディストリビューションに必要なプログラム言語とSDKをインストールする。
一般的な選択肢としては、Node.jsのMCP SDK、PythonのFastMCP、TypeScriptによる実装等がある。
MCPは2つの主要なトランスポート方式をサポートしている。
- Standard I/O (STDIO) トランスポート
- ローカル環境でのプロセス間通信に使用され、Claude Desktopなどのクライアントとの統合に最適である。
- HTTP/SSE (Server-Sent Events) トランスポート
- リモートサーバ上でMCPサーバを運用して、ネットワーク経由でアクセスする場合に使用される。
以下の例では、Node.jsのMCP SDKを使用したMCPサーバを構築している。
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { z } from "zod";
const server = new McpServer({
name: "sample-mcp-server",
version: "1.0.0",
});
// ツールの定義
server.tool(
"calculate-sum",
"2つの数値を加算する",
{
a: z.number().describe("1つ目の数値"),
b: z.number().describe("2つ目の数値"),
},
async ({ a, b }) => ({
content: [{ type: "text", text: `結果: ${a + b}` }],
})
);
// サーバの起動
const transport = new StdioServerTransport();
await server.connect(transport);
セキュリティでは、認証トークンの実装、HTTPS通信の設定、入力データのバリデーション、適切なエラーハンドリング等を行う必要がある。
特にHTTPトランスポートを使用する場合は、APIキーやOAuth2.0による認証・認可の実装も検討する必要がある。
パフォーマンスとスケーラビリティでは、ツールの実行時間の最適化、接続プールの管理、ログ記録の効率化が重要である。
また、コンテナ化 (Podman等) や オーケストレーション (Kubernetes) の導入により、複数のMCPサーバインスタンスを管理することも検討する。
MCPサーバのドキュメント化も重要な要素となる。
ツールの説明、パラメータの型定義、使用例を明確に記述することにより、AIモデルおよび開発者がサーバの機能を正確に理解することができる。
MCP Inspectorを使用することで、対話的にツールをテストおよび検証することが可能である。
モニタリングとログ収集の設定において、標準エラー出力 (stderr) を使用したログ記録、PrometheusやGrafanaによるメトリクス収集を行うことにより、
MCPサーバの健全性およびパフォーマンスを監視することができる。
MCPサーバを構築・運用する場合は、以下に示す事柄に注意する。
- STDIOトランスポートでは標準出力 (stdout) にログを出力しない。(JSON-RPC通信が破損する)
- ツールの実行時間を適切に管理して、タイムアウトを設定する。
- エラーハンドリングを適切に実装して、詳細なエラーメッセージを返す。
- セキュリティアップデートの適用
- アクセスログの監視とレート制限の実装
- ツールのバージョン管理とドキュメントの維持
- 定期的なバックアップの実施
サーバ環境のインストール
まず、システムの更新を行う。
# RHEL sudo dnf update # SUSE sudo zypper update # Banana Pi F3 (Armbian) / Raspberry Pi sudo apt update sudo apt upgrade
次に、Linuxサーバに必要な基本環境をインストールする。
# RHEL sudo dnf install curl wget git gcc-c++ make # SUSE sudo zypper install curl wget git gcc-c++ make # Banana Pi F3 (Armbian) / Raspberry Pi sudo apt install curl wget git build-essential
開発言語とフレームワークの選択
Node.js + MCP SDKを使用する場合
まず、Node.jsをインストールする。
RHEL / SUSEの場合、Node Version Manager (nvm) を使用することを推奨する。
# nvmのインストール (全ディストリビューション共通) curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v<バージョン 例 : 0.43.0>/install.sh | bash # Node.js LTS版のインストール nvm install --lts nvm use --lts
Banana Pi F3 (RISC-V) の場合は、パッケージ管理システムからインストールする。
# Banana Pi F3 (Armbian) sudo apt install nodejs npm # バージョン確認 node --version npm --version
もし、公式バイナリが存在しない場合は、ソースコードからビルドを行う。
# ソースからのビルド (RISC-V環境で必要な場合) git clone https://github.com/nodejs/node.git cd node git checkout v<バージョン 例 : 22.x> mkdir -p build && cd build ../configure --prefix=<任意のインストールディレクトリ> \ --dest-cpu=riscv64 make -j $(nproc) make install
次に、プロジェクトディレクトリを作成して、MCPサーバのプロジェクトを初期化する。
mkdir <プロジェクトディレクトリ> cd <プロジェクトディレクトリ> npm init -y
必要なJavaScriptライブラリをインストールする。
npm install @modelcontextprotocol/sdk zod
package.jsonファイルを編集して、ES Modulesを有効化する。
{
"name": "<任意の名前 例 : mcp-server>",
"version": "1.0.0",
"type": "module",
"scripts": {
"start": "node server.js",
"inspector": "npx @modelcontextprotocol/inspector node server.js"
},
"dependencies": {
"@modelcontextprotocol/sdk": "latest",
"zod": "^3.22.0"
}
}
Python + FastMCPを使用する場合
Pythonと仮想環境をインストールする。
# RHEL sudo dnf install python3 python3-pip python3-virtualenv # SUSE sudo zypper install python3 python3-pip python3-virtualenv # Banana Pi F3 (Armbian) / Raspberry Pi sudo apt install python3 python3-pip python3-venv
プロジェクトディレクトリを作成して、Python仮想環境を設定する。
mkdir -p <プロジェクトディレクトリ> cd <プロジェクトディレクトリ> python3 -m venv venv
Pythonの仮想環境をアクティベートする。
# Bash / Zshの場合 source venv/bin/activate # Fishの場合 source venv/bin/activate.fish
必要なPythonライブラリをインストールする。
pip install fastmcp httpx
※注意
venv/bin/activateスクリプトの設定を~/.profileファイル等に記述することは非推奨である。
activateスクリプトは相対パスで動作するため、フルパスで指定する必要がある。
これは、常に特定の仮想環境がアクティブになってしまうため、他のプロジェクトで異なる仮想環境を使用する場合に問題が発生するためである。
また、シェルのセッションごとに自動的にアクティベートすると、どの環境で作業しているのか理解し難い。
代替案として、以下に示すような方法が推奨される。
これは、必要な時のみ仮想環境をアクティベートすることが可能なため、柔軟な運用が可能になる。
特に、複数のプロジェクトを扱う場合は、"方法 2" や "方法 3" が便利である。
- エイリアスを設定する方法
- ~/.profileファイル等に記述する。
# 方法 1
alias activate-mcpserver="source <activateスクリプトのパス>"
- プロジェクトディレクトリに入った時のみ自動的にアクティベートする方法
- ~/.profileファイル または ~/.zprofileファイル等に記述する。
# 方法 2 (a) : Bash / Zsh
function cd()
{
builtin cd "$@"
# 新しいディレクトリに仮想環境が存在するか確認
if [ -d "venv" ]; then
# 既に仮想環境がアクティブでない場合のみアクティベート
if [ -z "$VIRTUAL_ENV" ]; then
source venv/bin/activate
# 異なる仮想環境に切り替える場合
elif [ "$VIRTUAL_ENV" != "$PWD/venv" ]; then
deactivate
source venv/bin/activate
fi
# venvディレクトリが存在しない場合、アクティブな仮想環境があれば無効化
elif [ -n "$VIRTUAL_ENV" ]; then
deactivate
fi
}
- プロジェクトディレクトリに入った時のみ自動的にアクティベートする方法
- ~/.config/fish/config.fishファイルに記述する。
# 方法 2 (b) : Fish
function cd
# 現在アクティブな仮想環境のパスを記録
set -l prev_venv "$VIRTUAL_ENV"
builtin cd $argv
# 新しいディレクトリに仮想環境が存在するか確認
if test -d "venv"
# 既に仮想環境がアクティブでない場合のみアクティベート
if test -z "$VIRTUAL_ENV"
source venv/bin/activate.fish
# 異なる仮想環境に切り替える場合
else if test "$VIRTUAL_ENV" != "$PWD/venv"
deactivate
source venv/bin/activate.fish
end
# venvディレクトリが存在しない場合、アクティブな仮想環境があれば無効化
else if test -n "$VIRTUAL_ENV"
deactivate
end
end
- direnvのような専用ツールを使用する方法
- プロジェクトディレクトリの.envrcファイルに記述する。
# 方法 3
layout python3 # Pythonの仮想環境を自動的に管理
MCPサーバの構築
Node.js + STDIOトランスポートを使用する場合
STDIOトランスポートは、ローカル環境でのプロセス間通信に使用される。
これは、Claude DesktopやCursor等のMCPクライアントと統合する場合に最適である。
// server.jsファイル
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { z } from "zod";
import os from "os";
// MCPサーバインスタンスの作成
const server = new McpServer({
name: "linux-system-mcp-server",
version: "1.0.0",
});
// ツール 1 : 数値計算
server.tool(
"add-numbers",
"2つの数値を加算する",
{
number1: z.number().describe("1つ目の数値"),
number2: z.number().describe("2つ目の数値"),
},
async ({ number1, number2 }) => ({
content: [
{
type: "text",
text: `計算結果: ${number1} + ${number2} = ${number1 + number2}`,
},
],
})
);
// ツール 2 : システム情報取得
server.tool(
"get-system-info",
"Linuxシステムの情報を取得する",
{},
async () => {
const info = {
platform: os.platform(),
arch: os.arch(),
hostname: os.hostname(),
cpus: os.cpus().length,
totalMemory: `${Math.round(os.totalmem() / 1024 / 1024)} MB`,
freeMemory: `${Math.round(os.freemem() / 1024 / 1024)} MB`,
uptime: `${Math.round(os.uptime() / 3600)} hours`,
};
return {
content: [
{
type: "text",
text: JSON.stringify(info, null, 2),
},
],
};
}
);
// ツール 3 : ファイル一覧取得
server.tool(
"list-files",
"指定されたディレクトリのファイル一覧を取得する",
{
path: z.string().describe("ディレクトリのパス"),
},
async ({ path }) => {
const fs = await import("fs/promises");
try {
const files = await fs.readdir(path);
return {
content: [
{
type: "text",
text: `ファイル一覧:\n${files.join("\n")}`,
},
],
};
} catch (error) {
return {
content: [
{
type: "text",
text: `エラー: ${error.message}`,
},
],
isError: true,
};
}
}
);
// サーバの起動
async function main() {
const transport = new StdioServerTransport();
await server.connect(transport);
// STDIOトランスポートではstderrに出力する (stdoutは使用禁止)
console.error("MCPサーバが起動しました");
}
main().catch((error) => {
console.error("サーバ起動エラー:", error);
process.exit(1);
});
Node.js + HTTPトランスポートを使用する場合
HTTPトランスポートは、リモートサーバ上でMCPサーバを運用し、ネットワーク経由でアクセスする場合に使用される。
まず、HTTP関連のライブラリをインストールする。
npm install express cors
HTTPサーバ対応の実装を行う。
// http-server.jsファイル
import express from "express";
import cors from "cors";
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { SSEServerTransport } from "@modelcontextprotocol/sdk/server/sse.js";
import { z } from "zod";
const app = express();
app.use(cors());
app.use(express.json());
const server = new McpServer({
name: "linux-system-mcp-server",
version: "1.0.0",
});
// ツールの定義 (STDIOトランスポートと同様)
server.tool(
"get-system-info",
"Linuxシステムの情報を取得する",
{},
async () => {
// 実装内容は省略
}
);
// SSEエンドポイントの設定
app.post("/sse", async (req, res) => {
const transport = new SSEServerTransport("/messages", res);
await server.connect(transport);
});
// ヘルスチェックエンドポイント
app.get("/health", (req, res) => {
res.json({ status: "ok", timestamp: new Date().toISOString() });
});
const PORT = process.env.PORT || 3000;
const HOST = process.env.HOST || "0.0.0.0";
app.listen(PORT, HOST, () => {
console.log(`MCPサーバがポート${PORT}で起動しました`);
console.log(`ホスト: ${HOST}`);
});
Python + FastMCPを使用する場合
FastMCPは、PythonでMCPサーバを構築するためのフレームワークである。
型ヒントとデコレータを使用して、ツールを定義することができる。
# server.pyファイル
from fastmcp import FastMCP
import platform
import os
import subprocess
mcp = FastMCP("Linux System MCP Server")
@mcp.tool()
def add_numbers(number1: float, number2: float) -> str:
"""2つの数値を加算する"""
result = number1 + number2
return f"計算結果: {number1} + {number2} = {result}"
@mcp.tool()
def get_system_info() -> dict:
"""Linuxシステムの情報を取得する"""
return {
"platform": platform.system(),
"architecture": platform.machine(),
"hostname": platform.node(),
"python_version": platform.python_version(),
"processor": platform.processor(),
}
@mcp.tool()
def list_files(path: str) -> str:
"""指定されたディレクトリのファイル一覧を取得する"""
try:
files = os.listdir(path)
return f"ファイル一覧:\n" + "\n".join(files)
except Exception as e:
return f"エラー: {str(e)}"
@mcp.tool()
def execute_command(command: str) -> str:
"""安全なシェルコマンドを実行する (制限付き)"""
# セキュリティのため、許可されたコマンドのみ実行
allowed_commands = ["ls", "pwd", "whoami", "date", "uptime"]
cmd_parts = command.split()
if not cmd_parts or cmd_parts[0] not in allowed_commands:
return f"エラー: コマンド '{cmd_parts[0] if cmd_parts else ''}' は許可されていません"
try:
result = subprocess.run(
command,
shell=True,
capture_output=True,
text=True,
timeout=5
)
return result.stdout if result.returncode == 0 else result.stderr
except subprocess.TimeoutExpired:
return "エラー: コマンドがタイムアウトしました"
except Exception as e:
return f"エラー: {str(e)}"
if __name__ == "__main__":
mcp.run()
MCP Inspectorによるテスト
WebMCP Inspectorは、Anthropic社が提供する対話的なデバッグツールである。
これにより、Webブラウザ上でMCPサーバのツールをテストおよび検証することができる。
MCP Inspectorをインストールする。
# Node.js版の場合 npm install @modelcontextprotocol/inspector --save-dev
package.jsonにスクリプトを追加する。
{
"scripts": {
"inspector": "npx @modelcontextprotocol/inspector node server.js"
}
}
MCP Inspectorを起動する。
npm run inspector
Webブラウザが自動的に開き、インスペクターのインターフェースが表示される。
ツールの一覧、パラメータの入力、実行結果の確認が可能である。
クライアント接続設定
Claude Desktopからの接続 (STDIO)
Claude Desktopの設定ファイルを編集する。
- MacOS / Linuxの場合
- ~/.config/Claude/claude_desktop_config.json
- Windowsの場合
- %APPDATA%\Claude\claude_desktop_config.json
設定ファイルの内容を編集する。
{
"mcpServers": {
"linux-system-server": {
"command": "node",
"args": ["/home/username/mcp-server/server.js"]
}
}
}
Pythonサーバの場合は以下に示すように設定する。
{
"mcpServers": {
"linux-system-python-server": {
"command": "/home/<ユーザ名>/mcp-server-python/venv/bin/python",
"args": ["/home/<ユーザ名>/mcp-server-python/server.py"]
}
}
}
環境変数を設定する必要がある場合は、envフィールドを追加する。
{
"mcpServers": {
"linux-system-server": {
"command": "node",
"args": ["/home/<ユーザ名>/mcp-server/server.js"],
"env": {
"API_KEY": "your-api-key-here",
"LOG_LEVEL": "debug"
}
}
}
}
リモートサーバへのSSH接続 (STDIO)
SSHを経由してリモートサーバ上のMCPサーバに接続する場合は、以下に示すように設定する。
{
"mcpServers": {
"remote-linux-server": {
"command": "ssh",
"args": [
"<ユーザ名>@<リモートサーバのIPアドレス>",
"cd ~/mcp-server && node server.js"
]
}
}
}
SSH鍵認証を設定しておくことが推奨される。
ssh-keygen -t ed25519 -C "mcp-client" ssh-copy-id username@remote-server-ip
HTTPS対応
HTTPトランスポートを使用する場合、HTTPS通信を設定することが推奨される。
Let's Encryptを使用する場合
Certbotをインストールする。
# RHEL sudo dnf install certbot python3-certbot-nginx # SUSE sudo zypper install python3-certbot python3-certbot-nginx # Banana Pi F3 (Armbian) / Raspberry Pi sudo apt install certbot python3-certbot-nginx
SSL証明書を取得する。
sudo certbot --nginx -d example.com
証明書の自動更新を設定する。
sudo systemctl enable certbot-renew.timer sudo systemctl start certbot-renew.timer
リバースプロキシの設定
HTTPトランスポートを使用する場合、Nginxをリバースプロキシとして設定することが推奨される。
Nginxを使用する場合
Nginxをインストールする。
# RHEL sudo dnf install nginx # SUSE sudo zypper install nginx # Banana Pi F3 (Armbian) / Raspberry Pi sudo apt install nginx
Nginxの設定ファイルを作成する。
# /etc/nginx/sites-available/mcp-serverファイル
server {
listen 80;
server_name yourdomain.com;
# HTTPからHTTPSへリダイレクト
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
server_name yourdomain.com;
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;
location / {
proxy_pass http://localhost:3000;
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;
proxy_cache_bypass $http_upgrade;
}
# SSEエンドポイント用の設定
location /sse {
proxy_pass http://localhost:3000/sse;
proxy_http_version 1.1;
proxy_set_header Connection '';
proxy_buffering off;
proxy_cache off;
proxy_read_timeout 86400s;
}
}
設定ファイルを有効化する。
# RHEL / SUSE sudo ln -s /etc/nginx/sites-available/mcp-server /etc/nginx/sites-enabled/ # Banana Pi F3 (Armbian) / Raspberry Pi sudo ln -s /etc/nginx/sites-available/mcp-server /etc/nginx/sites-enabled/
Nginxの設定をテストして再起動する。
sudo nginx -t sudo systemctl restart nginx
Systemdサービスファイルの作成
MCPサーバをシステムサービスとして常時起動させる場合、systemdユニットファイルを作成する。
Node.js版MCPサーバの場合
# /etc/systemd/system/mcp-server.serviceファイル
[Unit]
Description=MCP Server for Linux System
After=network.target
[Service]
Type=simple
User=<実行する任意のユーザ名>
WorkingDirectory=/home/<ユーザ名>/mcp-server
ExecStart=/usr/bin/node server.js
Restart=always
RestartSec=10
StandardOutput=journal
StandardError=journal
# 環境変数の設定 (必要に応じて)
Environment="NODE_ENV=production"
Environment="PORT=3000"
[Install]
WantedBy=multi-user.target
Python版MCPサーバの場合
# /etc/systemd/system/mcp-server-python.serviceファイル
[Unit]
Description=MCP Server for Linux System (Python)
After=network.target
[Service]
Type=simple
User=<実行する任意のユーザ名>
WorkingDirectory=/home/<ユーザ名>/mcp-server-python
ExecStart=/home/<ユーザ名>/mcp-server-python/venv/bin/python server.py
Restart=always
RestartSec=10
StandardOutput=journal
StandardError=journal
[Install]
WantedBy=multi-user.target
サービスを有効化して起動する。
sudo systemctl daemon-reload sudo systemctl enable mcp-server sudo systemctl start mcp-server
サービスの状態を確認する。
sudo systemctl status mcp-server
ログを確認する。
sudo journalctl -u mcp-server -f
ファイアウォールの設定
HTTPトランスポートを使用する場合、適切なポートを開放する必要がある。
Firewalldの場合
sudo firewall-cmd --permanent --add-service=http sudo firewall-cmd --permanent --add-service=https # カスタムポートを使用する場合 sudo firewall-cmd --permanent --add-port=3000/tcp sudo firewall-cmd --reload
設定を確認する。
sudo firewall-cmd --list-all
UFWの場合
sudo ufw allow 80/tcp sudo ufw allow 443/tcp # カスタムポートを使用する場合 sudo ufw allow 3000/tcp sudo ufw enable
設定を確認する。
sudo ufw status verbose
特定のIPアドレスからのアクセスのみを許可する場合は、以下のように設定する。
sudo ufw allow from 192.168.1.0/24 to any port 3000
セキュリティ設定
認証の実装
HTTPトランスポートを使用する場合、APIキーによる認証を行うことが推奨される。
// 認証ミドルウェアの実装例 (Node.js + Express)
function authenticateRequest(req, res, next) {
const apiKey = req.headers['x-api-key'];
if (!apiKey || apiKey !== process.env.API_KEY) {
return res.status(401).json({ error: 'Unauthorized' });
}
next();
}
app.use('/sse', authenticateRequest);
レート制限の実装
DoS攻撃を防ぐため、レート制限を行う。
npm install express-rate-limit
import rateLimit from 'express-rate-limit';
const limiter = rateLimit({
windowMs: 15 * 60 * 1000, // 15分
max: 100, // 最大100リクエスト
message: 'リクエストが多すぎます。しばらくしてから再試行してください。'
});
app.use('/sse', limiter);
入力データのバリデーション
ツールのパラメータに対して、適切なバリデーションを行う。
Zodスキーマを使用することにより、型安全性が確保される。
server.tool(
"read-file",
"ファイルの内容を読み取る",
{
path: z.string()
.min(1)
.max(500)
.regex(/^[a-zA-Z0-9._\/-]+$/)
.describe("ファイルのパス (英数字、ハイフン、スラッシュのみ)"),
},
async ({ path }) => {
// パス トラバーサル攻撃を防ぐ
if (path.includes('..')) {
return {
content: [{ type: "text", text: "エラー: 無効なパスです" }],
isError: true,
};
}
// 実装内容
}
);
監視とログ管理
ログの実装
MCPサーバでは、STDIOトランスポートを使用する場合、標準エラー出力 (stderr) にログを出力する必要がある。
標準出力 (stdout) にログを出力すると、JSON-RPC通信が破損する。
// Node.jsでのログ実装例
function log(level, message, data = {}) {
const logEntry = {
timestamp: new Date().toISOString(),
level,
message,
...data,
};
console.error(JSON.stringify(logEntry));
}
// 使用例
log('info', 'ツールが呼び出されました', { tool: 'get-system-info' });
log('error', 'エラーが発生しました', { error: error.message });
PrometheusとGrafanaによる監視
メトリクスを収集するため、Prometheus用のエクスポータを構築する。
npm install prom-client
import { register, Counter, Histogram } from 'prom-client';
// メトリクスの定義
const toolCallCounter = new Counter({
name: 'mcp_tool_calls_total',
help: 'ツール呼び出しの総数',
labelNames: ['tool_name', 'status'],
});
const toolCallDuration = new Histogram({
name: 'mcp_tool_call_duration_seconds',
help: 'ツール呼び出しの実行時間',
labelNames: ['tool_name'],
});
// メトリクスエンドポイント
app.get('/metrics', async (req, res) => {
res.set('Content-Type', register.contentType);
res.end(await register.metrics());
});
Prometheusをインストールする。
# RHELの場合 sudo dnf install prometheus # SUSEの場合 sudo zypper install prometheus # Banana Pi F3 (Armbian) / Raspberry Piの場合 wget https://github.com/prometheus/prometheus/releases/download/v2.x.x/prometheus-2.x.x.linux-arm64.tar.gz tar xf prometheus-2.x.x.linux-arm64.tar.gz
Prometheusの設定ファイルを編集する。
# prometheus.ymlファイル
global:
scrape_interval: 15s
scrape_configs:
- job_name: 'mcp-server'
static_configs:
- targets: ['localhost:3000']
Grafanaをインストールする。
# RHEL sudo dnf install grafana # SUSE sudo zypper install grafana # Banana Pi F3 (Armbian) / Raspberry Pi sudo apt install grafana
GrafanaとPrometheusを起動する。
sudo systemctl enable prometheus grafana-server sudo systemctl start prometheus grafana-server
バックアップとリストア
設定ファイルのバックアップ
定期的にMCPサーバの設定ファイルおよびコードをバックアップする。
#!/usr/bin/env sh
# backup.sh
BACKUP_DIR="/var/backups/mcp-server"
DATE=$(date +%Y%m%d_%H%M%S)
PROJECT_DIR="/home/username/mcp-server"
# バックアップディレクトリの作成
mkdir -p $BACKUP_DIR
# プロジェクトディレクトリの圧縮
tar -czf "$BACKUP_DIR/mcp-server_$DATE.tar.gz" -C $(dirname $PROJECT_DIR) $(basename $PROJECT_DIR)
# 30日以上前のバックアップを削除
find $BACKUP_DIR -name "*.tar.gz" -mtime +30 -delete
バックアップスクリプトを実行可能にする。
chmod u+x backup.sh
cronジョブとして設定する。
crontab -e
# 毎日午前2時にバックアップを実行 0 2 * * * /path/to/backup.sh
トラブルシューティング
MCPサーバが起動しない
- ログを確認する。
- sudo journalctl -u mcp-server -n 50
- ポートが既に使用されていないか確認する。
- sudo lsof -i :3000
- Node.js または Pythonのバージョンを確認する。
Claude Desktopから接続できない
- 設定ファイルのパスが正しいか確認する。
- ファイルの実行権限を確認する
- chmod u+x server.js
- STDIOトランスポートの場合、標準出力にログを出力していないか確認する。
ツールの実行が遅い
- ツールの実装を最適化する。
- タイムアウト設定を確認する。
- システムリソースを確認する
topコマンド またはhtopコマンド
RISC-V環境でNode.jsが動作しない
- ソースコードからビルドする必要がある場合がある。
- バージョン互換性を確認する。
- 依存関係を確認する
ldd /path/to/node
パフォーマンス最適化
Node.jsの最適化
# Node.jsのメモリ制限を増やす
node --max-old-space-size=4096 server.js
# クラスタリングによる負荷分散
# cluster.jsファイルを作成
import cluster from 'cluster';
import os from 'os';
if (cluster.isPrimary) {
const numCPUs = os.cpus().length;
for (let i = 0; i < numCPUs; i++) {
cluster.fork();
}
cluster.on('exit', (worker, code, signal) => {
console.error(`ワーカー ${worker.process.pid} が終了しました`);
cluster.fork();
});
}
else {
// サーバの起動
import('./server.js');
}
キャッシングの実装
頻繁にアクセスされるデータをキャッシュすることにより、パフォーマンスを向上させる。
npm install node-cache
import NodeCache from 'node-cache';
const cache = new NodeCache({ stdTTL: 600 }); // 10分間キャッシュ
server.tool(
"get-cached-data",
"キャッシュされたデータを取得する",
{},
async () => {
const cacheKey = 'system-info';
let data = cache.get(cacheKey);
if (!data) {
// データを取得してキャッシュに保存
data = await fetchSystemInfo();
cache.set(cacheKey, data);
}
return {
content: [{ type: "text", text: JSON.stringify(data) }],
};
}
);