Skip to content

Commit eebee32

Browse files
DennisTraubwzxxingarangatang
authored
feat: AWS IAM MCP client with SigV4 auth (#65)
* Add client * Add client tests * Add usage examples for MCP client * Update README * lint/format * Apply suggestions from code review Co-authored-by: wzxxing <169175349+wzxxing@users.noreply.github.com> Signed-off-by: Dennis Traub <dennis.traub@gmail.com> * Simplify aws_iam_mcp_client by returning streamablehttp_client directly * Simplify examples * Add example .env files * Apply suggestions from arangatang's code review Co-authored-by: Leonardo Araneda Freccero <arangatang@users.noreply.github.com> Signed-off-by: Dennis Traub <dennis.traub@gmail.com> * Apply further suggestions from review * Fix linting issues * Add unit tests for client usage examples * Add license headers to examples * Apply suggestions from code review Co-authored-by: Leonardo Araneda Freccero <arangatang@users.noreply.github.com> Signed-off-by: Dennis Traub <dennis.traub@gmail.com> * chore: use uv workspaces for the examples * Fix pyright errors * Rename to aws_iam_streamablehttp_client * Update github workflow to build workspace * Add frozen flag in GH workflow Signed-off-by: Dennis Traub <dennis.traub@gmail.com> * Add return type to client signature * Update docstring --------- Signed-off-by: Dennis Traub <dennis.traub@gmail.com> Co-authored-by: wzxxing <169175349+wzxxing@users.noreply.github.com> Co-authored-by: Leonardo Araneda Freccero <arangatang@users.noreply.github.com>
1 parent 711a80d commit eebee32

File tree

23 files changed

+4608
-332
lines changed

23 files changed

+4608
-332
lines changed

.github/workflows/python.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ jobs:
6161
uv run --frozen coverage report --fail-under=80
6262
6363
- name: Run pyright
64-
run: uv run --frozen pyright
64+
run: uv run --frozen --all-packages pyright
6565

6666
- name: Run ruff format
6767
run: uv run --frozen ruff format .

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
*~
33
*#
44
*.DS_Store
5+
.claude
56
.clinerules
67
*-toolbag/
78

README.md

Lines changed: 170 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2,43 +2,78 @@
22

33
## Overview
44

5-
The MCP Proxy for AWS serves as a lightweight, client-side bridge between MCP clients (AI assistants and developer tools) and backend AWS MCP servers.
5+
The **MCP Proxy for AWS** package provides two ways to connect AI applications to MCP servers on AWS:
66

7-
The proxy handles [SigV4](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_sigv.html) authentication using local AWS credentials and provides dynamic tool discovery, making it ideal for developers who want access to AWS Hosted SigV4 secured MCP Servers without complex gateway setups.
7+
1. **Using it as a proxy** - It becomes a lightweight, client-side bridge between MCP clients (AI assistants like Claude Desktop, Amazon Q Developer CLI) and MCP servers on AWS. (See [MCP Proxy](#mcp-proxy))
8+
2. **Using it as a library** - Programmatically connect popular AI agent frameworks (LangChain, LlamaIndex, Strands Agents, etc.) to MCP servers on AWS. (See [Programmatic Access](#programmatic-access))
9+
10+
11+
### When Do You Need This Package?
12+
13+
- You want to connect to **MCP servers on AWS** (e.g., using Amazon Bedrock AgentCore) that use AWS IAM authentication (SigV4) instead of OAuth
14+
- You're using MCP clients (like Claude Desktop, Amazon Q Developer CLI) that don't natively support AWS IAM authentication
15+
- You're building AI agents with popular frameworks like LangChain, Strands Agents, LlamaIndex, etc., that need to connect to MCP servers on AWS
16+
- You want to avoid building custom SigV4 request signing logic yourself
17+
18+
### How This Package Helps
19+
20+
**The Problem:** The official MCP specification supports OAuth-based authentication, but MCP servers on AWS can also use AWS IAM authentication (SigV4). Standard MCP clients don't know how to sign requests with AWS credentials.
21+
22+
**The Solution:** This package bridges that gap by:
23+
- **Handling SigV4 authentication automatically** - Uses your local AWS credentials (from AWS CLI, environment variables, or IAM roles) to sign all MCP requests using [SigV4](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_sigv.html)
24+
- **Providing seamless integration** - Works with existing MCP clients and frameworks
25+
- **Eliminating custom code** - No need to build your own MCP client with SigV4 signing logic
26+
27+
## Which Feature Should I Use?
28+
29+
**Use as a proxy if you want to:**
30+
- Connect MCP clients like Claude Desktop or Amazon Q Developer CLI to MCP servers on AWS with IAM credentials
31+
- Add MCP servers on AWS to your AI assistant's configuration
32+
- Use a command-line tool that runs as a bridge between your MCP client and AWS
33+
34+
**Use as a library if you want to:**
35+
- Build AI agents programmatically using popular frameworks like LangChain, Strands Agents, or LlamaIndex
36+
- Integrate AWS IAM-secured MCP servers directly into your Python applications
37+
- Have fine-grained control over the MCP session lifecycle in your code
838

939
## Prerequisites
1040

1141
* [Install Python 3.10+](https://www.python.org/downloads/release/python-3100/)
1242
* [Install the `uv` package manager](https://docs.astral.sh/uv/getting-started/installation/)
13-
* [Install and configure the AWS CLI with credentials](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-configure.html)
43+
* AWS credentials configured (via [AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-configure.html), environment variables, or IAM roles)
1444
* (Optional, for docker users) [Install Docker Desktop](https://www.docker.com/products/docker-desktop)
1545

16-
## Installation
46+
---
1747

18-
### Using PyPi
48+
## MCP Proxy
1949

50+
The MCP Proxy serves as a lightweight, client-side bridge between MCP clients (AI assistants and developer tools) and IAM-secured MCP servers on AWS. The proxy handles SigV4 authentication using local AWS credentials and provides dynamic tool discovery.
2051

21-
```
52+
### Installation
53+
54+
#### Using PyPi
55+
56+
```bash
2257
# Run the server
2358
uvx mcp-proxy-for-aws@latest <SigV4 MCP endpoint URL>
2459
```
2560

26-
### Using Local Repository
61+
#### Using a local repository
2762

28-
```
63+
```bash
2964
git clone https://github.com/aws/mcp-proxy-for-aws.git
3065
cd mcp-proxy-for-aws
3166
uv run mcp_proxy_for_aws/server.py <SigV4 MCP endpoint URL>
3267
```
3368

34-
### Using Docker
69+
#### Using Docker
3570

36-
```
71+
```bash
3772
# Build the Docker image
3873
docker build -t mcp-proxy-for-aws .
3974
```
4075

41-
## Configuration Parameters
76+
### Configuration Parameters
4277

4378
| Parameter | Description | Default |Required |
4479
|----------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------|--- |
@@ -55,12 +90,11 @@ docker build -t mcp-proxy-for-aws .
5590
| `--read-timeout` | Set desired read timeout in seconds | 120 |No |
5691
| `--write-timeout` | Set desired write timeout in seconds | 180 |No |
5792

58-
59-
## Optional Environment Variables
93+
### Optional Environment Variables
6094

6195
Set the environment variables for the MCP Proxy for AWS:
6296

63-
```
97+
```bash
6498
# Credentials through profile
6599
export AWS_PROFILE=<aws_profile>
66100

@@ -73,14 +107,14 @@ export AWS_SESSION_TOKEN=<session_token>
73107
export AWS_REGION=<aws_region>
74108
```
75109

76-
## Setup Examples
110+
### Setup Examples
77111

78112
Add the following configuration to your MCP client config file (e.g., for Amazon Q Developer CLI, edit `~/.aws/amazonq/mcp.json`):
79113
**Note** Add your own endpoint by replacing `<SigV4 MCP endpoint URL>`
80114

81-
### Running from local - using uv
115+
#### Running from local - using uv
82116

83-
```
117+
```json
84118
{
85119
"mcpServers": {
86120
"<mcp server name>": {
@@ -108,9 +142,9 @@ Add the following configuration to your MCP client config file (e.g., for Amazon
108142
}
109143
```
110144

111-
### Using Docker
145+
#### Using Docker
112146

113-
```
147+
```json
114148
{
115149
"mcpServers": {
116150
"<mcp server name>": {
@@ -129,6 +163,121 @@ Add the following configuration to your MCP client config file (e.g., for Amazon
129163
}
130164
```
131165

166+
---
167+
168+
## Programmatic Access
169+
170+
The MCP Proxy for AWS enables programmatic integration of IAM-secured MCP servers into AI agent frameworks. The library provides authenticated transport layers that work with popular Python AI frameworks.
171+
172+
### Integration Patterns
173+
174+
The library supports two integration patterns depending on your framework:
175+
176+
#### Pattern 1: Client Factory Integration
177+
178+
**Use with:** Frameworks that accept a factory function that returns an MCP client, e.g. Strands Agents, Microsoft Agent Framework. The `aws_iam_streamablehttp_client` is passed as a factory to the framework, which handles the connection lifecycle internally.
179+
180+
**Example - Strands Agents:**
181+
```python
182+
from mcp_proxy_for_aws.client import aws_iam_streamablehttp_client
183+
184+
mcp_client_factory = lambda: aws_iam_streamablehttp_client(
185+
endpoint=mcp_url, # The URL of the MCP server
186+
aws_region=region, # The region of the MCP server
187+
aws_service=service # The underlying AWS service, e.g. "bedrock-agentcore"
188+
)
189+
190+
with MCPClient(mcp_client_factory) as mcp_client:
191+
mcp_tools = mcp_client.list_tools_sync()
192+
agent = Agent(tools=mcp_tools, ...)
193+
```
194+
195+
**Example - Microsoft Agent Framework:**
196+
```python
197+
from mcp_proxy_for_aws.client import aws_iam_streamablehttp_client
198+
199+
mcp_client_factory = lambda: aws_iam_streamablehttp_client(
200+
endpoint=mcp_url, # The URL of the MCP server
201+
aws_region=region, # The region of the MCP server
202+
aws_service=service # The underlying AWS service, e.g. "bedrock-agentcore"
203+
)
204+
205+
mcp_tools = MCPStreamableHTTPTool(name="MCP Tools", url=mcp_url)
206+
mcp_tools.get_mcp_client = mcp_client_factory
207+
208+
async with mcp_tools:
209+
agent = ChatAgent(tools=[mcp_tools], ...)
210+
```
211+
212+
#### Pattern 2: Direct MCP Session Integration
213+
214+
**Use with:** Frameworks that require direct access to the MCP sessions, e.g. LangChain, LlamaIndex. The `aws_iam_streamablehttp_client` provides the authenticated transport streams, which are then used to create an MCP `ClientSession`.
215+
216+
**Example - LangChain:**
217+
```python
218+
from mcp_proxy_for_aws.client import aws_iam_streamablehttp_client
219+
220+
mcp_client = aws_iam_streamablehttp_client(
221+
endpoint=mcp_url, # The URL of the MCP server
222+
aws_region=region, # The region of the MCP server
223+
aws_service=service # The underlying AWS service, e.g. "bedrock-agentcore"
224+
)
225+
226+
async with mcp_client as (read, write, session_id_callback):
227+
async with ClientSession(read, write) as session:
228+
mcp_tools = await load_mcp_tools(session)
229+
agent = create_langchain_agent(tools=mcp_tools, ...)
230+
```
231+
232+
**Example - LlamaIndex:**
233+
```python
234+
from mcp_proxy_for_aws.client import aws_iam_streamablehttp_client
235+
236+
mcp_client = aws_iam_streamablehttp_client(
237+
endpoint=mcp_url, # The URL of the MCP server
238+
aws_region=region, # The region of the MCP server
239+
aws_service=service # The underlying AWS service, e.g. "bedrock-agentcore"
240+
)
241+
242+
async with mcp_client as (read, write, session_id_callback):
243+
async with ClientSession(read, write) as session:
244+
mcp_tools = await McpToolSpec(client=session).to_tool_list_async()
245+
agent = ReActAgent(tools=mcp_tools, ...)
246+
```
247+
248+
### Running Examples
249+
250+
Explore complete working examples for different frameworks in the [`./examples/mcp-client`](./examples/mcp-client) directory:
251+
252+
**Available examples:**
253+
- **[LangChain](./examples/mcp-client/langchain/)**
254+
- **[LlamaIndex](./examples/mcp-client/llamaindex/)**
255+
- **[Microsoft Agent Framework](./examples/mcp-client/agent-framework/)**
256+
- **[Strands Agents SDK](./examples/mcp-client/strands/)**
257+
258+
Run examples individually:
259+
```bash
260+
cd examples/mcp-client/[framework] # e.g. examples/mcp-client/strands
261+
uv run main.py
262+
```
263+
264+
### Installation
265+
266+
The client library is included when you install the package:
267+
268+
```bash
269+
pip install mcp-proxy-for-aws
270+
```
271+
272+
For development:
273+
```bash
274+
git clone https://github.com/aws/mcp-proxy-for-aws.git
275+
cd mcp-proxy-for-aws
276+
uv sync
277+
```
278+
279+
---
280+
132281
## Development & Contributing
133282

134283
For development setup, testing, and contribution guidelines, see:
@@ -138,8 +287,8 @@ For development setup, testing, and contribution guidelines, see:
138287

139288
Resources to understand SigV4:
140289

141-
- <https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_sigv.html>
142-
- SigV4: <https://github.com/boto/botocore/blob/develop/botocore/signers.py>
290+
- SigV4 User Guide: <https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_sigv.html>
291+
- SigV4 Signers: <https://github.com/boto/botocore/blob/develop/botocore/signers.py>
143292
- SigV4a: <https://github.com/aws-samples/sigv4a-signing-examples/blob/main/python/sigv4a_sign.py>
144293

145294
## License
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# The URL of your MCP server
2+
MCP_SERVER_URL="https://example-mcp-server.gateway.bedrock-agentcore.us-west-2.amazonaws.com/mcp"
3+
# The AWS service hosting the MCP server
4+
MCP_SERVER_AWS_SERVICE="bedrock-agentcore"
5+
# The AWS region where the MCP server is hosted
6+
MCP_SERVER_REGION="us-west-2"
7+
8+
# Your OpenAI API key for the agent's language model
9+
OPENAI_API_KEY="sk-..."
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
# Example: Microsoft Agent Framework
2+
3+
This example demonstrates how to use `aws_iam_streamablehttp_client` from `mcp-proxy-for-aws` to connect a [Microsoft Agent Framework](https://learn.microsoft.com/en-us/agent-framework/) agent to an MCP server using AWS IAM authentication.
4+
5+
**Note:** Microsoft Agent Framework accepts a factory function that returns an MCP client. The `aws_iam_streamablehttp_client` is passed as a factory to the framework's `MCPStreamableHTTPTool`, which handles the connection lifecycle internally.
6+
7+
## Prerequisites
8+
9+
- [Python 3.10+](https://www.python.org/downloads) and [uv](https://docs.astral.sh/uv/getting-started/installation/) installed
10+
- AWS credentials configured (via [AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-configure.html), environment variables, or IAM roles)
11+
- An [OpenAI API key](https://platform.openai.com/api-keys) for the language model
12+
13+
## Setup
14+
15+
Create a `.env` file or set the following environment variables:
16+
17+
```bash
18+
# MCP server details
19+
MCP_SERVER_URL=https://example.gateway.bedrock-agentcore.us-west-2.amazonaws.com/mcp
20+
MCP_SERVER_AWS_SERVICE=bedrock-agentcore
21+
MCP_SERVER_REGION=us-west-2
22+
23+
# OpenAI API key for the agent's LLM
24+
OPENAI_API_KEY=sk-...
25+
```
26+
27+
All four environment variables are required.
28+
29+
## Usage
30+
31+
Run the example:
32+
33+
```bash
34+
uv run main.py
35+
```
36+
37+
The agent will connect to the MCP server and list its available tools.
38+
39+
## How It Works
40+
41+
1. **Loads configuration** from environment variables or `.env` file
42+
3. **Creates an AWS IAM-authenticated MCP client** using `aws_iam_streamablehttp_client()`
43+
4. **Integrates with Agent Framework** by configuring `MCPStreamableHTTPTool.get_mcp_client`
44+
5. **Creates an agent** with access to the MCP server tools
45+
6. **Runs the agent** to demonstrate tool discovery and usage
46+
47+
## Example MCP Server URL Formats
48+
49+
**AgentCore Runtime URL:**
50+
51+
```text
52+
https://bedrock-agentcore.[AWS_REGION].amazonaws.com/runtimes/[RUNTIME_ID]/invocations?qualifier=DEFAULT&accountId=[AWS_ACCOUNT_ID]
53+
```
54+
55+
**AgentCore Gateway URL:**
56+
57+
```text
58+
https://[GATEWAY_ID].gateway.bedrock-agentcore.[AWS_REGION].amazonaws.com/mcp
59+
```
60+
61+
## Troubleshooting
62+
63+
### Common Issues
64+
65+
#### No AWS credentials available
66+
67+
- Verify AWS credentials are configured ([AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-configure.html), environment variables, or IAM roles)
68+
- Test with `aws sts get-caller-identity`
69+
70+
#### Missing environment variables
71+
72+
- Ensure all required variables are set: `MCP_SERVER_URL`, `MCP_SERVER_REGION`, `MCP_SERVER_AWS_SERVICE`, and `OPENAI_API_KEY`
73+
- Check your `.env` file or environment variable configuration
74+
75+
#### Connection errors
76+
77+
- Verify your MCP server details are correct
78+
- Ensure the MCP server is running and accessible
79+
- Verify your AWS credentials have the necessary permissions to access the MCP server

0 commit comments

Comments
 (0)