Community Extensions

Community extensions are pre-built custom actions and destinations shared by other Cai users. Browse and install them directly from the in-app extension browser, or from the cai-extensions repository on GitHub.

How to Install

  1. Open Settings > Community Extensions
  2. Browse available extensions
  3. Click Install on the extension you want
  4. The extension is added as a custom action or destination in your Cai settings

To uninstall, go back to Community Extensions and click the extension again.

Tip: You can also install extensions by copying a # cai-extension YAML snippet to your clipboard. Cai detects it automatically and shows a trust confirmation dialog. This is useful for installing extensions shared outside the community repository.

Extension Types

Type What it does Installs as Needs LLM?
prompt Sends clipboard text to the LLM with a custom instruction Action Yes
url Opens a URL with %s replaced by clipboard text Action No
shell Runs a shell command with the text Action No
webhook Sends text to an HTTP endpoint Destination No
deeplink Opens a URL scheme / deep link Destination No
applescript Runs an AppleScript with the text Destination No

Custom actions appear in the Cai action window. You trigger them just like built-in actions. Destinations are output targets that receive text after an action runs (or directly from clipboard).

Security

Cai takes a cautious approach to community extensions:

  • Trust confirmation: every extension shows a confirmation dialog before installation, whether installed from the in-app browser or via clipboard. You always see what it does before it’s added.
  • AppleScript and shell types cannot be installed via clipboard: these types are blocked from clipboard install for safety. You can install them through the in-app extension browser or create them manually in Settings.
  • No auto-execution: extensions are never run automatically. You must explicitly trigger them like any other action.

Caution: Only install extensions from sources you trust. Even though dangerous types are blocked, webhook destinations can still send your text to external servers. Always review the extension details before installing.

Creating an Extension

Each extension is a single YAML file inside a folder in the community repository. Here’s how to create one.

Required Fields

Every extension.yaml must start with # cai-extension on the first line and include these fields:

Field Description
name Display name shown in Cai (title case)
description One-line summary — what users see when browsing
author Your GitHub username
version Version string, quoted (e.g. "1.0")
tags Array of lowercase tags for search/filtering
icon SF Symbol name (e.g. envelope.fill)
type prompt, url, webhook, or deeplink

Prompt Action

Sends your selected text to the LLM with your instruction:

# cai-extension
name: Professional Email
description: Rewrite text as a polished professional email
author: your-github-username
version: "1.0"
tags: [writing, email]
icon: envelope.fill
type: prompt
prompt: |
  Rewrite the following text as a professional email.
  Keep the core message but make it polished and clear.
  Include a greeting and sign-off.
  Do not use any markdown formatting.

URL Action

Opens a URL with %s replaced by your selected text:

# cai-extension
name: Search StackOverflow
description: Search StackOverflow for the selected text
author: your-github-username
version: "1.0"
tags: [developer, search]
icon: magnifyingglass
type: url
url: "https://stackoverflow.com/search?q=%s"

Webhook Destination

Sends text to an HTTP endpoint:

# cai-extension
name: Send to Slack
description: Post text to a Slack channel via webhook
author: your-github-username
version: "1.0"
tags: [productivity, slack]
icon: bubble.left.fill
type: webhook
show_in_action_list: true
webhook:
  url: "{{slack_webhook_url}}"
  method: POST
  headers:
    Content-Type: application/json
  body: '{"text": "{{result}}"}'
setup:
  - key: slack_webhook_url
    label: Slack Webhook URL
    secret: false

Shell Action

Runs a shell command with your selected text. Shell actions can’t be installed via clipboard for safety — create them locally in Cai’s Custom Actions settings or install them through the in-app extension browser.

# cai-extension
name: Kill Port
description: Kill the process running on a given port number
author: your-github-username
version: "1.0"
tags: [developer, system]
icon: xmark.circle.fill
type: shell
shell: lsof -ti :{{result}} | xargs kill -9 && echo "Killed process on port {{result}}"

Deeplink Destination

Opens a URL scheme / deep link with the result text:

# cai-extension
name: Save to Bear
description: Create a new note in Bear
author: your-github-username
version: "1.0"
tags: [productivity, notes]
icon: doc.text
type: deeplink
show_in_action_list: true
deeplink: "bear://x-callback-url/create?text={{result}}"

Template Placeholders

Placeholder Used in Description
%s URL actions (type: url) Replaced with selected text, URL-encoded automatically
{{result}} Shell, webhook, deeplink, AppleScript Replaced with selected text. Escaping varies by type: JSON for webhooks, percent-encoding for deeplinks, AppleScript escaping for AppleScript, raw/unescaped for shell
{{field_key}} Any destination with setup: Replaced with user-configured setup field value (from Keychain or UserDefaults)

Setup Fields

Setup fields let users configure values like API keys and webhook URLs when they first use the extension. Define them with the setup key:

setup:
  - key: api_key
    label: "API Key"
    secret: true # stored in Keychain, masked in UI
  - key: channel
    label: "Channel Name"
    secret: false

Reference them in your templates with {{key_name}}.

Submitting an Extension

Share from Cai (recommended)

The easiest way to share a custom action or destination you’ve built:

  1. Open Settings > Custom Actions (or Custom Destinations)
  2. Click the share icon (↗) on the custom action or destination you want to share
  3. Cai copies the extension YAML to your clipboard and opens the community repo
  4. Fork the repo, create a folder under extensions/ with a kebab-case name (e.g. professional-email)
  5. Paste the YAML as extension.yaml and open a pull request

The generated YAML includes all the required fields. You just need to update author to your GitHub username, write a short description, and add relevant tags.

Create manually

You can also write the YAML by hand:

  1. Fork the cai-extensions repository
  2. Create a folder under extensions/ with a kebab-case name
  3. Add an extension.yaml file inside it (must start with # cai-extension)
  4. Open a pull request

Guidelines

  • One extension per folder: keep it focused
  • Test your extension in Cai before submitting (copy the YAML, press Option+C)
  • Use SF Symbol names for icons
  • Write a clear description: one sentence, no period
  • No API keys in YAML: use setup fields for secrets
  • applescript and shell types require extra review: these are accepted but will be scrutinized more carefully before merging

What Happens After You Submit

  1. CI validates your YAML automatically (required fields, format, type)
  2. A maintainer reviews your extension
  3. Once approved and merged, the extension appears in the community repository