🤖

【MCPサーバー】LambdaでMCPサーバーを動かそうとして発生したエラー対応

に公開

はじめに

MCPサーバーのDockerImageをLambdaのLWAを利用して構築時発生したエラーについて記載します。

この記事でわかる・できること

  • Lambdaを使ってMCPサーバーの注意点
  • FastMCPを使ってMCPサーバーの注意点

この記事の対象者

  • MCPサーバーを構築している人
  • Lambdaを使ってMCPサーバーを構築しようとしている人
  • FastMCPを使ってMCPサーバーの構築しようとしている人

動作環境・使用するツールや言語

  • Typescript
  • FastMCPを使ったMCPサーバの構築

構成内容

アーキテクチャ構成

アーキテクチャは以下の構成です。

MCPサーバーのコード

Anthropicのサンプルの天気に関するMCPサーバーになっています。

// server.ts
import { FastMCP } from "fastmcp";
import { alertsTool } from "./tools/alerts";
import { forecastTool } from "./tools/forecast";

const server = new FastMCP({
  name: "weather",
  version: "1.0.0",
});

// Add tools
server.addTool(alertsTool);
server.addTool(forecastTool);

// Start server
server.start({
  transportType: "httpStream",
  httpStream: {
    port: 8000,
  },
});

内容については公式ドキュメントを確認してください。
https://modelcontextprotocol.io/docs/develop/build-server#node

エラー①

Lambda関数URLにアクセスした際のエラー

 curl https://*****.lambda-url.ap-northeast-1.on.aws/mcp
{"errorType":"Runtime.ExitError","errorMessage":"RequestId: 59d6d43d-c844-47a2-a2e6-9b3069b43f48 Error: Runtime exited with error: exit status 142"}

エラー原因の確認

CloudWatchログ一覧

  1. handler名エラー
    entrypoint requires the handler name to be the first argument
    
    意味:Lambda Web Adapterが最初の引数をハンドラー名として期待しているが、nodeが渡されている
  2. 拡張機能の状態
    EXTENSION Name: lambda-adapter State: Ready Events: []
    
  3. 初期化エラー
    INIT_REPORT Init Duration: 31.87 ms Phase: init Status: error Error Type: Runtime.ExitError
    

エラー内容を受けて

nodeで実行したいのでこのままで渡せないか?

解決方法

変更内容

DockerFileのランタイムをnode:20からnode:20-slimに変更

FROM public.ecr.aws/docker/library/node:20-slim

結果

アクセスできた!

[FastMCP info] server is running on HTTP Stream at http://localhost:8000/mcp
[FastMCP info] Transport type: httpStream (Streamable HTTP, not SSE)

エラー原因

原因

node:20-slimは複雑なエントリーポイントスクリプトを持たない軽量化されたものなので、こちらの選択する必要があった。
これからはLWAのGithubのexampleをもとに決めるようにしたい。
https://github.com/awslabs/aws-lambda-web-adapter?tab=readme-ov-file#examples

エラー②

MCP InSpectorでツールでテスト実行

Connectエラー。HistoryのResponseから、サーバー情報がweatherであることは確認できるからURLへアクセスはできていそう。

エラー内容

/mcpなしのルートパスで実行

endpointがないらしい(404エラー)

Query parameters: {"url":"https://***.lambda-url.ap-northeast-1.on.aws","transportType":"streamable-http"}
Created StreamableHttp client transport
Client <-> Proxy  sessionId: ***
Error accessing endpoint (HTTP 404)

/mcpありのルートパスで実行

以下のないよ応を行けているが、404エラー。

  1. セッション確立に成功(Client↔Proxy↔Server)
  2. MCPメッセージの送受信を試行(POST/GETメッセージ)
    • POST message: MCPプロトコルの初期化メッセージをサーバーに送信
    • 複数のPOST: 初回が失敗したため再試行
    • GET message: SSE(Server-Sent Events)ストリームの確立を試行
  3. 404エラー
Query parameters: {"url":"https://***.lambda-url.ap-northeast-1.on.aws/mcp","transportType":"streamable-http"}
Created StreamableHttp client transport
Client <-> Proxy  sessionId: ***
Proxy  <-> Server sessionId: ***
Received POST message for sessionId ***
Received POST message for sessionId ***
Received GET message for sessionId ***
Error accessing endpoint (HTTP 404)

エラー内容を受けて

エンドポイントが正しく設定されていない?

解決方法

変更内容

MCPサーバー(server.ts)にhostを追加。

server.start({
  transportType: "httpStream",
  httpStream: {
    port: 8000,
    host: "0.0.0.0", //追加
  },
});

結果

tool呼び出しできた!
]

エラー原因理由

外部クライアント → Lambda URL → Lambda Handler → MCPサーバー(localhost:8000)
                                      ↓
                                  内部HTTPリクエスト
                                      ↓
                                  localhost のみ受付 → 404エラー
  • MCPサーバーがlocalhostのみでリッスン

ローカル以外からもリッスンできるようにしたい

# localhost:8000 でリッスン
netstat -ln | grep 8000
tcp 127.0.0.1:8000  # ← ローカルのみ

# 0.0.0.0:8000 でリッスン  
netstat -ln | grep 8000
tcp 0.0.0.0:8000    # ← すべてのインターフェース

修正後:

外部クライアント → Lambda URL → Lambda Handler → MCPサーバー(0.0.0.0:8000)
                                      ↓
                                  内部HTTPリクエスト ✅
                                      ↓
                                  正常に受信・処理

参考

Discussion