AD

alexjiaguo/dify-mcp

Developer tools
26 stars 0 forks Quality 59 Trend 32

The most complete Dify MCP server + CLI — 192 tools that let any AI agent build, test & ship Dify workflows autonomously.

Overview

Let any AI agent build, test, and ship Dify workflows autonomously — everything a human can do in the UI, now scriptable. Works with — Claude Code, Codex, Gemini CLI, Cursor, Cline, Windsurf, Roo Code, Continue, Zed, Aider, OpenCode, Antigravity, GitHub Copilot, Goose, Trae, Kilo Code, Warp, Crush, Droid, Amp, OpenHands, Cody, Augment, and Amazon Q Developer — plus any other MCP-compatible or shell-capable agent. Dify is a powerful open-source LLM app platform — but its workflow builder is a . What if you want an AI agent to programmatically create workflows, wire up nodes, test them, iterate, and publish — without a browser? is the bridge. It exposes the as a unified tool registry with : a CLI any shell-capable agent can drive, and an MCP server (stdio or Streamable HTTP) any MCP-compatible host can attach. Same 192 tools, same JSON contract, same safety guarantees. dify-mcp is agent-agnostic by design — no SDK lock-in, no proprietary protocol.

README


What is this?

Dify is a powerful open-source LLM app platform — but its workflow builder is a visual drag-and-drop editor. What if you want an AI agent to programmatically create workflows, wire up nodes, test them, iterate, and publish — without a browser?

dify-mcp is the bridge. It exposes the entire Dify console API as a unified tool registry with two surfaces: a CLI any shell-capable agent can drive, and an MCP server (stdio or Streamable HTTP) any MCP-compatible host can attach. Same 192 tools, same JSON contract, same safety guarantees.

┌──────────────────────────────────────────────────────────┐
│                    dify-mcp                              │
│                                                          │
│   ┌──────────┐    ┌────────────────────┐    ┌─────────┐ │
│   │  CLI     │───▶│   192-tool         │───▶│  Dify   │ │
│   │  difywf  │    │   registry         │    │  API    │ │
│   └──────────┘    │                    │    └─────────┘ │
│   ┌──────────┐    │  app · workflow    │         ▲      │
│   │  MCP     │───▶│  knowledge · rag   │─────────┘      │
│   │  stdio   │    │  agent · snippet   │                │
│   └──────────┘    │  workspace · ...   │                │
│                   └────────────────────┘                │
└──────────────────────────────────────────────────────────┘

Works with your favorite agents

dify-mcp is agent-agnostic by design — no SDK lock-in, no proprietary protocol. If your agent can run a shell command, it can use the CLI. If it speaks MCP, it can attach the server. Most popular agents do both:

Agent MCP CLI Quick setup
Claude Code ✅ ✅ claude mcp add dify -- difywf mcp serve
Codex ✅ ✅ [mcp_servers.dify] in ~/.codex/config.toml
Gemini CLI ✅ ✅ mcpServers.dify in ~/.gemini/settings.json
Cursor ✅ ✅ .cursor/mcp.json
Cline ✅ ✅ Same JSON shape as Cursor
Windsurf ✅ ✅ MCP server config in Windsurf settings
Roo Code ✅ ✅ MCP server config in Roo Code settings
Continue ✅ ✅ experimental.mcpServer in config.json
Zed ✅ ✅ context_servers in ~/.config/zed/settings.json
Aider - ✅ Run difywf commands directly in chat
OpenCode ✅ ✅ mcp.dify in opencode.json
Antigravity ✅ ✅ Common mcpServers JSON
GitHub Copilot ✅ ✅ servers.dify in .mcp.json
Goose ✅ ✅ extensions.dify in config.yaml
Trae ✅ ✅ Common mcpServers JSON
Kilo Code ✅ ✅ Common mcpServers JSON
Warp ✅ ✅ Common mcpServers JSON
Crush ✅ ✅ mcp add dify --command difywf --args mcp serve
Droid ✅ ✅ Common mcpServers JSON
Amp ✅ ✅ Common mcpServers JSON
OpenHands ✅ ✅ mcpServers.dify in ~/.openhands/mcp.json
Cody ✅ ✅ Common mcpServers JSON
Augment ✅ ✅ Common mcpServers JSON
Amazon Q Developer ✅ ✅ Common mcpServers JSON

Don’t see your agent? If it supports MCP or can run shell commands, it works. The connect section below has copy-paste configs for each host.

Why you’ll star this

  • Complete coverage. Not a subset. Not a wrapper around the public API alone. This talks to the internal console API — the same surface the Dify web UI uses. Create apps, author graphs node-by-node, validate, test-run, publish, manage versions, triggers, providers, plugins, RAG pipelines, snippets, agent configs, comments, annotations, audio, stats. If the UI can do it, so can your agent.

  • Agent-agnostic by design. No SDK lock-in. The CLI works with any agent that can run a shell command. The MCP server works with any MCP host. Both return structured JSON — { ok, data } or { ok: false, error: { code, message, retryable } } — so agents never scrape human-readable text. For large drafts and exports, the CLI’s --output-file keeps the full UTF-8 result off size-limited stdout transports.

  • Cookie auth, handled. Dify’s console uses cookie + CSRF double-submit, not Bearer tokens. dify-mcp captures, stores (keychain on macOS, else 0600 file), and auto-refreshes the session — including server-side refresh-token rotation. That same session now covers draft and published run/stop, file upload, dependency checks, and workspace switch. MCP hosts can call auth.import_cookies / auth.login_console without the CLI. DIFY_CONSOLE_COOKIE and --console-cookie work for non-interactive bootstrap.

  • Safe by default. Destructive operations require explicit confirm=true / --yes. Graphs are validated offline before sync (iteration/loop sub-graphs, sticky notes, and modern multi-case if-else included). Every mutation is audit-logged. --dry-run shows diffs without saving.

  • Zero build step. Runs directly on Node 23.6+ native TypeScript. No compiler, no bundler, no transpiler. Clone, install, go.

What’s new in v0.4.0

  • Workspace MCP tool providers (mcp.*). Connect external MCP servers to your Dify workspace: mcp.list, mcp.get, mcp.create, mcp.update, mcp.delete (confirm-gated), and mcp.refresh_tools.
  • App MCP Server access points (app.mcp_server_*). Expose any Dify workflow/agent app as an MCP server: app.mcp_server_get, app.mcp_server_set, and app.mcp_server_rotate (confirm-gated token regeneration).
  • Workspace Skills (skill.*). Full skill lifecycle and agent skill bindings: skill.list, skill.get, skill.versions, skill.references, skill.import, skill.publish, skill.delete (confirm-gated), skill.agent_bindings, and skill.set_agent_bindings.
  • Dify 1.17.1 compatibility & fixes. Verified compatibility against Dify 1.17.1 upstream console routes; fixed input validation ordering in snippet.import.

What’s new in v0.3.0

  • Classic knowledge bases (knowledge.*). Dataset CRUD, document create from file.upload ids (or full KnowledgeConfig), rename/delete, indexing status, hit-testing, and segment add/update/delete — confirm-gated where destructive.
  • Workspace member admin. workspace.invite_members, workspace.update_member_role, and workspace.remove_member (confirm-gated).
  • MCP progress notifications. Long SSE runs (workflow.run_draft, chat, …) emit notifications/progress when the host supplies a progressToken in tools/call _meta.
  • Local backup and migration. app.backup bulk-exports DSLs plus a manifest; app.restore dry-runs conflicts and imports to another configured Dify instance.
  • Explicit compatibility matrix. Dify 1.17.x and 1.16.x are supported; older versions are intentionally unsupported.

What’s new in v0.2.0

  • Cookie-complete authoring. Run, stop, upload, check deps, and switch workspaces with the same console session. MCP hosts authenticate without dropping to the CLI.
  • Safer HTTP MCP. Binds 127.0.0.1 by default. Binding 0.0.0.0 (Docker) requires DIFYWF_MCP_TOKEN. Host allowlist + 2MB body cap; /health stays open for probes.
  • Workflow-as-tool providers. Get, refresh, or delete the published-tool binding after you ship a version (workflow.tool_get / workflow.tool_refresh_provider / workflow.tool_delete).
  • Verified app tags. app.ensure_tag / app.remove_tag bind or unbind an exact tag name and read it back. Confirm-gated.
  • Smarter graph validation. Iteration/loop inner nodes, canvas custom-note stickies, and modern cases[] if-else branches no longer fail offline checks.
  • Large payloads. --yaml @file for DSLs that exceed OS argument limits; --output-file keeps big results off size-limited stdout.
  • Starter graphs. Ready-made templates in examples/ (echo, LLM, RAG). sync_draft no longer wipes omitted env/conversation secrets.

Live verified

Authoring loop verified against cloud.dify.ai 1.17.0 with console cookie auth:

  • ✅ Create app → sync draft (echo graph) → run draft → delete (MCP Streamable HTTP)
  • ✅ MCP transport: tools/call over stdio and Streamable HTTP
  • ✅ Example templates in examples/ validate clean (echo, LLM, RAG)
  • ✅ Unit tests · typecheck clean · MCP smoke (192 tools)

Dify compatibility

dify-mcp Dify DSL Graphon Support
0.4.x 1.17.x 0.7.0 0.7.0 Supported; cloud 1.17.0 live-verified; 1.17.1 offline-verified
0.3.x 1.17.x 0.7.0 0.7.0 Supported; cloud 1.17.0 live-verified
0.3.x 1.16.x 0.7.0 0.6.0 Best-effort; not live-verified
<=0.3.x <=1.15.x and 0.x varies varies Unsupported; no legacy adapter

Cloud and self-hosted Dify releases can expose different console contracts even within a minor series. When reporting an issue, include the response header x-version (or your deployment version), the difywf --version output, and the exact command/tool call. DSL version drift is a hard failure (DSL_VERSION_MISMATCH), not something the agent should edit around.

Not every one of the 192 tools is live-probed on every release. Coverage is densest on the authoring path (apps, workflow draft/run/publish, auth, MCP guardrails). Surfaces such as knowledge bases, RAG pipelines, snippets, agents, annotations, and audio are implemented against the console API contract and unit-tested; treat them as best-effort until you exercise them on your instance.

Known gaps vs the full Dify UI

Still deferred (not blocking for workflow authoring):

  • External knowledge / connector-specific ingest UIs beyond the classic dataset APIs
  • Fine-grained dataset permission member pickers in the UI sense (API body passthrough only)

Quickstart

Prerequisites: Node >= 23.6 (native TypeScript type stripping — no build step).

git clone https://github.com/alexjiaguo/dify-mcp.git
cd dify-mcp
npm install
npm link        # puts `difywf` on your PATH (optional)

Authenticate

The Dify console uses cookie + CSRF auth. The easiest path:

# 1. Export cookies from your browser (cookie-editor extension → Export → JSON)
# 2. Save as cookies.json, then:
difywf auth import-cookies --base-url https://cloud.dify.ai --file cookies.json

# Or self-hosted with email/password (no browser needed):
difywf auth login-console --base-url https://your-dify --email you@x --password '***'

# Non-interactive bootstrap can keep credentials out of process arguments:
DIFY_CONSOLE_EMAIL=you@x DIFY_CONSOLE_PASSWORD='***' \
  difywf auth login-console --base-url https://your-dify

# Deployments whose login endpoint expects the legacy encoded payload:
DIFY_CONSOLE_EMAIL=you@x DIFY_CONSOLE_PASSWORD='***' \
  DIFY_CONSOLE_PASSWORD_ENCODING=base64 \
  difywf auth login-console --base-url https://your-dify

difywf auth status   # confirm: shows base URL + cookie names (values masked)

# Non-interactive cookie bootstrap (Cookie header or cookie-editor JSON):
# DIFY_CONSOLE_COOKIE='console_token=...; csrf_token=...; refresh_token=...' \
#   difywf auth status --base-url https://cloud.dify.ai

Build a workflow

difywf agent guide                          # self-onboarding playbook for agents
difywf app list                             # see your apps
difywf app create --mode workflow --name "my-agent-workflow"

difywf wf node defaults  llm        # get the schema for an LLM node
difywf wf validate --graph examples/llm-workflow.json        # offline: structure, refs, cycles
difywf wf draft sync  --graph examples/llm-workflow.json --dry-run
difywf wf draft sync  --graph examples/llm-workflow.json
difywf wf test  --input query="hello"                # test-run the draft
difywf app import --yaml @workflow.yml --yes                  # file channel for large DSLs
difywf app ensure-tag  production --yes               # bind + verify exact tag name
difywf wf publish  --yes                             # ship it
difywf workflow tool refresh-provider  --yes        # rebind workflow-as-tool to the published version

Starter graphs live in examples/: minimal-workflow.json (echo), llm-workflow.json (start → LLM → answer), rag-workflow.json (knowledge retrieval). All three pass difywf wf validate with no error-level issues.

Back up and migrate

# Source instance: writes one DSL per app plus manifest.json (secrets excluded)
difywf app backup ./dify-backup

# Target instance: authenticate or set DIFY_API_BASE first, then preview
difywf app restore ./dify-backup --dry-run

# Import after reviewing name conflicts; skip is the default
difywf app restore ./dify-backup --yes

Filters are available for larger workspaces: --app-ids , --mode workflow, --name production, and --limit 50. Backups are local files with mode 0600. include_secret=true and overwrite=true both require --yes. Scheduled jobs, Git, and S3-compatible storage are intentionally not bundled; use dify-dsl-pipe when you need a dedicated backup service.

Connect your agent (MCP)

Same binary, same 192 tools. Copy-paste the config for your host:

There is no single universal MCP filename. What every host needs is the same local stdio launch command: difywf mcp serve. The examples below show the wrapper your host expects.

No difywf on PATH? Use the absolute path: node /path/to/dify-mcp/bin/difywf.js mcp serve.

Tools

192 tools across 21 namespaces. Run difywf --help for the full live list, or difywf agent guide for the agent-oriented playbook.

Namespace Tools What it does
app 22 List, create, update, verified tags, delete, export, bulk backup, import/restore, MCP server access points, copy, rename, convert, chat, complete
workflow 29 Get/sync drafts, validate (incl. iteration/loop sub-graphs), run, publish, workflow-as-tool providers, node last-run, variables, versions, HITL, features, triggers
mcp 6 List, get, create, update, delete, refresh tools for workspace MCP tool providers
skill 9 Workspace skills lifecycle: list, get, versions, references, import, publish, delete, agent skill bindings
provider 3 List providers, list models, set credentials
plugin 4 List, get, install, uninstall plugins
trigger 4 Create, enable, list, webhook triggers; run triggers
workspace 7 List, get, switch workspaces; list / invite / role-update / remove members
file 1 Upload files for use in runs (multipart {name, content_b64})
runs 4 List, get, node executions, export run traces
stats 5 Daily conversations/terminals, token costs, app interactions, online users
comment 3 List, add, resolve workflow comments
annotation 11 List, add, delete, reply, settings, export, batch import, hit histories
audio 3 Transcribe (STT), synthesize (TTS), list voices
knowledge 16 Classic knowledge-base datasets, documents, segments, indexing status, hit-testing
rag 18 Full RAG pipeline lifecycle: datasets, templates, draft, sync, run, publish, versions
snippet 22 Customized snippet lifecycle: create, import, draft, sync, run, publish, versions
agent 17 Agent guide, config skills/files, drive files/skills, sandbox read/upload
explore 2 Run and stop installed apps
archive 2 List and download workflow run archives
auth 4 Status, import cookies, console login, set tokens

Safety

Mechanism How it works
Confirm gates Destructive ops (delete, publish, restore, app.restore, set_credentials, plugin install, trigger create/enable, tag bind/unbind, workflow-tool refresh/delete, …) require confirm=true / --yes. Without it: exit code 4. app.backup also gates include_secret=true and overwrite=true. Graphs with code nodes need confirm unless DIFYWF_CODE_NODES=allow.
Offline validation sync_draft validates structure, variable refs, connectivity, and cycles before hitting the API — including iteration/loop inner nodes, custom-note stickies, and modern multi-case if-else. Errors abort with exit 5. Stale hashes are VALIDATION_FAILED and retryable. Omitting env vars keeps current draft values.
Dry-run --dry-run on sync_draft returns a structural diff without saving; app.restore --dry-run lists imports and name conflicts without writing to Dify.
Private URLs http-request nodes targeting private/loopback hosts warn (PRIVATE_URL). yaml_url imports to private hosts are rejected unless DIFYWF_ALLOW_PRIVATE_URL=1.
Audit log Every action appends to ~/.difywf/audit.jsonl (nested secrets/graphs redacted, mode 0600).
Auto-refresh Cookie sessions auto-refresh on 401 via the refresh-token cookie, with server-side rotation persisted. Console cookies cover run/stop/upload/deps/workspace; OpenAPI is fallback.
HTTP MCP lock Streamable HTTP binds 127.0.0.1 by default. Non-loopback binds require DIFYWF_MCP_TOKEN. Host allowlist + 2MB body cap.
Secret store ~/.difywf/hosts.json is 0600. On macOS, cookies/tokens prefer the OS keychain unless DIFYWF_HOME is set.

Error/exit codes: USAGE_ERROR(2), AUTH_REQUIRED(3), CONFIRM_REQUIRED(4), VALIDATION_FAILED(5), RBAC_DENIED(6), NOT_FOUND(7), DSL_VERSION_MISMATCH(8), RATE_LIMITED(9), SERVER_ERROR(10), NETWORK_ERROR(11). Check error.retryable before retrying.

Environment

See .env.example. Common knobs:

Variable Purpose
DIFY_API_BASE Dify instance URL (default https://cloud.dify.ai)
DIFY_CONSOLE_COOKIE Cookie header or cookie-editor JSON for non-interactive bootstrap
DIFY_CONSOLE_EMAIL / DIFY_CONSOLE_PASSWORD Headless auth login-console
DIFY_CONSOLE_PASSWORD_ENCODING plain (default) or base64 for legacy login payloads
DIFYWF_HOME Config + audit directory (default ~/.difywf)
DIFYWF_MCP_TRANSPORT / DIFYWF_MCP_HOST / DIFYWF_MCP_PORT / DIFYWF_MCP_TOKEN Streamable HTTP MCP
DIFYWF_CODE_NODES confirm (default), allow, or forbid
DIFYWF_ALLOW_PRIVATE_URL Set 1 to allow yaml_url imports to private hosts

Develop

npm test            # 122 unit tests
npm run typecheck   # tsc --noEmit
npm run smoke:mcp   # MCP stdio smoke (192 tools, JSON-RPC handshake)
npm run smoke:mcp:http   # MCP Streamable HTTP smoke (stateless POST /mcp)

No build step. Source runs directly via Node’s type stripping. GitHub Actions runs typecheck, unit tests, and both MCP smokes on every push to main.

Contributions welcome — see CONTRIBUTING.md.

License

Apache-2.0 — see LICENSE.

View this README on GitHub

Install

docker run -d --name dify-mcp \

Configuration

{ "mcpServers": { "dify": { "command": "difywf", "args": ["mcp", "serve"] } } }