# Plugin Development Guide

## Plugin Composition

A LobeChat plugin consists of the following components:

1. **Plugin Index**: Used to display basic information about the plugin, including the plugin name, description, author, version, and a link to the plugin manifest. The official plugin index can be found at [lobe-chat-plugins](https://github.com/lobehub/lobe-chat-plugins). If you want to publish a plugin to the official plugin marketplace, you need to [submit a PR](https://github.com/lobehub/lobe-chat-plugins/pulls) to this repository.
2. **Plugin Manifest**: Used to describe the functionality of the plugin, including the server-side description, frontend display information, and version number. For a detailed introduction to the manifest, see [manifest][manifest-docs-url].
3. **Plugin Services**: Used to implement the server-side and frontend modules described in the plugin manifest, as follows:
   - **Server-side**: Needs to implement the interface capabilities described in the `api` section of the manifest.
   - **Frontend UI** (optional): Needs to implement the interface described in the `ui` section of the manifest. This interface will be displayed in plugin messages, allowing for a richer display of information than plain text.

## Custom Plugin Workflow

This section will introduce how to add and use a custom plugin in LobeChat.

### **`1`** Create and Launch Plugin Project

You need to first create a plugin project locally, you can use the template we have prepared [lobe-chat-plugin-template][lobe-chat-plugin-template-url]

```bash
$ git clone https://github.com/lobehub/chat-plugin-template.git
$ cd chat-plugin-template
$ npm i
$ npm run dev
```

When you see `ready started server on 0.0.0.0:3400, url: http://localhost:3400`, it means the plugin service has been successfully launched locally.

![](https://github-production-user-asset-6210df.s3.amazonaws.com/28616219/265259526-9ef25272-4312-429b-93bc-a95515727ed3.png)

### **`2`** Add Local Plugin in LobeChat Role Settings

Next, go to LobeChat, create a new assistant, and go to its session settings page:

![](https://github-production-user-asset-6210df.s3.amazonaws.com/28616219/265259643-1a9cc34a-76f3-4ccf-928b-129654670efd.png)

Click the <kbd>Add</kbd> button on the right of the plugin list to open the custom plugin adding popup:

![](https://github-production-user-asset-6210df.s3.amazonaws.com/28616219/265259748-2ef6a244-39bb-483c-b359-f156ffcbe1a4.png)

Fill in the **Plugin Description File Url** with `http://localhost:3400/manifest-dev.json`, which is the manifest address of the plugin we started locally.

At this point, you should see that the identifier of the plugin has been automatically recognized as `chat-plugin-template`. Next, you need to fill in the remaining form fields (only the title is required), and then click the <kbd>Save</kbd> button to complete the custom plugin addition.

![](https://github-production-user-asset-6210df.s3.amazonaws.com/28616219/265259964-59f4906d-ae2e-4ec0-8b43-db36871d0869.png)

After adding, you can see the newly added plugin in the plugin list. If you need to modify the plugin configuration, you can click the <kbd>Settings</kbd> button on the far right to make changes.

![](https://github-production-user-asset-6210df.s3.amazonaws.com/28616219/265260093-a0363c74-0b5b-48dd-b103-2db6b4a8262e.png)

### **`3`** Test Plugin Function in Session

Next, we need to test whether the plugin's function is working properly.

Click the <kbd>Back</kbd> button to return to the session area, and then send a message to the assistant: "What should I wear?" At this point, the assistant will try to ask you about your gender and current mood.

![](https://github-production-user-asset-6210df.s3.amazonaws.com/28616219/265260291-f0aa0e7c-0ffb-486c-a834-08e73d49896f.png)

After answering, the assistant will initiate the plugin call, retrieve recommended clothing data from the server based on your gender and mood, and push it to you. Finally, it will provide a text summary based on this information.

![](https://github-production-user-asset-6210df.s3.amazonaws.com/28616219/265260461-c22ae797-2809-464b-96fc-d0c020f4807b.png)

After completing these operations, you have understood the basic process of adding custom plugins and using them in LobeChat.

<br />

## Local Plugin Development

In the above process, we have learned how to add and use plugins. Next, we will focus on the process of developing custom plugins.

### Manifest

The `manifest` aggregates information on how the plugin's functionality is implemented. The core fields are `api` and `ui`, which respectively describe the server-side interface capabilities and the front-end rendering interface address of the plugin.

Taking the `manifest` in the template we provided as an example:

```json
{
  "api": [
    {
      "url": "http://localhost:3400/api/clothes",
      "name": "recommendClothes",
      "description": "Recommend clothes to the user based on their mood",
      "parameters": {
        "properties": {
          "mood": {
            "description": "The user's current mood, with optional values: happy, sad, anger, fear, surprise, disgust",
            "enums": ["happy", "sad", "anger", "fear", "surprise", "disgust"],
            "type": "string"
          },
          "gender": {
            "type": "string",
            "enum": ["man", "woman"],
            "description": "The user's gender, which needs to be asked for from the user to obtain this information"
          }
        },
        "required": ["mood", "gender"],
        "type": "object"
      }
    }
  ],
  "gateway": "http://localhost:3400/api/gateway",
  "identifier": "chat-plugin-template",
  "ui": {
    "url": "http://localhost:3400",
    "height": 200
  },
  "version": "1"
}
```

In this manifest, it mainly includes the following parts:

1. `identifier`: This is the unique identifier of the plugin, used to distinguish different plugins. This field needs to be globally unique.
2. `api`: This is an array containing all the API interface information of the plugin. Each interface includes the url, name, description, and parameters fields, all of which are required. The `description` and `parameters` fields will be sent to GPT as the `functions` parameter of the [Function Call](https://sspai.com/post/81986), and the parameters need to comply with the [JSON Schema](https://json-schema.org/) specification. In this example, the API interface is named `recommendClothes`, and its function is to recommend clothes based on the user's mood and gender. The interface parameters include the user's mood and gender, both of which are required.
3. `ui`: This field contains information about the plugin's user interface, indicating from which address LobeChat loads the plugin's front-end interface. Since LobeChat plugin interface loading is implemented based on iframes, the height and width of the plugin interface can be specified as needed.
4. `gateway`: This field specifies the gateway for LobeChat to query the plugin's API interface. LobeChat's default plugin gateway is a cloud-based service, and requests for custom plugins need to be sent to a locally launched service. Remote calls to a local address are generally not feasible. The `gateway` field solves this problem. By specifying the gateway in the manifest, LobeChat will send plugin requests to this address, and the local gateway address will dispatch requests to the local plugin service. Published online plugins do not need to specify this field.
5. `version`: This is the version number of the plugin, which currently has no effect.

In actual development, you can modify the plugin's description list according to your own needs to declare the functionality you want to implement. For a complete introduction to each field in the manifest, see: [manifest][manifest-docs-url].

### Project Structure

The [lobe-chat-plugin-template][lobe-chat-plugin-template-url] template project uses Next.js as the development framework, and its core directory structure is as follows:

```
➜  chat-plugin-template
├── public
│   └── manifest-dev.json            # Manifest file
├── src
│   └── pages
│   │   ├── api                      # Next.js server-side folder
│   │   │   ├── clothes.ts           # Implementation of the recommendClothes interface
│   │   │   └── gateway.ts           # Local plugin proxy gateway
│   │   └── index.tsx                # Front-end display interface
```

This template uses Next.js as the development framework. You can use any development framework and language you are familiar with, as long as it can implement the functionality described in the manifest.

Contributions of more plugin templates using different frameworks and languages are also welcome.

### Server-Side

The server-side needs to implement the API interfaces described in the manifest. In the template, we use Vercel's [Edge Runtime](https://nextjs.org/docs/pages/api-reference/edge) to eliminate the need for maintenance.

#### API Implementation

For the Edge Runtime, we provide the `createErrorResponse` method in `@lobehub/chat-plugin-sdk` to quickly return error responses. Currently, the provided error types are detailed in: [PluginErrorType][plugin-error-type-url].

The implementation of the clothes interface in the template is as follows:

```ts
export default async (req: Request) => {
  if (req.method !== 'POST') return createErrorResponse(PluginErrorType.MethodNotAllowed);

  const { gender, mood } = (await req.json()) as RequestData;

  const clothes = gender === 'man' ? manClothes : womanClothes;

  const result: ResponseData = {
    clothes: clothes[mood] || [],
    mood,
    today: Date.now(),
  };

  return new Response(JSON.stringify(result));
};
```

Where `manClothes` and `womanClothes` are mock data and can be replaced with database queries in actual scenarios.

#### Plugin Gateway

Since the default plugin gateway for LobeChat is a cloud service `/api/plugins`, the cloud service sends requests to the address specified in the manifest's `api.url` to solve cross-origin issues.

For custom plugins, plugin requests need to be sent to the local service. Therefore, by specifying the gateway in the manifest (http://localhost:3400/api/gateway), LobeChat> will directly request this address, and then only the corresponding gateway needs to be created at that address.

```ts
import { createLobeChatPluginGateway } from '@lobehub/chat-plugins-gateway';

export const config = {
  runtime: 'edge',
};

export default createLobeChatPluginGateway();
```

[`@lobehub/chat-plugins-gateway`](https://github.com/lobehub/chat-plugins-gateway) contains the implementation of the plugin gateway in LobeChat [here](https://github.com/lobehub/lobe-chat/blob/main/src/pages/api/plugins.api.ts). You can use this package directly to create a gateway, allowing LobeChat to access the local plugin service.

### Plugin UI Interface

The custom UI interface for plugins is optional. For example, the official plugin [Web Content Extraction](https://github.com/lobehub/chat-plugin-web-crawler) does not have a corresponding user interface.

![](https://github-production-user-asset-6210df.s3.amazonaws.com/28616219/265263241-0e765fdc-3463-4c36-a398-aef177a30df9.png)

If you want to display richer information in plugin messages or include some interactive operations, you can customize a user interface for the plugin. For example, the following image shows the user interface for the [Search Engine](https://github.com/lobehub/chat-plugin-search-engine) plugin.

![](https://github-production-user-asset-6210df.s3.amazonaws.com/28616219/265263427-9bdc03d5-aa61-4f62-a2ce-88683f3308d8.png)

#### Implementation of Plugin UI Interface

LobeChat implements the loading of plugin UI through `iframe` and uses `postMessage` to communicate with the plugin. Therefore, the implementation of the plugin UI is consistent with regular web development. You can use any frontend framework and development language you are familiar with.

![](https://github-production-user-asset-6210df.s3.amazonaws.com/28616219/265263653-4ea87abc-249a-49f3-a241-7ed93ddb1ddf.png)

In the template we provide, we use React + Next.js + [antd](https://ant.design/) as the frontend interface framework. You can find the implementation of the user interface in [`src/pages/index.tsx`](https://github.com/lobehub/chat-plugin-template/blob/main/src/pages/index.tsx).

As for plugin communication, we provide relevant methods in [`@lobehub/chat-plugin-sdk`](https://github.com/lobehub/chat-plugin-sdk) to simplify communication between the plugin and LobeChat. You can actively retrieve the current message data from LobeChat using the `fetchPluginMessage` method. For detailed information about this method, see: [fetchPluginMessage][fetch-plugin-message-url].

```tsx
import { fetchPluginMessage } from '@lobehub/chat-plugin-sdk';
import { memo, useEffect, useState } from 'react';

import { ResponseData } from '@/type';

const Render = memo(() => {
  const [data, setData] = useState<ResponseData>();

  useEffect(() => {
    // Retrieve the current plugin message from LobeChat
    fetchPluginMessage().then((e: ResponseData) => {
      setData(e);
    });
  }, []);

  return <>...</>;
});

export default Render;
```

## Plugin Deployment and Release

Once you have finished developing the plugin, you can deploy it using your preferred method, such as using Vercel or packaging it as a Docker container for release, and so on.

If you want more people to use your plugin, feel free to [submit it for listing](https://github.com/lobehub/lobe-chat-plugins) on the plugin marketplace.

[![][submit-plugin-shield]][submit-plugin-url]

### Plugin Shield

[![lobe-chat-plugin](https://img.shields.io/badge/%F0%9F%A4%AF%20%26%20%F0%9F%A7%A9%20LobeHub-Plugin-95f3d9?labelColor=black&style=flat-square)](https://github.com/lobehub/lobe-chat-plugins)

```md
[![lobe-chat-plugin](https://img.shields.io/badge/%F0%9F%A4%AF%20%26%20%F0%9F%A7%A9%20LobeHub-Plugin-95f3d9?labelColor=black&style=flat-square)](https://github.com/lobehub/lobe-chat-plugins)
```

## Links

- **📘 Pluging SDK Documentation**: https://chat-plugin-sdk.lobehub.com
- **🚀 chat-plugin-template**: https://github.com/lobehub/chat-plugin-template
- **🧩 chat-plugin-sdk**: https://github.com/lobehub/chat-plugin-sdk
- **🚪 chat-plugin-gateway**: https://github.com/lobehub/chat-plugins-gateway
- **🏪 lobe-chat-plugins**: https://github.com/lobehub/lobe-chat-plugins

[fetch-plugin-message-url]: https://github.com/lobehub/chat-plugin-template
[lobe-chat-plugin-template-url]: https://github.com/lobehub/chat-plugin-template
[manifest-docs-url]: https://chat-plugin-sdk.lobehub.com/guides/plugin-manifest
[plugin-error-type-url]: https://github.com/lobehub/chat-plugin-template
[submit-plugin-shield]: https://img.shields.io/badge/🧩/🏪_submit_plugin-%E2%86%92-95f3d9?labelColor=black&style=for-the-badge
[submit-plugin-url]: https://github.com/lobehub/lobe-chat-plugins
