Skip to main content
Glama
debadatta30

s3-mcp-server

by debadatta30

在 ECS Fargate 上运行的 S3 MCP 服务器

一个远程的、经过 OAuth2 认证的 MCP 服务器,暴露只读的 S3 工具 (list_bucketslist_objectsget_bucket_public_accessget_bucket_size),设计为在 ECS Fargate 任务中运行,位于 ALB 和 CloudFront 之后,并以 Auth0 作为身份提供者。

整体架构

  • CloudFront 在边缘终止 TLS,并将所有头部(包括 Authorization) 通过普通 HTTP 转发到内部 ALB。

  • ALB 将请求交给 ECS Fargate 任务(端口 8080)。

  • 任务(server.py)在执行任何工具之前,会针对 Auth0 验证不记名令牌, 然后使用任务的 IAM 角色访问 S3——任何地方都不存在静态 AWS 凭证。

  • 任务通过 NAT 网关访问 Auth0 的 JWKS 端点和 S3 的公共 API, 因为它运行在私有子网中,且未配置 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, 并且必须与你部署的 URL 逐字节匹配。

    • 签名算法: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

    • 记下 DomainClient IDClient Secret——这些将成为 AUTH0_DOMAIN / AUTH0_CLIENT_ID / 你提供给 MCP 客户端的客户端密钥 (服务器本身从不使用密钥)。

  3. 为 API 授权该应用——这一步很容易遗漏。 分别创建 API 和应用 并会将它们关联起来。进入 API → Application Access 标签页 → 切换你的应用为开启。跳过这一步,每次授权尝试都会失败,并显示 invalid_request / “客户端未被授权访问资源服务器”,客户端甚至 看不到登录页面。

本地测试(传输层不需要 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>,其中 token 是 针对 AUTH0_CLIENT_ID 的应用客户端的 Auth0 访问令牌(JWT, aud 匹配 AUTH0_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 标志放入 gitignored 的 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 分钟)——如果你的客户端 不发送周期性 ping,请进一步提高。

  2. 健康检查路径。 目标组健康检查指向 /health,而不是 /sse—— /sse 需要认证并且是流式响应,ALB 的健康检查器不期望这两点。

  3. 凭证。 容器从不设置 AWS 凭证——boto3 通过容器凭证端点自动 从 Fargate 任务的 IAM 角色获取。不要将密钥烘焙到镜像或环境变量中。

  4. 出站流量。 任务在首次请求时(然后缓存一小时)通过 HTTPS 获取 Auth0 的 JWKS,并且每次工具调用都会调用 S3 的公共 API——两者都通过 NAT 网关出去,因为此堆栈没有配置 S3 VPC 网关端点。确保任务的子网 实际上具有 NAT 路由,或者为 S3 添加一个网关端点(免费,并且使该流量 远离公共互联网)。

  5. MCP SDK 自身的 DNS 重绑定保护会在任何真实域名后面静默破坏此功能。 FastMCPTransportSecuritySettings 默认具有一个 的允许主机列表, 这会拒绝每个带有真实 Host 头部(如你的 CloudFront 域名)的请求—— 即使在认证成功之后——并返回 421 Misdirected Request。这发生在 OAuth 流程完成之后,因此很容易被误认为是认证错误。此服务器在 server.py 中 禁用了它,因为 Auth0AuthMiddleware 已经用不记名令牌认证守卫了所有路由:

    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 将这些暴露为表单字段 (在其 Connectors 设置中),而不是原始 JSON。无论哪种方式,OAuth 重定向/令牌交换都由客户端根据 MCP 授权规范处理;此服务器仅在每个 请求上验证生成的承载令牌。

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