Skip to main content
Glama
debadatta30

s3-mcp-server

by debadatta30

S3 MCP 서버 on ECS Fargate

읽기 전용 S3 도구(list_buckets, list_objects, get_bucket_public_access, get_bucket_size)를 노출하는 원격 OAuth2 인증 MCP 서버로, Auth0를 ID 제공자로 사용하여 ALB 및 CloudFront 뒤의 ECS Fargate 태스크로 실행되도록 설계되었습니다.

작동 방식

  • CloudFront는 에지에서 TLS를 종료하고 모든 헤더(Authorization 포함)를 일반 HTTP를 통해 내부 ALB로 전달합니다.

  • ALB는 요청을 포트 8080의 ECS Fargate 태스크로 전달합니다.

  • 태스크(server.py)는 어떤 도구를 실행하기 전에 Auth0에 대해 Bearer 토큰을 검증한 후, 태스크의 IAM 역할을 사용하여 S3와 통신합니다. 정적 AWS 자격 증명은 어디에도 없습니다.

  • 태스크는 Auth0의 JWKS 엔드포인트와 S3의 퍼블릭 API에 모두 NAT Gateway를 통해 접근합니다. 프라이빗 서브넷에서 실행되고 S3 VPC 엔드포인트가 구성되지 않았기 때문입니다.

OAuth 핸드셰이크(로그인, PKCE 코드 교환)는 전적으로 MCP 클라이언트(예: Claude Desktop)와 Auth0 사이에서 이루어집니다. 서버는 맨 처음(자체 발견 문서 제공)과 맨 마지막(결과 토큰 검증)에만 관여합니다. 디버깅할 때 이 점을 명심하세요: 로그인 실패는 이 서버의 로그에 절대 나타나지 않습니다. 서버가 그 교환 과정에 포함되지 않았기 때문입니다.

Related MCP server: aws-safe-mcp

Auth0 설정

Auth0 테넌트(무료 티어로 충분)가 필요하며, 여기에 두 가지가 있어야 합니다:

  1. API — Auth0이 불투명한 토큰 대신 실제 JWT 액세스 토큰을 발급하도록 만듭니다.

    • 대시보드 → Applications → APIs → Create API

    • Identifier: 클라이언트가 연결할 정확한 URL, 예: https://your-domain.example.com/sse — 이것이 AUTH0_AUDIENCE가 되며 배포하는 환경과 바이트 단위로 일치해야 합니다.

    • 서명 알고리즘: RS256(기본값)

  2. 애플리케이션 — MCP 클라이언트가 인증하는 대상입니다.

    • 대시보드 → Applications → Applications → Create Application

    • 유형: Regular Web Application

    • Settings에서 Allowed Callback URLs를 MCP 클라이언트가 사용하는 리디렉션 URI(들)로 설정합니다(Claude Desktop의 경우: https://claude.ai/api/mcp/auth_callback)

    • Domain, Client ID, Client Secret을 기록해 둡니다. 이 값들은 AUTH0_DOMAIN / AUTH0_CLIENT_ID / MCP 클라이언트에 제공할 클라이언트 시크릿이 됩니다 (서버 자체는 시크릿이 필요하지 않습니다).

  3. API에 대한 애플리케이션 권한 부여 — 이 단계를 놓치기 쉽습니다. API와 애플리케이션을 별도로 생성하는 것만으로는 두 항목이 연결되지 않습니다. API → Application Access 탭으로 이동 → 애플리케이션을 켭니다. 이 단계를 건너뛰면 모든 인증 시도가 invalid_request / "Client is not authorized to access resource server" 오류와 함께 실패하며, 클라이언트가 로그인 페이지를 보기도 전에 실패합니다.

로컬 테스트(전송 계층에 AWS 필요 없음)

cp .env.example .env
# edit .env with your Auth0 tenant details if you want to test auth locally
pip install -r requirements.txt
python server.py

서버는 http://localhost:8080/sse에서 수신 대기합니다. /health는 인증 없이 200 ok를 반환합니다. 이는 ALB 대상 그룹 상태 확인 경로입니다.

다른 모든 경로는 Authorization: Bearer <token>이 필요하며, 여기서 토큰은 AUTH0_CLIENT_ID와 일치하는 앱 클라이언트에 대한 Auth0 액세스 토큰(JWT, audAUTH0_AUDIENCE와 일치)이어야 합니다.

Docker

docker build -t s3-mcp-server .
docker run -p 8080:8080 --env-file .env s3-mcp-server

Fargate에 배포

cd infra
pip install -r requirements.txt   # into a venv
cdk bootstrap   # first time only, per account/region
cdk deploy \
  -c auth0_domain=your-tenant.us.auth0.com \
  -c auth0_client_id=your-application-client-id \
  -c auth0_audience=https://your-domain.example.com/sse

auth0_audience는 CDK가 생성하려는 CloudFront 도메인과 일치해야 하며, 여기에 /sse가 추가됩니다. 첫 번째 배포에서는 알 수 없을 가능성이 높습니다. 한 번 배포하여 DistributionURL 출력을 얻은 후, 실제 audience 값으로 다시 배포합니다(이 작업은 한 번만 필요합니다. CloudFront 도메인은 동일한 스택의 이후 배포에서 안정적입니다).

매번 -c 플래그를 전달하는 대신, gitignore된 infra/cdk.context.json에 넣을 수 있습니다:

{
  "auth0_domain": "your-tenant.us.auth0.com",
  "auth0_client_id": "your-application-client-id",
  "auth0_audience": "https://your-domain.example.com/sse"
}

사람들이 자주 실수하는 부분

  1. ALB 유휴 제한 시간. SSE 연결은 오래 지속됩니다. ALB의 기본 유휴 제한 시간(60초)은 연결을 끊습니다. 이 스택은 300초(5분)로 설정합니다. 클라이언트가 주기적인 핑을 보내지 않는다면 더 높이십시오.

  2. 상태 확인 경로. 대상 그룹 상태 확인은 /health를 가리키며, /sse가 아닙니다. /sse는 인증이 필요하고 스트리밍 응답이므로 ALB 상태 확인기가 예상하는 방식이 아닙니다.

  3. 자격 증명. 컨테이너는 AWS 자격 증명을 설정하지 않습니다. boto3는 컨테이너 자격 증명 엔드포인트를 통해 Fargate 태스크의 IAM 역할에서 자동으로 가져옵니다. 키를 이미지나 환경 변수에 포함시키지 마십시오.

  4. 에그레스. 태스크는 첫 번째 요청 시 Auth0의 JWKS를 HTTPS를 통해 가져온 후(1시간 동안 캐싱), 모든 도구 호출에 대해 S3의 퍼블릭 API를 호출합니다. 둘 다 NAT Gateway를 통해 나갑니다. 이 스택은 S3 VPC Gateway Endpoint를 구성하지 않기 때문입니다. 태스크의 서브넷에 실제로 NAT 라우트가 있는지 확인하거나, S3용 Gateway Endpoint를 추가하십시오(무료이며, 해당 트래픽을 공용 인터넷에서 차단합니다).

  5. MCP SDK의 자체 DNS 재바인딩 보호는 실제 도메인 뒤에서 이 기능을 자동으로 손상시킵니다. FastMCPTransportSecuritySettings는 기본적으로 허용 호스트 목록을 가지며, 인증이 성공한 후에도 실제 Host 헤더(예: CloudFront 도메인)로 도착하는 모든 요청을 421 Misdirected Request로 거부합니다. 이는 OAuth 흐름이 완료된 후에 발생하므로 인증 버그로 오인하기 쉽습니다. 이 서버는 server.py에서 이를 비활성화합니다. 이미 Auth0AuthMiddleware가 Bearer 토큰 인증으로 모든 경로를 보호하고 있기 때문입니다:

    mcp = FastMCP(
        "s3-mcp-server",
        transport_security=TransportSecuritySettings(enable_dns_rebinding_protection=False),
    )

최소 IAM 태스크 역할 정책(위의 읽기 전용 도구)

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "S3ReadOnly",
      "Effect": "Allow",
      "Action": [
        "s3:ListAllMyBuckets",
        "s3:ListBucket",
        "s3:GetBucketAcl",
        "s3:GetBucketPolicyStatus",
        "s3:GetBucketPolicy"
      ],
      "Resource": "*"
    }
  ]
}

Resource를 특정 버킷 ARN으로 범위를 좁히십시오. 이 에이전트가 실제로 볼 수 있어야 하는 버킷을 알게 되면 말입니다. 나중에 쓰기 도구(예: 수명 주기 정책 변경)를 추가하는 경우, 이 정책을 확장하기보다는 별도의 더 좁은 문을 제공하십시오.

MCP 클라이언트 설정

원격 SSE 서버를 지원하는 모든 MCP 클라이언트를 배포된 URL로 지정하고, 위 설정 단계에서 얻은 Auth0 애플리케이션의 클라이언트 ID와 시크릿을 제공하십시오:

{
  "mcpServers": {
    "s3": {
      "url": "https://your-domain.example.com/sse",
      "oauth_client_id": "your-application-client-id",
      "oauth_client_secret": "your-application-client-secret"
    }
  }
}

정확한 설정 형식은 클라이언트에 따라 다릅니다. Claude Desktop은 원시 JSON 대신 Connectors 설정 아래 양식 필드로 이를 노출합니다. 어느 쪽이든 OAuth 리디렉션/토큰 교환은 MCP 권한 부여 사양에 따라 클라이언트가 처리합니다. 이 서버는 각 요청에 대해 결과 Bearer 토큰만 검증합니다.

F
license - not found
-
quality - not tested
C
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Servers

View all related MCP servers

Related MCP Connectors

  • A paid remote MCP for CLI tool MCP, built to return verdicts, receipts, usage logs, and audit-ready

  • MCP server for interacting with the Supabase platform

  • Hosted MCP server for agent governance: MCP config audits, injection scans, scope-policy checks.

View all MCP Connectors

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/debadatta30/s3-mcp-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server