Dify
English
English
  • Getting Started
    • Welcome to Dify
      • Features and Specifications
      • List of Model Providers
    • Dify Community
      • Deploy with Docker Compose
      • Start with Local Source Code
      • Deploy with aaPanel
      • Start Frontend Docker Container Separately
      • Environment Variables Explanation
      • FAQs
    • Dify Cloud
    • Dify Premium on AWS
    • Dify for Education
  • Guides
    • Model
      • Add New Provider
      • Predefined Model Integration
      • Custom Model Integration
      • Interfaces
      • Schema
      • Load Balancing
    • Application Orchestration
      • Create Application
      • Chatbot Application
        • Multiple Model Debugging
      • Agent
      • Application Toolkits
        • Moderation Tool
    • Workflow
      • Key Concepts
      • Variables
      • Node Description
        • Start
        • End
        • Answer
        • LLM
        • Knowledge Retrieval
        • Question Classifier
        • Conditional Branch IF/ELSE
        • Code Execution
        • Template
        • Doc Extractor
        • List Operator
        • Variable Aggregator
        • Variable Assigner
        • Iteration
        • Parameter Extraction
        • HTTP Request
        • Agent
        • Tools
        • Loop
      • Shortcut Key
      • Orchestrate Node
      • File Upload
      • Error Handling
        • Predefined Error Handling Logic
        • Error Type
      • Additional Features
      • Debug and Preview
        • Preview and Run
        • Step Run
        • Conversation/Run Logs
        • Checklist
        • Run History
      • Application Publishing
      • Structured Outputs
      • Bulletin: Image Upload Replaced by File Upload
    • Knowledge
      • Create Knowledge
        • 1. Import Text Data
          • 1.1 Import Data from Notion
          • 1.2 Import Data from Website
        • 2. Choose a Chunk Mode
        • 3. Select the Indexing Method and Retrieval Setting
      • Manage Knowledge
        • Maintain Documents
        • Maintain Knowledge via API
      • Metadata
      • Integrate Knowledge Base within Application
      • Retrieval Test / Citation and Attributions
      • Knowledge Request Rate Limit
      • Connect to an External Knowledge Base
      • External Knowledge API
    • Tools
      • Quick Tool Integration
      • Advanced Tool Integration
      • Tool Configuration
        • Google
        • Bing
        • SearchApi
        • StableDiffusion
        • Dall-e
        • Perplexity Search
        • AlphaVantage
        • Youtube
        • SearXNG
        • Serper
        • SiliconFlow (Flux AI Supported)
        • ComfyUI
    • Publishing
      • Publish as a Single-page Web App
        • Web App Settings
        • Text Generator Application
        • Conversation Application
      • Embedding In Websites
      • Developing with APIs
      • Re-develop Based on Frontend Templates
    • Annotation
      • Logs and Annotation
      • Annotation Reply
    • Monitoring
      • Data Analysis
      • Integrate External Ops Tools
        • Integrate LangSmith
        • Integrate Langfuse
        • Integrate Opik
    • Extension
      • API-Based Extension
        • External Data Tool
        • Deploy API Tools with Cloudflare Workers
        • Moderation
      • Code-Based Extension
        • External Data Tool
        • Moderation
    • Collaboration
      • Discover
      • Invite and Manage Members
    • Management
      • App Management
      • Team Members Management
      • Personal Account Management
      • Subscription Management
      • Version Control
  • Workshop
    • Basic
      • How to Build an AI Image Generation App
    • Intermediate
      • Build An Article Reader Using File Upload
      • Building a Smart Customer Service Bot Using a Knowledge Base
      • Generating analysis of Twitter account using Chatflow Agent
  • Community
    • Seek Support
    • Become a Contributor
    • Contributing to Dify Documentation
  • Plugins
    • Introduction
    • Quick Start
      • Install and Use Plugins
      • Develop Plugins
        • Initialize Development Tools
        • Tool Plugin
        • Model Plugin
          • Create Model Providers
          • Integrate the Predefined Model
          • Integrate the Customizable Model
        • Agent Strategy Plugin
        • Extension Plugin
        • Bundle
      • Debug Plugin
    • Manage Plugins
    • Schema Specification
      • Manifest
      • Endpoint
      • Tool
      • Agent
      • Model
        • Model Designing Rules
        • Model Schema
      • General Specifications
      • Persistent Storage
      • Reverse Invocation of the Dify Service
        • App
        • Model
        • Tool
        • Node
    • Best Practice
      • Develop a Slack Bot Plugin
      • Dify MCP Plugin Guide: Connect Zapier and Automate Email Delivery with Ease
    • Publish Plugins
      • Publish Plugins Automatically
      • Publish to Dify Marketplace
        • Plugin Developer Guidelines
        • Plugin Privacy Protection Guidelines
      • Publish to Your Personal GitHub Repository
      • Package the Plugin File and Publish it
      • Signing Plugins for Third-Party Signature Verification
    • FAQ
  • Development
    • Backend
      • DifySandbox
        • Contribution Guide
    • Models Integration
      • Integrate Open Source Models from Hugging Face
      • Integrate Open Source Models from Replicate
      • Integrate Local Models Deployed by Xinference
      • Integrate Local Models Deployed by OpenLLM
      • Integrate Local Models Deployed by LocalAI
      • Integrate Local Models Deployed by Ollama
      • Integrate Models on LiteLLM Proxy
      • Integrating with GPUStack for Local Model Deployment
      • Integrating AWS Bedrock Models (DeepSeek)
    • Migration
      • Migrating Community Edition to v1.0.0
  • Learn More
    • Use Cases
      • DeepSeek & Dify Integration Guide: Building AI Applications with Multi-Turn Reasoning
      • Private Deployment of Ollama + DeepSeek + Dify: Build Your Own AI Assistant
      • Build a Notion AI Assistant
      • Create a MidJourney Prompt Bot with Dify
      • Create an AI Chatbot with Business Data in Minutes
      • Integrating Dify Chatbot into Your Wix Website
      • How to connect with AWS Bedrock Knowledge Base?
      • Building the Dify Scheduler
      • Building an AI Thesis Slack Bot on Dify
    • Extended Reading
      • What is LLMOps?
      • Retrieval-Augmented Generation (RAG)
        • Hybrid Search
        • Re-ranking
        • Retrieval Modes
      • How to Use JSON Schema Output in Dify?
    • FAQ
      • Self-Host
      • LLM Configuration and Usage
      • Plugins
  • Policies
    • Open Source License
    • User Agreement
      • Terms of Service
      • Privacy Policy
      • Get Compliance Report
  • Features
    • Workflow
Powered by GitBook
On this page
  • Prerequisites
  • Create New Project
  • Select plugin type and template
  • Developing Tools Plugins
  • Debugging Plugins
  • Packing Plugin
  • Publishing Plugins
  1. Plugins
  2. Quick Start
  3. Develop Plugins

Tool Plugin

PreviousInitialize Development ToolsNextModel Plugin

Last updated 2 months ago

Tool type plugins are external tools that can be referenced by Chatflow / Workflow / Agent application types to enhance the capabilities of Dify applications. For example, adding online search capabilities, image generation capabilities, etc. to an application. Tool Type Plugins provide a complete set of tools and API implementations.

In this article, a "Tool Plugin" refers to a complete project that includes the tool provider file, functional code, and other related components. A tool provider may encompass multiple Tools (which can be understood as additional functionalities offered by a single tool), structured as follows:

- Tool provider
    - Tool A
    - Tool B

This article uses GoogleSearch as an example of how to quickly develop a tool type of plugin.

Prerequisites

  • Dify plugin scaffolding tool

  • Python, version ≥ 3.12

Create New Project

Run the CLI tool to create a new dify plugin project:

./dify-plugin-darwin-arm64 plugin init

If you have renamed the binary file to dify and copied it to the /usr/local/bin path, you can run the following command to create a new plugin project:

dify plugin init

In the following, the command-line tool dify is used. If issues occur, please replace the dify command with the appropriate path to your command-line tool.

Select plugin type and template

There are three types of plugins: tool, model and extension. All templates within SDK are provided with full code projects. The following part will use the Tool plugin template as an example.

Configuring Plugin Permissions

The plugin also needs to read permissions from the Dify platform to connect properly. The following permissions need to be granted for the example tool plugin:

  • Tools

  • Apps

  • Enable persistent storage Storage, allocate default size storage

  • Allow registration of Endpoint

Use the arrow keys to select permissions within the terminal and the "Tab" button to grant permissions.

After checking all the permission items, tap Enter to complete the creation of the plug-in. The system will automatically generate the plug-in project code.

Developing Tools Plugins

1. Create the tool vendor yaml file

The tool vendor file can be understood as the base configuration entry point for a tool type plugin, and is used to provide the necessary authorization information to the tool. This section demonstrates how to fill out that yaml file.

Go to the /provider path and rename the yaml file in it to google.yaml. The yaml file will contain information about the tool vendor, including the provider name, icon, author, and other details. This information will be displayed when the plugin is installed.

Example:

identity:
  author: Your-name
  name: google
  label:
    en_US: Google
    zh_Hans: Google
  description:
    en_US: Google
    zh_Hans: Google
  icon: icon.svg
  tags:
    - search
  • identity contains basic information about the tool provider, including author, name, label, description, icon, and more.

    • The icon needs to be an attachment resource, which needs to be placed in the _assets folder in the project root directory.

    • Tags help users quickly find plugins by category, here are all the tags currently supported.

    • class ToolLabelEnum(Enum):
        SEARCH = 'search'
        IMAGE = 'image'
        VIDEOS = 'videos'
        WEATHER = 'weather'
        FINANCE = 'finance'
        DESIGN = 'design'
        TRAVEL = 'travel'
        SOCIAL = 'social'
        NEWS = 'news'
        MEDICAL = 'medical'
        PRODUCTIVITY = 'productivity'
        EDUCATION = 'education'
        BUSINESS = 'business'
        ENTERTAINMENT = 'entertainment'
        UTILITIES = 'utilities'
        OTHER = 'other'

Make sure that the path to the file is in the /tools directory, the full path is below:

plugins:
  tools:
    - "google.yaml"

Where the google.yaml file needs to use its absolute path in the plugin project.

  • Completion of third-party service credentials

For ease of development, we have chosen to use the Google Search API provided by a third-party service, SerpApi. SerpApi requires an API Key in order to use it, so you need to add the credentials_for_provider field to the yaml file.

The full code is below:

identity:
  author: Dify
  name: google
  label:
    en_US: Google
    zh_Hans: Google
    pt_BR: Google
  description:
    en_US: Google
    zh_Hans: GoogleSearch
    pt_BR: Google
  icon: icon.svg
  tags:
    - search
credentials_for_provider: #Add credentials_for_provider field
  serpapi_api_key:
    type: secret-input
    required: true
    label:
      en_US: SerpApi API key
      zh_Hans: SerpApi API key
    placeholder:
      en_US: Please input your SerpApi API key
      zh_Hans: 请输入你的 SerpApi API key
    help:
      en_US: Get your SerpApi API key from SerpApi
      zh_Hans: 从 SerpApi 获取您的 SerpApi API key
    url: https://serpapi.com/manage-api-key
tools:
  - tools/google_search.yaml
extra:
  python:
    source: google.py
  • It is necessary to specify which tools are included in this provider. This example only includes a tools/google_search.yaml file.

  • For the provider, in addition to defining its basic information, you also need to implement some of its code logic, so you need to specify its implementation logic. In this example, the code file for the function is placed in google.py, but instead of implementing it for the time being, you write the code for google_search first.

2. Fill out the tool yaml file

There can be multiple tools under a tool vendor, and each tool needs to be described by a yaml file, which contains basic information about the tool, its parameters, its output, and so on.

Still using the GoogleSearch tool as an example, you can create a new google_search.yaml file in the /tools folder.

identity:
  name: google_search
  author: Dify
  label:
    en_US: GoogleSearch
    zh_Hans: Google Search
    pt_BR: GoogleSearch
description:
  human:
    en_US: A tool for performing a Google SERP search and extracting snippets and webpages.Input should be a search query.
    zh_Hans: A tool for performing Google SERP search and extracting snippets and webpages. Input should be a search query.
    pt_BR: A tool for performing a Google SERP search and extracting snippets and webpages.Input should be a search query.
  llm: A tool for performing a Google SERP search and extracting snippets and webpages.Input should be a search query.
parameters:
  - name: query
    type: string
    required: true
    label:
      en_US: Query string
      zh_Hans: Query string
      pt_BR: Query string
    human_description:
      en_US: used for searching
      zh_Hans: used for searching webpage content
      pt_BR: used for searching
    llm_description: key words for searching
    form: llm
extra:
  python:
    source: tools/google_search.py
  • identity contains the tool's basic information, including name, author, labels, description, etc.

  • parameters parameter list

    • name (required) parameter name, must be unique, cannot duplicate other parameter names

    • type (required) parameter type, currently supports nine types: string, number, boolean, select, secret-input, file, files, model-selector, app-selector, corresponding to string, number, boolean, dropdown menu, encrypted input field, file, file set, model selection, and application selection. For sensitive information, please use secret-input type

    • label (required) parameter label, used for frontend display

    • form (required) form type, currently supports two types: llm and form

      • In Agent applications, llm means the parameter is inferred by LLM, form means parameters that can be preset to use the tool

      • In workflow applications, both llm and form need to be filled in the frontend, but llm parameters will serve as input variables for tool nodes

    • required whether the field is required

      • In llm mode, if a parameter is required, the Agent must infer this parameter

      • In form mode, if a parameter is required, users must fill in this parameter in the frontend before starting the conversation

    • options parameter options

      • In llm mode, Dify will pass all options to LLM, which can make inferences based on these options

      • In form mode, when type is select, the frontend will display these options

    • default default value

    • min minimum value, can be set when parameter type is number

    • max maximum value, can be set when parameter type is number

    • human_description introduction displayed in frontend, supports multiple languages

    • placeholder prompt text for input fields, can be set when form type is form and parameter type is string, number, or secret-input, supports multiple languages

    • llm_description introduction passed to LLM. To help LLM better understand this parameter, please write as detailed information as possible about this parameter here so that LLM can understand it

3. Preparation of tool codes

After filling in the configuration information of the tool, you can start writing the functional code of the tool to realize the logical purpose of the tool. Create google_search.py in the /tools directory with the following contents.

from collections.abc import Generator
from typing import Any

import requests

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

SERP_API_URL = "https://serpapi.com/search"

class GoogleSearchTool(Tool):
    def _parse_response(self, response: dict) -> dict:
        result = {}
        if "knowledge_graph" in response:
            result["title"] = response["knowledge_graph"].get("title", "")
            result["description"] = response["knowledge_graph"].get("description", "")
        if "organic_results" in response:
            result["organic_results"] = [
                {
                    "title": item.get("title", ""),
                    "link": item.get("link", ""),
                    "snippet": item.get("snippet", ""),
                }
                for item in response["organic_results"]
            ]
        return result

    def _invoke(self, tool_parameters: dict[str, Any]) -> Generator[ToolInvokeMessage]:
        params = {
            "api_key": self.runtime.credentials["serpapi_api_key"],
            "q": tool_parameters["query"],
            "engine": "google",
            "google_domain": "google.com",
            "gl": "us",
            "hl": "en",
        }

        response = requests.get(url=SERP_API_URL, params=params, timeout=5)
        response.raise_for_status()
        valuable_res = self._parse_response(response.json())
        
        yield self.create_json_message(valuable_res)

4. Completion of tool vendor codes

Finally, you need to create a vendor code implementation code that will be used to implement the vendor's credential validation logic. If the credential validation fails, the ToolProviderCredentialValidationError exception will be thrown. After successful validation, the google_search tool service will be requested correctly.

Create a google.py file in the /provider directory with the following code:

from typing import Any

from dify_plugin import ToolProvider
from dify_plugin.errors.tool import ToolProviderCredentialValidationError
from tools.google_search import GoogleSearchTool

class GoogleProvider(ToolProvider):
    def _validate_credentials(self, credentials: dict[str, Any]) -> None:
        try:
            for _ in GoogleSearchTool.from_credentials(credentials).invoke(
                tool_parameters={"query": "test", "result_type": "link"},
            ):
                pass
        except Exception as e:
            raise ToolProviderCredentialValidationError(str(e))

Debugging Plugins

Dify provides remote debugging method, go to "Plugin Management" page to get the debugging key and remote server address.

Go back to the plugin project, copy the .env.example file and rename it to .env. Fill it with the remote server address and debugging key.

The .env file:

INSTALL_METHOD=remote
REMOTE_INSTALL_HOST=remote
REMOTE_INSTALL_PORT=5003
REMOTE_INSTALL_KEY=****-****-****-****-****

Run the python -m main command to launch the plugin. You can see on the plugin page that the plugin has been installed into Workspace. Other team members can also access the plugin.

Packing Plugin

After confirming that the plugin works properly, you can package and name the plugin with the following command line tool. After running it you can find the google.difypkg file in the current folder, which is the final plugin package.

# Replace ./google with your actual plugin project path.

dify plugin package ./google

Congratulations, you have completed the complete development, debugging and packaging process of a tool type plugin!

Publishing Plugins

Exploring More

Quick Start:

Plugins Specification Definition Documentaiton:

Tool structure

For detailed instructions on how to prepare scaffolding tools for plugin development, see .

If you are already familiar in plugin development, please refer to the to implement various types of plugins.

Plugins type
Plugins permissions

where the credentials_for_provider sub-level structure needs to satisfy the specification.

In this example, we simply request the serpapi and use self.create_json_message to return a string of json formatted data. For more information on the types of data returned, you can refer to the documentation.

You can now publish your plugin by uploading it to the ! Before uploading, make sure your plugin follows the . Once approved, the code will be merged into the master branch and automatically live in the .

Initializing Development Tools
Schema Definition
ProviderConfig
tool
Dify Plugins code repository
plugin release guide
Dify Marketplace
Develop Extension Type Plugin
Develop Model Type Plugin
Bundle Type Plugin: Package Multiple Plugins
Minifest
Endpoint
Reverse Invocation of the Dify Service
Tools
Models
Extend Agent Strategy