近年、AI エージェント間の通信標準として注目される Model Context Protocol(MCP)。本地动手で AWS Lambda 上に MCP Server を構築し、HolySheep AI をバックエンド API として活用する整套方案を詳しく解説します。
MCP Server とは?なぜクラウド構築が必要か
MCP は Claude(Anthropic)が提唱した AI モデルとツール間の通信プロトコルです。ローカル開発では十分な速度が出せますが、本番環境では以下の課題が生じます:
- 可用性:常時稼働が必要なインスタンス管理コスト
- スケーラビリティ:トラフィック増減への自動対応
- コスト効率:Serverless 化による従量課金
- レイテンシ:地理的に近いエッジでの処理
AWS Lambda + API Gateway の組み合わせは、これらの課題を Serverless アーキテクチャで一撃解決します。
アーキテクチャ全体図
┌─────────────┐ ┌──────────────┐ ┌─────────────────┐ ┌───────────────┐
│ Claude App │────▶│ AWS API GW │────▶│ AWS Lambda │────▶│ HolySheep API │
│ (MCP Client)│ │ (HTTPS) │ │ (MCP Server) │ │ /v1/chat/compl│
└─────────────┘ └──────────────┘ └─────────────────┘ └───────────────┘
│ │
│ ┌──────────────┐ │
└───────────▶│ DynamoDB │◀─────────────┘
│ (状態管理) │
└──────────────┘
前提条件と環境構築
# 必要なツールのインストール
npm install -g serverless
brew install awscli
aws configure
プロジェクト初期化
mkdir mcp-server-lambda && cd mcp-server-lambda
npm init -y
npm install @modelcontextprotocol/server-sdk aws-lambda aws-sdk
Step 1:MCP Server 本体の実装
// mcp-server/index.ts
import { MCPServer, Tool, Resource } from '@modelcontextprotocol/server-sdk';
import { LambdaClient } from './holy-sheep-client';
const holySheepClient = new LambdaClient({
baseUrl: 'https://api.holysheep.ai/v1',
apiKey: process.env.HOLYSHEEP_API_KEY!
});
// MCP Tool: AIチャット応答生成
const chatTool: Tool = {
name: 'ai_chat',
description: 'HolySheep AI を使用してチャット応答を生成',
inputSchema: {
type: 'object',
properties: {
model: {
type: 'string',
enum: ['gpt-4.1', 'claude-sonnet-4.5', 'gemini-2.5-flash', 'deepseek-v3.2'],
default: 'gpt-4.1'
},
messages: {
type: 'array',
items: {
type: 'object',
properties: {
role: { type: 'string', enum: ['user', 'assistant', 'system'] },
content: { type: 'string' }
}
}
},
temperature: { type: 'number', minimum: 0, maximum: 2, default: 0.7 }
},
required: ['messages']
},
async handler(params: any) {
const startTime = Date.now();
try {
const response = await holySheepClient.chatCompletions({
model: params.model,
messages: params.messages,
temperature: params.temperature
});
const latencyMs = Date.now() - startTime;
console.log([MCP] HolySheep応答: ${latencyMs}ms, tokens: ${response.usage.total_tokens});
return {
content: [
{ type: 'text', text: response.choices[0].message.content },
{ type: 'text', text: メタデータ: レイテンシ=${latencyMs}ms, モデル=${params.model} }
]
};
} catch (error) {
console.error('[MCP] エラー:', error);
throw error;
}
}
};
// サーバー初期化
const server = new MCPServer({
name: 'holysheep-mcp-server',
version: '1.0.0',
tools: [chatTool]
});
export { server };
Step 2:HolySheep API クライアントの実装
// holy-sheep-client.ts
interface ChatCompletionRequest {
model: string;
messages: Array<{ role: string; content: string }>;
temperature?: number;
max_tokens?: number;
}
interface ChatCompletionResponse {
id: string;
choices: Array<{
message: { role: string; content: string };
finish_reason: string;
}>;
usage: {
prompt_tokens: number;
completion_tokens: number;
total_tokens: number;
};
model: string;
created: number;
}
export class LambdaClient {
private baseUrl: string;
private apiKey: string;
constructor(config: { baseUrl: string; apiKey: string }) {
this.baseUrl = config.baseUrl;
this.apiKey = config.apiKey;
}
async chatCompletions(request: ChatCompletionRequest): Promise {
const url = ${this.baseUrl}/chat/completions;
const response = await fetch(url, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': Bearer ${this.apiKey},
'X-Request-ID': crypto.randomUUID()
},
body: JSON.stringify({
...request,
stream: false
})
});
if (!response.ok) {
const errorBody = await response.text();
throw new Error(
HolySheep API Error: ${response.status} ${response.statusText}\n +
Body: ${errorBody}\n +
Request-ID: ${response.headers.get('X-Request-ID')}
);
}
return response.json();
}
}
Step 3:AWS Lambda ハンドラの設定
// lambda-handler.ts
import { server } from './mcp-server';
export async function handler(event: any): Promise {
console.log('[Lambda] 受信イベント:', JSON.stringify(event, null, 2));
const startTime = Date.now();
try {
// CORS プリフライト対応
if (event.httpMethod === 'OPTIONS') {
return {
statusCode: 200,
headers: getCorsHeaders(),
body: ''
};
}
// MCP プロトコルリクエストの処理
const body = JSON.parse(event.body || '{}');
const { action, tool, params } = body;
let result: any;
switch (action) {
case 'call_tool':
// ツール呼び出しの実行
const toolHandler = server.getToolHandler(tool);
if (!toolHandler) {
throw new Error(Tool '${tool}' not found);
}
result = await toolHandler(params);
break;
case 'list_tools':
result