Skip to content
← Public packages

@kentcdodds/agent-files

Mint short-lived R2 PUT URLs for agent file handoffs; public download via managed r2.dev.

Version
0.0.0
License
Published
September 22, 2026
Pinned commit
ba0f573
Rating
No ratings yet
Forks
0
Adaptation effort
—

@kentcdodds/agent-files

Intent

Give Cursor (and other) agents a tiny, durable way to exchange files without shoving multi‑MB payloads through MCP base64 chunking or Dropbox. Mint a short‑lived R2 PUT URL with a small MCP call, PUT the bytes with curl/fetch, then share the public managed *.r2.dev download URL. Objects live in the agent-files bucket on Kent’s Cloudflare account and are meant to expire after about a week.

Prerequisites

  • User secret cloudflareApiToken (same token used by home-maintenance / stash) with permission to manage R2 on Cloudflare account a41d50ecaf0ae0f86dd1824ef6729cb2.
  • Token must be able to call https://api.cloudflare.com (R2 bucket create, managed public domain, temp-access-credentials).

Create or rotate the token in the Cloudflare dashboard: API Tokens. Prefer a custom token with Account → Cloudflare R2 → Edit (and Tokens → Read for parent key id resolution).

Setup

  1. Ensure cloudflareApiToken exists as a user secret in Kody (name only — never paste the value into chat or commits).
  2. First successful create-upload / upload auto-ensures:
    • R2 bucket agent-files on account a41d50ecaf0ae0f86dd1824ef6729cb2
    • Managed public *.r2.dev domain
    • Object lifecycle delete after ~7 days (best-effort; see below if it fails)
  3. No package-local secrets beyond the mounted user token.

Manual lifecycle (if auto-apply fails)

Dashboard → R2 → bucket agent-files → Settings → Object lifecycle → add a rule that deletes objects after 7 days (empty prefix = whole bucket).

How it works

  1. Call ./create-upload with { filename, confirm: true } (optional contentType, prefix, expiresInSeconds).
  2. PUT file bytes to upload.url with the returned upload.headers (Content-Type must match).
  3. Hand downloadUrl to whoever needs the file (Cursor cloud agent, human, …).
  4. Optionally ./get / ./delete by key.

Prefer ./create-upload over ./upload. The latter accepts small bytesBase64 payloads only and rejects oversized MCP bodies.

Done when

  • create-upload with confirm: true returns upload.url + downloadUrl
  • A real PUT to upload.url succeeds
  • GET downloadUrl returns 200 with the bytes
  • ./get({ key }) reports found: true
  • ./delete({ key, confirm: true }) removes the object

Bucket / public URL base are created on first use; check the first create-upload result’s downloadUrl host (e.g. https://pub-….r2.dev/…).

Report this listing

Log in to report this listing.