S3-compatible storage
The io.b3os/s3 pack: 6 actions with call snippets, fixture outputs, connection setup and error codes, generated from version 1.0.0.
io.b3os/s3 1.0.0 · storage, files, open-data · MIT
Read and write objects in S3-compatible storage (AWS S3, Cloudflare R2, DigitalOcean Spaces, Backblaze B2, Wasabi, Linode, Google Cloud Storage) through presigned URLs you generate with your own keys, and read public AWS buckets by name (open data such as NOAA). Objects come back as text, or parsed JSON for JSON objects; binary objects are not supported. No access keys are stored: this pack cannot sign requests.
Every call's result carries upstream_status and timing: validate_ms, inject_ms, render_ms, upstream_ms, map_ms and total_ms. upstream is the service's time; the others are B3OS's own (call actions). The snippets below show no timing values, because a fixture records none.
Connection
No credential: a keyless public API. Calls name no connection.
Hosts it reaches: *.amazonaws.com, *.r2.cloudflarestorage.com, *.r2.dev, *.digitaloceanspaces.com, *.backblazeb2.com, *.wasabisys.com, *.linodeobjects.com, storage.googleapis.com.
Actions
| Action | Effect | MCP tool | Title |
|---|---|---|---|
get-object | read | s3__get-object | Get object (URL) |
head-object | read | s3__head-object | Get object metadata (URL) |
put-object | write | s3__put-object | Upload object (presigned URL) |
delete-object | irreversible | s3__delete-object | Delete object (presigned URL) |
get-public-object | read | s3__get-public-object | Get public object (AWS) |
list-public-objects | read | s3__list-public-objects | List public bucket (AWS) |
get-object
Get object (URL). Download a text or JSON object from a presigned GET URL or a public object URL, with its content type, size, ETag and Last-Modified.
Ref io.b3os/s3/get-object@1.0.0 · effect read · no connection · MCP tool s3__get-object
bashcurl -s https://beta-api.b3os.org/v1/actions/call \ -H "Authorization: Bearer $B3OS_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "ref": "io.b3os/s3/get-object@1", "input": {"url": "https://noaa-ghcn-pds.s3.amazonaws.com/ghcnd-version.txt"} }'
tsimport { B3OS } from "@b3os/sdk";const b3os = new B3OS();const result = await b3os.actions.call({ ref: "io.b3os/s3/get-object@1", input: { url: "https://noaa-ghcn-pds.s3.amazonaws.com/ghcnd-version.txt" },});console.log(result.output);
pythonfrom b3os import B3OSb3os = B3OS()result = b3os.actions.call({ "ref": "io.b3os/s3/get-object@1", "input": { "url": "https://noaa-ghcn-pds.s3.amazonaws.com/ghcnd-version.txt", },})print(result["output"])
json{ "method": "tools/call", "params": { "name": "s3__get-object", "arguments": { "url": "https://noaa-ghcn-pds.s3.amazonaws.com/ghcnd-version.txt" } }}
Expose the pack as tools with --packs s3 on the local server or ?packs=s3 on the remote URL, and the agent calls s3__get-object with the action's input. The tool needs no connection. Without exposing the pack, actions_call takes the same input with ref.
Output, labeled fixture: Get object (URL) (response recorded 2026-10-26). From the bundle's fixtures/get-object.json, not a live call.
json{ "status": 200, "content_type": "application/octet-stream", "content_length": "270", "etag": "\"ce4b95c54fb467188f7cd0f8704193e7\"", "last_modified": "Mon, 26 Oct 2026 03:04:41 GMT", "body": "The current version of GHCN Daily is 3.35-upd-2026102417 (i.e, an update that started at 2026102417 [yyyymmddhh] UTC; yyyy=year; mm=month; dd=day; hh=hour),\ncreated by appending recently available data updates to the last fully reprocessed version: 3.35-por-2026101623.\n"}
When the service answers with an error, the call fails with upstream_error and pack_error.code is one of:
pack_error.code | Service status | Retryable | Message |
|---|---|---|---|
not_found | 404 | no | No such bucket or key (or the bucket does not allow listing). |
forbidden | 403 | no | Access denied: the object is not public, or the presigned URL expired, was signed for another method or has a mismatched Content-Type. |
invalid_request | 301, 307, 400, 412 | no | The bucket is in another region; use its regional endpoint URL. |
rate_limited | 429, 503 | yes | Object storage asked to slow down (SlowDown). |
head-object
Get object metadata (URL). Content type, size, ETag and Last-Modified of an object from a presigned HEAD URL or a public URL, without downloading it. Use it to check that an object exists.
Ref io.b3os/s3/head-object@1.0.0 · effect read · no connection · MCP tool s3__head-object
bashcurl -s https://beta-api.b3os.org/v1/actions/call \ -H "Authorization: Bearer $B3OS_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "ref": "io.b3os/s3/head-object@1", "input": { "url": "https://noaa-ghcn-pds.s3.amazonaws.com/ghcnd-countries.txt" } }'
tsimport { B3OS } from "@b3os/sdk";const b3os = new B3OS();const result = await b3os.actions.call({ ref: "io.b3os/s3/head-object@1", input: { url: "https://noaa-ghcn-pds.s3.amazonaws.com/ghcnd-countries.txt", },});console.log(result.output);
pythonfrom b3os import B3OSb3os = B3OS()result = b3os.actions.call({ "ref": "io.b3os/s3/head-object@1", "input": { "url": "https://noaa-ghcn-pds.s3.amazonaws.com/ghcnd-countries.txt", },})print(result["output"])
json{ "method": "tools/call", "params": { "name": "s3__head-object", "arguments": { "url": "https://noaa-ghcn-pds.s3.amazonaws.com/ghcnd-countries.txt" } }}
Expose the pack as tools with --packs s3 on the local server or ?packs=s3 on the remote URL, and the agent calls s3__head-object with the action's input. The tool needs no connection. Without exposing the pack, actions_call takes the same input with ref.
Output, labeled fixture: Get object metadata (URL) (response recorded 2026-10-26). From the bundle's fixtures/head-object.json, not a live call.
json{ "status": 200, "content_type": "application/octet-stream", "content_length": "3659", "etag": "\"f1243f811af1949b11f1bce625b961b1\"", "last_modified": "Fri, 03 Feb 2023 22:32:30 GMT"}
When the service answers with an error, the call fails with upstream_error and pack_error.code is one of:
pack_error.code | Service status | Retryable | Message |
|---|---|---|---|
not_found | 404 | no | No such bucket or key (or the bucket does not allow listing). |
forbidden | 403 | no | Access denied: the object is not public, or the presigned URL expired, was signed for another method or has a mismatched Content-Type. |
invalid_request | 301, 307, 400, 412 | no | The bucket is in another region; use its regional endpoint URL. |
rate_limited | 429, 503 | yes | Object storage asked to slow down (SlowDown). |
put-object
Upload object (presigned URL). Upload text (CSV, JSON, Markdown, logs, ...) to a presigned PUT URL, replacing any object at that key. If the URL was signed with a Content-Type, pass the same content_type. Returns the new ETag.
Ref io.b3os/s3/put-object@1.0.0 · effect write · no connection · MCP tool s3__put-object
bashcurl -s https://beta-api.b3os.org/v1/actions/call \ -H "Authorization: Bearer $B3OS_API_KEY" \ -H "Idempotency-Key: 7c1e2f6a-1d43-4a8e-b2a5-3f0c9d5e8b11" \ -H "Content-Type: application/json" \ -d '{ "ref": "io.b3os/s3/put-object@1", "input": { "url": "https://acme-reports.s3.us-east-1.amazonaws.com/daily/2026-10-26.csv?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAEXAMPLE%2F20261026%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20261026T080000Z&X-Amz-Expires=900&X-Amz-SignedHeaders=host&X-Amz-Signature=0000000000000000000000000000000000000000000000000000000000000000", "body": "date,orders\n2026-10-26,412\n", "content_type": "text/csv" } }'
tsimport { B3OS } from "@b3os/sdk";const b3os = new B3OS();const result = await b3os.actions.call({ ref: "io.b3os/s3/put-object@1", input: { url: "https://acme-reports.s3.us-east-1.amazonaws.com/daily/2026-10-26.csv?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAEXAMPLE%2F20261026%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20261026T080000Z&X-Amz-Expires=900&X-Amz-SignedHeaders=host&X-Amz-Signature=0000000000000000000000000000000000000000000000000000000000000000", body: "date,orders\n2026-10-26,412\n", content_type: "text/csv", },}, { idempotencyKey: crypto.randomUUID() });console.log(result.output);
pythonimport uuidfrom b3os import B3OSb3os = B3OS()result = b3os.actions.call({ "ref": "io.b3os/s3/put-object@1", "input": { "url": "https://acme-reports.s3.us-east-1.amazonaws.com/daily/2026-10-26.csv?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAEXAMPLE%2F20261026%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20261026T080000Z&X-Amz-Expires=900&X-Amz-SignedHeaders=host&X-Amz-Signature=0000000000000000000000000000000000000000000000000000000000000000", "body": "date,orders\n2026-10-26,412\n", "content_type": "text/csv", },}, idempotency_key=str(uuid.uuid4()))print(result["output"])
json{ "method": "tools/call", "params": { "name": "s3__put-object", "arguments": { "url": "https://acme-reports.s3.us-east-1.amazonaws.com/daily/2026-10-26.csv?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAEXAMPLE%2F20261026%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20261026T080000Z&X-Amz-Expires=900&X-Amz-SignedHeaders=host&X-Amz-Signature=0000000000000000000000000000000000000000000000000000000000000000", "body": "date,orders\n2026-10-26,412\n", "content_type": "text/csv" } }}
Expose the pack as tools with --packs s3 on the local server or ?packs=s3 on the remote URL, and the agent calls s3__put-object with the action's input. The tool needs no connection. Without exposing the pack, actions_call takes the same input with ref.
Output, labeled fixture: Upload object (presigned URL) (documented response shape, example values). From the bundle's fixtures/put-object.json, not a live call.
json{"status": 200, "etag": "\"9b2cf535f27731c974343645a3985328\""}
When the service answers with an error, the call fails with upstream_error and pack_error.code is one of:
pack_error.code | Service status | Retryable | Message |
|---|---|---|---|
not_found | 404 | no | No such bucket or key (or the bucket does not allow listing). |
forbidden | 403 | no | Access denied: the object is not public, or the presigned URL expired, was signed for another method or has a mismatched Content-Type. |
invalid_request | 301, 307, 400, 412 | no | The bucket is in another region; use its regional endpoint URL. |
rate_limited | 429, 503 | yes | Object storage asked to slow down (SlowDown). |
delete-object
Delete object (presigned URL). Delete the object a presigned DELETE URL points to. S3 answers 204 whether or not the key existed.
Ref io.b3os/s3/delete-object@1.0.0 · effect irreversible · no connection · MCP tool s3__delete-object
bashcurl -s https://beta-api.b3os.org/v1/actions/call \ -H "Authorization: Bearer $B3OS_API_KEY" \ -H "Idempotency-Key: 7c1e2f6a-1d43-4a8e-b2a5-3f0c9d5e8b11" \ -H "Content-Type: application/json" \ -d '{ "ref": "io.b3os/s3/delete-object@1", "input": { "url": "https://acme-reports.s3.us-east-1.amazonaws.com/daily/2026-10-25.csv?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAEXAMPLE%2F20261026%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20261026T080000Z&X-Amz-Expires=900&X-Amz-SignedHeaders=host&X-Amz-Signature=0000000000000000000000000000000000000000000000000000000000000000" } }'
tsimport { B3OS } from "@b3os/sdk";const b3os = new B3OS();const result = await b3os.actions.call({ ref: "io.b3os/s3/delete-object@1", input: { url: "https://acme-reports.s3.us-east-1.amazonaws.com/daily/2026-10-25.csv?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAEXAMPLE%2F20261026%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20261026T080000Z&X-Amz-Expires=900&X-Amz-SignedHeaders=host&X-Amz-Signature=0000000000000000000000000000000000000000000000000000000000000000", },}, { idempotencyKey: crypto.randomUUID() });console.log(result.output);
pythonimport uuidfrom b3os import B3OSb3os = B3OS()result = b3os.actions.call({ "ref": "io.b3os/s3/delete-object@1", "input": { "url": "https://acme-reports.s3.us-east-1.amazonaws.com/daily/2026-10-25.csv?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAEXAMPLE%2F20261026%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20261026T080000Z&X-Amz-Expires=900&X-Amz-SignedHeaders=host&X-Amz-Signature=0000000000000000000000000000000000000000000000000000000000000000", },}, idempotency_key=str(uuid.uuid4()))print(result["output"])
json{ "method": "tools/call", "params": { "name": "s3__delete-object", "arguments": { "url": "https://acme-reports.s3.us-east-1.amazonaws.com/daily/2026-10-25.csv?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAEXAMPLE%2F20261026%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20261026T080000Z&X-Amz-Expires=900&X-Amz-SignedHeaders=host&X-Amz-Signature=0000000000000000000000000000000000000000000000000000000000000000" } }}
Expose the pack as tools with --packs s3 on the local server or ?packs=s3 on the remote URL, and the agent calls s3__delete-object with the action's input. The tool needs no connection. Without exposing the pack, actions_call takes the same input with ref.
Output, labeled fixture: Delete object (presigned URL) (documented response shape, example values). From the bundle's fixtures/delete-object.json, not a live call.
json{"status": 204, "deleted": true}
When the service answers with an error, the call fails with upstream_error and pack_error.code is one of:
pack_error.code | Service status | Retryable | Message |
|---|---|---|---|
not_found | 404 | no | No such bucket or key (or the bucket does not allow listing). |
forbidden | 403 | no | Access denied: the object is not public, or the presigned URL expired, was signed for another method or has a mismatched Content-Type. |
invalid_request | 301, 307, 400, 412 | no | The bucket is in another region; use its regional endpoint URL. |
rate_limited | 429, 503 | yes | Object storage asked to slow down (SlowDown). |
get-public-object
Get public object (AWS). Download a text or JSON object from a public AWS S3 bucket by bucket name and key, for example bucket noaa-ghcn-pds and key ghcnd-version.txt (AWS Open Data). Uses the bucket's global virtual-hosted endpoint.
Ref io.b3os/s3/get-public-object@1.0.0 · effect read · no connection · MCP tool s3__get-public-object
bashcurl -s https://beta-api.b3os.org/v1/actions/call \ -H "Authorization: Bearer $B3OS_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "ref": "io.b3os/s3/get-public-object@1", "input": {"bucket": "noaa-ghcn-pds", "key": "ghcnd-version.txt"} }'
tsimport { B3OS } from "@b3os/sdk";const b3os = new B3OS();const result = await b3os.actions.call({ ref: "io.b3os/s3/get-public-object@1", input: { bucket: "noaa-ghcn-pds", key: "ghcnd-version.txt" },});console.log(result.output);
pythonfrom b3os import B3OSb3os = B3OS()result = b3os.actions.call({ "ref": "io.b3os/s3/get-public-object@1", "input": {"bucket": "noaa-ghcn-pds", "key": "ghcnd-version.txt"},})print(result["output"])
json{ "method": "tools/call", "params": { "name": "s3__get-public-object", "arguments": {"bucket": "noaa-ghcn-pds", "key": "ghcnd-version.txt"} }}
Expose the pack as tools with --packs s3 on the local server or ?packs=s3 on the remote URL, and the agent calls s3__get-public-object with the action's input. The tool needs no connection. Without exposing the pack, actions_call takes the same input with ref.
Output, labeled fixture: Get public object (AWS) (response recorded 2026-10-26). From the bundle's fixtures/get-public-object.json, not a live call.
json{ "status": 200, "content_type": "application/octet-stream", "content_length": "270", "etag": "\"ce4b95c54fb467188f7cd0f8704193e7\"", "last_modified": "Mon, 26 Oct 2026 03:04:41 GMT", "body": "The current version of GHCN Daily is 3.35-upd-2026102417 (i.e, an update that started at 2026102417 [yyyymmddhh] UTC; yyyy=year; mm=month; dd=day; hh=hour),\ncreated by appending recently available data updates to the last fully reprocessed version: 3.35-por-2026101623.\n"}
When the service answers with an error, the call fails with upstream_error and pack_error.code is one of:
pack_error.code | Service status | Retryable | Message |
|---|---|---|---|
not_found | 404 | no | No such bucket or key (or the bucket does not allow listing). |
forbidden | 403 | no | Access denied: the object is not public, or the presigned URL expired, was signed for another method or has a mismatched Content-Type. |
invalid_request | 301, 307, 400, 412 | no | The bucket is in another region; use its regional endpoint URL. |
rate_limited | 429, 503 | yes | Object storage asked to slow down (SlowDown). |
list-public-objects
List public bucket (AWS). List keys in a public AWS S3 bucket (ListObjectsV2), optionally under a prefix and grouped by a delimiter such as /. Returns S3's ListBucketResult XML as text: Contents (Key, Size, LastModified, ETag), CommonPrefixes, IsTruncated and NextContinuationToken for the next page.
Ref io.b3os/s3/list-public-objects@1.0.0 · effect read · no connection · MCP tool s3__list-public-objects
bashcurl -s https://beta-api.b3os.org/v1/actions/call \ -H "Authorization: Bearer $B3OS_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "ref": "io.b3os/s3/list-public-objects@1", "input": {"bucket": "noaa-ghcn-pds", "delimiter": "/", "max_keys": 3} }'
tsimport { B3OS } from "@b3os/sdk";const b3os = new B3OS();const result = await b3os.actions.call({ ref: "io.b3os/s3/list-public-objects@1", input: { bucket: "noaa-ghcn-pds", delimiter: "/", max_keys: 3 },});console.log(result.output);
pythonfrom b3os import B3OSb3os = B3OS()result = b3os.actions.call({ "ref": "io.b3os/s3/list-public-objects@1", "input": {"bucket": "noaa-ghcn-pds", "delimiter": "/", "max_keys": 3},})print(result["output"])
json{ "method": "tools/call", "params": { "name": "s3__list-public-objects", "arguments": {"bucket": "noaa-ghcn-pds", "delimiter": "/", "max_keys": 3} }}
Expose the pack as tools with --packs s3 on the local server or ?packs=s3 on the remote URL, and the agent calls s3__list-public-objects with the action's input. The tool needs no connection. Without exposing the pack, actions_call takes the same input with ref.
Output, labeled fixture: List public bucket (AWS) (response recorded 2026-10-26). From the bundle's fixtures/list-public-objects.json, not a live call.
json{ "bucket": "noaa-ghcn-pds", "xml": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<ListBucketResult xmlns=\"http://s3.amazonaws.com/doc/2006-03-01/\"><Name>noaa-ghcn-pds</Name><Prefix></Prefix><NextContinuationToken>1GVGTPA0SW8XTW9SRqMIbwN2TtACJKtuy4TBJIRiKxkkW+W9DRqJZIqPDoUgNVhdk</NextContinuationToken><KeyCount>3</KeyCount><MaxKeys>3</MaxKeys><Delimiter>/</Delimiter><IsTruncated>true</IsTruncated><Contents><Key>ghcnd-countries.txt</Key><LastModified>2023-02-03T22:32:30.000Z</LastModified><ETag>"f1243f811af1949b11f1bce625b961b1"</ETag><Size>3659</Size><StorageClass>STANDARD</StorageClass></Contents><CommonPrefixes><Prefix>csv.gz/</Prefix></CommonPrefixes><CommonPrefixes><Prefix>csv/</Prefix></CommonPrefixes></ListBucketResult>"}
When the service answers with an error, the call fails with upstream_error and pack_error.code is one of:
pack_error.code | Service status | Retryable | Message |
|---|---|---|---|
not_found | 404 | no | No such bucket or key (or the bucket does not allow listing). |
forbidden | 403 | no | Access denied: the object is not public, or the presigned URL expired, was signed for another method or has a mismatched Content-Type. |
invalid_request | 301, 307, 400, 412 | no | The bucket is in another region; use its regional endpoint URL. |
rate_limited | 429, 503 | yes | Object storage asked to slow down (SlowDown). |