MCP ExplorerExplorer

Minimum Mcp Streamablehttp

@Masa1984aon 14 days ago
1 MIT
FreeCommunity
AI Systems
MCP Streamable HTTP Server implemented with TypeScript/Node.js and Terraform for Azure deployment.

Overview

What is Minimum Mcp Streamablehttp

Minimum_MCP_StreamableHTTP is a server implementation utilizing the Model Context Protocol (MCP) Streamable HTTP transport. It is built with TypeScript/Node.js and is designed for automatic deployment to Azure Container Instances (ACI) using Terraform.

Use cases

Use cases include building scalable web applications, implementing microservices, and providing efficient data streaming services over HTTP in cloud environments.

How to use

To use Minimum_MCP_StreamableHTTP, deploy it using Terraform scripts which automate the provisioning of Azure resources. You can access the server via HTTP, and it includes sample tools for operations such as addition and greeting.

Key features

Key features include stateless design suitable for serverless environments, efficient communication through Streamable HTTP transport, complete automation with PowerShell scripts for one-command deployment, and a phased deployment process ensuring safety.

Where to use

Minimum_MCP_StreamableHTTP is ideal for cloud-based applications, particularly in serverless architectures and environments where automated deployment and management of resources are required.

Content

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 - プロジェクトの心臓部

ポイント

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

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

なぜ必要?

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

3. tsconfig.json - TypeScriptの設定

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(設定されている場合)

📖 関連リソース

Tools

No tools

Comments