> ## Documentation Index
> Fetch the complete documentation index at: https://docs.onyx.app/llms.txt
> Use this file to discover all available pages before exploring further.

# Craft Apps

> Let Craft read and act as each user in Slack, Gmail, Notion, and other applications

> [!NOTE]
>
> In Onyx 5.0, Craft Apps moved from **Admin Panel → Craft → Apps** to **Admin Panel → Plugins**.
> See [Where things moved](/admins/plugins/overview#where-things-moved-in-onyx-5).

A Craft App is a catalog of API endpoints for one application, such as Slack or Gmail.
Each user connects their own account. Craft then calls the application's API as that user.

This lets Craft read private Slack channels, reply in a thread, send an email, or update a Notion page.
Craft can only reach content that the connected account can access in the application.

Admins add Craft Apps in **Admin Panel → Plugins**. Users connect their accounts in **Plugins** in Craft or Chat.

> [!NOTE]
>
> Craft Apps work only in [Craft](/overview/core_features/craft). Main Chat does not support them.
> To give Chat access to the same application, add an [MCP server](/admins/plugins/mcp) for it.

## What Craft Apps can do

| App | Examples |
| - | - |
| **Slack** | Search messages, read channels and threads, post a message or a thread reply, open a direct message, upload files. |
| **Gmail** | Read messages, threads, and attachments. Manage labels and drafts. Send or trash messages. |
| **Google Calendar** | Read calendars, events, and free/busy times. Create, update, and delete events. |
| **Google Drive** | Read, create, edit, and delete files, Google Docs, Sheets, and Slides. List shared drives. |
| **Notion** | Search and read pages, databases, and comments. Create and update pages, blocks, and databases. Add comments. |
| **Linear** | Read teams, issues, and projects. Create issues and projects, edit projects, and comment on issues. |
| **GitHub** | Read repositories, issues, pull requests, files, and commits that the user can access. Create issues, comment, change files and branches, and open pull requests. |
| **HubSpot** | Read and search owners, contacts, companies, and deals. Create or update contacts, companies, and deals. |
| **Zendesk** | Search, read, create, update, and delete tickets. Read ticket metrics and users. Manage Help Center content, side conversations, and macros. |

Each built-in App defines its actions, such as **Read messages** or **Post a message**.
Admins set an approval policy for each action. See [Set action policies](#set-action-policies).

A [custom App](#custom-apps) gives Craft credentials and network access for any other public HTTP API.

### Craft Apps compared to MCP servers

| | Craft App | MCP server |
| - | - | - |
| Surfaces | Craft only | Chat, custom agents, and Craft |
| How Craft calls it | Craft sends HTTP requests to the provider API from its sandbox. The sandbox proxy adds the credentials. | Onyx calls MCP tools for the agent. |
| Approvals | A policy for each cataloged action | A policy for each MCP tool |
| Credentials in the sandbox | Never. The proxy injects them on the way out. | Never. Onyx holds them. |
| Use it when | A built-in App exists for the application | No built-in App exists, or Chat also needs the tools |

## Requirements

* Craft must be available. Craft is available on the Business and Enterprise plans.
  If you self-host Onyx, first follow [Deploying Craft](/deployment/local/craft).
* Only full admins can add, edit, or delete Craft Apps.

## Add a built-in App

![The Craft Apps catalog with Slack, Google Calendar, Google Drive, Gmail, Linear, GitHub, HubSpot, Notion, Zendesk, and Custom app](https://mintcdn.com/danswer/yAnT-i7LBUiCJgOS/assets/admins/plugins/craft_app_catalog.png?fit=max\&auto=format\&n=yAnT-i7LBUiCJgOS\&q=85\&s=cffa29a641037d73900895729d5bb948)

**1. Create an OAuth application with the provider**

On self-hosted Onyx, create an OAuth application in the provider. Use this redirect URI, with your Onyx domain:

```text theme={null}
https://<your-onyx-domain>/craft/v1/apps/oauth/callback
```

The scheme, host, and path must match exactly. Onyx builds the URI from `WEB_DOMAIN`.
See [Provider setup](#provider-setup) for each provider.

**2. Open the Craft Apps catalog**

Go to **Admin Panel → Plugins**, click **Add**, then select **Craft Apps**. Select the provider.

**3. Set the configuration**

On the **Configuration** tab, set:

| Setting | Effect |
| - | - |
| **Enable for Craft** | Makes the App available in Craft. |
| **Let users manage approval settings** | Lets users change approval policies for actions that you did not disable. |

**4. Enter the provider credentials**

On the **Authentication** tab, follow the setup instructions, then enter the client ID and client secret.
Onyx does not ask for a user's access token. Each user signs in later.

![The Slack Authentication tab with setup instructions, Client ID, and Client Secret](https://mintcdn.com/danswer/yAnT-i7LBUiCJgOS/assets/admins/plugins/craft_app_slack_auth.png?fit=max\&auto=format\&n=yAnT-i7LBUiCJgOS\&q=85\&s=ec9bc255be2b24b64191cbfd8fd83f9a)

**5. Review action policies**

On the **Tools** tab, set a policy for each action. Review every write, send, delete, and publish action.

![The Slack Tools tab with Auto-approve, Ask, and Disabled for each action](https://mintcdn.com/danswer/yAnT-i7LBUiCJgOS/assets/admins/plugins/craft_app_slack_tools.png?fit=max\&auto=format\&n=yAnT-i7LBUiCJgOS\&q=85\&s=f6059c241b4e53f18e1af71bcf2c3203)

**6. Add the App**

Click **Add**. Onyx then asks you to add skills to the App. Select existing skills, or click **Skip for now**.
See [Skills for Apps](#skills-for-apps).

**7. Test as a user**

Connect a test account from the [Plugins page](/overview/core_features/craft_apps#connect-an-app).
Test one read and one write. Make sure the approval card is clear, and check the result in the application.

On Onyx Cloud, Onyx manages the OAuth applications for built-in Apps. You do not enter client credentials.

You can add one instance of each built-in provider.

### Provider setup

> **Slack**
>
> Create a Slack app and add the Onyx redirect URI under **OAuth & Permissions**. Add these **User Token Scopes**:
>
> ```text theme={null}
> channels:history
> channels:read
> chat:write
> files:write
> groups:history
> groups:read
> im:history
> im:read
> im:write
> search:read
> users:read
> ```
>
> Craft acts with a user token; no bot user is required.
> Copy the Client ID and Client Secret from the Slack app's basic information.

> **Google Calendar**
>
> In Google Cloud Console, create or select a project, enable the **Google Calendar API**,
> configure the OAuth consent screen, and create an OAuth 2.0 Client ID of type **Web application**.
> Add the Onyx redirect URI under **Authorized redirect URIs**. Craft requests full Google Calendar access.

> **Google Drive**
>
> In Google Cloud Console, enable both the **Google Drive API** and **Google Docs API**,
> configure the OAuth consent screen, and create an OAuth 2.0 Web application client with the Onyx redirect URI.
> Craft requests the full Drive scope so it can read, create, edit, and delete files;
> action policies govern those operations inside Craft.

> **Gmail**
>
> In Google Cloud Console, enable the **Gmail API**, configure the OAuth consent screen,
> and create an OAuth 2.0 Web application client with the Onyx redirect URI. Craft requests `gmail.modify`,
> which covers reading, labels, drafts, trash, and sending but not permanent message deletion.

> **Linear**
>
> In Linear, open **Settings → API → OAuth applications**, create an OAuth application,
> and add the Onyx redirect URI to its callback URLs. Craft requests user-acting read and write access for issues,
> projects, and comments.

> **GitHub**
>
> In GitHub, open **Settings → Developer settings → OAuth Apps**, create an OAuth App,
> and use the Onyx redirect URI as its authorization callback URL. Craft requests `repo`, `read:org`, and `read:user`;
> the `repo` scope includes repositories the connecting user can access, including private repositories.

> **HubSpot**
>
> From a HubSpot developer account, create an app and add the Onyx redirect URI on its **Auth** tab.
> Configure read access for owners, contacts, companies, and deals. Contact, company,
> and deal write scopes are optional so read-only HubSpot accounts can still connect.

> **Notion**
>
> Create a **Public** integration from Notion's integrations settings and add the Onyx redirect URI under **OAuth
> Domain & URIs**. Choose the integration's read and write capabilities in Notion;
> Notion controls capabilities there rather than through OAuth scopes.

> **Zendesk**
>
> In Zendesk, open **Admin Center → APIs → OAuth clients** and add a client. Set **Client kind** to **Confidential**.
> Onyx uses PKCE together with the client secret. Add these allowed scopes:
>
> ```text theme={null}
> read
> tickets:write
> hc:write
> side_conversations:write
> macros:write
> ```
>
> Allow all of the scopes, even if you do not use every feature. Set the redirect URL to the Onyx redirect URI.
> Copy the secret when Zendesk shows it. Zendesk shows it only once. In Onyx, enter your Zendesk subdomain,
> the client's **Unique identifier**, and the secret.
> The subdomain selects the Zendesk account that the app can access. If you change the allowed scopes,
> each user must connect Zendesk again.

## Set action policies

Each action in a built-in App has one workspace policy:

| Policy | Effect | Typical use |
| - | - | - |
| **Auto-approve** | Craft runs the action without a prompt. | Narrow, low-risk reads |
| **Ask** | Craft stops before the request and shows the user an approval card. | Sends, creates, edits, and broad reads |
| **Disabled** | The proxy blocks the action. Users and scheduled tasks cannot override it. | Destructive or prohibited actions |

Built-in Apps start with defaults: most reads are **Auto-approve**, and most changes are **Ask**.
Review the defaults for your organization before users connect.

Use **Set permissions** to set every action at once, or set each action in the list.

> [!NOTE]
>
> If one request matches more than one action, the strictest policy applies: **Disabled**, then **Ask**,
> then **Auto-approve**. A request that does not match a cataloged action uses **Ask**.

### User approvals

When an action uses **Ask**, the user can approve once, approve for the session, or reject.
**Approve for session** applies only to matching actions in that session. It does not change the workspace policy.

If **Let users manage approval settings** is on, users can change the policy for their own account.
They cannot turn on an action that you set to **Disabled**.

### Scheduled Tasks

A [Scheduled Task](/overview/core_features/craft_scheduled_tasks) runs without a user present,
so it cannot show an approval card.
The task owner enables the Apps that the task can use in the task's **Approval settings**.
Each App starts with the owner's current approval settings. Changes apply only to that task.

* If **Let users manage approval settings** is off, the workspace policies apply to the task.
* Task settings cannot override **Disabled**.
* If a run reaches an action that needs approval, the run stops with the **Awaiting approval** status.
  The owner must change the task's approval settings, then run the task again.

## Skills for Apps

[Skills](/admins/managing_features/craft_skills) teach Craft how to use an App well,
for example which Slack channels to read first.
Open the App and select the **Skills** tab to add existing skills or create a new skill for the App.

## Custom Apps

Use a custom App for a public HTTP API that no built-in App covers.
A custom App gives Craft credentials and network access for the API. It does not have an action catalog.

![The Create custom app form with Name, Upstream URL patterns, Enable for Craft, and Let users manage approval settings](https://mintcdn.com/danswer/yAnT-i7LBUiCJgOS/assets/admins/plugins/craft_custom_app.png?fit=max\&auto=format\&n=yAnT-i7LBUiCJgOS\&q=85\&s=fc56b70df5ababdd0fbfa93f429a80ae)

**1. Open the form**

Go to **Admin Panel → Plugins**, click **Add**, select **Craft Apps**, then select **Custom app**.

**2. Set the configuration**

Enter a **Name** and one or more **Upstream URL patterns**. Type each pattern and press Enter.
The proxy injects credentials only into requests that match these patterns.

**3. Set the authentication**

On the **Authentication** tab, add the headers that the proxy injects, such as `Authorization: Bearer {api_key}`.
Optionally, add **Organization credentials** for values that every user shares.

![The custom app Authentication tab with header patterns and Organization credentials](https://mintcdn.com/danswer/yAnT-i7LBUiCJgOS/assets/admins/plugins/craft_custom_app_authentication.png?fit=max\&auto=format\&n=yAnT-i7LBUiCJgOS\&q=85\&s=5203c2e397c6e0731214d305b74b9c59)

**4. Create the App**

Click **Create**. Then add skills that explain how to call the API.

For example:

| Setting | Value |
| - | - |
| Upstream URL pattern | `https://api.example.com/v1/*` |
| Header | `Authorization` |
| Header value | `Bearer {api_key}` |
| Organization credential | `api_key` = a shared service token. Leave it empty to let each user enter a token. |

### Define URL patterns narrowly

Custom Apps use URL globs. Each pattern must start with `http://` or `https://`, and its host must be literal.
Wildcards are allowed only after the host.

```text theme={null}
# Recommended: one HTTPS host and a narrow path
https://api.example.com/v1/reports/*

# Too broad: every path on the host
https://api.example.com/*

# Invalid: wildcard in the host
https://*.example.com/*
```

> [!WARNING]
>
> Custom Apps cannot be used to reach private, loopback, link-local, cloud metadata,
> or other non-public network addresses.
> The sandbox proxy blocks internal destinations even when a URL pattern includes them.
> Expose only a deliberately secured, publicly routable HTTPS endpoint if Craft must call a custom service.

Avoid overlapping URL patterns between Apps. When more than one App claims the same URL,
the lowest-ID App—usually the earliest created—is selected first.
A disabled App can still claim the match before credential availability is checked,
so do not rely on enablement to disambiguate overlapping patterns.

### Configure credentials

In a header value, write each credential as a named placeholder:

```text theme={null}
Authorization: Bearer {api_key}
X-Workspace-ID: {workspace_id}
```

Add a value under **Organization credentials** when every user should use the same service identity.
Leave a placeholder without an organization value when each user should enter their own value when they connect the app.
You can also leave the header pattern empty for a public API that requires no credential.

Raw organization and user credentials are encrypted in Onyx-controlled storage.
They are not copied into the custom bundle or sandbox workspace. After a request passes its gate,
the sandbox proxy injects the rendered headers on the way out.

> [!WARNING]
>
> A custom App has no action catalog. Every request that matches its URL patterns requires approval.
> You cannot set a custom App request to **Auto-approve** or **Disabled**. To stop all use of a custom App,
> turn off **Enable for Craft**.

## Manage Apps

| Action | Effect |
| - | - |
| **Edit** | Click the App on the Plugins page. Change its configuration, credentials, action policies, or skills. |
| **Turn off Enable for Craft** | Hides the App from users and stops credential injection. Onyx keeps the configuration and user connections. |
| **Delete** | Click the trash icon. Onyx removes the App, its policies, user credentials, and its Scheduled Task settings. |

Onyx-managed Apps on Onyx Cloud cannot be deleted. Turn off **Enable for Craft** instead.

## Troubleshooting

> **A built-in app connection fails**
>
> Confirm the OAuth client ID and secret, the exact redirect URI, the enabled API or integration capabilities,
> and the required scopes.
> Check whether the provider's consent screen is limited to approved test users or workspace members.

> **An enabled app does not appear to users**
>
> Confirm that **Enable for Craft** is on and that the user has Craft access. Refresh the Plugins page.

> **A user connected successfully but an action is blocked**
>
> Check the action's admin policy and the scopes or capabilities granted by the external account.
> A **Disabled** policy cannot be overridden.
> An Ask request can also fail if the user rejects it or the approval expires.

> **A custom app prompts for every request**
>
> This is expected. A custom app has no action catalog,
> so every request that matches its URL patterns requires approval.

> **A custom app calls the wrong service or uses the wrong credential**
>
> Check for overlapping URL patterns. Make every host and path as specific as possible.
> The lowest-ID app wins when multiple apps match the same URL, including when that first app is disabled.

> **A Scheduled Task is awaiting approval**
>
> Confirm that the task owner is still connected to the app and that the app is on in the task's approval settings.
> Then check for a **Disabled** policy, or a different app than the prompt was expected to use.
> Correct the task and use **Run now**. The blocked run does not resume automatically.

> **[Craft Apps for users](/overview/core_features/craft_apps)**
>
> Connect accounts, guide Craft, and review approvals.

> **[Craft architecture](/security/architecture/craft)**
>
> Review egress controls, credential injection, and approval enforcement.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.