-
Notifications
You must be signed in to change notification settings - Fork 28
feat: Add Streamable HTTP Transport for MCP with AWS Lambda #191
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
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,164 @@ | ||
# Streamable HTTP Transport for MCP | ||
|
||
This repository now includes a **Streamable HTTP Transport** implementation that provides an alternative to the stdio-based approach for running MCP servers in AWS Lambda. | ||
|
||
## Why Streamable HTTP Transport? | ||
|
||
The original stdio-based approach requires creating child processes inside Lambda functions and bridging stdio communication. The Streamable HTTP transport eliminates this complexity by implementing native HTTP communication. | ||
|
||
### Architecture Comparison | ||
|
||
#### Original Stdio Approach | ||
``` | ||
[MCP Client] → [Lambda Invoke API] → [Lambda Function] | ||
→ [stdio bridge] → [Child Process MCP Server] | ||
→ [stdio response] → [Lambda Response] → [MCP Client] | ||
``` | ||
|
||
#### New Streamable HTTP Approach | ||
``` | ||
[MCP Client] → [HTTP POST with SigV4] → [Lambda Function URL] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't think this change should be specific to Lambda function URL, I know for the given example it is, but this can work for any HTTP call. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ack |
||
→ [StreamableHTTPServerTransport] → [MCP Tools with Context] | ||
→ [SSE/JSON Response] → [MCP Client] | ||
``` | ||
|
||
## Key Advantages | ||
|
||
- Better performance: No child process overhead, faster cold starts | ||
- Native AWS security: Built-in SigV4 authentication | ||
Badrinath-Chandi marked this conversation as resolved.
Show resolved
Hide resolved
|
||
- Real-time streaming: Server-Sent Events for notifications | ||
- Context passing: Clean mechanism to pass Lambda event data to tools | ||
- Cost effective: Direct Lambda Function URLs, no API Gateway needed | ||
Badrinath-Chandi marked this conversation as resolved.
Show resolved
Hide resolved
|
||
- Comprehensive error handling, retry logic, session management | ||
|
||
## Quick Start | ||
|
||
### 1. Install the Transport | ||
|
||
```bash | ||
cd src/typescript-streamable-http | ||
npm install | ||
npm run build | ||
``` | ||
|
||
### 2. Run the Examples | ||
|
||
```bash | ||
cd examples/streamable-http | ||
npm install | ||
|
||
# Start server | ||
npm run dev:server | ||
|
||
# In another terminal, start client | ||
npm run dev:client | ||
``` | ||
|
||
### 3. Deploy to AWS Lambda | ||
|
||
The examples include complete deployment instructions for AWS Lambda with Function URLs. | ||
|
||
## Implementation Highlights | ||
|
||
### Server Side | ||
```typescript | ||
import { StreamableHTTPServerTransport, extractContextFiled } from './src/typescript-streamable-http'; | ||
|
||
const transport = new StreamableHTTPServerTransport({ | ||
sessionIdGenerator: () => undefined, // Stateless for Lambda | ||
enableJsonResponse: false // Use SSE streaming | ||
}); | ||
|
||
// Extract context in MCP tools | ||
const context = extractContextFiled<UserContext>(mcpServer, 'context'); | ||
``` | ||
|
||
### Client Side | ||
```typescript | ||
import { StreamableHTTPClientTransport } from './src/typescript-streamable-http'; | ||
|
||
const transport = new StreamableHTTPClientTransport( | ||
new URL('https://your-function-url.lambda-url.us-west-2.on.aws/mcp'), | ||
{ context: { userId: '123', role: 'admin' } }, // Pass context | ||
'us-west-2', | ||
'lambda' | ||
); | ||
``` | ||
|
||
## Documentation | ||
|
||
- **[Transport Library README](src/typescript-streamable-http/README.md)** - Complete API documentation | ||
- **[Examples README](examples/streamable-http/README.md)** - Step-by-step examples | ||
- **[Server Example](examples/streamable-http/server-example.ts)** - Complete server implementation | ||
- **[Client Example](examples/streamable-http/client-example.ts)** - Client with streaming support | ||
|
||
## Comparison with Existing Approach | ||
|
||
| Feature | Stdio Transport | Streamable HTTP Transport | | ||
|---------|----------------|---------------------------| | ||
| **Architecture** | Child process + stdio bridge | Native HTTP communication | | ||
| **Cold Start** | Slower (process spawning) | Faster (direct HTTP) | | ||
| **Memory Usage** | Higher (multiple processes) | Lower (single process) | | ||
| **Context Passing** | Complex (environment variables) | Clean (HTTP headers) | | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Seems like an opinion here, I think we can still present this comparison table as feature list rather than making is "vs" , |
||
| **Streaming** | Limited | Full SSE support | | ||
| **Error Handling** | Basic | Comprehensive with retry | | ||
| **AWS Integration** | Manual invoke API | Native SigV4 + Function URLs | | ||
| **Scalability** | Limited by process limits | HTTP connection pooling | | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not sure about this limitation here. |
||
| **Cost** | Higher (API Gateway often needed) | Lower (direct Function URLs) | | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Missing APIG also brings additional work on client to manage its own throttling, WAF, phased launches. |
||
|
||
## Migration Guide | ||
|
||
### From Stdio to Streamable HTTP | ||
|
||
1. **Replace transport imports**: | ||
```typescript | ||
// Old | ||
import { stdioServerAdapter } from '@aws/run-mcp-servers-with-aws-lambda'; | ||
|
||
// New | ||
import { StreamableHTTPServerTransport } from './src/typescript-streamable-http'; | ||
``` | ||
|
||
2. **Update server initialization**: | ||
```typescript | ||
// Old - stdio adapter in Lambda handler | ||
export const handler = (event, context) => { | ||
return stdioServerAdapter(serverParams, event, context); | ||
}; | ||
|
||
// New - Express app with HTTP transport | ||
const app = express(); | ||
const transport = new StreamableHTTPServerTransport({...}); | ||
app.all('/mcp', (req, res) => transport.handleRequest(req, res)); | ||
``` | ||
|
||
3. **Update client connection**: | ||
```typescript | ||
// Old - Lambda invoke transport | ||
const transport = new LambdaFunctionClientTransport({...}); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do we need to call this LamdaFunctionClientTransport, can we make it more generic that works for non lambda endpoints also. |
||
|
||
// New - HTTP transport | ||
const transport = new StreamableHTTPClientTransport(url, options, region, service); | ||
``` | ||
|
||
## Production Deployments | ||
|
||
The Streamable HTTP transport is already being used in production environments with: | ||
- **Multi-stage deployments** (alpha, beta, gamma, prod) | ||
- **Multiple MCP servers** running as separate Lambda functions | ||
- **Real-time streaming** for long-running operations | ||
- **Context-aware tools** that access user and request data | ||
- **Automatic retry and reconnection** for reliability | ||
|
||
## Contributing | ||
|
||
This transport implementation represents a significant improvement over the stdio approach and is ready for community adoption. The code is production-tested and includes comprehensive examples and documentation. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Lets avoid such wide comparison languages IMO. |
||
|
||
## Next Steps | ||
|
||
1. **Test the examples** locally | ||
2. **Deploy to AWS Lambda** using the provided instructions | ||
3. **Integrate into your MCP applications** | ||
4. **Contribute improvements** back to the community | ||
|
||
The Streamable HTTP transport makes MCP with AWS Lambda more performant, scalable, and developer-friendly while maintaining full protocol compatibility. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1 @@ | ||
0.2.1 | ||
0.3.0 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is there a way to avoid this being part of checked in code? |
Uh oh!
There was an error while loading. Please reload this page.