Dify Integration
Dakera Memory is a tool plugin on the Dify Marketplace. It gives Dify Agent, Chatflow, and Workflow apps six memory tools — store, recall, search, get, update, forget — backed by a Dakera server you host yourself. Agents remember what matters across sessions, and stale context decays instead of piling up.
Plugin at a glance
| Field | Value |
|---|---|
| Identifier | dakera/dakera — author dakera, name dakera |
| Version | 0.0.1 · plugin type: tool |
| App types | Agent · Chatflow · Workflow |
| Runtime | Python 3.12 · architectures amd64 + arm64 |
| Permissions | tool only (no model / LLM permission requested) |
| Tools | store · recall · search · get · update · forget |
| Tags | productivity · utilities |
| Compatibility | Dify Community Edition and Dify Cloud |
In a Chatflow or Workflow, a Recall node pulls ranked context before your LLM node and a Store node saves what matters after it. In an Agent app, the model calls the Recall and Store tools itself.
When to use it
Dify is one of the fastest ways to build an LLM app, but its apps are stateless between runs — an Agent forgets everything the moment a conversation ends, and a Workflow starts every execution from a blank slate. Reach for Dakera Memory when you want your Dify app to:
- Remember users across sessions — preferences, decisions, and facts persist beyond a single chat.
- Keep context fresh, not bloated — memories are importance-scored and decay over time, so old low-value facts stop competing with what matters now.
- Stay on your own infrastructure — the plugin is a thin HTTP client for a Dakera server you run; nothing goes to Dakera AI or any third party.
If you only need short-term, in-conversation memory, Dify's built-in conversation variables are enough. Dakera is for durable memory that outlives the conversation and is shared, ranked, and prunable.
How a Dify tool plugin fits in
A Dify tool plugin registers a provider (here, credentials for your Dakera server) and a set of tools your apps can call. Once installed and authorized, each of the six Dakera tools becomes available in all three Dify app types — the difference is only who decides to call them:
| App type | How memory is invoked |
|---|---|
| Agent | You expose Store and Recall (and any others) as agent tools; the LLM decides when to remember and when to look things up, based on each tool's description. |
| Chatflow | The tools become nodes you place on the canvas — typically a Recall node before the LLM node and a Store node after it, wired explicitly. |
| Workflow | Same node model as Chatflow, for non-chat automations — e.g. a batch job that reads prior state with Search and writes results with Store. |
Because it is a tool plugin (not a model plugin), Dakera Memory requests only the tool permission and never touches your LLM configuration.
Quick Start
Run Dakera
The plugin is a thin client for a Dakera server you run yourself — no data goes to Dakera AI or any third party. The default API port is 3000:
git clone https://github.com/dakera-ai/dakera-deploy
cd dakera-deploy && docker compose up -d
# server + object store, API on :3000
Install the plugin
Install Dakera Memory from the Dify Marketplace, then add it to your app's tools. It targets Dify Agent, Chatflow, and Workflow apps and runs on both Community Edition and Dify Cloud.
Authorize
Provide two credentials. On save, the provider probes GET /health/live with a 5-second timeout, so a bad URL or wrong key fails fast at setup rather than mid-flow.
| Field | Required | Value |
|---|---|---|
| Dakera Server URL | Yes | Base URL of your self-hosted server, e.g. http://localhost:3000 (text input). Trailing slashes are trimmed. |
| Dakera API Key | No | dk-… — stored as a Dify secret. Leave empty for unauthenticated local dev (server started without DAKERA_API_KEY). |
401 from the health check means the API key was rejected; any status other than 200/204 means the server URL is wrong or the server is unhealthy. The credential save fails with a specific message in each case.The six tools
Every tool is namespaced by agent_id (default dify-agent) so different apps or users never see each other's memories. Recall and Search return each memory's ID, which chains directly into Get, Update, and Forget. Each tool maps to one REST call on your Dakera server:
| Tool | Purpose | REST call |
|---|---|---|
| Store | Persist an importance-weighted fact | POST /v1/memory/store |
| Recall | Top-k semantic retrieval, ranked | POST /v1/memory/recall |
| Search | Filtered browse by tags / importance | POST /v1/memory/search |
| Get | Fetch one memory by ID | GET /v1/memory/get/{id} |
| Update | Edit content / importance / tags | PUT /v1/memory/update/{id} |
| Forget | Delete, scoped by a selector | POST /v1/memory/forget |
Bearer token and is never echoed into tool output. Tool calls use a 15-second timeout; the credential health check uses 5 seconds.Tool reference
Every parameter below is taken from the plugin manifest. agent_id appears on all six tools (optional, default dify-agent); it is listed once per tool for completeness.
Store POST /v1/memory/store
Persist a memory for future recall. Write it as a concise, self-contained fact — good: "Alice prefers Rust over Python for backend services"; bad: "user has preferences". Returns the stored memory ID. An empty content makes no HTTP call.
| Parameter | Req | Type | Default | Description |
|---|---|---|---|---|
| content | req | string | — | The memory to persist. Concise, factual, self-contained. |
| agent_id | opt | string | dify-agent | Namespace for this memory. Must match the agent_id used by Recall. |
| importance | opt | number | 0.5 | 0.0–1.0 (clamped). Higher values decay more slowly — use 0.8–1.0 for durable facts. |
| session_id | opt | string | — | Tag the memory with a conversation ID to enable session-scoped recall. |
| tags | opt | string | — | Comma-separated tags, e.g. preference,ui,dark-mode. |
Recall POST /v1/memory/recall
Retrieve semantically relevant memories for a natural-language query, returned most-relevant-first with similarity scores. This is the in-conversation read. An empty query makes no HTTP call; top_k is clamped to 20.
| Parameter | Req | Type | Default | Description |
|---|---|---|---|---|
| query | req | string | — | Natural-language description of what you want to recall. |
| agent_id | opt | string | dify-agent | Namespace — use the same value as Store to retrieve the right memories. |
| top_k | opt | number | 5 | Number of memories to return, 1–20. |
| session_id | opt | string | — | Restrict recall to one session. Omit to search across all sessions for this agent. |
Search POST /v1/memory/search
Filtered browse over stored memories: combine an optional text query with tag, importance, and count filters. Use it to list or audit what an agent remembers rather than for precision recall. top_k is clamped to 50.
| Parameter | Req | Type | Default | Description |
|---|---|---|---|---|
| agent_id | opt | string | dify-agent | Namespace to search within. |
| query | opt | string | — | Optional text query. Omit to browse/filter without semantic matching. |
| tags | opt | string | — | Comma-separated tag filter — results must match all tags. |
| min_importance | opt | number | — | Lower bound on importance, 0.0–1.0. |
| top_k | opt | number | 10 | Number of memories to return, 1–50. |
Get GET /v1/memory/get/{id}
Fetch a single memory by its ID (as returned by Store, Recall, or Search), including content, importance, tags, and metadata. The agent_id is passed as a query parameter.
| Parameter | Req | Type | Default | Description |
|---|---|---|---|---|
| memory_id | req | string | — | The memory ID to fetch, e.g. mem_abc123. |
| agent_id | opt | string | dify-agent | Namespace the memory belongs to. |
Update PUT /v1/memory/update/{id}
Update an existing memory by ID. Only the fields you provide change — new content is re-embedded server-side, and tags replace (not merge with) the current tags.
| Parameter | Req | Type | Default | Description |
|---|---|---|---|---|
| memory_id | req | string | — | The memory ID to update. |
| agent_id | opt | string | dify-agent | Namespace the memory belongs to. |
| content | opt | string | — | Replacement content; the memory is re-embedded if provided. |
| importance | opt | number | — | New importance, 0.0–1.0. |
| tags | opt | string | — | Comma-separated tags that replace the memory's current tags. |
Forget POST /v1/memory/forget
Delete memories permanently. Provide memory_ids for targeted deletion, or delete everything matching a session_id, tags, or a below_importance threshold. At least one selector is required — with none, the tool refuses and makes no call. Returns the number of memories deleted.
| Parameter | Req | Type | Default | Description |
|---|---|---|---|---|
| agent_id | opt | string | dify-agent | Namespace to delete from. |
| memory_ids | opt* | string | — | Comma-separated IDs to delete, e.g. mem_a,mem_b. |
| session_id | opt* | string | — | Delete all memories tagged with this session. |
| tags | opt* | string | — | Delete memories matching all of these tags. |
| below_importance | opt* | number | — | Delete memories with importance strictly below this value (0.0–1.0). Prunes low-value memories. |
* Each selector is individually optional, but you must supply at least one of the four.
Recall vs. Search — when to use which
The two read tools look similar but answer different questions. Recall is the in-conversation call: a semantic match that returns the best hits ranked most-relevant-first, over a store where Dakera weights memories by importance and lets old ones decay — use it when the agent needs the most useful context right now. Search is the deterministic browse: filter by tags and min_importance to pull a specific slice, with a larger top_k ceiling (50 vs. 20) — use it when you want everything matching a rule, or to list and audit what an agent remembers. Both return memory IDs you feed into Get, Update, and Forget.
A worked loop
Wire memory into any Dify app in two moves:
- Early in the flow, call Recall with a query like
"user's preferred programming language and coding conventions"(sameagent_id) to pull prior context into the prompt. - When the agent learns something durable, call Store — e.g.
"Alice prefers Rust over Python for backend services"withimportance = 0.9.
Next session, recalling with the same agent_id surfaces that fact — ranked ahead of older, lower-importance memories. Over time, use Forget with below_importance = 0.3 to prune the noise, and Update when a fact changes (a moved office, a switched framework) so the memory is re-embedded instead of duplicated.
Wire it into a Chatflow
In a Dify Chatflow or Workflow app the memory tools become nodes you chain around your LLM. A minimal remember-then-answer loop uses two of the six tools:
Recall before the LLM
Add a Dakera · Recall tool node early in the flow. Feed the user's message in as the query and keep the same agent_id across runs so context carries over.
| Input | Value |
|---|---|
| query | the user's message (e.g. the sys.query variable) |
| agent_id | support-bot — stable per app |
| top_k | 5 |
Inject the memories into the prompt
Reference the Recall node's output in your LLM node's context/system prompt, so the model answers with prior knowledge already in hand.
Store what's durable after the LLM
Add a Dakera · Store tool node after the LLM to persist any new, durable fact — set importance higher (0.8–0.9) for preferences and commitments so they outlast decay.
The same pattern works in an Agent app: expose Store and Recall as tools and let the agent decide when to remember and when to look things up. Because each tool ships an LLM-facing description (e.g. "Store a memory for future recall … write it as a concise, self-contained fact"), the agent gets guidance on how to use them without extra prompting.
How it works under the hood
- The plugin is a thin HTTP client — every tool call is a JSON request to the Dakera server URL you configured, and nowhere else. There is no code execution, no filesystem access, and no arbitrary URL fetching; the destination is fixed per credential set.
- Store sends your text to the server, which embeds it server-side (no embedding model runs inside Dify) and persists it with an importance weight under the tool's
agent_idnamespace. - Recall runs semantic retrieval on the server and returns a ranked list with similarity scores. Because Dakera importance-scores memories and decays them over time, frequently-useful facts stay prominent while stale ones fade — the context you inject stays fresh instead of growing unbounded.
- The
dk-API key is stored as a Dify secret and attached only as anAuthorization: Bearerheader. Requests use bounded timeouts (5s for the health check, 15s for tool calls), and comma-separatedtags/memory_idsare trimmed before being sent.
Concretely, a Store call with an importance of 0.9 and two tags sends a single JSON request like this to your server, and gets back the stored memory's ID:
POST /v1/memory/store # Authorization: Bearer dk-...
{
"content": "Alice prefers Rust over Python for backend services",
"agent_id": "support-bot",
"importance": 0.9,
"tags": ["preference", "language"]
}
# → { "memory": { "id": "mem_abc123", ... } }
Privacy and security
The plugin's threat surface is deliberately small, and it ships a PRIVACY.md referenced from its manifest:
- One fixed destination. Every request goes to the base URL in your credentials — the plugin never fetches arbitrary per-invocation URLs, executes code or SQL, touches the filesystem, or drives a browser.
- Secrets stay secret. The
dk-API key is stored as a Dify secret, attached only as aBearertoken, and never written back into tool output. - Bounded requests. The credential health check times out at 5 seconds and every tool call at 15 seconds, so a stalled server can't hang your flow.
- Your data, your server. All memory content lives on the Dakera server you operate. Dakera handles no third-party accounts and no health, financial, or biometric data on your behalf.
Troubleshooting
| Symptom | Fix |
|---|---|
| Authorization fails on save | The provider validates against GET /health/live — confirm the server URL is reachable from Dify and includes scheme + port (e.g. http://host:3000). A 401 means the API key was rejected. |
| "Cannot reach Dakera server" | Network path from Dify to your server is blocked. On Dify Cloud, the server must be publicly reachable (or tunneled); localhost only works when Dify runs on the same host. |
| Recall returns nothing | Recall is scoped by agent_id — make sure Store and Recall use the same id, and that something was stored under it first. If you set a session_id on Recall, drop it to search across all sessions. |
| Important facts get missed | Raise importance on Store (0.8–0.9) for durable facts, and increase top_k on Recall (up to 20) if the agent needs more context per turn. |
| Need an exact slice, not a ranking | Use Search with tags + min_importance instead of Recall — it browses deterministically and returns up to 50 results. |
| Forget did nothing | Forget refuses to run without a selector. Pass at least one of memory_ids, session_id, tags, or below_importance. |
Related integrations
Links
- Dify Marketplace — Dakera Memory
- Source PR — langgenius/dify-plugins #2642
- Plugin source repository — dakera-py
- Dakera deploy — Docker Compose setup
- All integrations
Frequently Asked Questions
How do I add memory to a Dify agent?
Run a self-hosted Dakera server, install the Dakera Memory plugin from the Dify Marketplace, authorize it with your server URL (and optional API key), then add its Store and Recall tools to your Agent, Chatflow, or Workflow app.
Does the Dify plugin send my data to Dakera?
No. The plugin is a thin client for a Dakera server you host yourself. Memory content and queries are sent only to your configured server URL — not to Dakera AI or any third party. The API key is stored as a Dify secret and sent only as a bearer token.
What are the six tools?
Store persists an importance-weighted fact, Recall does ranked semantic retrieval, Search browses by tags and importance, Get fetches one memory by ID, Update edits content/importance/tags, and Forget deletes by a required selector — all namespaced by agent_id.
Which Dify app types does it support?
All three: Agent, Chatflow, and Workflow. In an Agent app the LLM decides when to call the tools; in Chatflow and Workflow you place them as nodes on the canvas. It runs on both Dify Community Edition and Dify Cloud.
Do I need an API key?
No — the API key is optional. Leave it empty for unauthenticated local development (a server started without DAKERA_API_KEY). For any shared or production server, set a dk- key so requests are authenticated.
Can Forget wipe all my memories by accident?
No. Forget requires at least one selector — memory_ids, session_id, tags, or below_importance. Called with none, it refuses and makes no request, so an unscoped mass-delete is impossible.
Ready to ship?
Deploy Dakera in minutes — self-hosted and free. Cloud managed hosting coming soon.
Give your AI agents persistent memory
Self-host free today — or join the Dakera Cloud waitlist for managed hosting, SLA & founder pricing.