Skip to main content
strands-icloud

๐ŸŽ strands-icloud

One Strands tool for the entire Apple ecosystem. Mail, Calendar, Messages, Contacts, Photos, Notes, Reminders, Find My โ€” local-first on macOS, remote-capable via standard protocols, exposable over MCP.

Built for Strands Agents. Battle-tested inside devduck.

use_apple(action="messages.search", query="flight")
use_apple(action="mail.unread", limit=10)
use_apple(action="photos.search", query="drone")   # โ† returns REAL image blocks the model can SEE
use_apple(action="findmy.locate", device="iPhone")

Table of Contents


Architecture

Two access layers, one dispatch surface:

flowchart TB
    A["๐ŸŽ use_apple(action=...)"]:::hub

    A --> L
    A --> R
    A --> C

    subgraph L["๐Ÿ–ฅ LOCAL ยท on-Mac ยท zero auth"]
        direction TB
        AS["AppleScript bridge<br/>Mail ยท Calendar ยท Contacts<br/>Notes ยท Reminders ยท Messages (send)"]
        FS["Direct file access<br/>chat.db (SQLite, read-only)<br/>Photos library (osxphotos)"]
    end

    subgraph R["๐ŸŒ REMOTE ยท anywhere ยท app-specific password โœ“"]
        direction TB
        IMAP["IMAP :993<br/>imap.mail.me.com"]
        CAL["CalDAV<br/>caldav.icloud.com"]
        CARD["CardDAV<br/>contacts.icloud.com"]
    end

    subgraph C["โ˜๏ธ CLOUD ยท pyicloud ยท real password + 2FA"]
        FM["Find My<br/>devices ยท locate ยท play sound"]
    end

    classDef hub fill:#0a84ff,stroke:#0a84ff,color:#fff,font-weight:bold
    classDef default fill:#1c1c1e,stroke:#3a3a3c,color:#f5f5f7
    style L fill:#0e2a12,stroke:#32d74b,color:#f5f5f7
    style R fill:#0b1f33,stroke:#0a84ff,color:#f5f5f7
    style C fill:#2a0e1a,stroke:#ff375f,color:#f5f5f7
flowchart LR
    subgraph clients["Consumers"]
        DD["๐Ÿฆ† devduck<br/>(pipx inject)"]
        SA["Strands Agent<br/>(pip install)"]
        CC["Claude Code / Desktop<br/>Cursor ยท Kiro<br/>(MCP)"]
        TERM["Terminal<br/>(uvx strands-icloud)"]
    end

    DD --> UA["use_apple"]
    SA --> UA
    CC -->|"strands-icloud-mcp<br/>stdio / HTTP"| UA
    TERM -->|"CLI"| UA

    classDef default fill:#1c1c1e,stroke:#3a3a3c,color:#f5f5f7
    style UA fill:#0a84ff,stroke:#0a84ff,color:#fff,font-weight:bold
    style clients fill:#000,stroke:#3a3a3c,color:#98989d

Why local-first? Your Mac already syncs everything via iCloud. Reading local data means zero auth, zero rate limits, zero Apple-breaking-the-API risk, and full history (Messages back to day one). Remote protocols are the fallback for headless/off-Mac deployments; pyicloud is only used where there is no local equivalent (Find My).

Module layout

strands_icloud/
โ”œโ”€โ”€ __init__.py      # exports use_apple
โ”œโ”€โ”€ use_apple.py     # @tool dispatch + all local backends (~850 lines)
โ”œโ”€โ”€ remote.py        # IMAP / CalDAV / CardDAV clients (stdlib imaplib + caldav + raw DAV)
โ”œโ”€โ”€ mcp.py           # MCP server entrypoint (strands-icloud-mcp)
โ””โ”€โ”€ cli.py           # terminal CLI (strands-icloud / uvx strands-icloud)

Installation

Into devduck (pipx)

pipx inject devduck git+ssh://git@github.com/cagataycali/strands-icloud.git
# or from a local clone:
pipx inject devduck /path/to/strands-icloud

Register the tool (add to ~/.zshrc):

export DEVDUCK_TOOLS="$DEVDUCK_TOOLS;strands_icloud:use_apple"

Standalone (any Strands agent)

pip install git+ssh://git@github.com/cagataycali/strands-icloud.git
from strands import Agent
from strands_icloud import use_apple

agent = Agent(tools=[use_apple])
agent("what's on my calendar this week?")

Dependencies

Package Used for Required?
strands-agents @tool decorator yes
osxphotos Photos library access photos.* only
pyicloud Find My findmy.* only
caldav CalDAV calendar client caldav.* only
keyring macOS Keychain credential lookup optional (falls back to env)
strands-mcp-server MCP entrypoint MCP only

Everything imports lazily โ€” a missing optional dep only disables its domain, never the whole tool.


CLI

Every action, straight from your terminal โ€” no agent required. Ships as the strands-icloud console script:

# zero-install via uv (private repo โ†’ use --from git+ssh)
uvx --from git+ssh://git@github.com/cagataycali/strands-icloud.git strands-icloud reminders.list

# short alias once published to PyPI
uvx strands-icloud reminders.list

# or just use the installed script (pipx/pip)
strands-icloud messages.search --query flight

Examples

# Messages
strands-icloud messages.chats -n 10
strands-icloud messages.search -q "baklava"
strands-icloud messages.send --to "+15517274110" --text "hey from the terminal"

# Mail โ€” local (Mail.app) or remote (IMAP, faster on big inboxes)
strands-icloud mail.unread -n 10
strands-icloud imap.search -q invoice --folder INBOX -n 5
strands-icloud imap.read -q 4762                  # read by message ID

# Calendar โ€” local or CalDAV (syncs to all devices)
strands-icloud calendar.events --days 14
strands-icloud caldav.create --title "Dentist" --start "2026-07-25 14:30" --calendar Home

# Photos โ€” save image files locally
strands-icloud photos.search --label dog -n 3 --save ./out
strands-icloud photos.recent -n 5 --no-images     # metadata only

# Everything else
strands-icloud contacts.search -q mom
strands-icloud notes.read -q "meeting"
strands-icloud findmy.locate --device iPhone
strands-icloud actions                            # list every available action
strands-icloud mcp --http --port 8010             # start the MCP server

# Machine-readable output
strands-icloud reminders.list --json | jq '.content[0].text'

CLI flags

Flag Maps to Notes
--query / -q query search text or message/note ID
--limit / -n limit default 20
--chat / --folder chat chat filter (messages) or IMAP folder
--calendar calendar_name
--save DIR โ€” write photo images to disk
--no-images with_images=False metadata only, saves tokens/time
--json โ€” structured output (image bytes omitted)
all others same-named param --to --text --subject --body --title --start --end --due --days --person --label --device --from-date --to-date

Exit code is 0 on success, 1 on error โ€” safe for scripting.


Permissions Setup (macOS)

macOS gates each data source separately. You need:

1. Full Disk Access (required: Messages, speeds up Mail)

System Settings โ†’ Privacy & Security โ†’ Full Disk Access โ†’ add the app that hosts the Python process:

  • Running in Terminal/iTerm/Ghostty โ†’ add that terminal app
  • Running as a launchd service โ†’ add the Python binary itself
  • Running inside an IDE โ†’ add the IDE

Restart the process after granting. Without FDA, messages.* fails with unable to open database file.

2. Automation permissions (per-app, auto-prompted)

First time you call each domain, macOS shows "...wants to control Mail.app" โ€” click OK. One prompt per (host app ร— target app) pair. These land in System Settings โ†’ Privacy & Security โ†’ Automation.

If you accidentally denied one:

tccutil reset AppleEvents          # resets ALL automation grants

3. Photos library access

osxphotos reads the Photos SQLite directly โ€” covered by Full Disk Access. Export of edited/iCloud-offloaded originals may trigger a Photos permission prompt on first use.


Credentials & Keychain

App-specific password (IMAP / CalDAV / CardDAV)

Generate at account.apple.com โ†’ Sign-In and Security โ†’ App-Specific Passwords. Format: xxxx-xxxx-xxxx-xxxx.

Store it in macOS Keychain (recommended):

security add-generic-password -a "you@icloud.com" -s "strands-icloud" -w "xxxx-xxxx-xxxx-xxxx"

Then only the username goes in your shell config:

# ~/.zshrc
export ICLOUD_USERNAME="you@icloud.com"

Credential resolution order for remote protocols:

  1. ICLOUD_PASSWORD env var (if set โ€” e.g. CI, containers)
  2. Keychain service strands-icloud (via keyring)
  3. Keychain service pyicloud (legacy compat)
  4. โ†’ error with instructions

Real password (Find My only)

pyicloud drives the iCloud web API, which uses Apple's GSA/SRP handshake โ€” app-specific passwords do not work there. If you want Find My:

security add-generic-password -a "you@icloud.com" -s "strands-icloud-real" -w "YOUR_REAL_PASSWORD"

Resolution order: ICLOUD_PASSWORD_REAL env โ†’ keychain strands-icloud-real โ†’ keychain pyicloud.

First login triggers 2FA once (run any findmy.* action interactively, or use the icloud CLI that ships with pyicloud). The session cookie is cached in ~/.pyicloud and lasts ~weeks.


Action Reference

Every action returns {"status": "success"|"error", "content": [{"text": ...}, ...]}. Photos actions append image blocks after the text block.

๐Ÿ’ฌ Messages

Backend: direct SQLite read of ~/Library/Messages/chat.db (opened mode=ro โ€” never locks Messages.app), AppleScript for sending. Full history, fast, works even if Messages.app is closed.

Action Params Description
messages.list chat (optional filter: name/number/email substring), limit Recent messages, chronological. chat matches chat_identifier, display_name, or handle
messages.search query (required), limit Full-text LIKE search over all message text, all time
messages.chats limit Conversations sorted by most recent activity, with message counts
messages.send to (phone/email), text Sends via Messages.app. Tries iMessage participant first, falls back to generic buddy (SMS relay if configured)
use_apple(action="messages.list", chat="+31638236164", limit=50)
use_apple(action="messages.search", query="baklava")
use_apple(action="messages.send", to="cagataycali@icloud.com", text="hey from my agent")

Timestamps are converted from Apple epoch (nanoseconds since 2001-01-01) automatically.

๐Ÿ“ง Mail (local โ€” Mail.app)

Backend: AppleScript. Mail.app must be running (open -gja Mail launches it hidden/background).

Action Params Description
mail.unread limit Unread from inbox. Scans newestโ†’oldest, capped at 400 most recent (see Performance)
mail.search query (required), limit Subject OR sender contains query. Uses Mail's whose filter โ€” slow on huge inboxes
mail.read query (subject substring) Full body (plain text) of first matching email
mail.send to, subject, body Composes and sends immediately via default account
use_apple(action="mail.unread", limit=10)
use_apple(action="mail.read", query="Run failed: CI")
use_apple(action="mail.send", to="x@y.com", subject="hi", body="sent by agent")

๐Ÿ“… Calendar (local โ€” Calendar.app)

Backend: AppleScript across all calendars.

Action Params Description
calendar.events days (default 7), limit Upcoming events across every calendar
calendar.create title, start (YYYY-MM-DD HH:MM), end (optional, default +1h), calendar_name (optional, default first writable) Creates event
use_apple(action="calendar.events", days=14)
use_apple(action="calendar.create", title="Dentist", start="2026-07-25 14:30", calendar_name="Home")

๐Ÿ‘ค Contacts (local โ€” Contacts.app)

Action Params Description
contacts.search query (name substring), limit Name, all phones, all emails

๐Ÿ–ผ Photos โ€” osxphotos with image blocks

Backend: osxphotos reading the Photos library database directly. The killer feature: results include Bedrock Converse-API image content blocks, so the model literally sees the photos (same mechanism as strands_tools.image_reader).

Action Params Description
photos.search query, person, label, from_date/to_date (YYYY-MM-DD), limit, with_images All filters AND-combined. query matches filename/title/description/labels/persons/albums. person = Photos face names. label = Apple's on-device ML labels (e.g. "Baklava", "Document", "Sea")
photos.recent limit, with_images Newest photos
photos.albums โ€” All album names
use_apple(action="photos.search", person="mom", from_date="2026-01-01")
use_apple(action="photos.search", label="dog", limit=5)
use_apple(action="photos.recent", limit=3, with_images=False)   # metadata only

Image pipeline: export original โ†’ if HEIC/oversized, convert via sips to JPEG (quality 80, max edge 1600px) โ†’ attach as {"image": {"format": ..., "source": {"bytes": ...}}}. Hard caps: max 5 images per response, 4 MB per image (context window protection). Exports land in /tmp/apple_photos_export/.

๐Ÿ“ Notes โ€” Notes.app

Action Params Description
notes.list limit Titles + modification dates (default account)
notes.read query (title substring) Full plaintext of first match
notes.create title, body New note in default account

โ˜‘๏ธ Reminders โ€” Reminders.app

Action Params Description
reminders.list limit Incomplete reminders with due dates
reminders.create title, due (optional) New reminder. Due date support is limited by AppleScript date quirks โ€” title always works

๐Ÿ“ฑ Find My โ€” pyicloud

Requires real Apple ID password (see Credentials). Session cached after first 2FA.

Action Params Description
findmy.devices โ€” All devices: name, model, battery %, coordinates
findmy.locate device (name substring) Coordinates + Apple Maps link + accuracy + timestamp
findmy.play_sound device Ping the device (the classic "find my phone in the couch")
use_apple(action="findmy.locate", device="iPhone")
# ๐Ÿ“ ร‡aฤŸatay's iPhone: (52.37403, 4.88969)
# https://maps.apple.com/?ll=52.37403,4.88969

๐ŸŒ IMAP (remote โ€” imap.mail.me.com)

Backend: Python stdlib imaplib, SSL port 993. Works from any machine โ€” Linux server, container, CI. App-specific password is sufficient.

Action Params Description
imap.folders โ€” List all mailboxes (INBOX, Archive, Sent Messages, ...)
imap.search query, chat (=folder, default INBOX), limit Searches SUBJECT OR FROM OR BODY. Returns message IDs for imap.read
imap.unread chat (=folder), limit UNSEEN messages
imap.read query (=message ID from search results), chat (=folder) Full body. Prefers text/plain, falls back to tag-stripped HTML. All fetches use BODY.PEEK โ€” never marks messages as read

Note: chat is reused as the folder parameter to keep the tool signature lean.

๐Ÿ“… CalDAV (remote โ€” caldav.icloud.com)

Action Params Description
caldav.calendars โ€” List calendars
caldav.events days, limit Upcoming events across all calendars, expanded recurrences
caldav.create title, start, end, calendar_name Create event โ€” syncs to all your Apple devices in seconds

๐Ÿ‘ค CardDAV (remote โ€” contacts.icloud.com)

Action Params Description
carddav.contacts query (optional name filter), limit Full addressbook via raw DAV: PROPFIND principal discovery โ†’ addressbook-home-set โ†’ REPORT addressbook-query โ†’ vCard parse (FN/TEL/EMAIL)

MCP Server

Everything above, exposed over the Model Context Protocol โ€” usable from Claude Code, Claude Desktop, Kiro, Cursor, or any MCP client. Pattern borrowed from strands-cad.

strands-icloud-mcp                      # stdio (default โ€” for desktop clients)
strands-icloud-mcp --http --port 8010   # streamable HTTP (multi-client)
strands-icloud-mcp --http --stateless   # stateless HTTP (horizontally scalable)
strands-icloud-mcp --agent-invocation   # also expose invoke_agent (full conversations)
strands-icloud-mcp --debug              # verbose logging (stderr)

Claude Code

claude mcp add apple -- strands-icloud-mcp

Claude Desktop

{
  "mcpServers": {
    "apple": {
      "command": "strands-icloud-mcp"
    }
  }
}

If installed inside a pipx venv, use the absolute path: ~/.local/pipx/venvs/devduck/bin/strands-icloud-mcp.

Implementation notes (learned the hard way in strands-cad)

  • stdout is sacred in stdio mode โ€” it's the protocol channel. All logging goes to stderr.
  • The server calls the raw tool function (mcp_server._tool_func), not agent.tool.mcp_server(...). Going through agent.tool.* marks the agent as mid-invocation; since stdio blocks forever, every nested tool call would then be rejected by the SDK.
  • --agent-invocation is off by default: tools-only surface. Enable it to let MCP clients run full agentic conversations against an embedded Strands agent.

Verified handshake

initialize            โ†’ serverInfo: strands-agent (1.27.x)
tools/list            โ†’ ["use_apple"]
tools/call use_apple(action="reminders.list")
                      โ†’ โ˜‘๏ธ 3 open reminders: ...

Parameter Reference

Full signature โ€” every param is optional except action:

Param Type Default Used by
action str โ€” everything (required)
query str None search actions, mail.read, notes.read, imap.read (=msg ID)
to str None messages.send, mail.send
text str None messages.send
subject, body str None mail.send, notes.create
title str None calendar.create, notes.create, reminders.create, caldav.create
chat str None messages.list (chat filter), imap.* (folder name)
person, label str None photos.search
device str None findmy.*
calendar_name str None calendar.create, caldav.create
start, end str None event creation, YYYY-MM-DD HH:MM
due str None reminders.create
from_date, to_date str None photos.search, YYYY-MM-DD
days int 7 calendar.events, caldav.events
limit int 20 all list/search actions
with_images bool True photos.* โ€” set False for metadata-only (saves tokens)

Response Format

# text-only actions
{
    "status": "success",
    "content": [{"text": "๐Ÿ“ง 5 unread:\n- [...] ..."}]
}

# photos with images โ€” text block first, then image blocks
{
    "status": "success",
    "content": [
        {"text": "๐Ÿ–ผ 3 photos:\n- IMG_4321.HEIC | 2026-07-21 12:59 | labels: Baklava, ..."},
        {"image": {"format": "jpeg", "source": {"bytes": b"..."}}},
        ...
    ]
}

# errors are never raised โ€” always structured
{
    "status": "error",
    "content": [{"text": "chat.db not found at ..."}]
}

Design Decisions

  1. One mega-tool, dot-namespaced actions (use_apple(action="messages.search")) instead of 25 separate tools. Keeps the agent's tool list small, matches the use_aws/use_spotify/adb convention, and lets one docstring teach the model the entire surface.
  2. Local-first, remote-fallback. AppleScript + direct file reads beat any network API for latency, history depth, and reliability. Remote protocols exist for off-Mac deployment of the same tool.
  3. Read-only by default at the storage layer. chat.db opens with ?mode=ro; IMAP fetches use BODY.PEEK. Writes only happen through explicit send/create actions via Apple's own apps/APIs.
  4. Graceful degradation. Optional deps import lazily inside the action branch. No osxphotos? Photos actions error cleanly with install instructions; everything else works.
  5. Structured errors, never exceptions. The agent can read the failure and route around it (e.g., fall back from mail.unread to imap.unread).
  6. Image budget. Max 5 images ร— โ‰ค4 MB, auto-downscaled to 1600px JPEG q80. A photo dump should never blow up the context window.

Performance Notes

Operation Cost Notes
messages.* (read) ~10 ms Direct SQLite, indexed
mail.unread 2โ€“30 s AppleScript iteration, newest-first, capped at 400 recent messages. The naive whose read status is false filter took >120 s on a 16k inbox โ€” that's why it scans instead
mail.search 10 sโ€“3 min Uses Mail's whose filter (server-side in Mail), acceptable but not instant on big inboxes. Prefer imap.search for speed
imap.search 1โ€“3 s iCloud does the searching
calendar.events 5โ€“60 s AppleScript iterates every calendar; slow with many calendars. caldav.events is usually faster
photos.search 5โ€“30 s first call osxphotos loads the library DB once per call; big libraries pay upfront. Filtering itself is in-memory and fast
caldav/carddav 1โ€“5 s Plain HTTPS

Rules of thumb: Messages โ†’ local always. Mail search โ†’ IMAP. Calendar list โ†’ CalDAV. Photos โ†’ local (only option). Sends โ†’ local (Apple handles delivery).


Troubleshooting

Symptom Cause Fix
unable to open database file on messages.* No Full Disk Access Grant FDA to host app, restart the process
Timeout on mail.* Mail.app not running or gigantic inbox open -gja Mail, wait for index; use imap.* instead
Not authorized to send Apple events Automation permission denied System Settings โ†’ Automation, or tccutil reset AppleEvents
PyiCloudFailedLoginException on findmy.* Using app-specific password pyicloud needs the real password (keychain strands-icloud-real)
2FA loop on findmy Expired session Re-auth interactively once; check ~/.pyicloud is writable
imap.* AUTHENTICATIONFAILED Bad/revoked app-specific password Regenerate at account.apple.com, update keychain entry
Photos export returns nothing Original offloaded to iCloud ("Optimize Mac Storage") Tool retries with use_photos_export=True (slower, downloads); ensure disk space
Keychain prompt blocks headless run keyring needs UI unlock security unlock-keychain in session, or use env vars for that host
MCP client sees no tools stdout polluted by a print Run with --debug, check nothing but JSON-RPC goes to stdout

Nuclear option for AppleScript weirdness: quit and relaunch the target app.


Security Model

  • App-specific password (keychain strands-icloud): grants mail/calendar/contacts via legacy protocols. Revocable at account.apple.com anytime without touching your real password. Cannot be used to log into iCloud web, change account settings, or access Find My.
  • Real password (keychain strands-icloud-real, optional): only needed for Find My. Never written to disk by this tool; keychain access requires your login session.
  • No plaintext secrets in dotfiles: only ICLOUD_USERNAME lives in ~/.zshrc.
  • Local data never leaves the machine except as tool results into your model provider (mind what you query if using a cloud LLM โ€” that's the actual data boundary here).
  • chat.db is opened read-only; the tool physically cannot modify or delete message history.

Known Limitations

  • macOS only for local actions (AppleScript, chat.db, osxphotos). Remote actions (imap.*, caldav.*, carddav.*) run anywhere Python does.
  • reminders.create due dates: AppleScript date construction is unreliable across locales; reminders are created without due dates for now.
  • messages.send requires Messages.app signed in; SMS relay needs an iPhone with Text Message Forwarding enabled.
  • mail.unread scans the 400 most recent inbox messages โ€” unread mail older than that won't appear (use imap.unread for exhaustive).
  • Group chat display names in Messages may be empty (falls back to chat identifier).
  • pyicloud is an unofficial client of a private API โ€” Apple can (and occasionally does) break it. Local + DAV paths are unaffected.
  • HEIC โ†’ JPEG conversion via sips loses HDR/depth metadata (irrelevant for model vision).

Development

git clone git@github.com:cagataycali/strands-icloud.git
cd strands-icloud
uv venv && source .venv/bin/activate
uv pip install -e .

# smoke test without an agent
python -c "
from strands_icloud.use_apple import use_apple
fn = getattr(use_apple, '_tool_func', use_apple)
print(fn(action='reminders.list', limit=3))
"

# reinject into devduck after changes
pipx inject devduck . --force

License

MIT ยฉ ร‡aฤŸatay ร‡alฤฑ

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

strands_icloud-0.1.0.tar.gz (26.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

strands_icloud-0.1.0-py3-none-any.whl (28.3 kB view details)

Uploaded Python 3

File details

Details for the file strands_icloud-0.1.0.tar.gz.

File metadata

  • Download URL: strands_icloud-0.1.0.tar.gz
  • Upload date:
  • Size: 26.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.5

File hashes

Hashes for strands_icloud-0.1.0.tar.gz
Algorithm Hash digest
SHA256 bf558718002e0122caf399d34af30a5f0cc4e1b858513fcdb34a8b7c7f0c193f
MD5 e7c9aa7c3796232eb9498102da920261
BLAKE2b-256 99384c132bf666fd7f2108234f9589ed4116fa90b9a29db28ea5f1dd2d313acb

See more details on using hashes here.

File details

Details for the file strands_icloud-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: strands_icloud-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 28.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.5

File hashes

Hashes for strands_icloud-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 0fa5f166616bb323671e881728df16c386e566ebfd0f0727022d26e947e6d90e
MD5 dd3d1d54629af76edee06439b7977b30
BLAKE2b-256 2563853a11c36e1cac58eb49e6c8e14b2f96004922fe5645afc7d5704303a8bb

See more details on using hashes here.

Release history Release notifications | RSS feed

0.2.0

2 files

This release

0.1.0 This release

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page