A Model Context Protocol (MCP) server that exposes AWS S3 operations through a secure, well-defined interface. This server provides tools for listing buckets and objects, and generating presigned URLs for safe data access.
Perfect for integrating S3 with Claude Desktop and other MCP clients!
- List Buckets: Enumerate all S3 buckets in your AWS account
- List Objects: Browse objects within a bucket with optional prefix filtering
- Presigned GET URLs: Generate secure, temporary URLs for downloading objects
- Presigned PUT URLs: Generate secure, temporary URLs for uploading objects (optional, requires ALLOW_WRITE flag)
- Input Validation: All inputs are validated using Zod schemas
- Logging: Structured logging with Pino
- Safe by Default: Write operations are disabled unless explicitly enabled
- Cross-Platform: Works on Windows, Mac, and Linux
# 1. Install and build
npm install
npm run build
# 2. Configure AWS credentials
cp .env.example .env
# Edit .env with your AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_REGION
# 3. Test connection
node examples/quick-test.jsFor Claude Desktop - Edit claude_desktop_config.json:
{
"mcpServers": {
"aws-s3": {
"command": "node",
"args": ["/absolute/path/to/aws-s3-mcp-server/dist/index.js"]
}
}
}For VS Code - Edit ~/.vscode/mcp.json:
{
"servers": {
"aws-s3": {
"type": "stdio",
"command": "node",
"args": ["/absolute/path/to/aws-s3-mcp-server/dist/index.js"]
}
}
}Replace the path with your actual installation directory.
- Claude Desktop: Restart β Ask "List my S3 buckets"
- VS Code: Reload window β
@aws-s3 list my buckets
π Complete guide: QUICKSTART.md
- Setup Guide - Complete installation and configuration instructions
- Usage Guide - How to use with Claude Desktop and examples
- Examples - Sample scripts for download/upload operations
npm install
npm run buildCreate a .env file in the root directory (see .env.example):
# Required
AWS_ACCESS_KEY_ID=your_access_key_here
AWS_SECRET_ACCESS_KEY=your_secret_key_here
AWS_REGION=us-east-1
# Optional: Enable write operations (presign_put)
ALLOW_WRITE=false
# Optional: Set log level (default: info)
LOG_LEVEL=infoπ For detailed setup instructions, see SETUP_GUIDE.md
The server uses stdio transport and communicates via standard input/output, making it suitable for integration with MCP clients like Claude Desktop.
npm startList all buckets:
"Show me all my S3 buckets"
List objects in a bucket:
"List all files in my-data-bucket"
Get download link:
"Give me a download link for report.pdf in my-docs-bucket"
Get upload link (if ALLOW_WRITE=true):
"Generate an upload URL for new-file.json in my-bucket"
π For complete usage examples, see USAGE_GUIDE.md
List all S3 buckets in the AWS account.
Input: None
Example Response:
[
{
"name": "my-bucket",
"creationDate": "2024-01-01T00:00:00.000Z"
}
]List objects in an S3 bucket with optional filtering.
Input:
bucket(required): The name of the S3 bucketprefix(optional): Filter objects by prefixmaxKeys(optional): Maximum number of objects to return (1-1000)
Example Response:
{
"objects": [
{
"key": "path/to/file.txt",
"size": 1024,
"lastModified": "2024-01-01T00:00:00.000Z",
"etag": "\"abc123\""
}
],
"isTruncated": false,
"keyCount": 1
}Generate a presigned URL for downloading an object.
Input:
bucket(required): The name of the S3 bucketkey(required): The object keyexpiresIn(optional): URL expiration time in seconds (default: 3600, max: 604800)
Example Response:
{
"url": "https://bucket.s3.amazonaws.com/key?X-Amz-Algorithm=...",
"expiresIn": 3600,
"bucket": "my-bucket",
"key": "path/to/file.txt"
}Generate a presigned URL for uploading an object (requires ALLOW_WRITE=true).
Input:
bucket(required): The name of the S3 bucketkey(required): The object keyexpiresIn(optional): URL expiration time in seconds (default: 3600, max: 604800)contentType(optional): Content type of the object
Example Response:
{
"url": "https://bucket.s3.amazonaws.com/key?X-Amz-Algorithm=...",
"expiresIn": 3600,
"bucket": "my-bucket",
"key": "path/to/file.txt",
"contentType": "application/json"
}npm run buildnpm run devnpm testnpm run lintnode examples/quick-test.js- Check Claude Desktop logs: Help β Show Logs
- Verify the server path in config is correct (use absolute path)
- Test manually:
node dist/index.js - Restart Claude Desktop
Error: Missing credentials
- Verify
.envfile exists in project root - Check no extra spaces in environment variables
- Ensure file is named exactly
.env(not.env.txt)
Error: Access Denied
- Verify IAM user has S3 permissions
- Check the bucket exists in the specified region
- Test credentials:
node examples/quick-test.js
Error: Invalid Access Key
- Verify AWS_ACCESS_KEY_ID is correct
- Check AWS_SECRET_ACCESS_KEY matches
- Ensure credentials haven't been rotated/deleted
- Set
ALLOW_WRITE=truein.envfile - Restart the MCP server
- Verify IAM user has PutObject permission
For buckets with millions of objects:
- Use prefix filtering:
"List files in my-bucket with prefix 'logs/2024/'" - Limit results:
"Show first 100 files in my-bucket" - Organize files with prefixes (like folders)
π For more troubleshooting, see SETUP_GUIDE.md
β DO:
- Store credentials in
.envfile (never commit to git) - Use IAM users with minimal required permissions
- Disable ALLOW_WRITE unless needed
- Use short expiration times for presigned URLs
- Rotate access keys regularly
β DON'T:
- Share presigned URLs publicly
- Use root AWS account credentials
- Commit
.envfile to version control - Grant broader permissions than necessary
aws-s3-mcp-server/
βββ dist/ # Compiled JavaScript (generated)
βββ src/ # TypeScript source code
β βββ index.ts # Main MCP server
β βββ index.test.ts # Unit tests
βββ examples/ # Example scripts and usage
β βββ quick-test.js # AWS connection test
β βββ test-upload.ps1 # Upload example
β βββ test-download.ps1 # Download example
βββ .env.example # Environment template
βββ package.json # Dependencies
βββ tsconfig.json # TypeScript config
βββ README.md # This file
βββ SETUP_GUIDE.md # Installation guide
βββ USAGE_GUIDE.md # Usage examples
- AWS credentials are loaded from environment variables only
- Write operations (presigned PUT URLs) are disabled by default
- All inputs are validated using Zod schemas
- Presigned URLs have configurable expiration (max 7 days)
- Logs are written to stderr to avoid interfering with stdio transport
- Issues: Report bugs or request features on GitHub
- Setup Help: See SETUP_GUIDE.md
- Usage Help: See USAGE_GUIDE.md
- Examples: Check the
examples/directory
Contributions are welcome! Please:
- Fork the repository
- Create a feature branch
- Make your changes
- Add tests if applicable
- Submit a pull request
MIT
| Task | Command |
|---|---|
| Install | npm install |
| Build | npm run build |
| Test AWS | node examples/quick-test.js |
| Start Server | npm start |
| Run Tests | npm test |
| Development Mode | npm run dev |
Need Help? Start with SETUP_GUIDE.md for installation or USAGE_GUIDE.md for examples!