CLAUDE.md•6 kB
# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## Project Overview
AWS Lambda deployment of the awslabs OpenAPI MCP Server, enabling serverless MCP (Model Context Protocol) interactions with OpenAPI-defined APIs.
This is a **monorepo** with **composition-based architecture**:
**Core Packages (Generic):**
- `packages/mcp-server/` - Generic MCP server (NO API-specific code)
- `packages/lambda-runtime/` - Generic Lambda runtime base
- `packages/infrastructure/` - Reusable CDK infrastructure (constructs, stack, config, app)
**API Packages (Specific):**
- `packages/apis/petstore/` - Swagger Petstore API
- `packages/apis/zoho-crm/` - Zoho CRM API with custom OAuth
## Architecture Principles
1. **Composition over Inheritance** - Generic constructs composed into API-specific stacks
2. **No Environment Variables in Generic Code** - All parameters passed explicitly
3. **API-Specific Code Isolation** - Custom auth providers live in API packages
4. **Plugin System** - Auth providers registered at runtime
## Key Components
### Generic Infrastructure Package (`packages/infrastructure/`)
Complete CDK deployment infrastructure:
- `infra_constructs/openapi_mcp_deployment.py` - Reusable CDK construct (Lambda + API Gateway)
- `stack.py` - Generic CDK stack using composition
- `config.py` - Base `ApiConfig` dataclass for API configurations
- `app.py` - CDK app entry point with automatic config discovery
- `runtime.py` - Default Lambda runtime (can be overridden by API packages)
- `Dockerfile` - Default Docker image (can be overridden by API packages)
All configuration is passed explicitly - no environment variable defaults in generic code.
### Generic Lambda Runtime (`packages/lambda-runtime/base_handler.py`)
- Fully parameterized - reads all config from environment variables
- No API-specific code
- Can be extended by API-specific runtimes
### Generic MCP Server (`packages/mcp-server/`)
- Zero API-specific code (Zoho auth removed)
- Only standard auth types: none, basic, bearer, api_key, cognito
- Plugin system allows runtime registration of custom auth providers
### API-Specific Packages (`packages/apis/*/`)
Each API package contains minimal files (leveraging the generic infrastructure):
- `config.py` - Python dataclass extending `ApiConfig` (from `mcp-openapi-infrastructure`)
- `cdk.json` - CDK configuration pointing to `mcp_openapi_infrastructure.app`
- `auth.py` - (Optional) Custom auth provider (e.g., Zoho OAuth)
- `runtime.py` - (Optional) Custom Lambda runtime that registers custom auth
- `Dockerfile` - (Optional) Custom Docker image if default doesn't suffice
## Configuration
### API Configuration (Python, not YAML)
Each API is configured via Python dataclasses in `packages/apis/*/config.py` by extending `ApiConfig`:
```python
from dataclasses import dataclass
from mcp_openapi_infrastructure import ApiConfig
@dataclass
class PetstoreConfig(ApiConfig):
api_name: str = "PetstoreAPI"
api_base_url: str = "https://petstore3.swagger.io/api/v3"
api_spec_url: str = "https://petstore3.swagger.io/api/v3/openapi.json"
auth_type: str = "none"
```
Benefits of Python config over YAML:
- Type safety with dataclasses
- IDE autocomplete and validation
- Can include validation logic and properties
- Environment variable access via `os.getenv()` in properties
- No separate YAML parsing needed
## Deployment Commands
Each API package is independently deployable using AWS CDK.
### Deploy Petstore API
```bash
cd packages/apis/petstore
# Bootstrap CDK (first time only)
cdk bootstrap
# Deploy
cdk deploy
# Destroy
cdk destroy
```
### Deploy Zoho CRM API
```bash
cd packages/apis/zoho-crm
# Set OAuth token
export ZOHO_OAUTH_TOKEN="your-token"
# Deploy
cdk deploy
```
### Adding a New API
1. Create a new directory in `packages/apis/your-api-name/`
2. Create `config.py` extending `ApiConfig` with your API details
3. Copy `cdk.json` from an existing API package (petstore)
4. (Optional) Add custom `auth.py` if needed (see Zoho example)
5. (Optional) Add custom `runtime.py` to register custom auth
6. (Optional) Add custom `Dockerfile` if needed
7. Deploy with `cdk deploy`
## Testing
### Local Testing
Each API package includes a Dockerfile for local testing:
```bash
cd packages/apis/petstore
docker build -t petstore-mcp -f Dockerfile ../../..
docker run --rm -p 8080:8080 petstore-mcp
# Test
curl -X POST http://localhost:8080/ \
-H "Content-Type: application/json" \
-d '{"jsonrpc": "2.0", "method": "tools/list", "id": 1}'
```
### Testing Deployed Lambda
```bash
curl -X POST https://<api-url>/ \
-H "Content-Type: application/json" \
-d '{"jsonrpc": "2.0", "method": "tools/list", "id": 1}'
```
## Important Notes
### Architecture
- **Composition over Inheritance**: Generic constructs composed into API stacks
- **No API-Specific Code in Core**: All API customizations in `packages/apis/`
- **Plugin System**: Custom auth providers registered at runtime
- **Python Configuration**: Dataclasses instead of YAML for type safety
### Deployment
- **Independent API Packages**: Each API is a standalone CDK app
- **Stack Naming**: Defined in `config.py` of each API package
- **Multi-API Support**: Deploy as many APIs as needed independently
- **Docker Image Deployment**: No Lambda layers needed
### Performance
- Lambda cold start: ~2-3 seconds (Docker image + OpenAPI spec loading)
- Warm start: ~100-300ms (HTTP server stays running between invocations)
- Session-based HTTP transport: full MCP protocol support with state management
- Lambda Web Adapter enables standard HTTP server patterns on Lambda
### Security
- OpenAPI spec must be accessible from Lambda (public URL or VPC access)
- Authentication credentials should use AWS Secrets Manager (not hardcoded)
- Environment variables passed from CDK stack to Lambda function
## License
Apache-2.0 - includes code from awslabs/mcp (see LICENSE and NOTICE files)