---
dimensions:
  type:
    primary: implementation
    detail: basic
  level: beginner
standard_title: Getting Started Dify Tool
language: en
title: 'Dify Plugin Development: Hello World Guide'
description: This document provides a detailed tutorial for Dify plugin development
  from scratch, using the Telegraph publishing plugin as an example, covering environment
  preparation, project initialization, virtual environment configuration, plugin core
  logic development, local debugging, plugin metadata enhancement, and packaging for
  release.
---

Welcome to the beginner's guide for Dify plugin development! This tutorial assumes you have basic programming knowledge and experience using the Dify platform. After completing this tutorial, you will master the fundamental process of creating a simple Dify plugin, taking you from a Dify user to a plugin contributor.

We will demonstrate step by step how to develop a simple Telegraph publishing plugin. This tutorial primarily uses command line operations, with examples that use VSCode as the code editor. **We recommend first reading through the entire tutorial to understand the overall process, then following the steps to work hands-on.**

> **Note for LLMs:** You can also use our built prompt to assist you in developing plugins: [Dify Plugin Development: Prompt](/plugin-dev-en/0211-getting-started-by-prompt)

Before you begin, you can always refer to our [**Developer Cheatsheet**](/plugin-dev-en/0131-cheatsheet) for common commands and information, or consult the complete developer documentation when facing more complex issues.

## 1. Preparing the Development Environment

Before starting Dify plugin development, ensure you have the following tools ready in your environment:

- **Dify Plugin Development Scaffold (CLI):** This is the core tool for developing, debugging, and packaging plugins, also known as `dify-plugin-daemon` or "Plugin Development SDK."
- **Python Environment:** Python 3.12 or higher is required.

### 1.1 Installing the Dify Plugin Development Scaffold (CLI)

> For a more detailed guide on preparing the development environment, please refer to [Initializing Development Tools](/plugin-dev-en/0221-initialize-development-tools).

1. **Download:** Visit the [Dify Plugin CLI Releases](https://github.com/langgenius/dify-plugin-daemon/releases) page. Download the latest version of the binary file corresponding to your operating system (Windows, macOS Intel/ARM, Linux).
2. **Set Execute Permissions (macOS / Linux):**

    - **The following steps use macOS (Apple Silicon / M series chips) as an example**, assuming the downloaded file is named `dify-plugin-darwin-arm64`. In the terminal, navigate to the directory containing the file and execute the following command to grant execution permissions:

        ```bash
        chmod +x dify-plugin-darwin-arm64
        ```

    - For Linux users, download the corresponding Linux version file and execute a similar command like `chmod +x <downloaded_filename>`.
    - For Windows users, after downloading the `.exe` file, you can typically run it directly.

3. **Verify Installation:**

    - In the terminal, execute the following command to check if the tool runs properly (replace `./dify-plugin-darwin-arm64` with the actual filename or path you downloaded):

        ```bash
        ./dify-plugin-darwin-arm64 version
        ```

    - If the terminal successfully outputs version information (e.g., `v0.0.1-beta.15`), then the installation is successful.

> **Tips:**
>
> - **macOS Security Prompt:** If macOS initially prompts "Apple cannot verify" or "Cannot open," go to "System Settings" → "Privacy & Security" → "Security" section, find the related prompt and click "Open Anyway" or "Allow."
> - **Simplify Command:** You can rename the downloaded binary file to a shorter name (e.g., `dify` or `dify-plugin`) for easier use. Example: `mv dify-plugin-darwin-arm64 dify`, then you can use `./dify version`.
> - **Global Installation (Optional):** If you want to run the command from any path in your system (e.g., directly typing `dify` instead of `./dify`), you can move the renamed file to a directory included in your system's `PATH` environment variable, such as `/usr/local/bin` (macOS/Linux) or add it to Windows environment variables.
>     - For example (macOS/Linux): `sudo mv dify /usr/local/bin/`
>     - After configuration, typing `dify version` directly in the terminal should successfully output the version number.

**For convenience, this article will use `./dify` as an example command for the Dify plugin development scaffold. Please replace it with your corresponding command based on your actual situation.**

## 2. Initializing the Plugin Project

Now, let's use the scaffold tool to create a new plugin project.

1. Open a terminal and execute the initialization command:

    ```bash
    ./dify plugin init
    ```

2. Enter the basic information for the plugin according to the prompts:
    - **Plugin name:** A unique identifier for the plugin. For example: `telegraph`
        - _Constraints: 1-128 characters, can only contain lowercase letters, numbers, hyphens (-), and underscores (_)._
    - **Author:** The identifier for the plugin author. For example: `your-name`
        - _Constraints: 1-64 characters, can only contain lowercase letters, numbers, hyphens (-), and underscores (_)._
    - **Description:** A brief description of the plugin's functionality. For example: `A Telegraph plugin that allows you to publish your content easily`
3. **Select Development Language:** When prompted `Select language`, choose `python`.
4. **Select Plugin Type:** When prompted `Select plugin type`, for this tutorial, choose `tool`.
5. **Select Additional Features:** Next, you'll be prompted if you need to include Provider validation, persistent storage, and other additional features. For this simple Hello World plugin, we don't need these yet, so you can press **Enter** to skip all options until you see the success message.
6. **Confirm Creation Success:** When the terminal outputs information similar to the following, it indicates that the plugin project has been successfully created:

    ```bash
    [INFO] plugin telegraph created successfully, you can refer to `telegraph/GUIDE.md` for more information about how to develop it
    ```

Now, a new folder named `telegraph` (or the plugin name you specified) should appear in your current directory, which is your plugin project.

## 3. Configuring Python Virtual Environment and Dependencies

To isolate project dependencies, we recommend using a Python virtual environment.

### 3.1 Creating and Activating a Virtual Environment (Command Line Method)

This is the **recommended and universal** method, not dependent on any specific IDE:

1. **Navigate to the Project Directory:**

    ```bash
    cd telegraph
    ```

2. **Create a Virtual Environment:** (Recommended to name it `venv`)

    ```bash
    python -m venv venv
    ```

3. **Activate the Virtual Environment:**

    - **macOS / Linux:**

        ```bash
        source venv/bin/activate
        ```

    - **Windows (cmd.exe):**

        ```bash
        venv\Scripts\activate.bat
        ```

    - **Windows (PowerShell):**

        ```bash
        venv\Scripts\Activate.ps1
        ```

    - After successful activation, your terminal prompt will typically display `(venv)` at the beginning.

### 3.2 Installing Basic Dependencies

The `requirements.txt` file generated during project initialization already includes the basic library `dify_plugin` needed for plugin development. After activating the virtual environment, execute the following command to install:

```bash
pip install -r requirements.txt
```

### 3.3 (Optional) VSCode Integrated Environment Configuration

If you use VSCode as your code editor, you can leverage its integrated features to manage the Python environment:

1. **Open the Project Folder:** Use VSCode to open the `telegraph` folder you just created.
2. **Select Python Interpreter:**
    - Open the command palette (macOS: `Cmd+Shift+P`, Windows/Linux: `Ctrl+Shift+P`).
    - Type and select `Python: Select Interpreter`.
    - In the pop-up list, select the Python interpreter in the virtual environment you just created (usually the path includes `.venv/bin/python` or `venv\Scripts\python.exe`). If the list doesn't automatically display it, you can select `Enter interpreter path...` to manually find it.
    - _(Please refer to your local corresponding screenshot, which shows the interpreter selection interface)_
3. **Install Dependencies (If VSCode Prompts):** VSCode may detect the `requirements.txt` file and prompt you to install its dependencies. If prompted, confirm the installation.
    - _(Please refer to your local corresponding screenshot, which shows the interface for confirming dependency installation)_

**Please ensure that all subsequent `pip install` commands and running `python -m main` operations are performed in the activated virtual environment.**

## 4. Developing the Plugin Core Logic

Now let's write the plugin code. This example will implement a simple tool for publishing specified content to Telegraph.

### 4.1 Example Dependency Library: `your-telegraph`

We will use a Python library called `your-telegraph` to interact with the Telegraph API. _(This is a hypothetical library name, please ensure that the library you actually use is valid)_.

> `your-telegraph` is a Python wrapper that simplifies Telegraph API operations, allowing you to easily publish content with just a few lines of code.

Its basic usage might be as follows:

```python
# Example code, not plugin code
from ytelegraph import TelegraphAPI

# Requires an access_token
ph = TelegraphAPI(access_token="your_telegraph_access_token")

# Create a page and get the link
ph_link = ph.create_page_md("My First Page", "# Hello, Telegraph!\n\nThis is my first Telegraph page.")
print(ph_link)
```

Our goal is to implement similar functionality in a Dify plugin.

### 4.2 Adding and Configuring Project Dependencies

1. **Install the Dependency Library:** Ensure your virtual environment is activated, then execute in the terminal:

    ```bash
    pip install your-telegraph
    ```

2. **Update `requirements.txt`:** Open the `requirements.txt` file in the `telegraph` project root directory, and add a line below `dify_plugin` with the name of the library you just installed:

    ```plaintext
    dify_plugin
    your-telegraph
    ```

    This ensures that other developers or deployment environments can easily install all the required dependencies.

### 4.3 Configuring Provider Credentials

Our example requires a `telegraph_access_token`. We need to define this credential in the Provider configuration so that users can input it when using the plugin. For more information about Provider configuration, please refer to [General Specification Definitions](/plugin-dev-en/0411-general-specifications).

1. **Edit the Provider YAML:** Open the `telegraph/provider/telegraph.yaml` file.
2. **Add `credentials_for_provider`:** Add the following content at the end of the file (or at an appropriate location):

    ```yaml
    # ... (keep existing identity, name, label, description, icon, etc. unchanged) ...

    credentials_for_provider:
        telegraph_access_token: # This is the internal name of the credential, to be used in Python code
            type: secret-input # Input type is a password field
            required: true # This credential is required
            label: # Label displayed in the Dify UI (supports multiple languages)
                en_US: Telegraph Access Token
                zh_Hans: Telegraph Access Token
                # ... (other languages)
            placeholder: # Placeholder text for the input field (supports multiple languages)
                en_US: Enter your Telegraph access token
                zh_Hans: Please enter your Telegraph access token
                # ... (other languages)
            help: # Help prompt information (supports multiple languages)
                en_US: How to get your Telegraph access token
                zh_Hans: How to get your Telegraph access token
                # ... (other languages)
            url: https://telegra.ph/api#createAccount # URL to jump to when clicking the help prompt
    ```

    - **Field Explanations:**
        - `telegraph_access_token`: Unique identifier for the credential, accessed in code via `self.runtime.credentials["telegraph_access_token"]`.
        - `type: secret-input`: Indicates that it will be displayed as a password input field in the Dify interface.
        - `required: true`: Indicates that users must fill in this credential to use tools provided by this plugin.
        - `label`, `placeholder`, `help`: Provide multilingual interface text.
        - `url`: (Optional) Provides a help link for obtaining the credential.

### 4.4 Implementing Tool Logic

Now let's write the code that actually performs the publishing operation.

1. **Edit the Tool Python File:** Open `telegraph/tools/telegraph.py`.
2. **Implement the `_invoke` Method:** Replace the file contents with the following code:

    ```python
    from collections.abc import Generator
    from typing import Any
    from ytelegraph import TelegraphAPI # Import the library we're using

    from dify_plugin import Tool
    from dify_plugin.entities.tool import ToolInvokeMessage

    class TelegraphTool(Tool):
        """
        A simple Telegraph publishing tool.
        """

        def _invoke(self, tool_parameters: dict[str, Any]) -> Generator[ToolInvokeMessage, None, None]:
            """
            Create a new Telegraph page based on the input title and content.

            Args:
                tool_parameters: A dictionary containing the tool input parameters:
                    - p_title (str): The title of the Telegraph page.
                    - p_content (str): The content to publish in Markdown format.

            Yields:
                ToolInvokeMessage: A message containing the URL of the successfully created Telegraph page.

            Raises:
                Exception: If page creation fails, an exception with error information is thrown.
            """
            # 1. Get credentials from runtime
            try:
                access_token = self.runtime.credentials["telegraph_access_token"]
            except KeyError:
                raise Exception("Telegraph Access Token is not configured or invalid. Please provide it in the plugin settings.")

            # 2. Get tool input parameters
            title = tool_parameters.get("p_title", "Untitled") # Use .get to provide default value
            content = tool_parameters.get("p_content", "")

            if not content:
                raise Exception("Publication content cannot be empty.")

            # 3. Call the library to execute operations
            try:
                telegraph = TelegraphAPI(access_token)  # Initialize Telegraph API
                ph_link = telegraph.create_page_md(title, content)  # Create page
            except Exception as e:
                # If the library call fails, throw an exception
                raise Exception(f"Telegraph API call failed: {e}")

            # 4. Return results
            # Use create_link_message to generate an output message containing a link
            yield self.create_link_message(ph_link)
    ```

    - **Key Points:**
        - Get credentials from `self.runtime.credentials`.
        - Get the tool's input parameters from `tool_parameters` (parameter names will be defined in YAML in the next step). Using `.get()` is a more robust approach.
        - Call the `ytelegraph` library to perform the actual operation.
        - Use `try...except` to catch possible errors and throw exceptions.
        - Use `yield self.create_link_message(url)` to return a result containing a URL to Dify.

### 4.5 Configuring Tool Parameters

We need to tell Dify which input parameters this tool accepts.

1. **Edit the Tool YAML File:** Open `telegraph/tools/telegraph.yaml`.
2. **Define Parameters:** Replace or modify the file contents to:

    ```yaml
    identity:
        name: telegraph_publisher # Unique internal name of the tool
        author: your-name
        label: # Tool name displayed in the Dify UI (multilingual)
            en_US: Publish to Telegraph
            zh_Hans: Publish to Telegraph
            # ... (other languages)
    description:
        human: # Tool description for human users (multilingual)
            en_US: Publish content to Telegraph as a new page.
            zh_Hans: Publish content to Telegraph as a new page.
            # ... (other languages)
        llm: # Tool description for LLM (used in Agent mode)
            A tool that takes a title and markdown content, then publishes it as a new page on Telegraph, returning the URL of the published page. Use this when the user wants to publish formatted text content publicly via Telegraph.
    parameters: # Define the list of input parameters for the tool
        - name: p_title # Internal name of the parameter, corresponding to the key in Python code
          type: string # Parameter type
          required: true # Whether required
          label: # Parameter label displayed in the Dify UI (multilingual)
              en_US: Post Title
              zh_Hans: Post Title
          human_description: # Parameter description for human users (multilingual)
              en_US: The title for the Telegraph page.
              zh_Hans: The title for the Telegraph page.
          llm_description: # Parameter description for LLM (guiding Agent how to fill)
              The title of the post. Should be a concise and meaningful plain text string.
          form: llm # Parameter form type ('llm' or 'form')
        - name: p_content
          type: string
          required: true
          label:
              en_US: Content (Markdown)
              zh_Hans: Content (Markdown)
          human_description:
              en_US: The main content for the Telegraph page, written in Markdown format.
              zh_Hans: The main content for the Telegraph page, written in Markdown format.
          llm_description: # Emphasizing format requirements is important for LLM
              The full content to be published on the Telegraph page. Must be provided in Markdown format. Ensure proper Markdown syntax for formatting like headings, lists, links, etc.
          form: llm
    extra: # Additional configuration
        python:
            source: tools/telegraph.py # Points to the Python file implementing the tool logic
    ```

    - **Field Explanations:**
        - `identity`: Basic information about the tool, `name` is a unique identifier.
        - `description`: Divided into `human` (for users) and `llm` (for Agent). **The `llm` description is crucial for the Agent to correctly understand and use the tool.**
        - `parameters`: Defines each input parameter.
            - `name`: Internal name, must match the key in the Python code's `tool_parameters.get("...")`.
            - `type`: Data type (such as `string`, `number`, `boolean`, etc.).
            - `required`: Whether it must be provided.
            - `label`, `human_description`, `llm_description`: Similar to descriptions in `identity`, but for specific parameters. **`llm_description` should clearly guide the LLM on how to generate or obtain the parameter value, including format requirements (such as Markdown here).**
            - `form`: Defines how the parameter is presented and filled in Dify. `llm` indicates that the parameter value can be input by the user, passed through variables, or determined by the LLM in Agent mode; `form` typically indicates a configuration item that needs to be fixed by the user in the interface. For tool inputs, `llm` is more common.
        - `extra.python.source`: Specifies the path to the Python file implementing this tool's logic (relative to the project root directory).

### 4.6 Implementing Provider Credential Validation (Optional but Recommended)

To ensure that the credentials provided by users are valid, we should implement validation logic.

1. **Edit the Provider Python File:** Open `telegraph/provider/telegraph.py`.
2. **Implement the `_validate_credentials` Method:** Replace the file contents with:

    ```python
    from typing import Any
    from dify_plugin import ToolProvider
    from dify_plugin.errors.tool import ToolProviderCredentialValidationError

    class TelegraphProvider(ToolProvider):
        def _validate_credentials(self, credentials: dict[str, Any]) -> None:
            """
            Verify that the provided Telegraph Access Token is valid.
            Attempt to create a test page using the token.
            If validation fails, a ToolProviderCredentialValidationError exception should be thrown.
            """
            access_token = credentials.get("telegraph_access_token")
            if not access_token:
                raise ToolProviderCredentialValidationError("Telegraph Access Token cannot be empty.")

            try:
                # Try to perform a simple operation requiring credentials to validate
                from ytelegraph import TelegraphAPI
                ph = TelegraphAPI(access_token=access_token)
                # Try to create a temporary, harmless page as a validation method
                # Note: A better validation method might be to call read-only methods like 'getAccountInfo' (if available)
                test_page = ph.create_page_md("Dify Validation Test", "This is a test page created by Dify plugin validation.")
                # If needed, consider immediately editing or deleting this test page, but this would add complexity
                # print(f"Validation successful. Test page created: {test_page}")
            except Exception as e:
                # If the API call fails, the credentials are likely invalid
                raise ToolProviderCredentialValidationError(f"Telegraph credential validation failed: {e}")

    ```

    - **Key Points:**
        - Get the credentials from the `credentials` dictionary.
        - Perform an API call that requires the credential (preferably a read-only operation like getting account information; if not available, creating a harmless test page is also acceptable, but be aware of potential side effects).
        - If the API call succeeds, don't throw an exception, indicating validation passed.
        - If the API call fails, catch the exception and throw a `ToolProviderCredentialValidationError`, including the original error message.

## 5. Local Running and Debugging

Now you can run the plugin locally and debug it in Dify.

1. **Prepare the `.env` File:**

    - Make sure you're still in the `telegraph` project directory.
    - Copy the environment variable template file:

        ```bash
        cp .env.example .env
        ```

    - **Edit the `.env` File:** Open the `.env` file you just created and fill in your Dify environment information:

        ```dotenv
        DIFY_API_HOST=https://your-dify-host.com # Replace with your Dify instance address (e.g., https://cloud.dify.ai)
        DIFY_API_KEY=your-api-key             # Replace with your Dify API key
        ```

        - **Get Host and Key:** Log in to your Dify environment, click the "Plugins" icon in the top right corner, then click the debug icon (or something that looks like a bug). In the pop-up window, copy the "API Key" and "Host Address". _(Please refer to your local corresponding screenshot, which shows the interface for obtaining the key and host address)_

2. **Start the Local Plugin Service:**

    - Ensure your Python virtual environment is activated.
    - In the `telegraph` directory, run the main program:

        ```bash
        python -m main
        ```

    - **Observe Terminal Output:** If everything is normal, you should see log information similar to the following, indicating that the plugin tool has been successfully loaded and connected to Dify:

        ```json
        {"event": "log", "data": {"level": "INFO", "message": "Installed tool: telegraph_publisher", "timestamp": 1678886400.123456}}
        {"event": "log", "data": {"level": "INFO", "message": "Plugin daemon started, waiting for requests...", "timestamp": 1678886400.123457}}
        ```

3. **View and Test in Dify:**

    - **Refresh the Dify Page:** Return to your Dify environment (in the browser), refresh the plugin management page (typically `https://your-dify-host.com/plugins`).
    - **Find the Plugin:** You should see a plugin named "Telegraph" (or the `label` you defined in the Provider YAML) in the list, possibly with a "Debugging" mark.
    - **Add Credentials:** Click on the plugin, and you'll be prompted to enter the "Telegraph Access Token" you defined earlier in `provider/telegraph.yaml`. Enter a valid token and save. If your validation logic (`_validate_credentials`) is implemented correctly, validation will be performed here. _(Please refer to your local corresponding screenshot, which shows the plugin appearing in the list and requesting authorization)_
    - **Use in Applications:** Now, you can add this tool node in Dify applications (such as Chatbot or Workflow) and try to call it! When you run the application and trigger the tool, the request will be forwarded to your local `python -m main` process for processing. You can see related log output in your local terminal for debugging.

4. **Stop the Local Service:** Press `Ctrl + C` in the terminal to stop the local plugin service.

This run -> test -> stop -> modify code -> run again cycle is the main workflow for plugin development.

## 6. Enhancing Plugin Metadata

To make the plugin more professional, discoverable, and understandable, we need to enhance some display information.

1. **Icon:**
    - Place an icon file representing your plugin in the `telegraph/_assets` directory (e.g., `icon.png`, `icon.svg`). Square, clear images are recommended.
2. **Provider Information (`provider/telegraph.yaml`):**

    - Ensure that the `label` (display name), `description` (function description), and `icon` (icon filename, such as `icon.png`) in the `identity` section are filled in and support multiple languages. This information is primarily displayed to users who _use_ the plugin in the Dify application orchestration interface.

    ```yaml
    identity:
        author: your-name
        name: telegraph # Internal name, keep unchanged
        label:
            en_US: Telegraph
            zh_Hans: Telegraph Publish Article
        description:
            en_US: A Telegraph plugin that allow you publish your content easily
            zh_Hans: A Telegraph plugin that allows you to publish your content easily
        icon: icon.png # Reference to the icon filename in the _assets directory
    ```

3. **Plugin Manifest (`manifest.yaml`):**

    - Edit the `manifest.yaml` file in the project root directory. This is the "ID card" for the entire plugin, and its information will be displayed on the **plugin management page** and **Plugin Marketplace** in Dify.
    - Be sure to update or confirm the following fields:
        - `label`: The **main display name** of the plugin (supports multiple languages).
        - `description`: An **overall introduction** to the plugin's functionality (supports multiple languages), which should clearly summarize its core value. Note that the marketplace display may have length limitations.
        - `icon`: The **main icon** of the plugin (directly enter the icon filename in the `_assets` directory, such as `icon.png`).
        - `tags`: Add category tags to the plugin, which helps users filter in the marketplace. For optional values, please refer to Dify's enumerations or documentation (such as `media`, `tools`, `data-processing`, etc.). You can refer to the [ToolLabelEnum definition](https://github.com/langgenius/dify-plugin-sdks/blob/main/python/dify_plugin/entities/tool.py).

    ```yaml
    label:
        en_US: Telegraph Publisher
        zh_Hans: Telegraph Publishing Assistant
    description:
        en_US: Easily publish content to Telegraph pages directly from your Dify applications. Supports Markdown formatting.
        zh_Hans: Easily publish content to Telegraph pages directly from your Dify applications. Supports Markdown formatting.
    icon: icon.png
    tags: ['media', 'content-creation'] # Example tags
    # ... (Keep other fields like author, name unchanged)
    ```

4. **README and Privacy Policy:**
    - `README.md`: Edit the `README.md` file in the project root directory. It will serve as the detailed introduction page for the plugin on the **Marketplace**, and should include richer information such as detailed functionality, usage examples, configuration guide, frequently asked questions, etc. You can refer to the style of the [AWS plugin marketplace page](https://marketplace.dify.ai/plugins/langgenius/aws_tools).
    - `PRIVACY.md`: If you plan to publish the plugin to the official Marketplace, you need to provide a privacy policy document `PRIVACY.md`, describing how the plugin handles data.

## 7. Packaging the Plugin

When plugin development is complete and passes local testing, you can package it into a `.difypkg` file for distribution or installation. For detailed information about plugin packaging and publishing, please refer to [Publishing Overview](/plugin-dev-en/0321-release-overview).

1. **Return to Parent Directory:** Ensure your terminal's current path is at **one level above** the `telegraph` folder.

    ```bash
    cd ..
    ```

2. **Execute the Packaging Command:**

    ```bash
    ./dify plugin package ./telegraph
    ```

    (Replace `./telegraph` with the actual path to your plugin project)

3. **Get the Package File:** After successful execution, a file named `telegraph.difypkg` (or `your_plugin_name.difypkg`) will be generated in the current directory.

This `.difypkg` file is a complete plugin package. You can:

- **Upload and install** it manually on the Dify plugin management page.
- **Share** it with others to install.
- According to Dify's specifications and processes, **publish it to the official Plugin Marketplace**, allowing all Dify users to discover and use your plugin. For specific publishing procedures, please refer to [Publish to Dify Marketplace](/plugin-dev-en/0322-release-to-dify-marketplace).

Congratulations! You have completed the entire process of developing, debugging, enhancing, and packaging your first Dify plugin. Now you can explore more complex and powerful plugin features based on this foundation.

## Next Learning Steps

- [Remote Debugging Plugins](/plugin-dev-en/0411-remote-debug-a-plugin) - Learn more advanced plugin debugging techniques
- [Persistent Storage](/plugin-dev-en/0411-persistent-storage-kv) - Learn how to use data storage in plugins
- [Slack Bot Plugin Development Example](/plugin-dev-en/0432-develop-a-slack-bot-plugin) - View a more complex plugin development case
- [Tool Plugin](/plugin-dev-en/0222-tool-plugin) - Explore advanced features of tool plugins

{/*
Contributing Section
DO NOT edit this section!
It will be automatically generated by the script.
*/}

---

[Edit this page](https://github.com/langgenius/dify-docs/edit/main/plugin-dev-en/0211-getting-started-dify-tool.mdx) | [Report an issue](https://github.com/langgenius/dify-docs/issues/new?title=Documentation%20Issue%3A%20getting-started-dify-t&body=%23%23%20Issue%20Description%0A%3C%21--%20Please%20briefly%20describe%20the%20issue%20you%20found%20--%3E%0A%0A%23%23%20Page%20Link%0Ahttps%3A%2F%2Fgithub.com%2Flanggenius%2Fdify-docs%2Fblob%2Fmain%2Fplugin-dev-en%2F0211-getting-started-dify-tool.mdx%0A%0A%23%23%20Suggested%20Changes%0A%3C%21--%20If%20you%20have%20specific%20suggestions%20for%20changes%2C%20please%20describe%20them%20here%20--%3E%0A%0A%3C%21--%20Thank%20you%20for%20helping%20improve%20our%20documentation%21%20--%3E)

