Use Xantly with Raycast (AI extensions)

Raycast AI itself is hosted, but open-source extensions that call LLMs via the Node SDK can route through Xantly. Works for both extension users and authors.

Raycast is a macOS-native launcher with a rich AI extension ecosystem. Raycast AI itself (the built-in chat) is hosted on Raycast's infra and doesn't currently support custom base URLs. But Raycast extensions that call LLMs via the Node SDK can route through Xantly, which unlocks any open-source extension that uses openai, @anthropic-ai/sdk, or the ai SDK.

Two audiences

  1. You use Raycast extensions that hit OpenAI/Anthropic APIs: set the env vars below and extensions will pick up Xantly automatically.
  2. You build Raycast extensions: use the OpenAI SDK with Xantly's base URL directly.

Prerequisites

Setup, as a Raycast extension user

Most Raycast extensions read OPENAI_API_KEY (sometimes OPENAI_API_BASE) from the environment. Set them in your shell:

export OPENAI_API_BASE=https://api.xantly.com/v1
export OPENAI_API_KEY=xantly_sk_...

Then restart Raycast (or reload the extension). The extension's OpenAI calls will now route through Xantly.

macOS launchers don't inherit shell env vars by default. Use launchctl setenv or create ~/Library/LaunchAgents/xantly.plist to export them globally:

launchctl setenv OPENAI_API_BASE https://api.xantly.com/v1
launchctl setenv OPENAI_API_KEY xantly_sk_...

(This persists across reboots if you add it to a LaunchAgent plist.)

Setup, as an extension author

In your package.json:

{
  "dependencies": {
    "@raycast/api": "^1.70.0",
    "openai": "^4.0.0"
  }
}

In your extension source:

import { getPreferenceValues } from '@raycast/api'
import OpenAI from 'openai'

interface Preferences {
  apiKey: string
  baseURL: string
  model: string
}

const prefs = getPreferenceValues<Preferences>()

const client = new OpenAI({
  baseURL: prefs.baseURL || 'https://api.xantly.com/v1',
  apiKey: prefs.apiKey,
})

const resp = await client.chat.completions.create({
  model: prefs.model || 'xantly/auto-value',
  messages: [{ role: 'user', content: 'Hello from Raycast' }],
})

And in your package.json preferences schema:

"preferences": [
  {
    "name": "baseURL",
    "type": "textfield",
    "required": false,
    "title": "Base URL",
    "description": "LLM API base URL (Xantly default)",
    "default": "https://api.xantly.com/v1"
  },
  {
    "name": "apiKey",
    "type": "password",
    "required": true,
    "title": "API Key",
    "description": "Xantly or OpenAI key"
  },
  {
    "name": "model",
    "type": "dropdown",
    "required": true,
    "title": "Model",
    "default": "xantly/auto-value",
    "data": [
      { "title": "Xantly Auto Quality", "value": "xantly/auto-quality" },
      { "title": "Xantly Auto Value", "value": "xantly/auto-value" },
      { "title": "Xantly Auto Speed", "value": "xantly/auto-speed" },
      { "title": "Claude Sonnet 4.6", "value": "anthropic/claude-sonnet-4.6" },
      { "title": "GPT-5.4", "value": "openai/gpt-5.4" }
    ]
  }
]

The pattern: if the extension lets you paste an OpenAI API key and optionally a base URL, Xantly works.

Model choice

Model IDWhen
xantly/auto-speedRaycast extensions, you want sub-second responses for launcher UX.
xantly/auto-valueBalanced quality/speed.
xantly/auto-qualityFor heavy-weight extensions (summarization, writing help).
groq/llama-3.3-70bFastest inference for short completions.

Default to speed tier, Raycast is a launcher; users want snap-response.

Verify

Run any Raycast AI extension (summarize clipboard, chat assistant, etc.) and check your Xantly dashboard, the call should log with cost + model + cache status.

What you get

Gotchas

Raycast AI built-in is not Xantly-compatible. The chat panel in Raycast Pro uses Raycast's hosted AI. Custom base URL isn't supported for the built-in, only for extensions.

Extension env var discovery. Some extensions use env vars, some require preferences, some hardcode. Check the extension's README.

Extension authors: respect user's own key. If the user already has OPENAI_API_KEY set for their direct OpenAI usage, don't clobber it. Read your own XANTLY_API_KEY pref or fall back to env.

launchctl setenv scope. Applies to future apps launched. Restart Raycast after setting.

Next steps