Zenod Memory

dev.zenod由 zenod.dev 發布官方發布者v0.1.0更新於 Nov 7, 2026

Memory you own: capture on WhatsApp, filed into your Markdown vault, recalled with citations.

已驗證Streamable HTTP可網頁執行檔案與儲存知識與記憶開發者工具

概覽

AI 產生的概覽

一個 MCP 記憶代理:把你告訴它的內容存進你自己的 GitHub Markdown 儲存庫,並讓助理搜尋、讀取並帶引用地提問。

可以做什麼
  • 非同步儲存記憶、擷取媒體或附件,再輪詢取得含提交 SHA 與 GitHub 連結的收據
  • 依關鍵字搜尋儲存庫,並依路徑讀取單一筆記
  • 透過唯讀研究迴圈回答模糊的跨筆記問題,回傳附引用來源的綜合答案
  • 查詢排隊中的儲存與擷取任務的狀態與結果
適用情境
適合希望助理保留持久、可引用、且以純 Markdown 形式存放在自己 git 儲存庫中的個人記憶,而不是放在廠商資料庫裡的情境。也適合已在 GitHub 上記筆記、希望回想時附帶憑據的人。
執行需求
遠端 MCP 端點(streamable HTTP),或自架的 Docker 實例。自架需要一個你擁有的 GitHub 儲存庫及可推送的權杖、一個 Anthropic 或 OpenAI 的 LLM 金鑰,以及 MCP 端點的 bearer 權杖(透過 ZENOD_API_TOKEN 固定,或首次啟動時產生)。端點一律要求 Authorization bearer 權杖;清單宣告使用 OAuth。
安裝前請注意
此服務持有可推送你儲存庫的 GitHub 權杖和 LLM API 金鑰,bearer 權杖應視同密碼。寫入是對你儲存庫的真實提交,擷取媒體會把內容送給擷取服務商。自架需要 Docker 與環境變數;README 說明獨立單元資料夾仍是藍圖,實際執行行為來自映像檔。

安裝

在 SourceWeft 中

  1. 開啟 儀表板中的 Zenod Memory,將其新增到工作區。
  2. 連接 所需的 憑證。它們會被私密儲存,絕不會在公開頁面上展示。
  3. 為需要使用其工具的對話啟用該服務。

Web executable,透過 Streamable HTTP。 遠端服務在工作區中設定後即可從網頁執行環境執行。

交給代理程式安裝

把這段提示詞貼上到 Claude Code、Codex、Cursor 等代理程式,或 SourceWeft 對話中。代理程式會讀取該伺服器的安裝指南,先向你展示發布者、端點和登入方式,經你同意後再把它新增到你的客戶端。金鑰不會寫進任何命令。

閱讀 https://sourceweft.com/mcp/dev.zenod%2Fmemory/install.md,並按其中說明把這個 MCP 伺服器接入我的客戶端。修改任何設定之前,先告訴我它的發布者、端點和登入方式,等我確認。不要把 API 金鑰寫進命令或我會提交的檔案;問我金鑰應從哪裡取得。

檢視代理程式所依據的安裝指南

其他 MCP 客戶端

把它新增到你客戶端的 mcpServers 設定中。 客戶端會在首次連接時完成 OAuth 登入。

{
  "mcpServers": {
    "zenod-memory": {
      "type": "http",
      "url": "https://cloud.zenod.dev/mcp"
    }
  }
}

README

Zenod — the memory unit

Zenod is a memory agent you talk to over plain MCP (streamable HTTP). You give it a GitHub repo to use as your memory vault; it stores what you tell it as immutable evidence + filed meaning with citations, and lets you search and read it back. Every write lands as a real git commit — Zenod hands you the commit SHA and GitHub URL as the receipt.

One box, one endpoint, one repo. Zenod is the only thing that holds your repo token. You never write the repo from anywhere else — attempts from another path fail loudly.


Quickstart — point a plain MCP client at a fresh Zenod

You need: Docker, a GitHub repo you own (empty is fine) + a token that can push to it, and an LLM key (Anthropic or OpenAI). No suite, no console — just this unit.

1. Run a fresh instance

From this folder (units/zenod/). Until the repo split fires, the image is the repo root image with AGENT=zenod:

bash
# from the repo rootdocker build -t zenod .
docker run --rm -p 8080:8080 \  -v "$PWD/zenod-data:/data" \  -e AGENT=zenod \  -e ZENOD_DATA_DIR=/data \  -e VAULT_REPO="your-org/your-memory-repo" \  -e GITHUB_TOKEN="ghp_xxx_a_token_that_can_push_to_that_repo" \  -e ANTHROPIC_API_KEY="sk-ant-..." \  -e ZENOD_API_TOKEN="pick-any-long-secret-string" \  zenod

That is Option B: configure by hand — the three env vars above are all Zenod needs. (In the full suite the keyring/Console mints the MCP token and pushes VAULT_REPO + GITHUB_TOKEN + LLM key to /api/provision instead; a stranger self-hosting doesn't need that path.)

Zenod is now serving MCP at http://localhost:8080/mcp. Check it is up:

bash
curl -s http://localhost:8080/api/health

2. Point any MCP client at it

The endpoint is vanilla MCP over streamable HTTP. Any MCP client works — e.g. Claude Desktop / claude with a custom connector, or the reference @modelcontextprotocol/inspector:

bash
npx @modelcontextprotocol/inspector# transport: Streamable HTTP# URL:       http://localhost:8080/mcp# header:    Authorization: Bearer <token>

Your token. /mcp always requires a bearer token — there is no tokenless mode. You control it two ways:

  • Pin it (recommended): set ZENOD_API_TOKEN in the run command above to any long secret string. That IS your bearer token — use it directly.
  • Don't pin it: if ZENOD_API_TOKEN is unset, Zenod generates a token on first boot and prints it once to the container logs (docker logs <container> | grep 'MCP bearer'). Copy it from there.

Send it as Authorization: Bearer <token> on every MCP call. (Treat it like a password. Note: GET /api/token is itself auth-gated — you need the token to call it — so use one of the two paths above to learn it in the first place.)

Run tools/list. You should see store_memory, ingest_memory, search_memory, get_memory, ask_brain, and get_task_result (full surface in SEAM-SURFACE.md).

Codex Desktop bearer-token setup

Codex Desktop's MCP server settings have two separate concepts:

  • URL: paste the Zenod MCP URL, for example https://<host>/mcp.
  • Bearer token env var: enter the environment variable name, for example ZENOD_MCP_TOKEN.

Do not paste the token itself into the Bearer token env var field. Codex reads that field as the name of an environment variable, then reads the actual bearer token from the Codex process environment.

For Codex CLI, this works when codex is launched from the same shell:

bash
export ZENOD_MCP_TOKEN="<token>"codex mcp add zenod --url https://<host>/mcp --bearer-token-env-var ZENOD_MCP_TOKEN

A normal shell export is temporary: it lasts only for that shell session and child processes. It does not survive a machine restart, and it does not affect an already running macOS GUI app launched from Finder, Dock, or Spotlight. For Codex Desktop, set the variable in the environment before starting Codex Desktop, or use a literal Authorization: Bearer <token> header in the MCP server settings.

3. Store / search / get

Store (mutating, async — returns a jobId, then poll):

jsonc
// tools/call store_memory{ "content": "My home insurance renews on March 3rd every year." }// -> returns { jobId: "..." }  (status: queued)
// tools/call get_task_result{ "jobId": "..." }// -> when done:// { status: "done", result: {//     evidenceRef: "Log/2026-07-05.md#^e-7f3a2c",//     pagesTouched: ["Areas/Insurance.md"],//     commitSha: "a1b2c3d...",              // <- your receipt: a real git commit//     githubUrls: ["https://github.com/your-org/your-memory-repo/blob/main/Areas/Insurance.md"]// } }

Open the githubUrls link — the memory is a committed file in your repo.

Ingest media/artifacts (mutating, async — returns a jobId, then poll):

jsonc
// tools/call ingest_memory{  "mediaType": "screenshot",  "artifactUrl": "https://example.test/screen.png",  "filename": "screen.png",  "sourceHint": "Claude upload",  "contentHint": "remember the renewal date visible in this screenshot",  "hints": ["insurance"]}// -> returns { jobId: "...", kind: "media_ingest", status: "queued" }
// tools/call get_task_result{ "jobId": "..." }// -> when done, result includes:// {//   status: "done",//   rawArtifact: { handle, archiveUrl, sha256 },//   extraction: { handle, ocrHandle, transcriptHandle, archiveUrl, provider },//   digest: { evidenceRef, pagesTouched, commitSha, githubUrls }// }// Opaque handles that Zenod cannot resolve still return a loud// media_ingest_processor_unavailable receipt instead of fake success.

Search (read, fast, no LLM):

jsonc
// tools/call search_memory{ "query": "insurance renewal" }// -> hits: [{ path, snippet, score, githubUrl }], or the explicit text//    "No memories match 'insurance renewal'." when there are none.

Get (read one note by path from a search hit):

jsonc
// tools/call get_memory{ "path": "Areas/Insurance.md" }// -> { path, frontmatter, body, githubUrl }

For fuzzy or cross-note questions ("what do I know about X?"), call ask_brain instead of search_memory — it runs a read-only research loop and returns a synthesized answer with cited sources.


What you can rely on (the contract)

  • The endpoint is standard MCP — nothing custom on the wire. tools/list + tools/call is all a caller needs to know. See ../../docs/SEAM-SPEC.md.
  • Every write returns a receipt. store_memory gives you a commitSha + GitHub URL (via get_task_result). ingest_memory gives an async media receipt with raw artifact, extraction/transcript archive, digest, commit, and archive fields. A read returns data or an explicit "none". No silent acks; failures error loudly with { code, message }.
  • Only Zenod holds your repo token. It is supplied to this one box (env or /api/provision) and read in exactly one place internally. Nothing else in the suite can write your repo. Any write attempt down another path fails loudly.
  • Your memory is just a git repo. Clone it, read it, leave — no lock-in.

Files in this unit

FileWhat it is
README.mdthis quickstart (an acceptance item)
SEAM-SURFACE.mdthe MCP tool surface + receipt shapes
EXTRACTION-MAP.mdfile-level extraction map (blueprint, RD-4 staged)
Dockerfileroot-image-reuse note (staged; build from repo-root Dockerfile)
docker-compose.zenod.ymldeploy stub

Status honesty: this folder is the seam of record for Zenod-as-a-unit. The physical extraction from the fused Console is STAGED behind the RD-4 split trigger and has not fired — see EXTRACTION-MAP.md. The running behavior above is real today (image with AGENT=zenod); the standalone folder is blueprint.

來源:units/zenod/README.md,提交 0d25720

工具

0
該伺服器需要登入,因此 SourceWeft 無法在沒有帳號的情況下讀取其工具,也未收錄。已連接帳號所能看到的內容可能因帳號及其權限而異。

版本歷史

1
  1. v0.1.0最新Nov 7, 2026

評分

已滿足適用檢查項的 85%

該評分衡量此收錄條目的完整程度,依據註冊中心條目、端點與公開來源計算得出。它不是對伺服器本身的評價,也不表示伺服器安全或目前可用:可連通性是帶日期的檢查結果,評分也不包含安裝量或使用者評價。

  • 近 30 天內可連通必需25 分
  • 已宣告認證方式必需10 分
  • 已列出工具15 分

    請讓伺服器在無憑證時回應 tools/list,或發布可在沙箱中無憑證啟動的軟體包。

  • 描述必需15 分
  • 圖示10 分
  • 文件15 分
  • 授權條款10 分