MCP server: One MCP server.

Zep Agent Memory

@dagMCP server ยท Native

Remote mcp server to let an agent interact with zep graphs.

v1.0.0
Freeno charge per call

One address for any MCP client, signed in with your Odel account.

What it does

5 read2 act

Grouped by tool name.

What it costs

Free

Odel charges nothing per call.

Tools

7 ยท grouped by tool name

Read ยท 5Look things up

Search memorysearch_memoryHybrid semantic + keyword search over the caller's memory graph. Defaults to searching both the personal space and the shared space, returning ranked facts (graph edges).4 parameters

Parameters

  • querystringrequired

    Natural-language search query.

  • spacestringoptional

    Restrict to one space, or 'all' to query both.

    One of self, shared, all

    Default "all"

  • scopestringoptional

    What to return: edges (facts), nodes (entities), or raw episodes.

    One of edges, nodes, episodes

    Default "edges"

  • limitintegeroptional

    Default 10

Input schema as JSON
{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "type": "object",
  "properties": {
    "query": {
      "type": "string",
      "minLength": 1,
      "description": "Natural-language search query."
    },
    "space": {
      "default": "all",
      "description": "Restrict to one space, or 'all' to query both.",
      "type": "string",
      "enum": [
        "self",
        "shared",
        "all"
      ]
    },
    "scope": {
      "default": "edges",
      "description": "What to return: edges (facts), nodes (entities), or raw episodes.",
      "type": "string",
      "enum": [
        "edges",
        "nodes",
        "episodes"
      ]
    },
    "limit": {
      "default": 10,
      "type": "integer",
      "minimum": 1,
      "maximum": 50
    }
  },
  "required": [
    "query"
  ]
}
List recent episodeslist_recentReturns the most recent raw episodes (untransformed memory entries) for a space. Useful for debugging what's been ingested or auditing recent activity.2 parameters

Parameters

  • spacestringoptional

    One of self, shared

    Default "self"

  • limitintegeroptional

    Default 10

Input schema as JSON
{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "type": "object",
  "properties": {
    "space": {
      "default": "self",
      "type": "string",
      "enum": [
        "self",
        "shared"
      ]
    },
    "limit": {
      "default": 10,
      "type": "integer",
      "minimum": 1,
      "maximum": 50
    }
  }
}
Who am IwhoamiReports the caller's Odel identity and the Zep graphs their memory spaces map to. Useful for debugging the secrets wiring.No parameters

Parameters

Takes no parameters.

Input schema as JSON
{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "type": "object",
  "properties": {}
}
Get entityget_entityLooks up an entity by name and returns the entity node plus all facts (edges) involving it. Use this for entity-centric questions like 'what do I know about Eyeshare?' โ€” complementary to search_memory, which is query-driven.2 parameters

Parameters

  • entitystringrequired

    Entity name to look up (matched semantically).

  • spacestringoptional

    One of self, shared, all

    Default "all"

Input schema as JSON
{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "type": "object",
  "properties": {
    "entity": {
      "type": "string",
      "minLength": 1,
      "description": "Entity name to look up (matched semantically)."
    },
    "space": {
      "default": "all",
      "type": "string",
      "enum": [
        "self",
        "shared",
        "all"
      ]
    }
  },
  "required": [
    "entity"
  ]
}
Explain episodeexplain_episodeGiven an episode UUID, returns the nodes (entities) and edges (facts) Zep extracted from it. Use for auditing extraction quality, tracing where a fact came from, or debugging why search returned (or didn't return) something. Episode UUIDs come from add_memory, list_recent, or search_memory results.2 parameters

Parameters

  • episodeUuidstring ยท uuidrequired

    UUID of the episode to inspect.

  • spacestringoptional

    The space the episode was written to.

    One of self, shared

    Default "self"

Input schema as JSON
{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "type": "object",
  "properties": {
    "episodeUuid": {
      "type": "string",
      "format": "uuid",
      "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
      "description": "UUID of the episode to inspect."
    },
    "space": {
      "default": "self",
      "description": "The space the episode was written to.",
      "type": "string",
      "enum": [
        "self",
        "shared"
      ]
    }
  },
  "required": [
    "episodeUuid"
  ]
}

Act ยท 2Change something

Add memoryadd_memoryStores a piece of text in the caller's memory graph. Defaults to the caller's personal space; pass space='shared' to write to the shared knowledge graph. Episodes are processed asynchronously by Zep โ€” entities and relationships extracted in the background.2 parameters

Parameters

  • contentstringrequired

    The text content to remember.

  • spacestringoptional

    Which space to write to.

    One of self, shared

    Default "self"

Input schema as JSON
{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "type": "object",
  "properties": {
    "content": {
      "type": "string",
      "minLength": 1,
      "description": "The text content to remember."
    },
    "space": {
      "default": "self",
      "description": "Which space to write to.",
      "type": "string",
      "enum": [
        "self",
        "shared"
      ]
    }
  },
  "required": [
    "content"
  ]
}
Add factadd_factAsserts a structured fact (subject โ€” relation โ†’ object) directly into the graph, bypassing entity extraction. Node names are matched against existing entities, and Zep invalidates existing facts the new one contradicts, so recording the new state of something is also how a superseded fact is retired.7 parameters

Parameters

  • sourceNodestringrequired

    Name of the source entity (subject).

  • relationstringrequired

    Relation in SCREAMING_SNAKE_CASE, e.g. WORKS_ON, REPORTS_TO.

  • targetNodestringrequired

    Name of the target entity (object).

  • factstringrequired

    Natural-language statement of the fact.

  • spacestringoptional

    One of self, shared

    Default "self"

  • validAtstring ยท date-timeoptional

    ISO 8601 timestamp the fact became true.

  • invalidAtstring ยท date-timeoptional

    ONLY set when a hard expiration is known at write time (e.g. contract end date, deprecation deadline).

Input schema as JSON
{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "type": "object",
  "properties": {
    "sourceNode": {
      "type": "string",
      "minLength": 1,
      "description": "Name of the source entity (subject)."
    },
    "relation": {
      "type": "string",
      "minLength": 1,
      "pattern": "^[A-Z][A-Z0-9_]*$",
      "description": "Relation in SCREAMING_SNAKE_CASE, e.g. WORKS_ON, REPORTS_TO."
    },
    "targetNode": {
      "type": "string",
      "minLength": 1,
      "description": "Name of the target entity (object)."
    },
    "fact": {
      "type": "string",
      "minLength": 1,
      "description": "Natural-language statement of the fact."
    },
    "space": {
      "default": "self",
      "type": "string",
      "enum": [
        "self",
        "shared"
      ]
    },
    "validAt": {
      "description": "ISO 8601 timestamp the fact became true.",
      "type": "string",
      "format": "date-time",
      "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
    },
    "invalidAt": {
      "description": "ONLY set when a hard expiration is known at write time (e.g. contract end date, deprecation deadline).",
      "type": "string",
      "format": "date-time",
      "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
    }
  },
  "required": [
    "sourceNode",
    "relation",
    "targetNode",
    "fact"
  ]
}
README2 min read

zep-agents-mcp

Odel module that exposes Zep Cloud as long-term memory for agents. Each caller has a personal space and, optionally, a shared space, both backed by Zep's temporal knowledge graph.

Built on @odel/module-sdk and the Zep V4 SDK, it runs on Cloudflare Workers as a stateless MCP server: a fresh server and transport per request.

Secrets

Each user configures these when installing the module. Odel injects them per request, so the module itself stores nothing.

SecretRequiredValue
ZEP_API_KEYyesZep Cloud project API key.
ZEP_USER_GRAPH_UUIDyesThe graph UUID of your Zep user. It is a different value from the user's own UUID.
ZEP_SHARED_GRAPH_UUIDnoUUID of a shared graph for memories across users. Without it, only space='self' is available.

The secrets are declared once in src/config.ts. That schema drives the odel://config manifest, the runtime check, and tool gating: an Odel caller who has not configured the required secrets does not see the tools.

Tools

ToolPurpose
add_memoryWrite text into a space; entities/relationships extracted async.
search_memoryHybrid semantic + keyword search over edges, nodes or episodes.
add_factAssert a structured (subject, relation, object) triple. Nodes are matched by name, and contradicted facts are invalidated by Zep.
get_entityLook up an entity by name and return all facts involving it โ€” entity-centric retrieval.
explain_episodeShow what nodes/edges Zep extracted from a given episode โ€” audit extraction quality.
list_recentList recent raw episodes, newest first โ€” debug/audit.
whoamiReport the Odel identity and the graphs the spaces map to.

Temporal fact lifecycle:

  • A new fact superseding an old one: add_fact the new state. Zep invalidates the facts it contradicts and keeps them as history. Zep V4 cannot set invalidAt on an existing edge, so there is no separate invalidate tool.
  • A fact with a known expiration at the moment of writing (contract end, deprecation deadline): add_fact with invalidAt set.

search_memory and get_entity default to space=all: both spaces when a shared graph is configured, otherwise the personal one.

Dev

bash
pnpm install
pnpm typecheck
pnpm dev          # wrangler dev

Without an Odel envelope (local wrangler dev, an inspector), every tool is listed. A call still needs the secrets in params._meta["app.odel/secrets"].

Architecture

src/
โ”œโ”€โ”€ index.ts          Worker entry, tool registration
โ”œโ”€โ”€ config.ts         declared secrets (configSchema)
โ”œโ”€โ”€ spaces.ts         space โ†’ Zep graph UUID routing
โ”œโ”€โ”€ zep/client.ts     per-call ZepClient from the caller's key, result helpers
โ””โ”€โ”€ tools/            one file per tool