# How Cherry Studio Handles Deep Link Protocols (cherrystudio://)

> Learn how Cherry Studio handles deep link protocols like cherrystudio. Discover the routing and specialized handlers for MCP server installation, configuration, and IPC messages.

- Repository: [CherryHQ/cherry-studio](https://github.com/cherryhq/cherry-studio)
- Tags: internals
- Published: 2026-02-27

---

**Cherry Studio registers the custom URL scheme `cherrystudio://` in the main process via Electron's `setAsDefaultProtocolClient`, routes incoming URLs through `handleProtocolUrl()` in [`ProtocolClient.ts`](https://github.com/cherryhq/cherry-studio/blob/main/ProtocolClient.ts), and dispatches them to specialized handlers for MCP server installation, provider configuration, or generic IPC messages to the renderer process.**

Cherry Studio is an open-source AI client built with Electron that enables external applications and web services to launch and control the app through custom deep links. The repository at `cherryhq/cherry-studio` implements a complete protocol handling system that works consistently across macOS, Windows, and Linux (including AppImage distributions) by registering the `cherrystudio://` scheme and parsing incoming URLs to trigger specific actions.

## Protocol Registration and OS Integration

When the application starts, the main process immediately registers the custom protocol to ensure the OS recognizes `cherrystudio://` links.

### Registering the URL Scheme

The `registerProtocolClient(app)` function in [`src/main/services/ProtocolClient.ts`](https://github.com/cherryhq/cherry-studio/blob/main/src/main/services/ProtocolClient.ts) (lines 15-25) calls Electron's `app.setAsDefaultProtocolClient('cherrystudio')`. This registers the scheme with the operating system so that any `cherrystudio://` URL opens in Cherry Studio rather than the default browser.

### Linux AppImage Deep Link Support

For Linux AppImage builds, deep linking requires additional desktop integration. The `setupAppImageDeepLink()` function (lines 60-99 in [`src/main/services/ProtocolClient.ts`](https://github.com/cherryhq/cherry-studio/blob/main/src/main/services/ProtocolClient.ts)) creates a `cherrystudio-url-handler.desktop` file containing:

```ini
MimeType=x-scheme-handler/cherrystudio;

```

The code then executes `update-desktop-database` to register the handler with the system MIME database, enabling AppImage users to open `cherrystudio://` links from browsers and other applications.

## Capturing Deep Links Across Platforms

Cherry Studio handles protocol activation differently depending on the operating system, as implemented in [`src/main/index.ts`](https://github.com/cherryhq/cherry-studio/blob/main/src/main/index.ts).

### macOS open-url Events

On macOS, Electron emits the `open-url` event when a user clicks a `cherrystudio://` link. The main process listens via `app.on('open-url', (event, url) => { ... })` (lines 221-243) and immediately forwards the URL string to the protocol router.

### Windows and Linux Second-Instance Handling

Windows and Linux do not use `open-url`. Instead, when a deep link activates an already-running instance, Electron fires the `second-instance` event. The code extracts the protocol URL from `process.argv` (lines 28-36 and 36-44 in [`src/main/index.ts`](https://github.com/cherryhq/cherry-studio/blob/main/src/main/index.ts)), scanning for any argument that starts with `cherrystudio://`.

## URL Routing and Action Dispatch

Once captured, all protocol URLs flow through `handleProtocolUrl(url)` in [`src/main/services/ProtocolClient.ts`](https://github.com/cherryhq/cherry-studio/blob/main/src/main/services/ProtocolClient.ts) (lines 27-44). The function parses the URL and dispatches based on the hostname:

```typescript
switch (urlObj.hostname.toLowerCase()) {
  case 'mcp':       handleMcpProtocolUrl(urlObj);   break;
  case 'providers': handleProvidersProtocolUrl(urlObj); break;
  default:          sendToRendererViaIPC(urlObj);
}

```

If the hostname matches neither `mcp` nor `providers`, the data is forwarded to the renderer process via the `protocol-data` IPC channel for custom handling.

## Specialized Protocol Handlers

Cherry Studio implements specific handlers for common deep-link workflows, accepting Base64-encoded JSON payloads to configure the application state.

### Installing MCP Servers via Protocol

The `handleMcpProtocolUrl` function in [`src/main/services/urlschema/mcp-install.ts`](https://github.com/cherryhq/cherry-studio/blob/main/src/main/services/urlschema/mcp-install.ts) processes URLs formatted as:

```

cherrystudio://mcp/install?servers=<base64-JSON>

```

The handler decodes the `servers` parameter and installs the specified Model Context Protocol (MCP) servers directly into the user's configuration. Each server installed via this method receives `installSource: 'protocol'` and defaults to `isTrusted: false`, triggering security warnings in the UI.

### Configuring Providers via Deep Links

The providers handler in [`src/main/services/urlschema/handle-providers.ts`](https://github.com/cherryhq/cherry-studio/blob/main/src/main/services/urlschema/handle-providers.ts) manages URLs like:

```

cherrystudio://providers/api-keys?data=<base64-JSON>

```

This decodes the provider configuration (including API keys and base URLs) and navigates the renderer to the provider settings page, automatically populating the form fields with the supplied data.

## Renderer Process Communication and Security

The protocol system includes security boundaries to protect users from malicious deep links.

### IPC Bridge for Generic Protocol Data

The preload script in [`src/preload/index.ts`](https://github.com/cherryhq/cherry-studio/blob/main/src/preload/index.ts) (lines 65-74) exposes `window.api.protocol.onReceiveData()`, which wraps `ipcRenderer.on('protocol-data', ...)`. Renderer code can subscribe to this API to receive arbitrary protocol URLs not handled by the main process sub-routes:

```typescript
const unsubscribe = window.api.protocol.onReceiveData(({ url, params }) => {
  console.log('Deep link received:', url);
});

```

This mechanism powers OAuth callbacks, such as the PPIO implementation in [`src/renderer/src/utils/oauth.ts`](https://github.com/cherryhq/cherry-studio/blob/main/src/renderer/src/utils/oauth.ts), where the provider redirects to `cherrystudio://?code=XYZ` and the renderer extracts the authorization code.

### Security Warnings for Protocol-Installed MCPs

When an MCP server is installed via a deep link, the [`ProtocolInstallWarning.tsx`](https://github.com/cherryhq/cherry-studio/blob/main/ProtocolInstallWarning.tsx) component renders a prominent warning in the settings UI. Because `isTrusted` defaults to `false` for protocol-installed servers, users must explicitly review and trust the configuration before the server becomes active, mitigating risks from malicious `cherrystudio://mcp/install` links.

## Practical Code Examples

### Constructing an MCP Install Deep Link

```typescript
// Define the MCP server configuration
const config = {
  mcpServers: {
    everything: {
      command: 'npx',
      args: ['-y', '@modelcontextprotocol/server-everything']
    }
  }
};

// Encode and construct the URL
const base64 = Buffer.from(JSON.stringify(config)).toString('base64');
const url = `cherrystudio://mcp/install?servers=${base64}`;

// Trigger from a web page or external app
window.open(url);

```

### Adding a Provider via Deep Link

```typescript
const provider = {
  id: 'tokenflux',
  baseUrl: 'https://tokenflux.ai/v1',
  apiKey: 'sk-xxxx',
  name: 'TokenFlux',
  type: 'openai'
};

// URL-safe Base64 encoding
const json = JSON.stringify(provider);
const base64 = Buffer.from(json).toString('base64')
               .replace(/\+/g, '_')
               .replace(/\//g, '-');

const url = `cherrystudio://providers/api-keys?v=1&data=${base64}`;
window.open(url); // Opens Cherry Studio and navigates to provider settings

```

### Listening for Protocol Data in the Renderer

```typescript
import { useEffect } from 'react';

useEffect(() => {
  const unsubscribe = window.api.protocol.onReceiveData(({ url, params }) => {
    // Handle OAuth callbacks or custom deep link data
    console.log('Protocol data:', url, params);
  });
  
  return unsubscribe;
}, []);

```

## Summary

- **Protocol Registration**: `registerProtocolClient()` in [`src/main/services/ProtocolClient.ts`](https://github.com/cherryhq/cherry-studio/blob/main/src/main/services/ProtocolClient.ts) registers `cherrystudio://` via Electron APIs and creates Linux desktop entries for AppImage support.
- **Cross-Platform Capture**: macOS uses `open-url` events while Windows/Linux extract URLs from `second-instance` argv, as implemented in [`src/main/index.ts`](https://github.com/cherryhq/cherry-studio/blob/main/src/main/index.ts).
- **Central Router**: `handleProtocolUrl()` parses the hostname and dispatches to `handleMcpProtocolUrl()`, `handleProvidersProtocolUrl()`, or falls back to IPC.
- **Secure Installation**: MCP servers installed via protocol receive `installSource: 'protocol'` and `isTrusted: false`, triggering UI warnings in [`ProtocolInstallWarning.tsx`](https://github.com/cherryhq/cherry-studio/blob/main/ProtocolInstallWarning.tsx).
- **Renderer Bridge**: The preload script exposes `protocol.onReceiveData()` for OAuth flows and custom deep-link handling via the `protocol-data` IPC channel.

## Frequently Asked Questions

### What URL scheme does Cherry Studio use for deep links?

Cherry Studio registers the **`cherrystudio://`** scheme (not `cherry://`). This is defined in [`src/main/services/ProtocolClient.ts`](https://github.com/cherryhq/cherry-studio/blob/main/src/main/services/ProtocolClient.ts) where `app.setAsDefaultProtocolClient('cherrystudio')` is called during application startup.

### How does Cherry Studio handle deep links on Linux AppImage builds?

The `setupAppImageDeepLink()` function creates a `.desktop` file with `MimeType=x-scheme-handler/cherrystudio;` and runs `update-desktop-database` to register the handler with the system. This allows AppImage distributions to intercept `cherrystudio://` URLs without requiring system-wide installation.

### Can I trigger OAuth flows using Cherry Studio's protocol handler?

Yes. The renderer can listen for protocol data via `window.api.protocol.onReceiveData()` (exposed in [`src/preload/index.ts`](https://github.com/cherryhq/cherry-studio/blob/main/src/preload/index.ts)). When an OAuth provider redirects to `cherrystudio://?code=XYZ`, the URL is captured in the main process and forwarded via IPC to the renderer, which extracts the code and completes the token exchange, as demonstrated in the PPIO OAuth implementation.

### What security measures exist for protocol-installed MCP servers?

Servers installed via `cherrystudio://mcp/install` are marked with `installSource: 'protocol'` and default to `isTrusted: false`. The UI renders a warning component ([`ProtocolInstallWarning.tsx`](https://github.com/cherryhq/cherry-studio/blob/main/ProtocolInstallWarning.tsx)) alerting users that the server originated from an external link and requires explicit trust verification before activation.