Documentsdify
Plugin Architecture
Plugin Architecture
Type
Topic
Status
Published
Created
Jul 7, 2026
Updated
Jul 7, 2026
Created by
Dosu Bot
Updated by
Dosu Bot

Plugin Architecture#

Dify plugins are self-contained packages that extend the platform with tools, models, endpoints, agent strategies, datasources, or triggers. Each plugin ships a manifest.yaml that declares its identity, resource requirements, permissions, and pointers to provider YAML definitions. The Dify API layer validates manifests against a Pydantic model (PluginDeclaration) at install time; at runtime, the plugin daemon is the source of truth.


manifest.yaml Schema#

Every plugin root contains exactly one manifest.yaml. The canonical fields are defined by PluginDeclaration in api/core/plugin/entities/plugin.py:

FieldTypeNotes
versionsemver stringPlugin release version; validated with packaging.version.Version
authorstringPattern ^[a-zA-Z0-9_-]{1,64}$
namestringPattern ^[a-z0-9_-]{1,128}$, lowercase only
label / descriptionI18nObjectLocalized strings (e.g., en_US, zh_Hans, pt_BR)
icon / icon_darkfilenameSVG path relative to plugin root
categoryPluginCategoryAuto-detected from presence of tool, model, etc.
created_atdatetimeISO 8601
resourcePluginResourceRequirementsMemory (bytes) + permission flags
pluginsPluginsLists of provider YAML paths under tools, models, endpoints, datasources, triggers
metaMetaRunner config (language, version, entrypoint, arch) and optional minimum_dify_version
verifiedboolSet by marketplace; defaults false

Category auto-detection: The @model_validator on PluginDeclaration inspects the top-level tool, model, datasource, agent_strategy, and trigger keys and sets category accordingly; a plugin with none of these is categorized as Extension .

Installation sources: PluginInstallationSource supports Github, Marketplace, Package, and Remote .


Single-Provider-per-Plugin Convention#

Official plugins follow a strict one-provider-per-plugin layout. The plugins.tools (or plugins.models) list in manifest.yaml always contains a single entry pointing to provider/<name>.yaml:

  • Slack: plugins.tools: [provider/slack.yaml]
  • AWS Tools: plugins.tools: [provider/aws_tools.yaml]
  • OpenAI: plugins.models: [provider/openai.yaml]

The provider YAML (provider/<name>.yaml) holds the provider identity, optional credentials_for_provider, and a tools list of individual tool YAML paths. The AWS provider, for example, references 22+ tool YAML files under tools/. Each tool YAML has a paired .py implementation.


Directory Layout#

A standard plugin folder looks like:

<plugin-name>/
├── manifest.yaml # Plugin declaration (root of plugin identity)
├── main.py # Entrypoint: Plugin(DifyPluginEnv()).run()
├── provider/
│ ├── <name>.yaml # Provider identity, credentials, tool refs
│ └── <name>.py # Provider Python class
├── tools/
│ ├── <tool>.yaml # Tool schema (parameters, descriptions)
│ └── <tool>.py # Tool implementation
├── _assets/ # Icons, screenshots
├── pyproject.toml # Python deps (requires dify_plugin>=0.9.0)
└── uv.lock

Permissions and Resource Requirements#

The resource block controls both memory allocation and capability permissions :

  • resource.memory: integer bytes (AWS uses 256 MB , Slack/OpenAI use 1 MB )
  • resource.permission: nested flags for tool, model (with sub-flags llm, text_embedding, rerank, tts, speech2text, moderation), node, endpoint, storage (capped 1 KB–1 GB )

Validation & Loading#

The API does not parse manifest.yaml directly. The plugin daemon handles YAML loading; the API receives JSON which is validated via Pydantic model_validate(). The primary entry points are:


Key Source References#

ResourceLink
PluginDeclaration Pydantic modelapi/core/plugin/entities/plugin.py
Slack manifest example (tool plugin)tools/slack/manifest.yaml
AWS manifest example (tool plugin)tools/aws/manifest.yaml
OpenAI manifest example (model plugin)models/openai/manifest.yaml
AWS provider YAML (tool list)tools/aws/provider/aws_tools.yaml
Plugin Architecture | Dosu