Skip to main content
Glama
debadatta30

s3-mcp-server

by debadatta30

Servidor S3 MCP en ECS Fargate

Un servidor MCP remoto con autenticación OAuth2 que expone herramientas de solo lectura de S3 (list_buckets, list_objects, get_bucket_public_access, get_bucket_size), diseñado para ejecutarse como una tarea de ECS Fargate detrás de un ALB y CloudFront, con Auth0 como proveedor de identidad.

Cómo se conecta

  • CloudFront termina TLS en el borde y reenvía cada cabecera (incluyendo Authorization) a un ALB interno a través de HTTP simple.

  • ALB pasa la solicitud a la tarea de ECS Fargate en el puerto 8080.

  • La tarea (server.py) valida el token de portador contra Auth0 antes de ejecutar cualquier herramienta, luego se comunica con S3 usando el rol IAM de la tarea — sin credenciales AWS estáticas en ningún lado.

  • La tarea accede tanto al endpoint JWKS de Auth0 como a la API pública de S3 a través de un NAT Gateway, ya que se ejecuta en subredes privadas y no se ha configurado ningún endpoint de VPC para S3.

El handshake OAuth (inicio de sesión, intercambio de código PKCE) ocurre completamente entre el cliente MCP (por ejemplo, Claude Desktop) y Auth0 — el servidor solo participa al principio (sirviendo su propio documento de descubrimiento) y al final (validando el token resultante). Tenga esto en cuenta al depurar: un inicio de sesión fallido nunca aparece en los registros de este servidor, porque el servidor nunca formó parte de ese intercambio.

Related MCP server: aws-safe-mcp

Configuración de Auth0

Necesita un tenant de Auth0 (el nivel gratuito es suficiente) con dos cosas:

  1. Una API — esto hace que Auth0 emita tokens de acceso JWT reales en lugar de tokens opacos.

    • Panel → Applications → APIs → Create API

    • Identifier: la URL exacta a la que se conectarán los clientes, por ejemplo, https://your-domain.example.com/sse — esto se convierte en AUTH0_AUDIENCE y debe coincidir byte por byte con lo que implemente detrás.

    • Algoritmo de firma: RS256 (por defecto)

  2. Una Aplicación — cómo se autentica el cliente MCP.

    • Panel → Applications → Applications → Create Application

    • Tipo: Regular Web Application

    • En Settings, establezca Allowed Callback URLs a la(s) URI(s) de redirección que use su cliente MCP (para Claude Desktop: https://claude.ai/api/mcp/auth_callback)

    • Anote el Domain, Client ID y Client Secret — estos se convierten en AUTH0_DOMAIN / AUTH0_CLIENT_ID / el secreto de cliente que le da a su cliente MCP (el servidor mismo nunca necesita el secreto).

  3. Autorice la Aplicación para la API — este paso es fácil de pasar por alto. Crear una API y una Aplicación por separado no las vincula. Vaya a la API → pestaña Application Access → active su Aplicación. Si omite esto, cada intento de autorización falla con invalid_request / "Client is not authorized to access resource server", antes de que el cliente vea una página de inicio de sesión.

Prueba local (no se necesita AWS para la capa de transporte)

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

El servidor escucha en http://localhost:8080/sse. /health devuelve 200 ok sin requerir autenticación — esa es la ruta de verificación de salud del grupo de destino del ALB.

Cada otra ruta requiere Authorization: Bearer <token> donde el token es un access token de Auth0 (JWT, aud coincidiendo con AUTH0_AUDIENCE) para un cliente de aplicación que coincida con AUTH0_CLIENT_ID.

Docker

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

Despliegue en 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 debe coincidir con el dominio de CloudFront que CDK está a punto de crear, con /sse añadido — probablemente no lo sabrá en el primer despliegue. Despliegue una vez para obtener la salida DistributionURL, luego vuelva a desplegar con el valor real de audiencia (esto solo necesita hacerse una vez; el dominio de CloudFront es estable en despliegues posteriores de la misma pila).

En lugar de pasar banderas -c cada vez, puede ponerlas en un infra/cdk.context.json ignorado por git:

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

Cosas que suelen causar problemas

  1. Tiempo de espera de inactividad del ALB. Las conexiones SSE son de larga duración. El tiempo de espera de inactividad predeterminado del ALB (60s) las matará. Esta pila lo establece en 300 (5 min) — auméntelo si su cliente no envía pings periódicos.

  2. Ruta de verificación de salud. La verificación de salud del grupo de destino apunta a /health, no a /sse/sse requiere autenticación y es una respuesta de transmisión, ninguna de las cuales espera el verificador de salud del ALB.

  3. Credenciales. El contenedor nunca establece credenciales AWS — boto3 las obtiene automáticamente del rol IAM de la tarea de Fargate a través del endpoint de credenciales del contenedor. No incruste claves en la imagen o en las variables de entorno.

  4. Salida. La tarea obtiene el JWKS de Auth0 a través de HTTPS en la primera solicitud (luego lo almacena en caché durante una hora), y llama a la API pública de S3 para cada llamada de herramienta — ambas salen a través del NAT Gateway, ya que esta pila no configura un S3 VPC Gateway Endpoint. Asegúrese de que la subred de la tarea tenga realmente una ruta NAT, o añada un Gateway Endpoint para S3 (gratuito, y mantiene ese tráfico fuera de la internet pública).

  5. La protección de reenlace de DNS del SDK de MCP romperá silenciosamente esto detrás de cualquier dominio real. FastMCP's TransportSecuritySettings por defecto tiene una lista de hosts permitidos vacía, lo que rechaza cada solicitud que llega con una cabecera Host real (como su dominio de CloudFront) — incluso después de que la autenticación tenga éxito — con 421 Misdirected Request. Esto ocurre después de que se complete el flujo OAuth, por lo que es fácil confundirlo con un error de autenticación. Este servidor lo deshabilita en server.py, ya que Auth0AuthMiddleware ya protege cada ruta con autenticación de token de portador:

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

Política de rol IAM mínima para la tarea (herramientas de solo lectura arriba)

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

Escopo Resource a ARNs de bucket específicos una vez que sepa qué buckets debe poder ver este agente. Si luego añade una herramienta de escritura (por ejemplo, cambios en la política de ciclo de vida), asígnele su propia declaración más restringida en lugar de ampliar esta.

Configuración del cliente MCP

Apunte cualquier cliente MCP que admita servidores SSE remotos a su URL desplegada, con el Client ID y Secret de la Aplicación de Auth0 de los pasos de configuración anteriores:

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

La forma exacta de la configuración depende del cliente — Claude Desktop expone estos como campos de formulario en su configuración de Connectors en lugar de JSON sin procesar. De cualquier manera, el intercambio de redirección/token OAuth es manejado por el cliente según la especificación de autorización de MCP; este servidor solo valida el token de portador resultante en cada solicitud.

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