Skip to content

Security & Authentication

By default, the S3 Documentation MCP server runs in open access mode for easy local development. For shared or remote deployments, enable API key authentication.

Terminal window
ENABLE_AUTH=false
  • ✅ No authentication required
  • ✅ Perfect for local development
  • ⚠️ Not recommended for shared networks or remote access
Terminal window
ENABLE_AUTH=true
MCP_API_KEY=your-secret-key-here
  • ✅ All endpoints require valid API key (except /health)
  • ✅ Supports multiple authentication methods
  • ✅ Secure for shared/remote deployments

Use a cryptographically secure random key:

Terminal window
# macOS/Linux
openssl rand -hex 32
# Output example:
# 3f7a8b2c9d4e1f6g8h5i7j9k0l2m3n4o5p6q7r8s9t0u1v2w3x4y5z6a7b8c9d0

Or use a password manager to generate a strong random string.

Edit your .env file:

Terminal window
# Enable authentication
ENABLE_AUTH=true
# Set your API key
MCP_API_KEY=3f7a8b2c9d4e1f6g8h5i7j9k0l2m3n4o5p6q7r8s9t0u1v2w3x4y5z6a7b8c9d0
Terminal window
# Docker Compose
docker-compose restart
# From source
npm start
Section titled “Method 1: Authorization Header (Recommended)”

Send the API key in the Authorization header as a Bearer token:

Terminal window
curl -H "Authorization: Bearer your-secret-key" \
http://localhost:3000/mcp

Why recommended?

  • ✅ More secure (not logged in URLs)
  • ✅ Standard HTTP authentication pattern
  • ✅ Not visible in browser history or server logs

Send the API key as a URL parameter:

Terminal window
curl "http://localhost:3000/mcp?api_key=your-secret-key"

Use when:

  • Browser-based testing
  • Tools that don’t support custom headers
  • Quick debugging

⚠️ Note: Query parameters appear in logs and browser history.

Edit ~/.cursor/mcp.json:

{
"mcpServers": {
"doc": {
"type": "streamable-http",
"url": "http://127.0.0.1:3000/mcp",
"headers": {
"Authorization": "Bearer your-secret-key"
},
"note": "S3 Documentation RAG Server with authentication"
}
}
}

Edit your Claude Desktop configuration file:

  • macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
  • Windows: %APPDATA%/Claude/claude_desktop_config.json
{
"mcpServers": {
"doc": {
"type": "streamable-http",
"url": "http://127.0.0.1:3000/mcp",
"headers": {
"Authorization": "Bearer your-secret-key"
},
"note": "S3 Documentation RAG Server with authentication"
}
}
}

When authentication is enabled:

  • POST /mcp - MCP protocol endpoint
  • All MCP tools (search_documentation, refresh_index, get_full_document)
  • All MCP resources (resources/list, resources/read)
  • GET /health - Health check endpoint
{
"error": "Unauthorized",
"message": "Missing API key"
}

HTTP Status: 401 Unauthorized

{
"error": "Unauthorized",
"message": "Invalid API key"
}

HTTP Status: 401 Unauthorized

  • ✅ Use strong, randomly generated keys (32+ characters)
  • ✅ Store keys securely (e.g., in environment variables, not in code)
  • ✅ Rotate keys periodically
  • ✅ Use different keys for different environments (dev, staging, prod)
  • ❌ Never commit keys to version control
  • ❌ Never share keys in plain text (email, chat, etc.)

Local Development:

Terminal window
ENABLE_AUTH=false

No need for authentication on localhost.

Shared Network (Office, VPN):

Terminal window
ENABLE_AUTH=true
MCP_API_KEY=<strong-random-key>

Protect against unauthorized access from the network.

Remote/Public Deployment:

Terminal window
ENABLE_AUTH=true
MCP_API_KEY=<strong-random-key>

Always enable authentication for internet-facing deployments.

While API key authentication provides basic security, consider these additional measures for production:

  1. HTTPS/TLS: Use a reverse proxy (nginx, Caddy) with SSL certificates
  2. Rate Limiting: Implement rate limiting at the proxy level
  3. IP Whitelisting: Restrict access to known IP addresses
  4. Network Isolation: Run in a private VPC or behind a firewall
  5. Monitoring: Log authentication attempts and alert on failures
Terminal window
ENABLE_AUTH=false
Terminal window
ENABLE_AUTH=true
MCP_API_KEY=staging-3f7a8b2c9d4e1f6g8h5i7j9k0l2m3n4o
Terminal window
ENABLE_AUTH=true
MCP_API_KEY=prod-5p6q7r8s9t0u1v2w3x4y5z6a7b8c9d0e1f2g3h4i5j6k7

Cause: Authentication is enabled but no API key was provided.

Solution:

  • Add Authorization: Bearer <key> header
  • Or append ?api_key=<key> to the URL
  • Check MCP client configuration

Cause: The provided API key doesn’t match the configured key.

Solution:

  • Verify the key in .env matches the one in your request
  • Check for typos or extra spaces
  • Ensure the key wasn’t truncated
  • Restart the server after changing .env

Authentication Works in curl but Not in MCP Client

Section titled “Authentication Works in curl but Not in MCP Client”

Cause: MCP client configuration might be incorrect.

Solution:

  • Verify the headers section in your MCP config
  • Ensure the key is correctly formatted
  • Restart the MCP client after config changes

The /health endpoint is always accessible without authentication, useful for monitoring:

Terminal window
# Works even with ENABLE_AUTH=true
curl http://localhost:3000/health

Response:

{
"status": "healthy",
"timestamp": "2025-10-25T10:30:00.000Z",
"version": "0.0.0"
}