R2 Bucket MCP
Allows uploading, downloading, listing, and deleting files on Cloudflare R2 buckets.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@R2 Bucket MCPupload vitalo APK v2.1.0"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
r2-bucket-mcp
Servidor MCP stdio para Cursor y otros clientes MCP. Sube archivos locales a Cloudflare R2 (S3-compatible) sin ejecutar scripts shell. Pensado para APKs de proyectos (vitalo, linkbox, nestle, …) y cualquier otro archivo.
Qué hace
Expone cinco tools MCP:
Tool | Uso |
| APKs con key |
| Cualquier archivo con key opcional |
| Descargar por key (URL o guardar local) |
| Listar objetos por prefijo |
| Borrar objeto por key |
La respuesta incluye downloadUrl (URL pública CDN si R2_PUBLIC_BASE_URL está configurada, o presigned URL temporal).
Related MCP server: S3 MCP Server
Instalación
cd /Users/samuelgerardocastrolopez/Desktop/r2-bucket-mcp
npm installCredenciales R2
Usa las mismas variables que opencode_whatsapp/.env (sin copiar secretos al repo):
Abre
opencode_whatsapp/.enven tu máquina.Copia los valores de
R2_ACCESS_KEY_ID,R2_SECRET_ACCESS_KEY,R2_BUCKET,R2_ENDPOINT(oR2_ACCOUNT_ID), y opcionalmenteR2_PUBLIC_BASE_URL.Para pruebas locales, crea
.enven este repo desde.env.example(nunca lo commitees).
Variable | Requerida | Descripción |
| sí | Access key R2 |
| sí | Secret key R2 |
| sí | Bucket (default: |
| sí* | Endpoint S3-compatible |
| sí* | Alternativa a endpoint explícito |
| no | Prefijo global opcional |
| no | CDN pública; si falta, presigned URL |
| no | Default: 604800 (7 días) |
| no | Límite validación MCP (default: 500 MB) |
* Al menos uno de R2_ENDPOINT o R2_ACCOUNT_ID.
Prueba manual
Arranque stdio (proceso queda esperando; Ctrl+C para salir):
node index.js
# stderr: [r2-bucket-mcp] ready (stdio)Smoke test con credenciales en .env local (sube un .smoke-test.txt temporal):
npm run smokeRegistrar en Cursor
Settings → MCP o edita ~/.cursor/mcp.json.
Usa la ruta absoluta de node (which node). Ejemplo:
{
"mcpServers": {
"r2-bucket": {
"type": "stdio",
"command": "/Users/samuelgerardocastrolopez/.nvm/versions/node/v22.17.0/bin/node",
"args": [
"/Users/samuelgerardocastrolopez/Desktop/r2-bucket-mcp/index.js"
],
"env": {
"R2_ACCESS_KEY_ID": "PEGAR_ACCESS_KEY",
"R2_SECRET_ACCESS_KEY": "PEGAR_SECRET_KEY",
"R2_BUCKET": "apks",
"R2_ENDPOINT": "https://<account-id>.r2.cloudflarestorage.com",
"R2_PUBLIC_BASE_URL": "https://cdn.tudominio.com"
}
}
}
}Reinicia Cursor o recarga servidores MCP tras cambiar mcp.json.
Uso desde agentes
APKs: preferir
upload_apkconproject,versionyfilePathabsoluto.Otros archivos:
upload_fileconfilePathy opcionalmentekey,prefix,contentType.Listar:
list_filesconprefixopcional (ej.vitalo/).Descargar:
get_fileconkey; opcionalfilePathabsoluto para guardar en disco.Borrar:
delete_fileconkeycompleta (ej.vitalo/2.1.0/app-release.apk).
Ejemplo de key generada por upload_apk:
vitalo/2.1.0/app-release.apkRespuesta JSON (campo principal para compartir el enlace):
{
"ok": true,
"bucket": "apks",
"key": "vitalo/2.1.0/app-release.apk",
"size": 12345678,
"contentType": "application/vnd.android.package-archive",
"downloadUrl": "https://cdn.tudominio.com/vitalo/2.1.0/app-release.apk",
"publicUrl": "https://cdn.tudominio.com/vitalo/2.1.0/app-release.apk",
"presignedUrl": null
}Si no hay R2_PUBLIC_BASE_URL, downloadUrl será una presigned URL y publicUrl será null.
Integración SDK
Con un agente SDK local y settingSources: ['user'], el agente carga el mismo MCP definido en ~/.cursor/mcp.json. También puedes pasar mcpServers inline en la config del agente con las mismas credenciales en env.
Tools
upload_file
Parámetro | Requerido | Descripción |
| sí | Ruta absoluta al archivo local |
| no | Clave en el bucket (default: basename) |
| no | Prefijo override (sin |
| no | MIME explícito |
upload_apk
Parámetro | Requerido | Descripción |
| sí | Ruta absoluta al APK |
| sí | Alias ( |
| sí | Versión ( |
| no | Default: |
get_file
Parámetro | Requerido | Descripción |
| sí | Clave del objeto (ej. |
| no | Ruta absoluta local para guardar; sin ella solo devuelve URLs |
list_files
Parámetro | Requerido | Descripción |
| no | Filtro de prefijo (ej. |
| no | Máximo por página (default: 100, max: 1000) |
| no | Token de paginación de una respuesta anterior |
delete_file
Parámetro | Requerido | Descripción |
| sí | Clave del objeto (ej. |
Available Tools
5 toolsdelete_fileA
Delete an object from R2 by key (e.g. vitalo/2.1.0/app-release.apk). Global R2_KEY_PREFIX is applied automatically if configured.
| Name | Required | Description | Default |
|---|---|---|---|
| key | Yes | Object key in the bucket (e.g. vitalo/2.1.0/app-release.apk) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Discloses that it deletes (destructive) and that a global prefix is applied automatically. Lacks details on error handling (e.g., key not found), idempotency, or authentication requirements. No annotations provided to supplement.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, minimal and clear. No wasted words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Adequate for a simple delete operation with one parameter. Does not specify return value or error cases, but the purpose is clear.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema covers the key parameter with description. The description adds value by explaining the automatic prefix behavior, which is not in the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Clearly states action (delete) and resource (object from R2). Distinguishes from siblings like get_file, list_files, upload_apk, upload_file. Includes example key and mentions automatic prefix.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Implicitly indicates when to use (delete an object). Does not explicitly exclude other scenarios or compare to siblings, but the context of sibling tools provides alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_fileA
Get/download an object from R2 by key. Returns downloadUrl (public CDN or presigned). Optionally saves to a local filePath on the MCP host. Global R2_KEY_PREFIX is applied if configured.
| Name | Required | Description | Default |
|---|---|---|---|
| key | Yes | Object key in the bucket (e.g. vitalo/2.1.0/app-release.apk) | |
| filePath | No | Absolute local path to save the file. If omitted, only returns URLs and metadata. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations provided, but description discloses key behaviors: returns downloadUrl, optional local save, global prefix application. Lacks details on error handling or authentication, but adequate for a read operation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three concise sentences, front-loaded with purpose, no redundant information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Covers core functionality and parameter semantics, but lacks details on return structure (e.g., metadata fields) and error scenarios. Adequate for a simple retrieval tool without output schema.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, and description adds value by explaining the Optional filePath behavior and global prefix application, beyond what schema provides.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Description clearly states the tool retrieves an object from R2 by key, distinguishing it from sibling tools like delete_file, list_files, upload_apk, and upload_file which perform different operations.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Description implies usage for downloading objects, but does not explicitly state when to use vs alternatives. However, sibling tool names are self-explanatory, providing sufficient context.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_filesA
List objects in the R2 bucket. Optional prefix filters keys (e.g. vitalo/ or vitalo/2.1.0/). Combines with global R2_KEY_PREFIX if set. Use continuationToken to paginate.
| Name | Required | Description | Default |
|---|---|---|---|
| prefix | No | Key prefix filter (e.g. vitalo/ or vitalo/2.1.0/) | |
| maxKeys | No | Max objects per page (default: 100, max: 1000) | |
| continuationToken | No | Pagination token from a previous list_files response |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description must bear the burden. It describes the listing behavior and mentions combination with a global prefix, but it doesn't explicitly state that the operation is read-only or non-destructive, nor does it mention rate limits or authentication needs.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences, no fluff, front-loaded with the main action. Every clause earns its place, and it's easy to scan.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description should explain the return format (e.g., keys, continuationToken). It does not. The parameter coverage is fine, but the missing return info is a gap for a listing tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema covers all three parameters with descriptions, achieving 100% coverage. However, the description adds value by explaining the combination with global R2_KEY_PREFIX and giving concrete prefix examples, which goes beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool lists objects in an R2 bucket, with optional prefix filtering and pagination. It distinguishes from sibling tools (delete, get, upload) which perform different operations.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides clear usage context: listing objects, filtering by prefix, and paginating. It doesn't explicitly state when not to use it, but the sibling tools cover other operations, making the intent clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
upload_apkA
Upload an Android APK to R2 using the convention {project}/{version}/{filename}. Prefer this tool for APK releases (vitalo, linkbox, nestle, diageo, contador, …).
| Name | Required | Description | Default |
|---|---|---|---|
| filePath | Yes | Absolute path to the APK on the MCP host | |
| project | Yes | Project alias (e.g. vitalo, linkbox, nestle, diageo, contador) | |
| version | Yes | Version or tag (e.g. 2.1.0) | |
| filename | No | APK filename in the bucket (default: app-release.apk) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, and the description does not disclose behavioral traits such as whether the upload overwrites existing files, requires authentication, rate limits, or any side effects. The naming convention is mentioned, but that is about parameter structure, not behavior.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description consists of two concise sentences, both essential. The first sentence states the purpose and naming convention, and the second provides usage preference. No filler words; front-loaded with the primary action.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given no output schema and no annotations, the description leaves out important context such as return value, error handling, overwrite behavior, or prerequisites. While the purpose is clear, the completeness is insufficient for an agent to fully understand the tool's effects.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3. The description adds marginal value by explaining the naming convention, but the schema already documents each parameter (e.g., 'Absolute path to the APK', 'Project alias', etc.). The description does not provide additional semantic depth beyond what the schema offers.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the action ('Upload'), the resource ('Android APK to R2'), and the naming convention ('{project}/{version}/{filename}'). It distinguishes from sibling tools like upload_file by specifying 'Prefer this tool for APK releases', indicating specialization.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly says 'Prefer this tool for APK releases (vitalo, linkbox, nestle, diageo, contador, …)', providing clear context on when to use it. However, it does not explicitly state when not to use it or name alternatives, so it's slightly below the top score.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
upload_fileB
Upload a local file to Cloudflare R2. filePath must be an absolute path on the host where this MCP runs. Returns downloadUrl (public CDN URL if R2_PUBLIC_BASE_URL is set, otherwise a presigned URL).
| Name | Required | Description | Default |
|---|---|---|---|
| filePath | Yes | Absolute path to the local file on the MCP host | |
| key | No | Destination key in the bucket (e.g. vitalo/2.1.0/app-release.apk). Default: file basename | |
| prefix | No | Key prefix override (without global R2_KEY_PREFIX) | |
| contentType | No | Explicit MIME type; inferred from extension if omitted |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, and the description lacks details on behavioral traits such as whether uploads overwrite existing keys, permissions needed, or any side effects. It does mention the return value but is insufficient for full transparency.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is very concise: three sentences that cover the essential purpose, a critical constraint (absolute path), and the return value. No extraneous information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description is fairly complete for a simple upload tool, explaining the file path requirement and return value. However, it does not address overwrite behavior or differentiate from the sibling upload_apk, leaving some contextual gaps.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema has 100% description coverage, and the description essentially restates the schema information (e.g., default key basename, prefix override). It adds no new meaning beyond what is already in the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool uploads a local file to Cloudflare R2, specifying 'filePath must be an absolute path'. However, it does not explicitly differentiate from the sibling tool 'upload_apk' which likely has a similar purpose.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description only mentions that filePath must be an absolute path on the host, but provides no guidance on when to use this tool versus alternatives like upload_apk or the other sibling tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
5 tool updates
v1.0.0- First observed
delete_file - First observed
get_file - First observed
list_files - First observed
upload_apk - First observed
upload_file
TDQS
Scored across 5 tools
Each tool has a clearly distinct purpose: delete, get, list, upload specifically for APKs, and general upload. No ambiguity between operations.
All tool names follow a consistent verb_noun pattern in snake_case (delete_file, get_file, list_files, upload_apk, upload_file).
Five tools cover the essential CRUD operations for interacting with an R2 bucket: get, delete, list, upload general, and upload for APKs. This is well-scoped.
The tool set covers the core lifecycle for objects in a bucket: listing, retrieving, deleting, and uploading (with a specialized variant for APKs). No obvious gaps for the stated purpose.
Maintenance
Related MCP Connectors
Persistent file storage for AI agents via MCP and curl. Upload, download, and version files.
Create a free sandbox object storage bucket; upload, download, list, inspect, and delete objects.
Cloud file relay: chunked uploads, folders, share links, inline text reads, ZIP packing.
File uploads for AI agents. Upload, list, and manage files. No signup required.
Related MCP Servers
- AlicenseBqualityDmaintenanceEnables AI assistants to manage MinIO object storage through comprehensive bucket operations, file uploads/downloads, batch processing, permissions management, and URL generation. Supports both automatic and manual connection modes with flexible authentication options.19152MIT
- AlicenseAqualityDmaintenanceEnables interaction with S3-compatible storage services like AWS S3 and Cloudflare R2, supporting bucket management, object listing, reading, uploading, and deletion operations.5199ISC
- AlicenseNot gradedqualityFmaintenanceEnables seamless integration with Backblaze B2 cloud storage for managing buckets, uploading/downloading files, handling large multipart uploads, and managing application keys through natural language interactions.71MIT
- AlicenseNot gradedqualityCmaintenanceEnables interaction with AWS S3 storage through bucket operations (create, delete, list), object management (upload, download, delete, list), and bucket policy configuration using AWS credentials.212MIT