> ## Documentation Index
> Fetch the complete documentation index at: https://dify-6c0370d8-preview-yajing-marketplace-doc.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Publish a Plugin to Marketplace

> Prepare and validate a .difypkg, submit it for Marketplace review, respond to the pull request, and review the published plugin's performance and feedback in Creator Center

Submit your plugin for Marketplace review through a pull request to [`langgenius/dify-plugins`](https://github.com/langgenius/dify-plugins).

## What You Need

* A working plugin project tested with the current Dify Community Edition or Dify Cloud.
* The [Dify plugin CLI](https://github.com/langgenius/dify-plugin-daemon) for packaging.
* Python 3 and [`yq`](https://github.com/mikefarah/yq) for local validation.
* A public source repository that reviewers and users can inspect.

<Note>
  The Marketplace accepts a packaged `.difypkg`, not your source tree. Reviewers still use the source repository declared in your metadata and PR to understand behavior that cannot be proven from the package alone.
</Note>

## Prepare the Package

<Tabs>
  <Tab title="Runtime files">
    Include only files needed when the plugin runs: `manifest.yaml`, provider or tool definitions, source code, dependencies, README files, privacy policy, and assets.

    Do not package development state such as `.git/`, virtual environments, caches, logs, `.DS_Store`, local settings, IDE files, or test artifacts. Never include `.env` files, access tokens, private keys, cloud credentials, or other secrets.
  </Tab>

  <Tab title="Metadata and docs">
    Confirm that `manifest.yaml` accurately declares the author, name, version, plugin type, runner, icon, source repository, contact information, and privacy policy.

    The primary `README.md` must be in English and explain setup, usage, required APIs or credentials, connection requirements, and the source repository. Put translations under `readme/README_<locale>.md`.
  </Tab>

  <Tab title="Dependencies">
    Keep dependencies minimal and pinned closely enough to be reproducible. Avoid bare requirements, direct URL installs, and git-based installs unless the PR explains why they are required.

    Python plugins must use `dify-plugin >= 0.9.0`. The validator also checks dependency metadata and queries the [OSV database](https://osv.dev/) for known vulnerabilities.
  </Tab>
</Tabs>

### Document Privacy and Network Access

Your `PRIVACY.md` or hosted privacy policy must describe what user data the plugin collects, stores, logs, or sends to third parties. If the plugin collects no user data, say so explicitly.

When a plugin contacts external services, you can declare the expected domains in `manifest.yaml`:

```yaml theme={null}
network:
  domains:
    - api.example.com
    - "*.cdn.example.com"
```

Static analysis cannot discover every URL assembled at runtime or hidden inside a vendor SDK. Declaring domains makes those destinations visible even when the scanner cannot infer them from source code.

## Classify the Risk

Choose the highest level that matches the plugin. You will select exactly one level in the Marketplace PR template.

| Level      | Use It When                                                                                                                                                                                                |
| :--------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Low**    | The plugin calls fixed, documented HTTPS APIs and does not execute user-controlled code, commands, SQL, file operations, browser automation, or arbitrary network requests.                                |
| **Medium** | The plugin processes uploaded files or user-provided URLs, performs write actions in a third-party service, sends user content externally, or handles personal data that is not highly sensitive.          |
| **High**   | The plugin can execute code or commands, run SQL, access databases or file systems, use SSH/SFTP, automate browsers, proxy or crawl arbitrary URLs, bundle executables, or handle sensitive personal data. |

<Warning>
  If more than one level could apply, select the higher level. A lower label does not reduce review scope; it only creates inconsistent evidence and delays review.
</Warning>

For medium- and high-risk plugins, document the security boundary: how inputs are constrained, where data goes, which credentials are used, what timeouts apply, and how errors avoid exposing secrets.

## Build and Validate Locally

<Steps>
  <Step title="Package the plugin">
    From the directory above your plugin project, run:

    ```bash theme={null}
    dify plugin package ./your-plugin
    ```

    The command creates a `.difypkg` archive. Inspect its filename and file size before continuing.
  </Step>

  <Step title="Clone the Marketplace Toolkit">
    ```bash theme={null}
    git clone https://github.com/langgenius/dify-marketplace-toolkit.git
    cd dify-marketplace-toolkit
    ```
  </Step>

  <Step title="Run package validation">
    ```bash theme={null}
    python3 validator/validate-difypkg.py /path/to/your-plugin.difypkg \
      --output-dir ./validation-report
    ```

    To compare sensitive-capability findings with your planned PR disclosure, save the PR body to a file and add `--pr-body-file /path/to/pr-body.md`.
  </Step>

  <Step title="Resolve the report">
    Open `validation-report/summary.md`, then inspect the generated `*.errors.txt` and `*.warnings.txt` files.

    Exit code `0` means no blocking package-level errors were found. Exit code `1` means a blocking finding or environment error must be resolved. Warnings do not fail validation, but reviewers may ask for clarification.
  </Step>
</Steps>

The local validator checks safe extraction, package contents and size, secret patterns, binaries, manifest and README metadata, dependency policy, Python compilation and safety patterns, outbound domains, dependency vulnerabilities, financial-activity signals, and optional sensitive-capability disclosure.

<Tip>
  Only the vulnerability lookup reaches the network. Add `--offline` when necessary; the report will list dependencies without claiming that they are vulnerability-free.
</Tip>

## Choose the Submission Type

<Tabs>
  <Tab title="New plugin">
    Create a package directory under your author namespace:

    ```text theme={null}
    <author>/<plugin-name>/<plugin-package>.difypkg
    ```

    The package metadata, source repository, contact information, README, privacy policy, and risk disclosure must all describe the same plugin.
  </Tab>

  <Tab title="Version update">
    Increment `version` in `manifest.yaml`, rebuild the package, and add the new `.difypkg` to the existing plugin directory.

    An update PR should normally add only the new package file. Keep old published packages unless a maintainer explicitly asks otherwise. Summarize fixes, features, migrations, and breaking changes in **What changed** so the release pipeline can extract useful release notes.
  </Tab>
</Tabs>

## Open the PR

<Steps>
  <Step title="Fork and synchronize the repository">
    Fork [`langgenius/dify-plugins`](https://github.com/langgenius/dify-plugins), then clone your fork and keep its `main` branch synchronized with upstream.

    ```bash theme={null}
    git clone https://github.com/<your-github-name>/dify-plugins.git
    cd dify-plugins
    git remote add upstream https://github.com/langgenius/dify-plugins.git
    git fetch upstream
    git switch main
    git merge --ff-only upstream/main
    ```
  </Step>

  <Step title="Create a focused branch">
    ```bash theme={null}
    git switch -c add-<plugin-name>-<version>
    mkdir -p <author>/<plugin-name>
    cp /path/to/plugin.difypkg <author>/<plugin-name>/
    ```

    Confirm that the branch changes exactly one `.difypkg` package:

    ```bash theme={null}
    git status --short
    git diff --stat
    ```
  </Step>

  <Step title="Commit and push">
    ```bash theme={null}
    git add <author>/<plugin-name>/<plugin-package>.difypkg
    git commit -m "add <plugin-name> <version>"
    git push -u origin HEAD
    ```
  </Step>

  <Step title="Create the pull request">
    Open a PR from your fork to `langgenius/dify-plugins:main`. Keep the PR out of draft only when the package and description are ready for automated and human review.
  </Step>
</Steps>

<Warning>
  Submit one `.difypkg` per PR. Combining plugins or versions prevents CI from identifying a single package path and blocks the submission.
</Warning>

## Complete the Submission Template

The current template is part of the review contract. Do not delete fields or replace it with a short free-form description.

<AccordionGroup>
  <Accordion title="Plugin information">
    Provide the author, plugin name, version, public source repository, and a monitored contact channel. These values must agree with `manifest.yaml` and the package documentation.
  </Accordion>

  <Accordion title="Submission type and changes">
    Select **New plugin** or **Version update**, then explain what the plugin does or what changed in this version. Write release-note-quality details for updates, including migrations and breaking changes.
  </Accordion>

  <Accordion title="Risk level">
    Select exactly one of **Low risk**, **Medium risk**, or **High risk**. The repository applies a matching `risk:*` label. Selecting none or multiple levels produces `risk: missing` and a bot comment.
  </Accordion>

  <Accordion title="Required checks">
    Confirm package hygiene, testing, README quality, privacy coverage, and English localization only after verifying each item. If a requirement has a limitation, explain it in **Reviewer notes** instead of silently checking the box.
  </Accordion>

  <Accordion title="Security and privacy notes">
    List command or code execution, SQL, SSH/SFTP, browser automation, file operations, arbitrary URL fetching, proxying, and sensitive-data handling. Write `None` only when none apply.
  </Accordion>

  <Accordion title="Local validation and reviewer notes">
    Paste the validator command and result. Add known limitations, package or binary exceptions, migration notes, and context reviewers need to interpret warnings.
  </Accordion>
</AccordionGroup>

## Help Reviewers Verify Your Plugin

| Do                                                           | Avoid                                                                           |
| :----------------------------------------------------------- | :------------------------------------------------------------------------------ |
| Use English for the PR title, body, and primary README.      | Mixing untranslated CJK text into the primary submission fields.                |
| Link the exact public source repository for the package.     | Linking an organization homepage or unrelated monorepo root without directions. |
| Explain why sensitive behavior is necessary and constrained. | Describing a high-risk capability as low risk because it is optional.           |
| Include concrete validation commands and results.            | Saying “tested” without environment or result details.                          |
| Keep package bytes and disclosure in sync.                   | Copying an old PR body for a changed version.                                   |

<h2 id="after-you-submit">
  Handle PR Checks and Review
</h2>

Opening the PR, pushing commits, or marking a draft ready for review starts the automated checks. Use the result to decide whether you need to act.

| Result                | What You Do                                                                                                                                                              |
| :-------------------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Pass**              | Wait for maintainer review. A passing check does not guarantee approval.                                                                                                 |
| **Blocking error**    | Fix the package or PR, rebuild when needed, and update the same PR. Do not open a replacement PR.                                                                        |
| **Warning**           | Review the finding. Fix an actual problem, or add context when the behavior is intentional. A warning alone does not fail the check, but a reviewer may request changes. |
| **Changes requested** | Update the source, rebuild the package when needed, push the correction to the same PR, and respond to the reviewer.                                                     |

After approval and merge, the repository validates the package again and uploads it to the production Marketplace. You do not need to start CI or upload the approved package yourself.

<h2 id="manage-published-plugins">
  Review Plugin Performance and Feedback in Creator Center
</h2>

After your plugin appears in Marketplace, view its performance data on the **Plugin** page in [Creator Center](https://creators.dify.ai/). Review individual ratings, likes, and feedback messages in [**Inbox**](https://creators.dify.ai/dashboard/inbox).

### Review Your Published Plugins

Under your personal account, connect the GitHub account used to publish your plugins. If you have connected multiple accounts, select the account whose plugins you want to view.

Each plugin card shows its downloads, overall rating, rating count, and likes.

### Review Plugin Performance and Feedback With Your Team

Select the organization your team uses. Any plugins listed there are visible to all organization members.

When creating a new organization for plugins, find the Plugin ID on the plugin's Marketplace details page. Enter the part before `/` in **Unique handle**. For example, if the Plugin ID is `team-name/plugin-name`, enter `team-name`.

<Frame caption="Plugin ID on the Marketplace Details Page">
  <img src="https://mintcdn.com/dify-6c0370d8-preview-yajing-marketplace-doc/tFyXtsR8plDhPNWj/images/develop-plugin/publish/marketplace-plugin-id.png?fit=max&auto=format&n=tFyXtsR8plDhPNWj&q=85&s=2c61cf5f63f7baa85be5820cab49731a" alt="Plugin ID on the Marketplace Details Page" width="1568" height="500" data-path="images/develop-plugin/publish/marketplace-plugin-id.png" />
</Frame>

After you create the organization, the plugins appear there automatically. Invite teammates to view the same plugins without connecting their own GitHub accounts.

#### Claim Missing Organization Plugins

If a plugin published under your organization's name does not appear on the organization's **Plugin** page, open **Claim plugin** to request access to its performance data and feedback.

1. Under your personal account, select **Claim plugin**.
2. For each plugin, copy its Plugin ID from its Marketplace details page and pair it with the PR that originally published it.
3. Confirm your contact email and describe your role in maintaining the plugins. If a different GitHub account opened the PRs, explain why.
4. Select **Submit claim**.

Track the request in **Claim history**. After approval, the plugins included in the claim appear under the corresponding organization. If the claim is rejected, review the reason and select **New Claim** to update the evidence and resubmit it.

## Related Resources

<CardGroup cols={2}>
  <Card title="PR template" icon="file-lines" href="https://github.com/langgenius/dify-plugins/blob/main/.github/pull_request_template.md">
    Review the live template before submitting; repository requirements can evolve.
  </Card>

  <Card title="Plugin review guidelines" icon="magnifying-glass" href="https://github.com/langgenius/dify-plugins/blob/main/docs/plugin-review-guidelines.md">
    See how maintainers inspect documentation, dependencies, privacy, and sensitive capabilities.
  </Card>
</CardGroup>
