AWS 기술 블로그

Amazon Bedrock AgentCore Gateway: 엔터프라이즈 AI 에이전트를 위한 통합 도구 관리 솔루션

1. 도입

생성형 AI 기술의 발전과 함께 AI 에이전트는 단순한 질의응답을 넘어 실제 업무를 수행하는 핵심 시스템으로 자리잡고 있습니다. 많은 기업들이 AI 에이전트를 활용하여 고객 서비스를 자동화하고, 내부 업무 프로세스를 개선하며, 직원들의 생산성을 높이고 있습니다.
하지만 AI 에이전트가 실제 업무를 수행하려면 외부 시스템과 연결되어야 합니다. 캘린더를 조회하고, 데이터베이스를 검색하며, API를 호출하고, 이메일을 발송하는 등의 작업을 위해서는 다양한 도구(Tool)가 필요합니다. 결국 AI 에이전트의 실질적인 가치는 얼마나 많은 도구에 접근하고 활용할 수 있느냐에 달려 있습니다.

기존 AI 에이전트의 동작 구조

AI 에이전트는 사용자의 질의를 받으면 목표를 설정하고, 답변에 필요한 도구를 선택하여 실행합니다. 예를 들어 “다음 주 팀 미팅 일정을 잡고 참석자들에게 알려줘”라는 요청을 받으면, Calendar API로 가능한 시간을 확인하고, 참석자 정보를 조회한 후, Email이나 Slack API로 초대장을 발송하며, 회의실 예약 시스템과 연동하여 장소를 확보합니다.

AI 에이전트의 도구 관리 복잡성 증가

초기의 단순한 구조에서 엔터프라이즈 환경으로 확장되면서, AI 에이전트의 도구 관리가 급격히 복잡해졌습니다. 에이전트는 각 도구의 API 방식, 인증 방법, 호출 규칙을 모두 이해해야 합니다. 새로운 도구를 추가할 때마다 에이전트 코드를 수정해야 하므로 확장성과 유지보수성이 떨어집니다. N개의 에이전트와 M개의 도구가 연결되면서 복잡성이 N×M으로 기하급수적으로 증가하고, 규모가 커질수록 관리가 불가능한 상태에 빠지게 됩니다.

이런 복잡성을 줄이기 위해 MCP(Model Context Protocol)A2A(Agent2Agent)와 같은 표준 프로토콜이 등장했습니다. MCP 동작 과정은 아래와 같습니다.

  1. 사용자로 부터 질문 쿼리를 받으면, 에이전트가 사용자의 질문에 답변하기 위해, 사용 가능한 도구 목록을 요청하게 됩니다.
  2. 이 요청은 MCP 클라이언트를 통해 전달되고, 연결되어 있는 각각의 MCP 서버가 가지고 있는 도구 정보들을 전달해줍니다
  3. 도구 목록을 전달받은 에이전트는 사용할 도구의 이름과 매개변수를 선택해서 다시 MCP 서버로 요청하게 됩니다.
  4. MCP 서버는 해당 요청을 받아 실제 외부 API를 실행합니다.
  5. MCP 서버에서 실행된 결과값은 MCP 클라이언트를 통해 전달됩니다.

이와 같은 구조를 통해 에이전트는 이제 각 도구의 API를 개별적으로 알 필요 없이, list_tools()call_tool()이라는 공통 인터페이스를 통해 모든 도구와 상호작용할 수 있게 되었습니다.

하지만 프로토콜 표준화만으로는 실질적인 운영 문제를 모두 해결할 수 없습니다. 엔터프라이즈 환경에서는 여전히 MCP 서버를 직접 구축하고, 기존 API 스펙을 변환하며, 인프라를 관리해야 합니다. 여러 MCP 서버를 사용한다면, MCP 클라이언트가 MCP 서버와 통신하기 위해 각 엔드포인트를 관리하고 인증을 처리해야 하는 부담이 있습니다. 수백 개의 에이전트와 수천 개의 도구를 운영하는 기업에게는 보안, 확장성, 관리 용이성을 모두 갖춘 솔루션이 필요합니다.

Amazon Bedrock AgentCore Gateway는 바로 이러한 과제를 해결하기 위해 설계된 서비스입니다.

2. Amazon Bedrock AgentCore Gateway 의 주요 기능

Amazon Bedrock AgentCore Gateway는 엔터프라이즈 환경에서 AI 에이전트의 도구 관리 복잡성을 해결하는 완전 관리형 서비스입니다. Gateway는 중앙 집중식 허브로서, 에이전트가 수많은 도구를 검색하고, 액세스하고, 호출할 수 있는 통합 인터페이스를 제공합니다.

기존에는 MCP Client가 각 MCP 서버의 엔드포인트를 개별적으로 관리해야 했습니다. 하지만 AgentCore Gateway를 사용하면, 여러 환경에 분산된 도구들과 MCP 서버들을 중앙에서 통합 관리하기 때문에, 단일 엔드포인트만 알고 있으면 내부에 연결된 모든 도구에 접근할 수 있습니다. 인증, 권한, 라우팅은 Gateway가 처리하므로, 에이전트는 각 도구별 인증을 관리할 필요가 없어집니다. 게다가 서버리스로 자동 확장되기 때문에 운영 부담도 최소화됩니다.

용어 정리

  • Amazon Bedrock AgentCore Gateway: 고객이 표준 MCP 작업(예: listTools 및 invokeTool)을 실행하기 위해 MCP 클라이언트를 통해 호출할 수 있는 HTTP 엔드포인트입니다. 고객은 boto3와 같은 AWS SDK를 사용하여 이 AmazonCore Gateway를 호출할 수도 있습니다.
  • Bedrock AgentCore Gateway Target: 고객이 AmazonCore Gateway에 Target을 연결하는 데 사용하는 리소스입니다. 현재 AgentCore Gateway의 Target으로 지원되는 유형은 다음과 같습니다.
    • MCP Server
    • Lambda ARN
    • API 사양 (OpenAPI, Smithy)
    • 빌트인 템플릿 도구
  • MCP Transport: 클라이언트(LLM을 사용하는 애플리케이션)와 MCP 서버 간의 메시지 이동 방식을 정의하는 메커니즘입니다. 현재 AgentCore Gateway는 Streamable HTTP 연결만 전송으로 지원합니다.

주요 기능

기존 REST API와 AWS Lambda 함수를 MCP 도구로 자동 변환

Amazon Bedrock AgentCore Gateway의 핵심 기능은 기존에 사용하던 API 서비스와 AWS Lambda 함수를 자동으로 MCP 호환 도구로 변환하는 것입니다. 인프라나 호스팅 관리 없이, OpenAPI 사양이나 Smithy 모델을 적용하거나 AWS Lambda 함수를 등록하기만 하면, Gateway가 모든 도구에 대해 표준화된 MCP 인터페이스를 자동으로 제공합니다. 이를 통해 개발자는 복잡한 변환 작업 없이 핵심적인 에이전트 구현에 집중할 수 있게 돕니다.

통합 인터페이스 제공

Amazon Bedrock AgentCore Gateway는 여러 MCP 서버와 도구 집합을 하나의 통합 인터페이스로 결합합니다. MCP Client와 MCP Server가 1:1 관계였던 것과 달리, 이제 MCP Client는 AgentCore Gateway의 단일 endpoint만 알고 있으면 됩니다. 이로 인해 에이전트가 도구를 사용하기 위한 연결 구조가 단순화되고, 운영 복잡성이 크게 줄어듭니다. Gateway는 현재 MCP의 Streamable HTTP 전송 연결을 지원합니다.

엔터프라이즈 보안 및 인증 지원

Amazon Bedrock AgentCore Gateway는 포괄적인 보안 모델을 지원합니다. 이중 인증 모델을 통해 수신 요청과 Target 리소스에 대한 안전한 액세스 제어를 보장합니다. Inbound Auth는 Gateway에 액세스하려는 사용자의 유효성을 검증하고, Outbound Auth는 Gateway가 인증된 사용자를 대신하여 백엔드 리소스에 안전하게 연결할 수 있도록 합니다. IAM 자격 증명과 OAuth 기반 인증 흐름을 모두 지원하여, 사용자와 Target 리소스 간에 안전한 브리지를 구축합니다.

시맨틱 도구 검색

Gateway 생성 시 해당 기능을 활성화하면, 자연어 쿼리를 통해 지능적으로 도구를 검색하는 built-in 도구가 자동으로 서버리스 프로비저닝됩니다. 자동으로 도구를 인덱싱하고, 수천 개의 도구 중에서 특정 컨텍스트에 가장 적합한 도구를 검색함으로써, 프롬프트 크기를 최소화하고 지연 시간을 줄이면서 에이전트가 효과적으로 도구를 활용할 수 있습니다. 또한 사용자 질문의 맥락을 이해가 도구 검색을 하기 때문에, 더 정확한 도구 선택을 통한 전반적인 성능을 개선할 수 있습니다. 이는 도구가 많고 사용 사례에 가장 적합한 도구를 찾아야 할 때 특히 유용합니다.

3. Amazon Bedrock AgentCore Gateway를 활용한 도구 호출

Gateway와 Target을 설정하고 도구를 등록했다면, 이제 이를 통해 실제 도구 호출을 수행할 수 있습니다. Agent framework나 MCP Inspector, MCP 클라이언트가 있는 애플리케이션에, 해당 gateway를 MCP 서버로 등록해서 사용할 수 있습니다. 그럼 통합된 MCP 인터페이스를 통해, 구성된 모든 도구들에 액세스 하게 됩니다.

Gateway가 생성되면 단일 엔드포인트가 제공되는데, 이 엔드포인트 URL의 경로를 확인하면 /mcp로 끝나는 것을 볼 수 있습니다. 이는 해당 Gateway가 MCP 서버로써 동작한다는 의미입니다. AgentCore Gateway는 MCP에서 핵심적으로 사용하는 아래 두 가지 표준 MCP 작업을 그대로 노출합니다. MCP 프로토콜에서 사용하는 인터페이스 패턴은 MCP 공식 문서에서 확인할 수 있습니다.

  • tools/list : 사용 가능한 도구 목록 확인
{
  "jsonrpc": "2.0",
  "method": "tools/list",
  "id": 1
}
  • tools/call : 특정 도구를 호출
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "tool_name",
    "arguments": {
      // 도구별 필요한 파라미터
    }
  },
  "id": 2
}

MCP 클라이언트는 일반적인 MCP 서버를 호출할 때와 동일하게, Gateway의 엔드포인트에 JSON-RPC 요청을 보내기만 하면 됩니다. Gateway가 표준 MCP 인터페이스를 제공하므로, 다음과 같은 이점을 얻을 수 있습니다.

  • 일관성: 서로 다른 Target에 연결된 도구들도 동일한 방식으로 호출할 수 있습니다.
  • 호환성: 기존 MCP 생태계와 완벽하게 호환됩니다.
  • 확장성: 새로운 도구를 추가해도 호출 패턴이 변하지 않아 시스템 확장이 용이합니다.

결과적으로 개발자는 복잡한 통합 로직 없이도 다양한 도구들을 일관된 방식으로 활용할 수 있으며, AWS 관리형 서비스의 안정성과 오픈 표준인 MCP의 유연성을 동시에 확보할 수 있습니다.

3.0. Amazon Bedrock Gateway의 MCP 서버 연결 확인하기

Amazon Bedrock AgentCore Gateway는 MCP 서버로써 동작하기에 일반적인 MCP 서버처럼 접근할 수 있습니다. 위 스크린샷은 MCP Inspector를 통해 Gateway에 연결된 것을 보여줍니다. MCP Inspector는 MCP 서버를 테스트하고 디버깅하기 위한 개발자 도구입니다. MCP 서버의 엔드포인트 URL과 Authentication 정보가 있으면, MCP 서버에 연결하여 제공되는 도구 목록들을 확인하고 실제로 도구 호출 및 응답을 확인할 수 있습니다.

MCP Inspector는 설치 없이 npx 를 통해 직접 실행할 수 있습니다.

npx @modelcontextprotocol/inspector node build/index.js

기본적으로 포트 6274에서 클라이언트 UI가 실행되고, 포트 6277에서 프록시 서버가 실행됩니다. 브라우저에서 http://localhost:6274 접속하면 인터랙티브 UI를 통해 서버 연결 상태 확인, 도구/리소스 목록 시각화, 실시간 테스트 및 결과 확인이 가능합니다. UI를 통해 빠르게 도구 목록을 확인하거나 MCP 서버에 대한 연결 디버깅이 필요한 경우 활용할 수 있습니다.

3.1. 도구 리스트 조회

Curl을 사용한 도구 리스트 조회

Curl을 사용해서 Gateway에 등록되어 있는 도구 목록을 받아올 수 있습니다.

curl -X POST \
  https://mygateway-id.gateway.bedrock-agentcore.us-west-2.amazonaws.com/mcp \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -d '{
    "jsonrpc": "2.0",
    "id": "list-tools-request",
    "method": "tools/list"
  }'

tools/list 호출은 페이지 단위로 처리되므로, 한 번의 호출로 전체 도구 목록을 받아오지 못할 수 있습니다. 그렇기 때문에 더 이상 페이지가 남지 않을 때 까지 여러 페이지의 도구를 가져오는 loop를 구현해야 합니다. 이를 위해 nextCursor 필드가 더 이상 채워지지 않을 때까지 한 페이지씩 도구를 가져옵니다. 실제 많은 MCP 서버에서는 여러 페이지의 도구를 가져오는 루프를 반복합니다.

HTTP 요청을 통한 도구 리스트 조회

Python의 requests 패키지를 활용하여 단순하게 구현하는 경우 아래와 같이 표현될 수 있습니다.

from mcp.client.streamable_http import streamablehttp_client 


def create_streamable_http_transport(mcp_url: str, access_token: str):
    return streamablehttp_client(mcp_url, headers={"Authorization": f"Bearer {access_token}"}) 
    
def get_all_tools_from_mcp_endpoint(gateway_endpoint, jwt_token, client):
    more_tools = True
    tools_count = 0
    tools_list = []

    requestBody = {"jsonrpc": "2.0", "id": 2, "method": "tools/list", "params": {}}
    next_cursor = ""

    while more_tools:
        if tools_count == 0:
            requestBody["params"] = {}
        else:
            print(f"\nGetting next page of tools since a next cursor was returned\n")
            requestBody["params"] = {"cursor": next_cursor}

        headers = {
            "Authorization": f"Bearer {jwt_token}",
            "Content-Type": "application/json",
        }

        print(f"\n\nListing tools for gateway {gateway_endpoint}")

        response = requests.post(gateway_endpoint, json=requestBody, headers=headers)

        tools_json = response.json()
        tools_count += len(tools_json["result"]["tools"])

        for tool in tools_json["result"]["tools"]:
            mcp_tool = MCPTool(
                name=tool["name"],
                description=tool["description"],
                inputSchema=tool["inputSchema"],
            )
            mcp_agent_tool = MCPAgentTool(mcp_tool, client)
            short_descr = tool["description"][0:40] + "..."
            print(f"adding tool '{mcp_agent_tool.tool_name}' - {short_descr}")
            tools_list.append(mcp_agent_tool)

        if "nextCursor" in tools_json["result"]:
            next_cursor = tools_json["result"]["nextCursor"]
            more_tools = True
        else:
            more_tools = False

    print(f"\nTotal tools found: {tools_count}\n")
    return tools_list

Strands Agents SDK를 활용한 도구 리스트 조회

Strands Agents SDK에서는 MCP 서버에서 사용 가능한 도구 집합을 반환하는 list_tools_sync() 함수를 제공합니다. 위와 같이 MCP endpoint에 일일이 요청하는 형태로 구현하지 않더라도 간단하게 전체 도구 집합을 받아올 수 있습니다.

from strands.tools.mcp.mcp_client import MCPClient 


def get_all_mcp_tools_from_mcp_client(client):
    more_tools = True
    tools = []
    pagination_token = None
    while more_tools:
        tmp_tools = client.list_tools_sync(pagination_token=pagination_token)
        tools.extend(tmp_tools)
        if tmp_tools.pagination_token is None:
            more_tools = False
        else:
            more_tools = True 
            pagination_token = tmp_tools.pagination_token
    return tools


mcp_client = MCPClient(
    lambda: create_streamable_http_transport(mcp_url, access_token)
)

with mcp_client:
    tools = get_all_mcp_tools_from_mcp_client(mcp_client)
    print(f"Found the following tools: {[tool.tool_name for tool in tools]}")

3.2. 도구 호출

Curl을 사용한 도구 호출

Curl을 사용해서 Gateway endpoint로 특정 도구를 호출할 수 있습니다. 아래는 searchProducts 도구를 호출한 예시입니다.

  • name : 도구 이름
  • arguments : 도구를 호출할 때 필요한 파라미터
curl -X POST \
  https://mygateway-id.gateway.bedrock-agentcore.us-west-2.amazonaws.com/mcp \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -d '{
    "jsonrpc": "2.0",
    "id": "invoke-tool-request",
    "method": "tools/call",
    "params": {
      "name": "searchProducts",
      "arguments": {
        "query": "wireless headphones",
        "category": "Electronics",
        "maxResults": 2,
        "priceRange": {
          "min": 50.00,
          "max": 200.00
        }
      }
    }
}'

HTTP 요청을 통한 도구 호출

유사한 방법으로 Python의 requests 패키지를 활용해 도구 호출에 대한 응답을 얻을 수 있습니다.

import requests
import json

gateway_url = "https://${GatewayEndpoint}/mcp"
headers = {
    "Content-Type": "application/json",
    "Authorization": "Bearer ${AccessToken}"
}

tool_name = "{TargetId}__{ToolName}"
arguments = {
    "arg1": "argument_value1"
}

payload = {
    "jsonrpc": "2.0",
    "id": "call-tool-request",
    "method": "tools/call",
    "params": {
        "name": tool_name,
        "arguments": arguments
    }
}
  
response = requests.post(gateway_url, headers=headers, json=payload)
print(json.dumps(response.json(), indent=2))

Strands Agents SDK를 활용한 도구 호출

from strands.tools.mcp.mcp_client import MCPClient
from mcp.client.streamable_http import streamablehttp_client


mcp_url = {gatewayUrl}
access_token = {AccessToken}

def create_streamable_http_transport(mcp_url: str, access_token: str):
    return streamablehttp_client(mcp_url, headers={"Authorization": f"Bearer {access_token}"})

mcp_client = MCPClient(lambda: create_streamable_http_transport(mcp_url, access_token))

with mcp_client:
    result = mcp_client.call_tool_sync(
        tool_use_id="tool-123",  # 도구 호출을 위한 unique ID
        name="openapi-target-1___get_orders",  # 호출하고자 하는 도구의 이름
        arguments={}  # 호출하고자 하는 도구의 arguments
    )
    print(result)

또는 Strands Agents의 에이전트 Event Loop를 우회하여 MCP 도구를 직접 호출할 수도 있습니다. agent.tool.<tool_name>(args) 구문을 사용하여 Gateway에 등록된 MCP 도구를 호출할 수 있습니다. 예를 들어, Calc2___add_numbers 라는 도구를 호출하는 경우 아래와 같이 작성할 수 있습니다.

direct_result = simple_agent.tool.Calc2___add_numbers(firstNumber=10, secondNumber=20)

전체 코드 예시는 아래와 같습니다.

from strands import Agent
from strands.models import BedrockModel
from strands.handlers import null_callback_handler
from strands.tools.mcp.mcp_client import MCPClient


client = MCPClient(
    lambda: streamablehttp_client(
        f"{gatewayEndpoint}", headers={"Authorization": f"Bearer {jwtToken}"}
    )
)

bedrockmodel = BedrockModel(
    model_id="us.anthropic.claude-3-7-sonnet-20250219-v1:0",
    temperature=0.7,
    streaming=True,
    boto_session=session,
)

with client:
    all_tools = get_all_mcp_tools_from_mcp_client(client)
    print(f"\nFound {len(all_tools)} tools from list_tools_sync() on mcp client\n")

    simple_agent = Agent(
        model=bedrockmodel,
        tools=all_tools,
        callback_handler=null_callback_handler
    )
    
    direct_result = simple_agent.tool.Calc2___add_numbers(
        firstNumber=10, secondNumber=20
    )
    
    resp_json = json.loads(direct_result["content"][0]["text"])
    search_results = resp_json["tools"]
    
    print(f"result = {search_results}")

이 외에도 MCP Python SDK, LangGraph, Strands Agents 등 MCP Client를 지원하는 SDK들을 활용할 수 있습니다. 관련된 코드 스니펫은 공식 문서에서 확인할 수 있습니다.

4. Amazon Bedrock AgentCore Gateway의 시맨틱 검색

실제 엔터프라이즈 환경에서는 각 Target에 수백 개의 도구가 있을 수 있고, Gateway를 통해 여러 Target을 연결하면 결과적으로 수백 또는 수천 개의 도구가 존재하게 됩니다. 여기서 일반적인 MCP 도구 목록 호출(tools/list)을 사용하면 모든 도구가 반환되어 에이전트의 프롬프트에 모든 도구 정보가 포함됩니다. 이는 토큰 사용량과 지연시간을 급격히 증가시킬 뿐만 아니라, 과도한 도구 메타데이터로 인해 에이전트의 도구 선택 정확도까지 저하시킵니다.

Gateway는 이 문제를 해결하기 위해 x_amz_bedrock_agentcore_search라는 내장 도구를 자동으로 서버리스 프로비저닝합니다. 이 도구를 사용하면 자연어 쿼리를 통해 지능적으로 필요한 도구만 검색할 수 있습니다. 예를 들어 Zendesk, Salesforce, Slack, JIRA 같은 타사 서비스나 기존 엔터프라이즈 REST 서비스에 연결했을 때, 사용자 질문의 맥락을 이해해서 정말 필요한 도구만 선별적으로 제공하는 것이죠. 이를 통해 프롬프트 크기를 최소화하고, 더 정확한 도구 선택으로 에이전트의 전반적인 성능을 개선할 수 있습니다.

Gateway 생성 시 시맨틱 검색을 활성화했다면, Gateway의 MCP 엔드포인트에 tools/call 메서드로 POST 요청을 보내 자연어 쿼리로 도구를 검색할 수 있습니다. 결과적으로 AgentCore Gateway는 확장 가능하고 고성능의 도구 검색 환경을 제공하면서, 에이전트의 지연 시간과 비용, 정확성을 동시에 개선합니다.

4.1. 시맨틱 검색 기능 활성화

AgentCore Gateway를 생성할 때 Semantic search 검색 옵션을 활성화 하여 built-in 도구를 프로비저닝 할 수 있습니다.

코드를 사용하여 AgentCore Gateway를 생성하는 경우, 아래 코드와 같이 search_config 를 정의하여 시맨팀 검색 기능을 사용할 수 있습니다.

def create_gateway(gateway_name, gateway_desc):
    # Enable semantic search of tools
    search_config = {
        "mcp": {"searchType": "SEMANTIC", "supportedVersions": ["2025-03-26"]}
    }
    
    # Create the gateway
    response = agentcore_client.create_gateway(
        name=gateway_name,
        roleArn=gateway_role_arn,
        authorizerType="CUSTOM_JWT",
        description=gateway_desc,
        protocolType="MCP",
        authorizerConfiguration={
            "customJWTAuthorizer": {
                "allowedClients": [cognito_response["client_id"]],
                "discoveryUrl": cognito_response["discovery_url"],
            }
        },
        protocolConfiguration=search_config,
    )

    return response["gatewayId"]

시맨틱 검색 기능을 활성화 하면, Gateway에 등록된 도구에 x_amz_bedrock_agentcore_search 가 자동으로 생성된 것을 확인할 수 있습니다.


생성된 x_amz_bedrock_agentcore_search 의 스키마는 아래와 같습니다.

{
  "name": "x_amz_bedrock_agentcore_search",
  "description": "A special tool that returns a trimmed down list of tools given a context. Use this tool only when there are many tools available and you want to get a subset that matches the provided context.",
  "inputSchema": {
    "type": "object",
    "properties": {
      "query": {
        "type": "string",
        "description": "search query to use for finding tools"
      }
    },
    "required": ["query"]
  }
}

4.2. 시맨틱 검색 기능 사용

x_amz_bedrock_agentcore_search 도구에 사용자의 질의에 해당되는 query 값을 입력하게 되면 가장 연관성이 높은 도구들을 검색하여 오름차순으로 반환합니다. 아래의 이미지는 “분석을 위한 도구”라고 검색했을 때, 가지고 있는 도구 중 가장 연관도가 높은 CalcTools_analyze_time_series 도구를 가장 우선순위 높게 찾아낸 것을 확인할 수 있습니다.

프로비저닝 된 빌트인 도구도 MCP 도구로써 접근할 수 있기에, tools/call 메서드를 사용하여 x_amz_bedrock_agentcore_search 도구를 호출할 수 있습니다.

HTTP 요청을 통한 시맨틱 도구 검색

import requests


# Gateway의 시맨틱 검색 도구를 직접 호출
def tool_search(gateway_endpoint, jwt_token, query):
    response = requests.post(
        gateway_endpoint,
        headers={
            "Authorization": f"Bearer {jwt_token}",
            "Content-Type": "application/json",
        },
        json={
            "jsonrpc": "2.0",
            "id": 2,
            "method": "tools/call",
            "params": {
                "name": "x_amz_bedrock_agentcore_search",
                "arguments": {"query": query},
            },
        },
    )

    toolResp = response.json()
    tools = toolResp["result"]["structuredContent"]["tools"]
    return tools


# 시맨틱 검색 도구 호출 결과
tools_found = tool_search(
    gateway_endpoint=gatewayEndpoint,
    jwt_token=jwtToken,
    query="find me 3 credit research tools"
)

print(f"Top tool found: {tools_found[0]['name']}")

Strands Agents의 시맨틱 도구 검색 활용 방법

from strands import Agent
from strands.tools.mcp.mcp_client import MCPClient, MCPAgentTool

from mcp.client.streamable_http import streamablehttp_client
from mcp.types import Tool as MCPTool


# MCP 도구를 Strands Agent 도구로 변환
def tools_to_strands_mcp_tools(tools, top_n):
    strands_mcp_tools = []
    for tool in tools[:top_n]:
        mcp_tool = MCPTool(
            name=tool["name"],
            description=tool["description"],
            inputSchema=tool["inputSchema"],
        )
        strands_mcp_tools.append(MCPAgentTool(mcp_tool, client))
    return strands_mcp_tools


client = MCPClient(
    lambda: streamablehttp_client(
        f"{gatewayEndpoint}", headers={"Authorization": f"Bearer {jwtToken}"}
    )
)

with client:
    # 시맨틱 도구 검색을 이용해 적합한 도구 검색
    tools_found = tool_search(
        gateway_endpoint=gatewayEndpoint,
        jwt_token=jwtToken,
        query="tools for doing addition, subtraction, multiplication, division",
    )

    # 검색한 도구를 활용한 에이전트 정의
    agent = Agent(
        tools=tools_to_strands_mcp_tools(
            tools_found,
            5,
        ),
    )

    # 에이전트 질의
    result = agent("(10*2)/(5-3)")
    print(f"{result.message['content'][0]['text']}")

5. Amazon Bedrock AgentCore Gateway의 보안 액세스

AgentCore Gateway의 보안은 크게 두 가지 방향으로 나뉩니다. 게이트웨이로 들어오는 Inbound 액세스와, Target 서비스로 나가는 Outbound 연결에 대한 보안입니다.

Inbound Auth

Inbound Auth는 MCP 클라이언트로부터 들어오는 요청을 검증합니다. Gateway는 MCP 인증 사양을 따르며 OAuth 기반 인증을 사용해 들어오는 도구 호출을 검증하고 승인합니다. 악의적인 트래픽은 OAuth 리소스 서버로 동작하는 Gateway를 통해 이 단계에서 차단될 수 있습니다. Amazon Cognito, Okta, Auth0 같은 다양한 ID 공급자와 연동할 수 있으며, 클라이언트 ID와 Target을 지정해서 특정 애플리케이션만 에이전트가 도구에 접근하도록 세밀하게 제어할 수 있습니다.

Outbound Auth

Outbound Auth는 MCP 서버가 외부 API나 서비스에 액세스 할 때 사용합니다. 아웃바운드 보안 모델은 Target에 따라 다릅니다.

  • AWS Lambda / Smithy 모델 Target: IAM 기반 인증을 사용해, 각 Target 별로 최소 권한 원칙을 적용할 수 있습니다.
  • OpenAPI Target: 아래 두 가지 인증 방법을 지원합니다.
    • API 키: 사용자 정의 가능한 매개 변수 이름으로 header 또는 query parameter로 보낼 키를 구성할 수 있습니다.
    • 2LO용 OAuth 토큰: OAuth(2LO) 토큰 인증 방식을 통해 사용자 상호 작용 없이 안전한 M2M 통신을 안전하게 처리할 수 있습니다.

이 모든 자격 증명은 AgentCore Identity를 통해 안전하게 관리됩니다. 개발자가 직접 복잡한 보안 로직을 다루지 않아도, 한 번 설정만 해두면 Gateway가 알아서 토큰 유효성 검증, 아웃바운드 토큰 캐싱, 보안 통신 처리를 담당합니다.

권한 부여 흐름

권한 부여 단계 flow를 보면 다음과 같습니다.

1. 워크로드 아이덴티티 획득

AgentCore Gateway가 초기화될 때, AgentCore Identity 서비스는 해당 게이트웨이 대해 워크로드 아이덴티티(Workload Identity)를 자동으로 생성합니다. 이 아이덴티티는 이후 모든 인증/권한 관련 흐름에서 식별자로 사용됩니다.

2. 인바운드 OAuth2 토큰 인증 및 권한 검증

에이전트를 호출하는 클라이언트는 OAuth2 JWT(Bearer Token)를 포함한 요청을 보냅니다. 이 토큰은 Amazon Cognito, Okta, Auth0 등 OIDC/OAuth2 제공자에서 발급된 것으로, Gateway는 이를 다음과 같은 방식으로 처리합니다.

  • Discovery URL과 Allowed audience / client ID 정보를 기반으로 JWT 유효성을 확인하합니다.
  • 토큰의 aud, client_id 등의 클레임을 검증하여 요청자에게 요청할 권한이 있는지 판단합니다.

3. 워크로드 액세스 토큰 획득 (Workload Access Token)

인바운드 JWT가 유효하다면, 에이전트 런타임은 bedrock-agentcore:GetWorkloadAccessTokenForJWT API를 호출해 Workload Access Token을 얻습니다. 이는 에이전트가 인증된 상태임을 대표하는 단기 토큰입니다. 에이전트는 이 토큰을 WorkloadAccessToken 헤더를 통해 이후 요청에 활용합니다.

4. 워크로드 토큰 → 외부 엑세스 토큰(outbound token) 교환

에이전트가 외부 API나 서비스(예: Google Drive 등)를 호출해야 할 경우, Gateway는 Outbound Auth 구성을 통해 다음과 같은 흐름을 지원합니다.

  • 에이전트는 AgentCore Identity의 Token Vault에 저장된 자격 증명을 사용해 OAuth 토큰(2LO 또는 3LO)을 요청할 수 있습니다. 이때 requires_access_token 데코레이터 등을 통해 간편하게 토큰을 확보할 수 있습니다.
  • Gateway는 이전에 획득한 워크로드 토큰과 연동해 외부 API 호출을 위한 OAuth 액세스 토큰 또는 API 키 등을 안전하게 관리하고 전달합니다.

6. Amazon Bedrock AgentCore Gateway 생성 방법

Amazon Bedrock AgentCore Gateway를 생성하기 위한 방법으로는 콘솔, AgentCore starter toolkit, AWS CLI, Boto3 중 하나를 선택해 활용할 수 있습니다.

6.1. 인바운드 인증 구성

먼저 OAuth 인증을 위한 identity provider를 준비합니다.

# 인바운드 인증 구성
auth_config = {
    "customJWTAuthorizer": { 
        "discoveryUrl": cognito_discovery_url
        "allowedClients": [client_id],
    }
}

6.2. Gateway 생성

AWS 콘솔, SDK를 사용하여 MCP endpoint 역할을 할 게이트웨이를 생성합니다. 각 API 엔드포인트 또는 기능은 MCP 호환 도구가 되며 MCP 서버 URL을 통해 사용할 수 있습니다. 게이트웨이를 보호하기 위해 인바운드 인증을 사용하여 게이트웨이로의 입력을 제어할 수 있습니다. 여기에서 사용되는 IAM 역할은 Gateway를 생성/나열/가져오기/삭제할 권한이 있어야 합니다

AgentCore Starter toolkit (CLI)을 활용한 예시

agentcore create_mcp_gateway \
  --region us-west-2 \
  --name my-gateway \
  --role-arn arn:aws:iam::123456789012:role/my-gateway-service-role \
  --authorizer-config '{
      "customJWTAuthorizer": {
        "discoveryUrl": "https://cognito-idp.us-west-2.amazonaws.com/some-user-pool/.well-known/openid-configuration",
        "allowedClients": ["clientId"]
      }
    }' \
  --enable_semantic_search

AWS CLI를 활용한 예시

aws bedrock-agentcore-control create-gateway \
  --name my-gateway \
  --role-arn arn:aws:iam::123456789012:role/my-gateway-service-role \
  --protocol-type MCP \
  --authorizer-type CUSTOM_JWT \
  --authorizer-configuration '{
    "customJWTAuthorizer": {
      "discoveryUrl": "https://cognito-idp.us-west-2.amazonaws.com/some-user-pool/.well-known/openid-configuration",
      "allowedClients": ["clientId"]
    }
  }' \
  --protocol-configuration '{
    "mcp": {
        "searchType": "SEMANTIC"
    }
  }'

Boto3를 활용한 예시

import boto3

gateway_client = boto3.client('bedrock-agentcore-control')

# 게이트웨이 생성
create_response = gateway_client.create_gateway(
    name='my-gateway',
    roleArn = 'arn:aws:iam::123456789012:role/my-gateway-service-role',
    protocolType='MCP',
    authorizerType='CUSTOM_JWT',
    authorizerConfiguration=auth_config, 
    description='Test AgentCore Gateway'
)

gatewayID = create_response["gatewayId"]
gatewayURL = create_response["gatewayUrl"]

6.3. 아웃바운드 인증 구성

아웃바운드 인증을 위해 OAuth 토큰이나 API 키를 사용할 수 있습니다.

Boto3를 활용한 예시

# API Key
gateway_client.create_api_key_credential_provider(
    name="CustomAPIKey",
    apiKey="",
)

# OAuth
gateway_client.create_oauth2_credential_provider(
    name="CustomOAuthTokenCfg", 
    credentialProviderVendor="CustomOauth2", 
    oauth2ProviderConfigInput=provider_config
)

Amazon Bedrock AgentCore Control plane API 문서를 참고하여 자격 증명 공급자에 따라 request body를 채울 수 있습니다.

6.4. Gateway Target 생성 : 이름, 설명, API 사양

게이트웨이가 특정 도구로 라우팅 할 수 있도록 Target을 구성합니다. 게이트웨이에 연결될 Target을 생성하면 각 Target에서 정의한 도구들을 확인할 수 있습니다. 이 때 도구 이름은 Target 유형에 따라 달라집니다. MCP를 통해 표시되는 도구 이름은 ${target_name}__${tool_name}와 같은 형태로 구성 됩니다.

Target을 등록하기 위해서는 미리 준비해둔, 호스팅 중인 RESTful 서비스와 API 스펙 또는 AWS Lambda 함수와 JSON 스키마가 필요합니다. Target 별로 준비 및 구성되어야 하는 값들이 다르므로 아래 섹션 7에서 상세 설명을 확인할 수 있습니다.

Boto3를 활용한 예시

# Target 생성하기
response = gateway_client.create_gateway_target(
    gatewayIdentifier=gatewayID,
    name=targetName,
    description='Target using SDK',
    targetConfiguration=target_config,
    credentialProviderConfigurations=credential_config
)

7. Amazon Bedrock AgentCore Gateway 의 Target 유형

Target은 AmazonCore Gateway에 Target을 연결하는 데 사용하는 리소스입니다. 현재 AgentCore Gateway의 Target으로 지원되는 유형은 다음과 같습니다.

7.1. MCP server Target

MCP server Target은 로컬 도구, 데이터 접근, 또는 커스텀 함수를 제공하는 MCP 서버를 Gateway에 연결합니다. 사전 구성된 MCP 서버를 Gateway의 Target으로 정의하면, 에이전트가 발견하고 호출할 수 있는 도구로 사용할 수 있습니다. Gateway는 Target을 통해 도구를 연결하여 에이전트 런타임과 통합합니다.

7.2. REST API Target 생성

REST API Target은 OpenAPI 사양이나 Smithy 사양을 사용하여 정의된 REST API를 Gateway에 연결합니다. 기존에 구현되어 있는 API 서비스가 있고, 이것에 대응되는 OpenAPI나 Smithy 스펙이 있다면, MCP 도구로써 사용이 가능합니다. Gateway는 들어오는 MCP 요청을 이러한 API에 대한 HTTP 요청으로 변환하고 응답 서식을 처리합니다.

기존의 REST API를 Target으로 생성하기 위해서는 호스팅 되어 있는 REST API 서버와 OpenAPI Spec이 필요합니다. OpenAPI Spec은 S3에 업로드 되어있어야 하고, Target 생성 시에 해당 S3 경로를 지정해야 합니다.

Boto3를 활용한 예시

import boto3
  
agentcore_client = boto3.client('bedrock-agentcore-control')
  
target = agentcore_client.create_gateway_target(
    gatewayIdentifier="your-gateway-id",
    name="SearchAPITarget",
    targetConfiguration={
        "mcp": {
            "openApiSchema": {
                "s3": {
                    "uri": "s3://your-bucket/path/to/open-api-spec.json",
                    "bucketOwnerAccountId": "123456789012"
                }
            }
        }
    },
    credentialProviderConfigurations=[
        {
            "credentialProviderType": "API_KEY",
            "credentialProvider": {
                "apiKeyCredentialProvider": {
                    "providerArn": "arn:aws:agent-credential-provider:us-east-1:123456789012:token-vault/default/apikeycredentialprovider/abcdefghijk",
                    "credentialLocation": "HEADER",
                    "credentialParameterName": "X-API-Key"
                }
            }
        }
    ]
)

7.3. AWS Lambda Target 생성

AWS Lambda Target은 AWS Lambda 함수를 MCP 도구로 직접 사용할 수 있게 합니다. AWS Lambda 함수와 도구의 입출력 구조를 정의하는 JSON 스키마를 함께 정의하면, MCP 도구로 변환할 수 있습니다. AWS Lambda 를 Target으로 생성하는 경우, AWS Lambda ARN과 도구를 설명할 수 있는 JSON 스키마를 함께 등록합니다.

AgentCore Starter toolkit (CLI)을 활용한 예시

agentcore create_mcp_gateway_target \
  --gateway-arn arn:aws:bedrock-agentcore:us-east-1:123456789012:gateway/my-gateway \
  --gateway-url https://gateway-id.gateway.bedrock-agentcore.us-west-2.amazonaws.com/mcp \
  --role-arn arn:aws:iam::123456789012:role/AgentCoreGatewayExecutionRole \
  --target-type lambda

Boto3를 활용한 예시

lambda_target_config = {
    "mcp": {
        "lambda": {
            "lambdaArn": "${LAMBDA_ARN}",
            "toolSchema": {
                "inlinePayload": [
                    {
                        "name": "create_booking",
                        "description": "Create a new booking at restaurant_name",
                        "inputSchema": {
                            "type": "object",
                            "properties": {
                                "restaurant_name": {
                                    "type": "string",
                                    "description": "name of the restaurant handling the reservation"
                                },
                                "guest_name": {
                                    "type": "string",
                                    "description": "The name of the customer to have in the reservation"
                                },
                                "num_guests": {
                                    "type": "integer",
                                    "description": "The number of guests for the booking"
                                }
                            },
                            "required": ["restaurant_name", "guest_name", "num_guests"]
                        }
                    }
                ]
            }
        }
    }
}

response = gateway_client.create_gateway_target(
    gatewayIdentifier=gatewayID,
    name='LambdaUsingSDK',
    description='Lambda Target using SDK',
    targetConfiguration=lambda_target_config,
    credentialProviderConfigurations=[ 
        { "credentialProviderType" : "GATEWAY_IAM_ROLE" }
    ]
)

Target이 되는 AWS Lambda 함수 구현

Target이 되는 AWS Lambda 함수는 도구로 사용되기 위해 구현되어야 하는 규칙이 있습니다. lambda_handler 는 arguments로 eventcontext 객체를 받게 되는데, event 객체에는 MCP에서 AWS Lambda 입력으로 매핑된 요청 속성이 포함되어야 하고, context 객체에는 게이트웨이 ID, Target ID 및 도구 이름과 같은 유용한 정보가 포함됩니다.

  • context 객체

context 객체에는 Gateway ID, Target ID, 도구 이름 등 도구 호출에 필요한 정보들이 포함되어 있습니다. 이 정보들은 context.client_context.custom 딕셔너리를 통해 값을 받아올 수 있습니다.

def lambda_handler(event, context):
    toolName = context.client_context.custom['bedrockAgentCoreToolName']
    print(context.client_context)

AWS Lambda의 context custom 객체로 사용할 수 있는 값들은 아래와 같습니다.

  • bedrockAgentCoreEndpointId : 요청을 받은 Gateway 엔드포인트의 ID
  • bedrockAgentCoreTargetId : 요청을 함수로 라우팅한 Gateway Target의 ID
  • bedrockAgentCoreMessageVersion : 요청에 사용된 메시지 형식의 버전
  • bedrockAgentCoreToolName : 호출되는 도구의 이름
  • bedrockAgentCoreSessionId : 현재 호출의 세션 ID (동일 세션 내에서 여러 도구 호출을 연관시키는 데 사용)

예를 들어 context.client_context를 통해 들어오는 값을 보면 아래와 같이 구성되어 있습니다.

ClientContext([custom={
   'bedrockAgentCoreTargetId': 'Q1NLVBYUSY’,
   'bedrockAgentCoreGatewayId': 'testgwforlambda-zgnz79pxw2’,
   'bedrockAgentCoreMessageVersion': '1.0’,
   'bedrockAgentCoreToolName': 'LambdaUsingSDK___get_order_tool'
},env=None,client=None])
  • event 객체

event 객체는 Target으로 등록하기 위해 정의한 inputSchema와 일치해야 합니다. 예를 들어 위에서 정의된 도구 스키마를 사용하는 경우, AWS Lambda 함수는 아래와 같이 작성할 수 있습니다.

def handle_create_booking(event):
    restaurantName = event["restaurant_name"]
    guestName = event["guest_name"]
    numGuests = int(event["num_guests"])
    return {
        "statusCode": 200,
        "body": f"Booking id 12345, for {numGuests} guests at {restaurantName} for {guestName} created."
    }


def lambda_handler(event, context):
    print(f"event: {event}")
    print(f"context: {context}")
    print(f"context.client_context: {context.client_context}")

    toolName = context.client_context.custom["bedrockAgentCoreToolName"]
    print(f"Original toolName: , {toolName}")
    
    delimiter = "___"
    if delimiter in toolName:
        toolName = toolName[toolName.index(delimiter) + len(delimiter):]

    print(f"toolName: {toolName}")

    if toolName == "create_booking":
        result = handle_create_booking(event)
    else:
        result = f"Unrecognized toolName: {toolName}"

    return result

이와 같은 구조를 통해 AWS Lambda 함수 코드에서 어떤 도구가 호출 되는지 확인하고, 그에 따라 함수의 동작을 사용자 정의할 수 있습니다.

7.4. Integrations Target 생성

Integration Target은 기업에서 제공하는 도구 템플릿입니다. 다양한 써드파티 업체에서 제공하는 도구들을 선택하여 즉시 사용 가능합니다. Amazon부터 Jira, Confluence, Slack, Zoom, Tavily 등 자주 쓰는 서비스들을 MCP 도구로 사용할 수 있도록 미리 템플릿을 제공하고 있습니다. 현재 지원되는 Integration Target은 공식 문서에서 확인 가능합니다.

콘솔 화면에서 Integration Provider를 선택하게 되면, 아래와 같이 Integration Provider 마다 제공하고 있는 여러 개의 도구 템플릿을 확인할 수 있습니다.


각 도구 템플릿에는 포함하고 있는 도구들의 스펙이 정의되어 있습니다. 하나의 도구 템플릿에는 복수개의 도구 정보가 정의되어 있을 수 있습니다.

예를 들어, Amazon Provider를 선택하면 CloudWatch, DynamoDB, Bedrock 등의 템플릿을 제공합니다. CloudWatch 템플릿의 경우, 알람 히스토리를 검색하거나, 대시보드 정보를 받아오거나, 메트릭 리스트를 받아오는 등의 도구들이 포함되어 있습니다. DynamoDB 템플릿에는 테이블 생성, 아이템 조회, 업데이트, 검색 등 훨씬 많은 양의 도구들이 포함되어 있습니다.

8. Best Practices

도구 지연 시간 최소화

게이트웨이와 같은 리전에서 AWS Lambda 함수를 사용하고, 빠른 콜드 스타트를 위해 AWS Lambda 기능을 최적화해야 합니다. 낮은 대기 시간이 필요한 AWS Lambda 함수에 대해서는 프로비저닝된 동시성을 사용하고, REST API가 낮은 지연 시간과 높은 가용성을 가지고 있는지 확인해야 합니다.

효율적인 도구 스키마 사용

잘 설계된 도구 스키마는 게이트웨이의 성능을 향상시킬 수 있습니다. 스키마를 가능한 한 단순하게 유지하고, 매개 변수에 적절한 데이터 유형을 사용해야 합니다. 에이전트가 도구를 올바르게 사용할 수 있도록 매개 변수에 대한 명확한 설명을 포함하고, 필수 필드를 사용하여 에이전트가 필요한 매개 변수를 제공하도록 합니다.

API 그룹화

Agentic 애플리케이션의 비즈니스 도메인에 따라 MCP 도구를 그룹화하고, 아웃바운드 인증자를 기준으로 도구를 그룹화하며, API 유형에 따라 API를 그룹화하는 것이 좋습니다.

시맨틱 검색 활성화

시맨틱 검색은 에이전트가 작업에 적합한 도구를 찾을 수 있도록 도와줌으로써, 에이전트와 게이트웨이 상호 작용의 전반적인 성능을 향상시킵니다.

모니터링 및 최적화

로그를 분석하여 패턴과 문제를 식별하고, 정기적으로 성과 지표를 검토하고 필요에 따라 조정해야 합니다.

9. 정리

과제 기존 방식 Amazon Bedrock AgentCore Gateway 도입 후
프로토콜 구현 직접 MCP/A2A 서버를 구축하고 유지해야 함 Gateway가 MCP 도구 제공 및 변환을 자동화
API 연동 매번 수작업으로 API 래핑 OpenAPI 또는 AWS Lambda → 바로 도구 전환 가능
인프라 운영 서버 관리, 스케일링, 모니터링을 직접 처리해야 함 서버리스 인프라 + 자동 확장/모니터링
보안·인증 복잡한 보안 통제 구현 필요 인바운드·아웃바운드 인증, 권한 관리 내장
도구 탐색 도구가 많아질수록 에이전트 선택 어려움 지능형 도구 검색으로 “정확한 도구 선택” 가능

Amazon Bedrock AgentCore Gateway는 AI 에이전트가 엔터프라이즈 환경에서 실제로 작동하는 프로덕션 시스템이 되기 위한 핵심 인프라를 제공합니다. 개발자는 더 이상 인프라, 보안, 통합의 복잡성에 시간을 쓰지 않고, 진정으로 가치 있는 AI 에이전트를 만드는 데 집중할 수 있습니다. 즉, 수백 개의 에이전트와 수천 개의 도구를 운영해야 하는 대규모 조직에서 많은 도구들을 안전하고 확장 가능하게 중앙에서 관리해야 하는 과제를 해결합니다. 이를 통해 AI 에이전트의 엔터프라이즈급 운영이 비로소 현실이 됩니다.

10. 참고 자료

자세한 내용은 작성된 글에 대한 상세 설명과 데모를 포함한 프레젠테이션 영상을 통해 확인하실 수 있습니다. 또한 Amazon Bedrock AgentCore Gateway를 이해하는 데에 도움이 되는 문서, Amazon Bedrock AgentCore의 다른 기능에 대한 소개는 아래 링크들을 참조하실 수 있습니다.

Yoojung Lee

Yoojung Lee

이유정 Solutions Architect는 자율주행, 디지털트윈, AI 연구개발 경험을 바탕으로 고객이 비즈니스 목표를 달성하도록 아키텍처 설계 가이드와 기술을 지원하고 있습니다.