0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

[MCP] aws lambdaをMCPを介してlangchainで扱う

Last updated at Posted at 2025-08-09

はじめに

本記事はaws lambdaで作成した関数をMCPを介してlangchainで使用するまでの流れを説明します。
尚、本記事では後続で説明する全体像に沿って行います。そのため各種ライブラリの細かい部分については触れていないのでお気を付けください。

全体像

使用するライブラリ

  • AWS Lambda MCP Serverlambda - MCP Client間のブリッジとして働きます。)
  • langchain_mcp_adaptersMCP形式をlangchainのToolに変換します。)

フロー図

langchain_mcp_adaptersはClient初期化時にConfiguration-Based Clientを扱うことに注意します。
コードイメージは次のようになります(READMEから抜粋)。

from langchain_mcp_adapters.client import MultiServerMCPClient
from langgraph.prebuilt import create_react_agent

client = MultiServerMCPClient(
    {
        "math": {
            "command": "python",
            # Make sure to update to the full absolute path to your math_server.py file
            "args": ["/path/to/math_server.py"],
            "transport": "stdio",
        },
        "weather": {
            # Make sure you start your weather server on port 8000
            "url": "http://localhost:8000/mcp/",
            "transport": "streamable_http",
        }
    }
)
tools = await client.get_tools()
agent = create_react_agent("openai:gpt-4.1", tools)
math_response = await agent.ainvoke({"messages": "what's (3 + 5) x 12?"})
weather_response = await agent.ainvoke({"messages": "what is the weather in nyc?"})

構築手順

構築は次の手順で行っていきます。

  1. Lambda関数の作成
  2. MCP2Lambdaを使用してLambda関数を読み込む(Configの作成)
  3. langchain_mcp_adaptersMCP ToolLangchain Toolに変換
  4. Langchain llmbindして使用。

手順1: Lambda関数の作成

Lambda関数を作成します。
注意として関数の説明がToolの説明になるので明確で分かりやすい説明を作成します。
それ以外のVPCの設定などは適宜ご自身の環境に合わせてセットしてください。

私は次のようなDummyの関数を作成しました。

import json

def lambda_handler(event, context):
    """
    TEST
    """    
    response_message = "Hello from your dummy Lambda!"
    
    return {
        'statusCode': 200,
        'body': response_message
    }

手順2: MCP2Lambdaを使用してLambda関数を読み込む(Configの作成)

MCP2Lambdaを使用してLambda関数を読み込みます。(Configuration-Based Clientを作成)

MCP2Lambdaのドキュメントに書いてある通り、uvxdockerコマンドもサポートされています。
本記事ではdockerコマンドを使用します。

別の方法でpythonスクリプトとして起動することもできます。(そちらは後半の開発時の注意点にて)

configの作成

configは次のようになります。ご自身の環境に合わせて作成お願いします。

{
    "your-server-name": {
        "command": "docker",
        "args": [
            "run",
            "--rm",
            "--interactive",
            "--volume",
            "mount-your-.aws-path", # 例: /mnt/c/Users/user/.aws:/app/.aws:ro
            "--env",
            "AWS_REGION=ap-northeast-1",
            "--env",
            "AWS_PROFILE=default",
            "awslabs/lambda-tool-mcp-server:latest",
            ],
            }
            }

設定できるパラメーターについてはドキュメントを確認してください。

私の環境だけかもしれませんが、awslabs/lambda-tool-mcp-server:latestなんかどこにも無いよというエラーが出されました。
その場合はgitレポcloneしてlambda_tool_mcp_serverbuildしてください。

手順3: langchain_mcp_adaptersMCP ToolLangchain Toolに変換

先ほど作成したconfiglangchain_mcp_adaptersで使用して、Configuration-Based Clientを作成。
get_tools()Langchain Toolに変換します。

正常に動くと、Lambda関数名が取得できます。
またコード中のtoolsは既にlangchainのtool形式になっているため、そのままlangchainにて使用可能です。

import asyncio
from langchain_mcp_adapters.client import MultiServerMCPClient

async def main():
    client = MultiServerMCPClient(
        # ここにconfigを入れる。
    )

    tools = await client.get_tools()
    for t in tools:
        print(t.name)

if __name__ == "__main__":
    asyncio.run(main())

手順4: Langchain llmbindして使用。

手順3まででlangchainで使用することのできるToolが完成しているので、あとは通常通り使用することができます。
完成した例を下記に示します。

import asyncio
import os
from dotenv import load_dotenv
load_dotenv()
from langchain_mcp_adapters.client import MultiServerMCPClient
from langchain_openai import ChatOpenAI

llm = ChatOpenAI(name="gpt-4.1-mini")

async def main():
    client = MultiServerMCPClient(
        # ここにconfig
    )

    tools = await client.get_tools()
    
    print("Tools found:")
    for t in tools:
        print(f"- {t.name}")
    
    print(tools[0])
    
    print("LLM response")
    llm_with_tools = llm.bind_tools(tools)

    response = llm_with_tools.invoke("あなたはどのようなtoolを使用可能ですか?名前を教えてください。")
    print(response.content)

if __name__ == "__main__":    
    asyncio.run(main())

開発時の注意点

最後に本開発時の注意点として2点記載します。

MCP Inspectorを使おう

先ほどの手順ではConfigを作成したのちにすぐにlamgchainに統合しました。
しかしこれでは作成したConfigが正しいかどうかを確認できません。

そこで開発時にはMCP Inspectorを使用して動作確認を行ってからlangchainもしくは別のMCP Hostに統合しましょう。

方法については以下の記事を参考に進めることでスムーズに進められます。

MCP2Lambdaのバグを認識する

これは別に本件に限らずですが、外部で作成されたMCP関連のツールを使用する際には必ず中身を確認しなければなりません。

有名な話ではプロンプトインジェクション攻撃が組み込まれている可能性があります。

また、MCP2Lambdaawslabsが作成したものですが、そもそもMCP自体が比較的新しい技術でありこのツール自体にもいくつかのバグは残ってしまっている状態です。

少なくとも私が見つけた致命的なバグはlist_tools()を行った際に50件までしか取得できない。要するにページネーションの仕組みが抜け落ちてしまっていたことです。

これは3ヶ月ほどまえにissueとして登録されていましたが、issueの発行者が音信不通になってしまいClosedになっています。

恐らく他の使用者は小規模で扱う方が多いため、このバグは認識されにくいものになってると思われます。

この部分の対処法としてはgit cloneして、対象のfileを直し、Configcommandをpythonスクリプト実行のものに変更してください。

uvの場合の例を下記に示します。

import asyncio
import os
from dotenv import load_dotenv
load_dotenv()
from langchain_mcp_adapters.client import MultiServerMCPClient
from langchain_openai import ChatOpenAI

llm = ChatOpenAI(name="gpt-4.1-mini")

async def main():
    client = MultiServerMCPClient(
        {
            "mcp-server": {
                # commandを'uv'に変更
                "command": "uv",
                
                # argsを、uv runで直接スクリプトを実行する形に変更
                "args": [
                    "run",
                    # サーバーのメインスクリプトへのパスを指定
                    "./lambda_tool_mcp_server/server.py"
                ],
                
                # envは前回と同じ
                "env": {
                    "AWS_REGION": "ap-northeast-1",
                    "AWS_PROFILE": "default",
                },                           
                "transport": "stdio"
            }
        }
    )

    print("Fetching tools using uvx...")
    tools = await client.get_tools()
    
    print("Tools found:")
    for t in tools:
        print(f"- {t.name}")
    
    print(tools[0])
    
    print("LLM")
    llm_with_tools = llm.bind_tools(tools)

    response = llm_with_tools.invoke("あなたはどのようなtoolを使用可能ですか?名前を教えてください。")
    print(response.content)

if __name__ == "__main__":    
    asyncio.run(main())
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?