generated from amazon-archives/__template_Apache-2.0
-
Notifications
You must be signed in to change notification settings - Fork 515
[Blog] Hosting OpenSearch MCP Server with Amazon Bedrock AgentCore #3893
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
jiapingzeng
wants to merge
9
commits into
opensearch-project:main
Choose a base branch
from
jiapingzeng:main
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
9 commits
Select commit
Hold shift + click to select a range
c2b357e
initial draft
jiapingzeng 2772764
Doc review
kolchfa-aws e06456d
Apply suggestions from code review
jiapingzeng 178cbc6
Apply suggestions from code review
jiapingzeng 3360c01
update variable names, removed workaround section
jiapingzeng 047c0c8
Update supported region
jiapingzeng 5092daa
Update 2025-08-04-Hosting-OpenSearch-MCP-server-with-Bedrock-AgentCor…
jiapingzeng bbb5fc0
Merge branch 'opensearch-project:main' into main
jiapingzeng c08f8d1
add link to AWS doc
jiapingzeng File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
269 changes: 269 additions & 0 deletions
269
_posts/2025-08-04-Hosting-OpenSearch-MCP-server-with-Bedrock-AgentCore.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,269 @@ | ||
--- | ||
layout: post | ||
title: "Hosting the OpenSearch MCP server with Amazon Bedrock AgentCore" | ||
authors: | ||
- jiapingzeng | ||
date: 2025-08-27 | ||
categories: | ||
- technical-post | ||
meta_keywords: OpenSearch MCP Server, Model Context Protocol, OpenSearch clusters, Amazon Bedrock, Bedrock AgentCore, AWS CloudFormation, OpenSearch integration, AI agents | ||
meta_description: Learn to deploy OpenSearch MCP server on Bedrock AgentCore Runtime to securely connect AI agents with OpenSearch clusters using CloudFormation or CLI methods. | ||
--- | ||
|
||
The [OpenSearch MCP server](https://github.com/opensearch-project/opensearch-mcp-server-py) enables AI agents to interact with OpenSearch clusters through the Model Context Protocol (MCP). While you can run the OpenSearch MCP server locally, hosting it on Amazon Bedrock AgentCore Runtime provides a scalable, managed solution that's accessible from anywhere. | ||
|
||
In this post, we'll walk you through two approaches to deploying the OpenSearch MCP server on Bedrock AgentCore: using an AWS CloudFormation template for a quick setup and manually configuring it using the AgentCore CLI. | ||
|
||
## Prerequisites | ||
|
||
Before you begin, ensure that you have the following: | ||
|
||
- An OpenSearch cluster | ||
- Access to one of the supported Bedrock AgentCore Regions: `us-east-1`, `us-west-2`, `eu-central-1`, or `ap-southeast-2` | ||
|
||
**Note**: While Bedrock AgentCore is only available in these four AWS Regions, your MCP server can connect to OpenSearch clusters in other Regions over the public internet. | ||
|
||
## Method 1: Using a CloudFormation template (available to Amazon OpenSearch Service users) | ||
|
||
The fastest way to get started is to use the [OpenSearch MCP server CloudFormation template](https://docs.aws.amazon.com/opensearch-service/latest/developerguide/cfn-template-mcp-server.html), which automatically provisions all necessary resources. | ||
|
||
### Deploying the template | ||
|
||
The CloudFormation template requires these parameters: | ||
|
||
**Required**: | ||
- **Agent name**: A name for your MCP server. | ||
- **OpenSearch endpoint**: Your cluster's endpoint URL. | ||
- **OpenSearch Region**: The AWS Region in which your cluster is located. | ||
|
||
**Optional**: | ||
- **Amazon Elastic Container Registry (Amazon ECR) repository**: Used to store the container image; auto-created if not specified. | ||
- **Execution role**: An AWS Identity and Access Management (IAM) role for AgentCore Runtime; auto-created with proper permissions if not specified. | ||
- **OAuth Discovery URL, Allowed Clients IDs, Allowed Audience**: OAuth 2.0 configuration. If not provided, the template creates Amazon Cognito resources automatically. | ||
|
||
### Understanding the outputs | ||
|
||
Once deployment completes, it produces these key outputs: | ||
|
||
- **AgentCoreArn**: The Amazon Resource Name (ARN) of your Bedrock AgentCore Runtime. | ||
- **TokenEndpoint**: The token endpoint obtained from your discovery endpoint. | ||
- **MCPServerEndpoint**: The URL of your hosted MCP server. | ||
|
||
### Obtaining an access token | ||
|
||
To use your MCP server, you'll need a JWT token from the OAuth authorizer. If you used the auto-created Cognito setup, follow these steps to obtain the token: | ||
|
||
1. Navigate to the **CloudFormation Resources** tab. | ||
2. Find **CognitoUserPool** and select its **Physical ID**. | ||
3. Go to **App clients** and note the **Client ID** and **Client Secret**. | ||
|
||
Then obtain a token: | ||
|
||
```bash | ||
export TOKEN_ENDPOINT="<YOUR TOKEN ENDPOINT>" | ||
export CLIENT_ID="<YOUR CLIENT ID>" | ||
export CLIENT_SECRET="<YOUR CLIENT SECRET>" | ||
|
||
curl --http1.1 -X POST $TOKEN_ENDPOINT \ | ||
-H "Content-Type: application/x-www-form-urlencoded" \ | ||
-d "grant_type=client_credentials&client_id=$CLIENT_ID&client_secret=$CLIENT_SECRET" | ||
``` | ||
|
||
The response contains the token: | ||
|
||
```json | ||
{"access_token":"xxxxx","expires_in":3600,"token_type":"Bearer"} | ||
``` | ||
|
||
**Note**: Cognito tokens expire every 60 minutes by default. | ||
|
||
## Method 2: Using the Bedrock AgentCore CLI | ||
|
||
You can also use the Bedrock AgentCore CLI directly. | ||
|
||
### Creating the MCP server code | ||
|
||
First, create your MCP server implementation: | ||
|
||
**opensearch_mcp_server.py** | ||
```python | ||
from mcp_server_opensearch import streaming_server | ||
import asyncio | ||
import os | ||
|
||
os.environ["OPENSEARCH_URL"] = "https://your-opensearch-endpoint.com" | ||
os.environ["AWS_REGION"] = "us-east-1" | ||
|
||
if __name__ == "__main__": | ||
asyncio.run(streaming_server.serve(port=8000, host="0.0.0.0", stateless=True)) | ||
``` | ||
|
||
Note: `AWS_REGION` is optional if the OpenSearch cluster and AgentCore Runtime are in the same Region. The Dockerfile generated by AgentCore will have `AWS_REGION` as an environment variable. | ||
|
||
**requirements.txt** | ||
``` | ||
opensearch-mcp-server-py>=0.3.1 | ||
``` | ||
|
||
### Setting up OAuth (Optional) | ||
|
||
If you don't have an existing OAuth authorizer, create one using Amazon Cognito by following the instructions provided in the [Bedrock AgentCore documentation](https://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/runtime-mcp.html#runtime-mcp-appendix). | ||
|
||
### Configuring AgentCore deployment | ||
|
||
Install the AgentCore toolkit: | ||
|
||
```bash | ||
pip install bedrock-agentcore-starter-toolkit | ||
``` | ||
|
||
Configure your deployment: | ||
|
||
```bash | ||
agentcore configure -e opensearch_mcp_server.py --protocol MCP | ||
``` | ||
|
||
Follow the prompts to perform the following actions: | ||
- Auto-create an execution role (or specify an existing one). | ||
- Auto-create an ECR repository (or specify an existing one). | ||
- Select your `requirements.txt` file. | ||
- Configure the OAuth authorizer with the discovery URL and client ID. | ||
|
||
### Deploying to AgentCore Runtime | ||
|
||
Deploy your MCP server: | ||
|
||
```bash | ||
agentcore launch | ||
``` | ||
|
||
After successful deployment, generate your MCP server URL: | ||
|
||
```bash | ||
export AWS_REGION="<YOUR AWS REGION>" | ||
export AGENT_ARN="<YOUR AGENT ARN>" | ||
export ENCODED_AGENT_ARN=$(echo $AGENT_ARN | sed 's/:/%3A/g; s/\//%2F/g') | ||
echo "https://bedrock-agentcore.$AWS_REGION.amazonaws.com/runtimes/$ENCODED_AGENT_ARN/invocations?qualifier=DEFAULT" | ||
``` | ||
|
||
## Configuring OpenSearch access | ||
|
||
Regardless of the deployment method you used, you need to map your AgentCore execution role to an OpenSearch backend role so the MCP server can access your data. | ||
|
||
Follow the instructions provided at [Fine-grained access control in Amazon OpenSearch Service](https://docs.aws.amazon.com/opensearch-service/latest/developerguide/fgac.html#fgac-access-control) to configure the appropriate backend role mapping. | ||
|
||
## Using Your Hosted MCP server | ||
|
||
The following sections show you how to test and use your new hosted MCP server. | ||
|
||
natebower marked this conversation as resolved.
Show resolved
Hide resolved
|
||
### Testing with the Amazon Q Developer CLI | ||
|
||
The easiest way to test your MCP server is with the Amazon Q Developer CLI. Configure `~/.aws/amazonq/mcp.json`: | ||
|
||
```json | ||
{ | ||
"mcpServers": { | ||
"opensearch-mcp-server": { | ||
"command": "mcp-proxy", | ||
"timeout": 60000, | ||
"args": [ | ||
"<YOUR MCP URL>", | ||
"--transport", | ||
"streamablehttp" | ||
], | ||
"env": { | ||
"API_ACCESS_TOKEN": "<YOUR ACCESS TOKEN>" | ||
} | ||
} | ||
} | ||
} | ||
``` | ||
|
||
Start the Amazon Q Developer CLI: | ||
|
||
```bash | ||
$ q | ||
✓ opensearch-mcp-server loaded in 3.22 s | ||
``` | ||
|
||
Verify that the tools are available: | ||
|
||
```bash | ||
> /tools | ||
|
||
Tool Permission | ||
Built-in: | ||
- execute_bash * trust read-only commands | ||
- fs_read * trusted | ||
- fs_write * not trusted | ||
- report_issue * trusted | ||
- use_aws * trust read-only commands | ||
|
||
opensearch-mcp-server (MCP): | ||
- ClusterHealthTool * not trusted | ||
- CountTool * not trusted | ||
- ExplainTool * not trusted | ||
- GetShardsTool * not trusted | ||
- IndexMappingTool * not trusted | ||
- ListIndexTool * not trusted | ||
- MsearchTool * not trusted | ||
- SearchIndexTool * not trusted | ||
``` | ||
|
||
Now you can ask questions about your OpenSearch data! For examples of what you can do, check out the blog post [Unlocking agentic AI experiences with OpenSearch](https://opensearch.org/blog/unlocking-agentic-ai-experiences-with-opensearch/). | ||
|
||
### Using custom agents | ||
|
||
You can integrate your hosted MCP server with any MCP-compatible agent. Here's an example using the Strands Agents framework: | ||
|
||
```python | ||
import os | ||
import requests | ||
from strands import Agent | ||
from strands.tools.mcp import MCPClient | ||
from mcp.client.streamable_http import streamablehttp_client | ||
|
||
def get_bearer_token(discovery_url: str, client_id: str, client_secret: str): | ||
response = requests.get(discovery_url) | ||
discovery_data = response.json() | ||
token_endpoint = discovery_data['token_endpoint'] | ||
|
||
data = { | ||
'grant_type': 'client_credentials', | ||
'client_id': client_id, | ||
'client_secret': client_secret | ||
} | ||
headers = { | ||
'Content-Type': 'application/x-www-form-urlencoded' | ||
} | ||
|
||
response = requests.post(token_endpoint, data=data, headers=headers) | ||
token_data = response.json() | ||
return token_data['access_token'] | ||
|
||
if __name__ == "__main__": | ||
discovery_url = os.environ["DISCOVERY_URL"] | ||
client_id = os.environ["CLIENT_ID"] | ||
client_secret = os.environ["CLIENT_SECRET"] | ||
mcp_url = os.environ["MCP_URL"] | ||
|
||
bearer_token = get_bearer_token(discovery_url, client_id, client_secret) | ||
|
||
opensearch_mcp_client = MCPClient(lambda: streamablehttp_client(mcp_url, { | ||
"authorization": f"Bearer {bearer_token}", | ||
"Content-Type": "application/json" | ||
})) | ||
|
||
with opensearch_mcp_client: | ||
tools = opensearch_mcp_client.list_tools_sync() | ||
agent = Agent(tools=tools) | ||
agent("list indices") | ||
``` | ||
|
||
## Conclusion | ||
|
||
Hosting your OpenSearch MCP server on Amazon Bedrock AgentCore Runtime provides a scalable, managed solution for integrating OpenSearch with AI agents. Whether you choose the quick CloudFormation deployment or the CLI approach, you'll have a robust, cloud-hosted MCP server that can serve multiple agents and applications. | ||
|
||
The hosted approach eliminates the need to manage infrastructure while providing enterprise-grade security through OAuth authentication and fine-grained access control. This makes it ideal for production deployments where you need reliable, scalable access to your OpenSearch data from AI agents. | ||
|
||
Ready to get started? Try the CloudFormation template for the fastest setup, or use the CLI method if you need more control over your deployment configuration. |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.