MCP Servers

A collection of Model Context Protocol servers, templates, tools and more.

M
Minimum MCP Streamablehttp

MCP server by Masa1984a

Created 6/8/2025
Updated 16 days ago
Repository documentation and setup instructions

MCP Streamable HTTP Server with Terraform

Model Context Protocol (MCP) の Streamable HTTP transport を使用したサーバー実装です。TypeScript/Node.jsで構築され、Terraformを使用してAzure Container Instances (ACI) へ自動デプロイします。

🎯 プロジェクト概要

本プロジェクトは、MCPサーバーをHTTP経由でアクセス可能にし、Infrastructure as Code (Terraform) で管理する実装例です:

  • ステートレス設計: Azure Container Instancesなどのサーバーレス環境に最適
  • Streamable HTTP Transport: HTTPストリーミングによる効率的な通信
  • 完全自動化: PowerShellスクリプトによるワンコマンドデプロイ
  • 段階的デプロイ: インフラ → イメージプッシュ → アプリケーションの順序で安全にデプロイ
  • サンプルツール実装: add(加算)とgreet(挨拶)の2つのツール

🏗️ アーキテクチャ

┌─────────────────────────────────────────────────────────────────┐
│                          Azure Cloud                           │
├─────────────────────────────────────────────────────────────────┤
│  ┌─────────────────────┐    ┌─────────────────────────────────┐  │
│  │ Resource Group      │    │ Azure Container Registry (ACR)  │  │
│  │ (Terraformで管理)    │    │ (Terraformで作成)              │  │
│  └─────────────────────┘    └─────────────────────────────────┘  │
│            ↓                              ↓                        │
│  ┌─────────────────────────────────────────────────────────────┐  │
│  │ Azure Container Instances (ACI)                             │  │
│  │ (Terraformでデプロイ)                                        │  │
│  │ ┌─────────────────────────────────────────────────────────┐│  │
│  │ │ MCP Streamable HTTP Server                              ││  │
│  │ │ - Node.js 20                                           ││  │
│  │ │ - Express.js                                           ││  │
│  │ │ - Port 8080                                            ││  │
│  │ │ - Stateless Mode                                       ││  │
│  │ └─────────────────────────────────────────────────────────┘│  │
│  │ Public FQDN: mymcp-server.japaneast.azurecontainer.io      │  │
│  └─────────────────────────────────────────────────────────────┘  │
└─────────────────────────────────────────────────────────────────┘
                                     ▲
                                     │ HTTP/HTTPS
                                     │
┌─────────────────────────────────────────────────────────────────┐
│                        Client Side                             │
├─────────────────────────────────────────────────────────────────┤
│  ┌─────────────────────┐    ┌─────────────────────────────────┐  │
│  │ MCP Inspector       │    │ Future: ChatGPT Integration     │  │
│  │ (Testing Tool)      │    │ (MCP Custom Connector)          │  │
│  └─────────────────────┘    └─────────────────────────────────┘  │
└─────────────────────────────────────────────────────────────────┘

📁 プロジェクト構成

Minimum_MCP/
├── app/                    # アプリケーション本体
│   ├── src/               # TypeScriptソースコード
│   │   └── server.ts     # MCPサーバー実装
│   ├── dist/             # コンパイル済みJavaScript
│   ├── package.json      # Node.js依存関係
│   ├── tsconfig.json     # TypeScript設定
│   ├── Dockerfile        # コンテナイメージ定義
│   └── .dockerignore     # Docker除外設定
├── terraform/             # インフラ定義(Infrastructure as Code)
│   ├── main.tf           # Azureリソース定義
│   ├── variables.tf      # 変数定義
│   ├── outputs.tf        # 出力値定義
│   ├── terraform.tfvars  # 【要設定】環境固有の値
│   └── versions.tf       # Terraformバージョン管理
├── scripts/               # 自動化スクリプト
│   ├── deploy.ps1        # 完全自動デプロイスクリプト
│   └── build-and-push.ps1 # Dockerイメージビルド&プッシュ
└── .gitignore            # Git除外設定

🚀 クイックスタート

前提条件

開発環境(Windows 11):

  • PowerShell 5.1+
  • Node.js 20.x+
  • npm 10.x+
  • Terraform 1.5.0+
  • Podman 5.x(またはDocker)
  • Azure CLI 2.70+

Azureアカウント:

  • 有効なAzureサブスクリプション
  • Contributor以上の権限

🔑 Azure Subscription IDの取得方法

方法1: Azure ポータルから取得

  1. Azure Portal にログイン
  2. 左側メニューまたは検索バーで「サブスクリプション」を検索
  3. 使用するサブスクリプションをクリック
  4. 「概要」ページに表示される「サブスクリプション ID」をコピー

Azure Portal Subscription

方法2: Azure CLIから取得(推奨)

# 1. Azure CLIのインストール確認
az --version

# インストールされていない場合は以下から入手:
# https://docs.microsoft.com/ja-jp/cli/azure/install-azure-cli-windows

# 2. Azureにログイン
az login
# → ブラウザが開きます。Azureアカウントでログイン

# 3. アカウント一覧を表示
az account list --output table
# 出力例:
# Name                  CloudName    SubscriptionId                        State    IsDefault
# --------------------  -----------  ------------------------------------  -------  -----------
# My Subscription       AzureCloud   xxx  Enabled  True

# 4. 現在のサブスクリプションIDのみ取得
az account show --query "id" --output tsv
# → xxx

# 5. 複数のサブスクリプションがある場合、使用するものを選択
az account set --subscription "サブスクリプション名またはID"

方法3: PowerShellから取得

# Azure PowerShellモジュールを使用
Connect-AzAccount
Get-AzSubscription | Select-Object Name, Id

初期設定(必須)

  1. terraform.tfvarsの作成
# テンプレートから設定ファイルを作成
cd terraform
copy terraform.tfvars.template terraform.tfvars

# 設定ファイルを編集
notepad terraform.tfvars

以下の値を実際の環境に合わせて変更:

# プロジェクト固有の値を設定
prefix   = "yourname123"  # ← 一意のプレフィックスに変更
location = "japaneast"

# Azure Subscription ID(各自の環境に合わせて変更)
subscription_id = "xxx"  # ← 実際のIDに変更

重要な注意事項:

  • prefixグローバルに一意である必要があります(ACR名に使用されるため)
  • 例: johndoe123, testmcp2024, など
  • 3-20文字の英数字のみ使用可能

完全自動デプロイ(推奨)

# プロジェクトルートで実行
.\scripts\deploy.ps1

# 以下が自動実行されます:
# 1. TypeScriptのビルド
# 2. Terraformの初期化
# 3. インフラの作成(Resource Group + ACR)
# 4. Dockerイメージのビルド
# 5. ACRへのイメージプッシュ
# 6. Container Instancesのデプロイ

実行時間:約3-5分

動作確認

デプロイ完了後、以下のURLが表示されます:

# ヘルスチェック
Invoke-WebRequest -Uri "http://mymcp-server.japaneast.azurecontainer.io:8080/health" -Method GET

# MCP Inspectorで接続
# Transport Type: Streamable HTTP
# URL: http://mymcp-server.japaneast.azurecontainer.io:8080/mcp

🔧 詳細な使用方法

ローカル開発

cd app

# 依存関係のインストール
npm install

# 開発サーバーの起動(ファイル変更監視)
npm run dev

# TypeScriptビルド
npm run build

# 本番サーバーの起動
npm start

手動での段階的デプロイ

自動デプロイではなく、段階的に確認しながらデプロイしたい場合:

cd terraform

# 1. Terraform初期化
terraform init

# 2. インフラのみ作成(Resource Group + ACR)
terraform apply "-target=azurerm_resource_group.main" "-target=azurerm_container_registry.acr"

# 3. ACR情報の確認
terraform output acr_login_server
$password = terraform output -raw acr_admin_password

# 4. Dockerイメージのビルド&プッシュ
cd ../app
podman build -t mcp-server:latest .
echo $password | podman login $(terraform output -raw acr_login_server) --username $(terraform output -raw acr_admin_username) --password-stdin
podman tag mcp-server:latest $(terraform output -raw acr_login_server)/mcp-server:latest
podman push $(terraform output -raw acr_login_server)/mcp-server:latest

# 5. Container Instancesのデプロイ
cd ../terraform
terraform apply "-target=azurerm_container_group.aci"

リソースの削除

cd terraform

# 全リソースの削除
terraform destroy
# → yes を入力して確認

# 状態ファイルも削除する場合
Remove-Item -Force terraform.tfstate*
Remove-Item -Recurse -Force .terraform

📋 トラブルシューティング

よくあるエラーと対処法

1. Terraform実行時のエラー

Error: `subscription_id` is a required provider property

解決法: terraform/terraform.tfvarsにSubscription IDを設定してください。

2. ACR名の重複エラー

Error: The registry DNS name mymcpacr is already in use

解決法: terraform/terraform.tfvarsprefixを一意の値に変更してください。

3. Container Groupのイメージアクセスエラー

Error: InaccessibleImage: The image 'mymcpacr.azurecr.io/mcp-server:latest' in container group

解決法: Dockerイメージがプッシュされていません。build-and-push.ps1を実行してください。

4. PowerShell実行ポリシーエラー

cannot be loaded because running scripts is disabled on this system

解決法:

Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser

ログの確認方法

# Container Instancesのログ確認
az container logs --resource-group rg-mymcp --name mymcp-container

# リアルタイムログ監視
az container logs --resource-group rg-mymcp --name mymcp-container --follow

# コンテナの状態確認
az container show --resource-group rg-mymcp --name mymcp-container --query "containers[0].instanceView.currentState"

📚 IT学習者向け詳細解説

プロジェクト構造の理解

Minimum_MCP/
├── app/                    # アプリケーション本体
│   ├── src/               # TypeScriptソースコード
│   │   └── server.ts     # メインのサーバーファイル
│   ├── dist/             # コンパイル済みJavaScript(自動生成)
│   │   ├── server.js     # 実行可能なJSファイル
│   │   ├── server.d.ts   # 型定義ファイル
│   │   └── *.map         # デバッグ用マップファイル
│   ├── node_modules/     # 依存パッケージの実体
│   ├── package.json      # プロジェクト設定と依存関係
│   ├── package-lock.json # 依存関係のバージョン固定
│   ├── tsconfig.json     # TypeScriptコンパイラ設定
│   ├── Dockerfile        # Dockerイメージ構築設定
│   └── .dockerignore     # Docker除外ファイル設定
├── terraform/             # インフラ定義
│   ├── main.tf           # メインのリソース定義
│   ├── variables.tf      # 変数定義
│   ├── outputs.tf        # 出力値定義
│   ├── terraform.tfvars  # 変数の実際の値
│   └── versions.tf       # バージョン制約
└── scripts/               # 自動化スクリプト

Node.js/TypeScriptの基礎知識

TypeScriptとJavaScriptの関係

TypeScriptは、JavaScriptに型システムを追加した言語です:

// TypeScript(src/server.ts)- 開発時に型チェック
const greet = (name: string): string => {
  return `Hello, ${name}!`;
}

// コンパイルエラー: 型が合わない
greet(123); // Error: Argument of type 'number' is not assignable to parameter of type 'string'

tscコンパイラで変換

// JavaScript(dist/server.js)- 実行時は型情報なし
const greet = (name) => {
  return `Hello, ${name}!`;
}

Node.jsの役割

Node.jsはJavaScriptの実行環境です:

TypeScript(人間が書く)
    ↓ tscコンパイラ
JavaScript(マシンが理解)
    ↓ 
Node.js(V8エンジンで実行)

各ファイルの詳細解説

1. package.json - プロジェクトの心臓部

{
  "name": "mcp-streamable-http-server",
  "version": "1.0.0",
  "type": "module",              // ES Modules使用宣言
  "scripts": {
    "build": "tsc",              // npm run build → TypeScriptコンパイル
    "start": "node dist/server.js", // npm start → 本番実行
    "dev": "tsx watch src/server.ts" // npm run dev → 開発モード
  },
  "dependencies": {
    "express": "^5.1.0",         // 本番で必要(実行時に使用)
    "@modelcontextprotocol/sdk": "^1.12.1"
  },
  "devDependencies": {
    "typescript": "^5.8.3",      // 開発時のみ(コンパイラ)
    "@types/express": "^5.0.2",  // 開発時のみ(型定義)
    "tsx": "^4.19.4"             // 開発時のみ(TS直接実行)
  }
}

ポイント

  • dependencies: 本番環境で必要なパッケージ
  • devDependencies: 開発時のみ必要なパッケージ
  • scripts: よく使うコマンドのショートカット

2. package-lock.json - 依存関係の完全な固定

{
  "packages": {
    "express": {
      "version": "5.1.0",  // 厳密なバージョン指定
      "resolved": "https://registry.npmjs.org/express/-/express-5.1.0.tgz",
      "integrity": "sha512-..."  // ファイルの整合性チェック
    }
  }
}

なぜ必要?

  • チーム全員が同じバージョンを使用
  • 「私の環境では動くのに...」を防ぐ
  • npm ciコマンドで高速・確実にインストール

3. tsconfig.json - TypeScriptの設定

{
  "compilerOptions": {
    "target": "ES2022",          // 出力するJSのバージョン
    "module": "NodeNext",        // モジュールシステム
    "outDir": "./dist",          // 出力先ディレクトリ
    "rootDir": "./src",          // ソースコードの場所
    "strict": true,              // 厳密な型チェック
    "sourceMap": true            // デバッグ用マップ生成
  },
  "include": ["src/**/*"],       // コンパイル対象
  "exclude": ["node_modules"]    // 除外するフォルダ
}

4. server.ts - メインのソースコード

// 1. 必要なモジュールのインポート
import express from 'express';
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';

// 2. Expressアプリケーションの初期化
const app = express();
app.use(express.json());  // JSONボディのパース

// 3. MCPサーバーの初期化
const server = new McpServer({
  name: 'mcp-streamable-http-server',
  version: '1.0.0'
});

// 4. ツールの定義(関数のようなもの)
server.tool(
  'add',  // ツール名
  { a: z.number(), b: z.number() },  // パラメータの型定義
  async ({ a, b }) => ({  // 実装
    content: [{
      type: 'text',
      text: String(a + b)
    }]
  })
);

// 5. HTTPエンドポイントの設定
app.post('/mcp', async (req, res) => {
  // MCPプロトコルの処理
});

// 6. サーバーの起動
const PORT = process.env.PORT || 8080;
app.listen(PORT, () => {
  console.log(`Server listening on port ${PORT}`);
});

5. Dockerfile - コンテナ化の設定

# ベースイメージ(軽量版Node.js)
FROM node:20-slim

# 作業ディレクトリ設定
WORKDIR /app

# 依存関係定義ファイルをコピー(キャッシュ効率化)
COPY package*.json ./

# 本番用パッケージのみインストール
RUN npm ci --only=production

# ビルド済みコードをコピー
COPY dist ./dist

# ポート公開(ドキュメント的)
EXPOSE 8080

# 環境変数設定
ENV NODE_ENV=production

# 起動コマンド
CMD ["node", "dist/server.js"]

最適化のポイント

  1. 軽量イメージ使用(node:20-slim)
  2. レイヤーキャッシュ活用(package*.jsonを先にコピー)
  3. 開発用パッケージを除外(--only=production)

6. .dockerignore - Dockerビルド時の除外設定

node_modules    # コンテナ内で再インストールするから不要
src             # TypeScriptソースは不要(distがあれば十分)
*.ts            # TypeScriptファイルは全て不要
tsconfig.json   # コンパイル設定も不要

開発フローの理解

graph LR
    A[TypeScript開発] --> B[npm run dev]
    B --> C[自動コンパイル・再起動]
    C --> D[動作確認]
    D --> A
    
    A --> E[npm run build]
    E --> F[dist/生成]
    F --> G[Dockerビルド]
    G --> H[ACRプッシュ]
    H --> I[ACIデプロイ]

npmコマンドチートシート

| コマンド | 説明 | 実行内容 | |---------|------|---------| | npm install | 依存関係インストール | package.jsonを読んでnode_modules作成 | | npm ci | クリーンインストール | package-lock.jsonから厳密にインストール | | npm run build | ビルド | tscを実行してTypeScript→JavaScript | | npm run dev | 開発モード | ファイル監視&自動再起動 | | npm start | 本番起動 | node dist/server.js |

よくある質問(FAQ)

Q: なぜTypeScriptを使うの?

A: 型安全性により、開発時にエラーを発見できます:

// TypeScript - コンパイル時にエラー発見
function divide(a: number, b: number): number {
  return a / b;
}
divide("10", "2");  // Error: 文字列は渡せない

// JavaScript - 実行時まで分からない
function divide(a, b) {
  return a / b;
}
divide("10", "2");  // "10" / "2" = 5(暗黙の型変換)

Q: node_modulesはなぜ巨大?

A: 各プロジェクトが独立して全ての依存関係を持つため:

  • express本体
  • expressが依存するパッケージ
  • それらが依存するパッケージ...
  • 全てがnode_modulesに物理的に保存される

Q: distフォルダを編集してもいい?

A: いいえ。distは自動生成されるため:

  • 手動編集しても次回ビルドで上書きされる
  • 必ずsrc/のTypeScriptを編集する
  • distは.gitignoreに追加(バージョン管理しない)

Q: 開発環境と本番環境の違いは?

A: 主な違い: | 項目 | 開発環境 | 本番環境 | |------|---------|---------| | 実行方法 | tsx(TypeScript直接) | node(JavaScript) | | ファイル監視 | あり(自動再起動) | なし | | エラー表示 | 詳細 | 最小限 | | パッケージ | 全て | dependenciesのみ |

Q: DockerfileのCMDとRUNの違いは?

A: タイミングが違います:

  • RUN: イメージ構築時に実行(npm installなど)
  • CMD: コンテナ起動時に実行(node server.jsなど)

🔍 Terraform詳細解説

Terraformとは?

Terraformは HashiCorp社が開発した Infrastructure as Code (IaC) ツールです。インフラストラクチャをコードで定義し、バージョン管理できます。

各Terraformファイルの詳細

1. versions.tf - プロバイダーとバージョン管理

terraform {
  required_version = ">= 1.5.0"  # Terraform本体のバージョン制約
  
  required_providers {
    azurerm = {
      source  = "hashicorp/azurerm"  # プロバイダーのソース
      version = "~> 4.0"             # 4.x系の最新を使用
    }
  }
}

provider "azurerm" {
  features {}                        # 必須の空ブロック
  subscription_id = var.subscription_id  # どのAzureアカウントを使うか
}

解説:

  • required_version: Terraformの最小バージョンを指定
  • required_providers: 使用するプロバイダー(Azureとの連携部分)
  • provider: プロバイダーの設定

2. variables.tf - 変数定義

variable "prefix" {
  description = "リソース名のプレフィックス"
  type        = string
  # defaultがないので必須入力
}

variable "location" {
  description = "Azureリージョン"
  type        = string
  default     = "japaneast"  # デフォルト値あり
}

variable "container_cpu" {
  description = "コンテナのCPU割り当て"
  type        = string      # 数値だが文字列で定義(Azureの仕様)
  default     = "0.5"       # 0.5コア
}

変数の型:

  • string: 文字列
  • number: 数値
  • bool: 真偽値
  • list: リスト
  • map: マップ(辞書)

3. terraform.tfvars - 変数の実際の値

# これが実際に使われる値
prefix   = "mymcp"
location = "japaneast"
subscription_id = "xxx"

重要: このファイルには秘密情報が含まれるため、.gitignoreに追加推奨

4. main.tf - リソース定義(メイン)

# リソースブロックの構文:
# resource "リソースタイプ" "リソース名" {
#   設定項目 = 値
# }

# 1. リソースグループ(全てのリソースを格納する箱)
resource "azurerm_resource_group" "main" {
  name     = "rg-${var.prefix}"  # 変数の参照
  location = var.location
  
  tags = {
    Environment = "Production"
    Project     = "MCP-Server"
  }
}

# 2. Container Registry(Dockerイメージの保管庫)
resource "azurerm_container_registry" "acr" {
  name                = "${var.prefix}acr"  # グローバルに一意
  resource_group_name = azurerm_resource_group.main.name  # 他リソース参照
  location            = azurerm_resource_group.main.location
  sku                 = "Basic"  # Basic/Standard/Premium
  admin_enabled       = true     # 管理者アクセス有効化
  
  tags = {
    Environment = "Production"
    Project     = "MCP-Server"
  }
}

# 3. Container Group(実際にアプリが動く場所)
resource "azurerm_container_group" "aci" {
  name                = "${var.prefix}-container"
  resource_group_name = azurerm_resource_group.main.name
  location            = azurerm_resource_group.main.location
  os_type             = "Linux"
  
  # コンテナの定義
  container {
    name   = "mcp-server"
    image  = "${azurerm_container_registry.acr.login_server}/mcp-server:${var.image_tag}"
    cpu    = var.container_cpu
    memory = var.container_memory
    
    ports {
      port     = 8080
      protocol = "TCP"
    }
    
    environment_variables = {
      NODE_ENV = "production"
      PORT     = "8080"
    }
  }
  
  # ACR認証情報
  image_registry_credential {
    server   = azurerm_container_registry.acr.login_server
    username = azurerm_container_registry.acr.admin_username
    password = azurerm_container_registry.acr.admin_password
  }
  
  dns_name_label = "${var.prefix}-server"  # FQDN生成用
  
  tags = {
    Environment = "Production"
    Project     = "MCP-Server"
  }
}

リソース間の依存関係:

Resource Group
    ↓ 依存
Container Registry
    ↓ 依存
Container Group

5. outputs.tf - 出力値定義

output "resource_group_name" {
  value = azurerm_resource_group.main.name
}

output "acr_login_server" {
  value = azurerm_container_registry.acr.login_server
  # 例: mymcpacr.azurecr.io
}

output "acr_admin_password" {
  value     = azurerm_container_registry.acr.admin_password
  sensitive = true  # terraform output では表示されない
}

output "container_url" {
  value = "http://${azurerm_container_group.aci.fqdn}:8080"
  # 例: http://mymcp-server.japaneast.azurecontainer.io:8080
}

使い方:

# 値の取得
terraform output container_url
# "http://mymcp-server.japaneast.azurecontainer.io:8080"

# センシティブな値の取得
terraform output -raw acr_admin_password
# パスワードが表示される

Terraformの基本コマンド

| コマンド | 説明 | 用途 | |---------|------|------| | terraform init | 初期化 | プロバイダーのダウンロード | | terraform plan | 実行計画 | 変更内容の事前確認 | | terraform apply | 適用 | リソースの作成・更新 | | terraform destroy | 破棄 | 全リソースの削除 | | terraform output | 出力 | 作成済みリソースの情報取得 | | terraform state list | 状態一覧 | 管理中のリソース確認 |

Terraformの状態管理

Terraformはterraform.tfstateファイルで現在の状態を管理:

{
  "version": 4,
  "terraform_version": "1.5.0",
  "resources": [
    {
      "type": "azurerm_resource_group",
      "name": "main",
      "instances": [
        {
          "attributes": {
            "id": "/subscriptions/.../resourceGroups/rg-mymcp",
            "location": "japaneast",
            "name": "rg-mymcp"
          }
        }
      ]
    }
  ]
}

重要:

  • このファイルを失うと、Terraformは既存リソースを認識できなくなる
  • チーム開発では、Azure Blob StorageやTerraform Cloudで共有

段階的デプロイの仕組み

# -targetオプションで特定のリソースのみ操作
terraform apply "-target=azurerm_resource_group.main" "-target=azurerm_container_registry.acr"

これにより:

  1. まずインフラ(RG + ACR)を作成
  2. Dockerイメージをプッシュ
  3. 最後にコンテナをデプロイ

という順序制御が可能になります。

Terraformのベストプラクティス

  1. 変数の活用

    # ハードコーディングを避ける
    # 悪い例
    location = "japaneast"
    
    # 良い例
    location = var.location
    
  2. タグの統一

    # 全リソースに同じタグを付ける
    tags = {
      Environment = var.environment
      Project     = var.project_name
      ManagedBy   = "Terraform"
    }
    
  3. 命名規則

    # リソースタイプを含める
    name = "rg-${var.prefix}"      # リソースグループ
    name = "${var.prefix}acr"      # ACR
    name = "${var.prefix}-vm"      # 仮想マシン
    
  4. 出力の活用

    # 他のスクリプトで使う値は必ず出力
    output "important_value" {
      value = azurerm_resource.example.important_attribute
    }
    

トラブルシューティングガイド

TypeScript関連

# エラー: Cannot find module 'express'
npm install
npm install -D @types/express

# エラー: tsc: command not found
npm install -D typescript

Docker関連

# エラー: port is already allocated
lsof -i :8080  # Mac/Linux
netstat -ano | findstr :8080  # Windows

# ビルドが遅い
# .dockerignoreにnode_modulesが含まれているか確認

Azure関連

# ACR認証エラー
az acr update --name $ACR_NAME --admin-enabled true

# コンテナログ確認
az container logs --resource-group $RESOURCE_GROUP --name $CONTAINER_NAME

Terraform関連

# 状態の不整合
terraform refresh  # 実際のリソースと同期

# 特定リソースの再作成
terraform taint azurerm_container_group.aci  # 次回applyで再作成
terraform apply

# 状態から削除(リソースは残る)
terraform state rm azurerm_container_group.aci

さらなる学習リソース

  1. TypeScript

  2. Node.js/Express

  3. Docker

  4. Azure

  5. Terraform

  6. MCP


🛠️ カスタマイズ

環境変数の追加

terraform/main.tfのContainer Group定義内で環境変数を追加:

environment_variables = {
  NODE_ENV = "production"
  PORT     = "8080"
  MY_CUSTOM_VAR = "value"  # 追加
}

リソースサイズの変更

terraform/variables.tfで定義されている値を変更:

variable "container_cpu" {
  description = "コンテナのCPU割り当て"
  type        = string
  default     = "1"  # 0.5 → 1 に変更
}

variable "container_memory" {
  description = "コンテナのメモリ割り当て(GB)"
  type        = string
  default     = "2"  # 1 → 2 に変更
}

新しいMCPツールの追加

app/src/server.tsでツールを追加:

// 新しいツールの追加例
server.tool(
  'multiply',
  {
    a: z.number().describe('First number'),
    b: z.number().describe('Second number')
  },
  async ({ a, b }) => ({
    content: [{
      type: 'text',
      text: `${a} × ${b} = ${a * b}`
    }]
  })
);

📚 技術スタック詳細

Terraform

Infrastructure as Code (IaC) の実装:

  • 宣言的なリソース管理
  • 状態管理による差分デプロイ
  • モジュール化された構成

PowerShell自動化

deploy.ps1の処理フロー:

1. TypeScriptビルド
   ↓
2. Terraform初期化
   ↓
3. インフラ作成(段階的)
   - Resource Group
   - Container Registry
   ↓
4. Dockerイメージビルド&プッシュ
   ↓
5. アプリケーションデプロイ
   - Container Instances

Docker最適化

マルチステージビルドではなく、事前ビルド方式を採用:

  • 開発環境でTypeScriptをビルド
  • Dockerイメージには実行に必要な最小限のファイルのみ含める
  • イメージサイズ: 約220MB(node:20-slim使用)

🔐 セキュリティ考慮事項

  1. Subscription ID:

    • terraform.tfvarsはGitHubに公開しない
    • 必要に応じて.gitignoreに追加
  2. ACR認証:

    • 管理者権限は開発・テスト用
    • 本番環境ではService Principalやマネージドアイデンティティを使用
  3. ネットワーク:

    • デフォルトでパブリックアクセス
    • 必要に応じてVNet統合を検討

📄 ライセンス

このプロジェクトはMITライセンスの下で公開されています。

🤝 貢献

プルリクエストやイシュー報告を歓迎します。貢献する前に:

  1. 既存のコードスタイルに従ってください
  2. Terraformのフォーマットを実行してください: terraform fmt
  3. TypeScriptのリントを実行してください: npm run lint(設定されている場合)

📖 関連リソース

Quick Setup
Installation guide for this server

Installation Command (package not published)

git clone https://github.com/Masa1984a/Minimum_MCP_StreamableHTTP
Manual Installation: Please check the README for detailed setup instructions and any additional dependencies required.

Cursor configuration (mcp.json)

{ "mcpServers": { "masa1984a-minimum-mcp-streamablehttp": { "command": "git", "args": [ "clone", "https://github.com/Masa1984a/Minimum_MCP_StreamableHTTP" ] } } }