emem, the verifiable memory protocol for the physical world

io.github.Vortx-AI由 GitHub 账号 Vortx-AI 发布v2.4.5更新于 Nov 7, 2026

Shared, verifiable memory for machines and AI. Encode where data lives; decode with any AI.

发布方自己的服务:Memory.fit

已验证Streamable HTTP可网页运行位置与生活知识与记忆数据与分析

概览

AI 生成的概览

面向 AI 代理的共享签名记忆:解析地点与对象、读取可验证事实、生成引用令牌并校验回执。

可以做什么
  • 为现实世界对象和地点建立并解析共享身份与规范单元地址
  • 读取某地点的签名事实、检索语料、解引用结果,并就某地点提出自然语言问题
  • 生成、解析和打包引用令牌,并在服务器上校验 ed25519 回执
  • 发现来源之间的矛盾、将数值与所引事实比对,并对草稿执行引用策略检查
  • 按嵌入向量查找最近单元,并记录把标签或外部 ID 关联到对象的署名声明
适用场景
当多个代理或模型需要指称同一地点、对象或测量值,并互相传递能经受摘要压缩、且无需信任发送方即可核验的引用时使用。它面向地理空间与对地观测问题,而非通用文档检索。
运行要求
读取无需账号或密钥:连接托管的 MCP 端点,或用 Docker 在本地运行容器镜像。自托管需要为 EMEM_DATA 挂载持久卷,其中保存节点签名密钥;EMEM_BIND、PORT、EMEM_PUBLIC_URL 和 EMEM_TLS_DOMAINS 为可选设置。签名写入需要密钥。
安装前请注意
其他代理写入的笔记是陌生人的散文,会被标记为数据而非指令;签名只说明是谁写的,不说明内容为真。写入共享实体空间会改变其他代理的解析结果,且按影响范围分级,读取免费。托管节点上的 guard 检查仅为建议性,不会拦截任何内容。自托管时若未挂载 EMEM_DATA 卷,可能丢失签名密钥。

安装

在 SourceWeft 中

  1. 打开 控制台中的 emem, the verifiable memory protocol for the physical world,将其添加到工作区。
  2. 为需要使用其工具的对话启用该服务。

Web executable,通过 Streamable HTTP。 远程服务在工作区中配置后即可从网页运行时运行。

交给智能体安装

把这段提示词粘贴到 Claude Code、Codex、Cursor 等智能体,或 SourceWeft 对话中。智能体会读取该服务器的安装指南,先向你展示发布者、端点和登录方式,经你同意后再把它添加到你的客户端。密钥不会写进任何命令。

阅读 https://sourceweft.com/mcp/io.github.Vortx-AI%2Femem/install.md,并按其中说明把这个 MCP 服务器接入我的客户端。修改任何配置之前,先告诉我它的发布者、端点和登录方式,等我确认。不要把 API 密钥写进命令或我会提交的文件;问我密钥应从哪里获取。

查看智能体所依据的安装指南

其他 MCP 客户端

把它添加到你客户端的 mcpServers 配置中。

{
  "mcpServers": {
    "emem-the-verifiable-memory-protocol-for": {
      "type": "http",
      "url": "https://emem.dev/mcp"
    }
  }
}

README

[emem logo]

The epistemic settlement layer for AI.

When agents, people and machines disagree about the world, emem settles what was observed, by whom, when and how. Every record is signed, has a content id, and anyone can check it offline.

Try it, no key · Start here · Quickstart · A worked example · Verify a token · Agent guide · Docs

[ci] [PyPI] [npm] [License: Apache-2.0] [Whitepaper DOI]

[ChatGPT] [Claude plugin] [GitHub MCP Registry] [Install in VS Code] [Dify]

[Three panels. Your data: files, machines and archives, with source files kept local. Each sends a signed record into shared memory, where records link by identity, history and derivations. Any AI, whether Claude, ChatGPT or your own agent, resolves the same record and verifies it. Caption: one reference, the same record, checked independently.]

What "settlement" means here

In finance, a settlement layer is where a trade becomes final. Both sides then agree on what moved, from whom and when, and nobody can change the record later.

AI needs the same for knowledge. One agent says a field's greenness was 0.89 on 12 March. A second agent has 0.85, a summary says "about 0.9", and a bank asks where the number came from. Without a settlement layer, each copy drifts and nobody can say which value is the original.

emem settles such claims. It does not settle what is true. It settles what was claimed, and the evidence behind it:

Question in a disputeHow emem settles it
Which exact value?A content id: the BLAKE3 hash of the record's canonical bytes. Change one byte and the id changes.
Who said it?An Ed25519 signature, by the responder for a measured fact, or by the agent's own key for a note.
When was it known?An append-only RFC 6962 log, with signed tree heads and independent witnesses.
Measured from what?Each fact names its source bytes, its method and its registry version.
Derived how?A derivation cites its input facts. For pure operations, emem computes the value again before it records it.
Nothing there?A signed absence that says where emem looked and why nothing qualified.
Corrected later?The new record supersedes the old one. The old bytes stay readable.
Two sources disagree?Both records stay, with a signed disagrees_with edge. emem never averages them away.

After settlement, two parties that do not trust each other can point at one token. Both get the same bytes, the same signature and the same history. Neither has to trust the other, and neither has to trust emem.

What settlement does not do

  • It does not make a value true. A signature says who signed. It does not say that the sensor or the model was right.
  • It is not consensus. One responder signs each fact. Witnesses co-sign the log head, so a split history is detectable, but they do not vote on values.
  • It does not move your data. A source can keep its files and publish only a commitment to them (see below).

Settle without moving the file

Today, to trust a piece of data, you usually have to hold it. A lab emails the spreadsheet, a satellite downlinks the whole capture, and every copy is one more place where the data can leak or change.

emem splits the job in two:

  • The source encodes, and its data stays private. A file server, a lab, a camera or a payload computer hashes what it holds into units. It signs a small record under its own key. The bytes do not leave. A commitment to them leaves: a content id, a Merkle root, a signature.
  • emem is the decoding half. Any model, in Claude, in ChatGPT or in your own code, resolves a short token back to that exact record. It checks who signed it, and it proves that one unit belongs to the whole. It does not have to trust the sender or emem.

A token lets a reader resolve the published record and check content against it. A tree token over a private file shows only the units that you choose to publish.

What crosses, and what stays

SourceWhere it is encodedWhat crossesWhat staysStatus
Documents, datasets, model weights, codethe tokeniser on emem.dev (in your browser: code by definition, safetensors by tensor, zip and pptx by entry, PDF by page) or tree_proof.py on your machineone emem:tree: token: each unit's BLAKE3 folded into a Merkle root, in an index you signevery unit you do not choose to publishshipped
Your own algorithmwherever you run itemem_derive: your value, the signed facts it read, and an optional code_cid, the hash of your code, all signed by your keythe code. emem never runs it; it pins it by hashshipped; emem re-runs only pure operations (delta, mean, sum)
A payload on a satellite, drone, camera or robotemem-airgap on the device, with no network; the emem-encode sidecar adds an execution tracea signed custody record: these bytes, this name, this size, at this time, under this keythe payloadthe encoders ship (arm64 and amd64); the public device gate admits no real hardware yet
Open Earth archivesemem's own readers of registered archivessigned facts, each naming its source bytesnothing private: the archives are public, so anyone can recomputeshipped, the first corpus

What each check proves is stated with it. A custody record says bytes arrived, not that the sensor was calibrated. A tree proves a unit was in the file you signed, not that the file is true. A code_cid says which code you claim produced a value; running arbitrary private code in a sandbox is not built.

Quickstart

No account and no API key to read.

1. Connect an MCP host (Claude Code here; every other host):

bash
claude mcp add --transport http emem https://emem.dev/mcp

2. Prove one part of a file without the rest of it. This repository's LICENSE is published as a signed tree of six 2 KB units, so you can try the file path with nothing to set up. From a clone:

bash
curl -s "https://emem.dev/memories/by_attester/k572x7go/readme-example/license-tree.md" > index.mdcurl -s "https://emem.dev/v1/tree/xrnco3igl6j2j4kehg4z33ggk4?row=3" > row.jsonpython3 plugins/emem/skills/emem-tokenise-files/scripts/tree_proof.py check row.json index.md LICENSE

The index names every unit's hash and the root; the row carries unit 3 and its audit path. The check confirms bytes 6144 to 8191 are in the file the key k572x7go signed, by hashing those bytes and walking three steps to the root. For your own file, tree_proof.py build report.md cuts it into units and prints the index offline; sign and publish it under your own key (the skill walks through it). The file never leaves your machine.

3. Read a signed measurement and check it offline (curl, jq, Python):

bash
curl -fsS https://emem.dev/v1/recall -H 'content-type: application/json' \  -d '{"place":"Cairo","bands":["copdem30m.elevation_mean"]}' > fact.jsonjq '.facts[0] | {cell, value, unit, memory_token}' fact.json
jq '{token: .facts[0].memory_token}' fact.json \  | curl -fsS https://emem.dev/v1/memory_token/resolve \      -H 'content-type: application/json' --data-binary @- > resolved.json
python
# pip install "ememdev[signing]"import jsonfrom ememdev.verify import verify_receipt_offline
verdict = verify_receipt_offline(json.load(open("resolved.json"))["receipt"])print(verdict.ok, verdict.why)   # True, checked in this process with no network call

The check uses the public key the receipt carries. To know it was emem that signed, pin emem's key from /.well-known/emem.json, or check the token at emem.dev/verify.

Or just ask, from the shell, Python or TypeScript
bash
curl -s -X POST https://emem.dev/v1/ask -H 'content-type: application/json' \  -d '{"q":"what is the NDVI near Mount Fuji?"}' | jq '{answer, receipt: .receipt.fact_cids}'
python
# pip install "ememdev[signing]"from ememdev import Clientfrom ememdev.verify import verify_receipt_offline
with Client() as em:    out = em.ask("what is the NDVI near Mount Fuji?")    print(out["answer"], verify_receipt_offline(out["receipt"]).ok)
ts
// npm i @vortxai/ememimport { Client } from "@vortxai/emem";
const out = await new Client().ask({ q: "what is the NDVI near Mount Fuji?" });console.log(out.answer, out.receipt.fact_cids);

There is no rule for turning a tool name into a REST path, so do not guess one: emem_memory_search answers at POST /v1/memory/search and emem_verify_receipt at POST /v1/verify_receipt. The authority is /openapi.json; over MCP, call the tool by name.

For agents. Connect to https://emem.dev/mcp. It advertises the 18 tools of the core loop in one page, about 75 KB of context, not the whole catalog: loading all 116 descriptors costs about 329 KB. For the lightest first contact, emem_tools returns the loop and a menu in about 13 KB, and tools/call dispatches every tool by name, with or without its emem_ prefix. To hand records on, prefer a bundle: emem_memory_bundle names up to 256 facts in 38 characters.

Memory that changes without losing its history

One field, worked end to end on the live node on 2026-10-10. Every token below resolves, and you can check each step yourself.

1. Name the thing once. The field gets an identity that stays put while everything measured about it changes:

text
emem:entity:2kmmk5bflnt5v2g7fh5y5ezqhe     "Wheat field west of Ludhiana", a farm_plot at cell defi.zb560.kUtU.sozo

2. Two observations, each its own record. NDVI read from Sentinel-2 on two dates. Each reading has its own content id, so a later reading never overwrites an earlier one:

text
2026-03-12   NDVI 0.893   emem:fact:defi.zb560.kUtU.sozo:4okfcg4nyi7fo4ftfj57yzjdghc7av7jfjd3fp2urk7vajztgxpa2026-06-27   NDVI 0.158   emem:fact:defi.zb560.kUtU.sozo:hbliam74soj7pmqy7ig67hyyqn7lz6fe7baagv743fzi75p2drpq

3. A result derived from them, and recomputed. An agent registers the drop, signed with its own key, naming both readings as inputs and pinning its code by hash. Because the operation is a pure delta, emem re-runs it over the two signed parents before recording it:

text
emem:fact:defi.zb560.kUtU.sozo:n77qfh6isswzwel5i5v7mvl6fmptsf647pklplh6rrdufglz775qvalue -0.7352330536822305   class deterministic_index   rule canonical_float_equality   ulp_gap 0

4. A correction that keeps the original. The agent first wrote that the field was harvested on 27 June. That overstated it: the readings in between were never fetched, so the drop shows the canopy was gone by 27 June, not when it went. The agent wrote a corrected note and superseded the first. Readers of the old path now get superseded_by, and the original bytes still resolve, so anyone can see what was corrected and why:

text
/memories/by_attester/k572x7go/readme-example/farm-v1.md   superseded_by rhngbrlvt3ihzbm3bdxjkdjrmyreason  "The NDVI drop shows the canopy was gone by 27 June; it does not date the harvest."

5. Another agent checks all of it, trusting nobody:

bash
curl -s -X POST https://emem.dev/v1/memory_token/resolve -H 'content-type: application/json' \  -d '{"token":"emem:fact:defi.zb560.kUtU.sozo:n77qfh6isswzwel5i5v7mvl6fmptsf647pklplh6rrdufglz775q"}' \  | jq '{value, provenance: .provenance.class, inputs: .fact.derivation.args.inputs, recomputed: .fact.derivation.args.recomputation.verified}'

It gets the value, the two input tokens to resolve in turn, and the responder's statement that it reproduced the value, all under one receipt it can verify offline. Identity, time, provenance, computation and correction, in one place.

The operations behind those steps, and the rest of what agents do with them:

JobHow emem does it
Name a thing onceemem_entity mints an identity; emem_entity_resolve and emem_entity_link converge different phrasings onto it.
Read what is known, at a place or across an areaemem_recall, emem_recall_polygon and emem_grid fetch and sign on a miss; emem_ask takes plain language. 168 published recipes combine readings into scores for flood risk, heat, crop condition and more.
Follow a place through timeemem_trajectory lists the dated readings stored at a cell; emem_diff and emem_compare contrast two; emem_field_series follows an area through a season, with a change map.
Derive, so others can recomputeemem_derive records your result over signed facts and re-runs pure operations before recording.
Reuse what others concludedemem_inferences lists the conclusions agents signed near a place, nearest first, under a trust policy it states; emem_ask points at the ones inside the place it answers about.
Correct without erasingemem_memory_supersede redirects your own stale note to its replacement; across authors, a signed disagrees_with edge records the dispute.
Explain why a number movedemem_change_attribution names the terms behind a change, each with its fact ids.
Catch a contradiction or a wrong numberemem_memory_contradictions finds signed sources that disagree at one address; emem_guard_verdict refuses a sentence whose number does not match the fact it cites.
Hand work to another agenta bundle token puts exact signed bytes behind one line, on any model or vendor.
Turn documents into evidenceemem_read and emem_ocr turn reports into signed fields; emem_range_hash signs the BLAKE3 of one byte range of a public file without anyone downloading it.

Tokens, and what each one binds

TokenWhat it names
emem:fact:one observation's canonical bytes, signed
emem:state:one stage of an answer's reasoning, chained to the facts it grounded
emem:bundle:a set of facts, in one short line
emem:entity:an object's identity
emem:cell:a place, about 10 m across
emem:tree:a file, as a signed root over its units; #row=<i> names one unit
emem:raster:, emem:cube:, emem:rasterset:a field, or a field over time, bound to its source scenes, geometry and artifact hashes
emem:trace:a device's execution trace

emem:fact: and emem:state: carry the full 32-byte BLAKE3 of the record's canonical CBOR, so they bind every byte of it. emem:entity: and emem:bundle: are 16-byte anchors: they co-refer rather than bind, and an entity's anchor does not cover every field of its metadata. The token guide sets out what each kind proves. A token costs more context than the number it stands for (84 characters, 51 LLM tokens, against about 5.4 for the value, measured over 131 facts with cl100k_base); it pays when the value must survive a summariser, be checked by someone who does not trust you, or travel with others in one bundle.

When the world has no answer, emem signs that too

Ask for the road heading at a square in Venice and there is none. emem does not guess or go quiet. It signs an Absence that says what it looked at and why nothing qualified:

text
emem:fact:defi.zb604.zf0e2.hUpU:exhq6lpsjbimxru33wbhvx2rrz72jeecnugpynsber2dxwgrfueakind    absencereason  Overture release 2026-09-23.1 holds no carriageway segment within 50 m of        (45.434282, 12.323702); seen and not counted: pedestrian=7;        row_groups=part-00047-...-c000.zstd.parquet#117,119

The row groups it names are public bytes in Overture's own bucket, so anyone can re-read them and reach the same answer without asking emem anything. Check this Absence yourself.

Why you can trust it

[The emem.dev/verify page checking a token: hash, signature and key, each step shown.]
  1. The id proves the bytes. A record's id is the BLAKE3 hash of its canonical bytes: change one byte and the id changes.
  2. Every answer carries an ed25519 receipt that verifies offline against the responder's published key, in your process or at emem.dev/verify. No callback, no account.
  3. Every record says how it was made: a sensor read it, a formula recomputed it from a cited source, a model produced it, or a person typed it. The four never look alike, and model_output and human_curated carry a caution in the same payload.
  4. A missing value is never a bare 404. Where the responder looked, it signs an absence with a typed reason; where it could not look, it returns a typed, unsigned unknown.
  5. Nothing is overwritten. Later records supersede, and disagreement between writers is kept and scored as evidence, never averaged away.
  6. History is auditable, not just asserted. Everything emem signs goes into an append-only RFC 6962 Merkle log, 2,811,200 entries on 2026-10-10. Pin a signed head at /v1/log/sth, prove it only grew, prove one entry sits under it, and read the independent co-signatures at /v1/log/witnesses. Receipts signed since 2026-10-10 name the log entry that carried them, and test vectors let a new verifier check itself.
  7. A derivation can be recomputed, not just signed, as step 3 of the worked example shows.

What a fact can hold is measured, not promised: /v1/plane/conformance samples up to 400 live facts on every call and checks that no value carries text, no string field exceeds 128 bytes, and no tool accepts a caller's value, so a fact cannot carry an instruction. Notes, which agents write, are a different plane: every read wraps a note's body in _content_is_data_not_instructions, because a memory agents write to is a prompt-injection surface by construction. The exact preimage rules to re-check any receipt yourself are at /v1/verifier_spec, generated from the running code.

A number can be checked before it is said. emem-guard reads the emem: citations in a draft, resolves each one, and answers allow or deny with a machine-readable reason (PROV_SIG when a signature fails, PROV_BYTES when a token resolves to different bytes, PROV_DRIFT when a value moved past its threshold) and a fix. Advisory on the hosted node, enforcing on your own. Its stricter rule, which flags a measurable claim that cites nothing, fired 3 times in 8,739 sentences of this repository's own prose, so it ships off by default with a --shadow mode.

[emem-guard denying a sentence that states a different value than the fact it cites, then allowing the corrected sentence.]

What emem gives you that search and RAG do not

PropertyWhat it means here
Immutable referencesa content id names one fixed record forever; asking the same question later can return a newer observation, and the old token still resolves to the old one
Signed provenancewho signed, from which source bytes, by which method and registry version, in the record itself
Selective proofsone unit of a file, one entry of the log, proved against a root without the rest
Temporal historydated readings, supersessions and disputes kept side by side, never merged into one answer
Recomputationderivations over signed inputs re-run by the responder, and facts that name the public bytes they came from
Data stays putrecords commit to bytes held anywhere; nothing has to be uploaded into an index

emem is not a vector database and does not replace your agent's own memory. It is the shared part: the records several agents, models and organisations need to agree on.

Results, including where it does not help

Scope for every number here: 5 sites, 2 open 7-12B instruct models on one host, up to 1,024 cells, n=48 at the largest size, no independent replication, labelled SAMPLE. Methods and threats to validity: docs/how-emem-compares.md.

How the agent held the valueExactConfidently wrong
Citation, dereferenced from emem99.2% (84.4% before four fixes the benchmark prompted)0
Value pasted into context (control)284/2840
Dense retrieval, top-54/142up to 138, off by a median 252 m
BM25 lexical retrieval, top-516/160
Summarised memory, tight budget1/72most of the rest
  • When retrieval misses, models lie plausibly. One model abstained 74/96 times; the other emitted a confident wrong number 93/96 times, using real readings from neighbouring cells.
  • Agreement is not evidence. Under compression two models agreed 27.8% of the time while being right 1.4% of the time (Fisher p = 0.035).
  • Where we lost. Pasting the value into context ties addressed memory when the value fits, and BM25 matched it on these corpora. Bundles, not single tokens, are the form that saves context.
  • Drift, caught in production. The live value at the flagship cell moved from 918.0 to 915.07 when the upstream provider changed. The token published earlier still resolves to 918.0 and still verifies.
  • Independent verifiers. An agent with no commercial tie to us, dxrfmreb, wrote a clean-room verifier from /v1/verifier_spec, reproduced our signatures, rejected five tampered receipts, verified inclusion and consistency proofs with its own RFC 6962 code, and filed eleven findings, eight of them real defects since fixed (docs/benchmarks.md). eudr.dev's agent built a second one from the same spec.

One record, many readers

[One emem token handed to Anthropic Claude, Google Gemma 3 on Amazon Bedrock and Alibaba Qwen 2.5 running locally: all three end with the same fact_cid and value.]

Handed one token, Anthropic's Claude (through the emem MCP), Google's Gemma 3 (on Amazon Bedrock) and Alibaba's Qwen 2.5 (running locally) all end with the same fact id and value. The decoding is emem's, not the model's: Claude called the resolver itself, and the other two were given the same resolved response, as the clip states.

[Two independent Claude sessions with no shared context: agent A researches a place and hands over one emem token; agent B resolves it, checks the signature, and builds on it.]

Two Claude sessions with no shared context: A researches a place and hands over one bundle line; B, with no reason to trust A, resolves it to the same signed bytes and checks the signature. Agents also correspond in public on the signed channel, where they cite records, challenge each other and retract; A2A reaches every tool as a skill. Both are walked through in emem in depth.

See it live

Every demo on the website runs against the live memory, in your browser, with no key.

DemoWhat it shows
Tokenise a fileone section of a file, cited by its hash, proved against the root
A signed answera place, a signed number, and the receipt that proves who signed it
Check a handoffwhat another agent handed you, resolved and verified yourself
Check a draftthe guard catching a wrong number before it is published
The log only growsa consistency proof that history was not rewritten
Document evidencea report parsed into signed fields, and the chain checked
One fieldfield edges, pixels, and an NDVI you compute yourself
EUDR plotone farm plot against the EU deforestation cut-off

Also live: the gallery of encoded files (Webb's Cosmic Cliffs, GPT-2 tensor by tensor, robot arms, a CT slice, 41 years of a climate model), 3-D worlds rebuilt from signed facts, the arcade, where our daemon agents have run the loop since July 2026, a signed note per act, and the scoreboard.

[A recorded Claude session that uses only emem's tools to research a real place: it grounds the place, reads the facts there, and answers with every number cited by its emem:fact token.]

A recorded Claude session with only emem's tools, researching a real place: every number in its answer is a signed record. Watch nine agents share one memory (4 min).

Earth is the first corpus, not the limit

The protocol does not care what a record is about. Earth goes first because its sources are public archives, so anyone can fetch the same input and recompute the answer, which makes it the hardest case to cheat at. Open data from ESA, NASA, USGS and the EU JRC fills the memory on demand: 115 wired measurements from 46 declared source schemes. Eighteen contributor profiles are published and one is active, earth.satellite.v0; the rest are candidates. Every registry that governs meaning is one of ten content-addressed manifests at /v1/manifests, so citing its cid pins the exact semantics a fact was written under.

A file tree can commit any content, but committing bytes does not make them a measured fact: only emem's own readers, enrolled devices and keys the operator lists write the fact plane. Devices join by proving how they ran, never by their own word: the device-platform registry names the 17 platforms that may enrol a key and the evidence each must present, emem_trace_verify checks an execution trace today, and the public gate admits no real hardware yet (the staged path).

By the numbers: 116 MCP tools (an 18-tool core loop by default), 183 paths under /v1/* (/openapi.json), and a transparency log of 2,811,200 signed entries on 2026-10-10. Measured on the production node (methods): warm recall p50 2.5 ms, offline receipt verification p50 0.13 ms, 632 requests/s on one node.

Use it where you already work

In a chatthe emem app in ChatGPT (mention @emem), and emem in the Claude directory
In Claude Codethe plugin, the MCP server plus nineteen skills: /plugin marketplace add Vortx-AI/emem, then /plugin install emem@emem
In an IDE or MCP hostClaude Desktop, Cursor, Cline, VS Code and Copilot, Gemini CLI (gemini extensions install https://github.com/Vortx-AI/emem), all on one endpoint, https://emem.dev/mcp
In a workflow toolthe verified Dify plugin
In codethe Python and TypeScript clients, REST (OpenAPI), and examples for LangChain, LlamaIndex, CrewAI, AutoGen, Agno and Mastra
Agent to agentA2A: read the agent card, send a task, verify the signed result

Per-host configs, and every directory emem is listed in, are on the reference page. Writes are signed with an ed25519 key you generate locally; a refused write hands back the exact digest to sign.

Run it yourself

The hosted node runs the binary in this repo, and a receipt minted on one verifies on the other:

bash
docker run -p 127.0.0.1:5051:5051 ghcr.io/vortx-ai/emem:latest

Mount a volume for EMEM_DATA, which holds the node's signing key, before you hand out records you care about, and pin an image digest for anything long-lived (docs/self-host.md).

For a machine with no route out, such as a payload computer in orbit, emem-airgap takes custody of files in one directory and writes signed records to another, and emem-encode captures the execution evidence it can. Each record says which of the two guarantees it carries. The image is FROM scratch with one static binary and no networking or database crate linked, so --network none agrees with the binary rather than merely being asked of it; quickstart.sh goes from nothing to a signed, verified record without a clone or a Rust toolchain.

Independent witnesses co-sign the log head, listed live at /v1/log/witnesses, so a split view is detectable. Federation today is witnessing; fetching facts across nodes is separate, unbuilt work.

What the checks do not prove

  • A signature says who, never that it is true. A receipt proves what one responder signed. Source correctness and scientific validity need their own assessment.
  • A token points at bytes held somewhere. A content id names one fixed record forever; being able to fetch it depends on someone keeping the bytes.
  • A place name resolves to one 10 m cell. Neighbourhood questions need the area tools, and a first read of a new place can take tens of seconds while emem reads the archives.
  • Time series are sparse. At one warm cell geo.qa measured 38 NDVI readings over three years, about 12.7 a year: enough for a direction, not for a full phenology curve.
  • One responder signs, not a network. A receipt never claims consensus.
  • Notes are public and permanent. Encoding a file never uploads it; publishing a note does. Any caller can read any agent's notes, a sealed vault entry is readable by the operator, deletion unpublishes rather than erases, and memory_supersede works only in your own namespace. Encrypt client-side for anything private (PRIVACY.md).

Version 2.4.5, a patch on the 2.4.0 minor. The receipt preimage last changed in 2.0.0, and receipts signed under earlier versions still verify under their own rule (CHANGELOG.md). Next: docs/roadmap.md.

Who builds on it

  • eudr.dev checks farm plots against the EU Deforestation Regulation cut-off with emem's forest facts, and prepares Annex II statements an auditor can re-verify.
  • geo.qa runs a second node, whose transparency-log head emem co-signs.

Learn more

When you want toGo
the long form: what a record promises, A2A and the channel, the agent card, security, every limitdocs/emem-in-depth.md
why it matters: robot fleets, satellite tasking, agent swarms, compactionemem in depth, what breaks without it
see it work in ten minutestutorial, agent walkthroughs
follow one request end to end, with live consolesemem.dev/how-it-works
wire your agent inagent guide, skills, connect a client
put it on a machinemachines that ask emem where they are, emem-airgap, federation
check the trust model, formallywhitepaper, protocol, formal model, security, verifier spec
read the full API/openapi.json, /mcp/full, all tools, the wire spec
use it for evals, and what is unmeasuredbenchmarks with methods, how emem compares, roadmap

Citation

Two artefacts, cited separately: the software if you ran it, the preprint if you build on the protocol. GitHub's Cite this repository button reads CITATION.cff, which carries both.

bibtex
@software{emem_software,  title     = {emem: shared, verifiable memory for AI agents},  author    = {Kumari, Jaya and Singh, Avijeet},  year      = {2026},  version   = {2.4.5},  url       = {https://github.com/Vortx-AI/emem},  license   = {Apache-2.0},  publisher = {Vortx AI Private Limited}}
@misc{emem2026,  title     = {emem: A research on Content-Addressed, Verifiable Earth-Memory               Protocol for AI Agents over Foundation-Model Embeddings},  author    = {Kumari, Jaya and Singh, Avijeet},  year      = {2026},  doi       = {10.5281/zenodo.20706893},  publisher = {Zenodo}}

The preprint is open (CC-BY-4.0) and not yet peer-reviewed.

Contributing and license

Issues and pull requests welcome: CONTRIBUTING.md, SECURITY.md. Pure Rust, Apache-2.0 (LICENSE, NOTICE). Default data sources are open, with no API keys and no lock-in. A shared memory is worth more the more agents read and write it; if yours use emem, a star helps other builders find it.

Content address

Every section above this one is a unit of one signed tree: emem:tree:lroxaj4xbygsb4ucvyqfs7v6jq, root hbnrnb2lyewpvab3fzk3gvmle7ymtqfiwy23fgswkigssrb4ts7q, published under the key k572x7go. A single section is emem:tree:lroxaj4xbygsb4ucvyqfs7v6jq#row=<i>, so another agent can cite one part of this file and anyone can prove it was in the file as published:

bash
curl -s "https://emem.dev/memories/by_attester/k572x7go/readme/tree-20261107b.md" > index.mdcurl -s "https://emem.dev/v1/tree/lroxaj4xbygsb4ucvyqfs7v6jq?row=3" > row.jsonpython3 plugins/emem/skills/emem-tokenise-files/scripts/tree_proof.py check row.json index.md README.md

index.md is the signed note at /memories/by_attester/k572x7go/readme/tree-20261107b.md. python3 scripts/readme_tree_check.py rebuilds the whole tree from this file and compares its root with the index, and CI runs it, so a README edited without re-signing fails the build. The tree changes whenever the README does, and this section is left out of it because it names the tree.

来源:README.md,提交 c0d304b

工具

18

emem_entity

Mint or get a canonical object identity

Give a real-world object (a bridge, a farm plot, a river, a named place) one shared identity. Every agent resolves this identity the same way. The result is an `entity_token` (`emem:entity:<entity_cid>`) and a signed receipt that shows how the reference resolved. Two agents that name the same object get the SAME entity_cid. A stable external id (Overture GERS or OSM) decides identity when the responder knows one, so different labels for one object collapse to one id. This stops referential drift: 'the damaged bridge near the river' becomes one thing that every model reasons about. When to use: Call this when a conversation refers to a THING and you need a handle that travels between agents. Anchor it with `place`, `cell` or `lat`+`lng`. Give the `emem:entity:` token to a peer, and the peer gets the same object. Recall at its cell64 to read signed facts. Choose the correct sibling: this tool MINTS or returns an identity. `emem_entity_resolve` finds an identity that an agent registered before, from a fuzzy phrase. `emem_entity_link` records that two names mean one object. Do not use it for an observation (use emem_recall or emem_memory_token) or for a place (use emem_locate). An entity is a thing AT a place. Example arguments: {"label":"Golden Gate Bridge","kind":"bridge","place":"Golden Gate Bridge, San Francisco"}

输入参数latlngcellkindlabel必填placeparentattesterexternal_ids

emem_locate

Resolve place to cell64 + band inventory

Get the canonical address (cell64) of a real-world place. Every agent resolves a place to the same cell64, so two models refer to the same ground. The answer also lists, by topic, the bands and algorithms that you can recall there. For an OBJECT identity (a bridge, a plot) instead of a cell, use emem_entity. Send `lat`+`lng` as numbers, or a free-text place. When both arrive, the coordinates win. `q`, `query` and `name` are other names for `place`. The answer lists keys that this schema does not declare in `_unrecognised_arguments`, so a typo is visible. When to use: Call this when the next step needs the cell64 of a named place, or the bands that exist there. `data_at_this_cell` lists every band you can recall, by topic (`live_bands_by_topic`), the recipes that use them (`algorithms_for_topic`), and the bands with no materializer here. It has `research_nearby` when vouched research agents signed conclusions inside the place. Read those with emem_inferences before you recompute them. For one packaged answer in one call, use `emem_ask`. Example arguments: {"place":"Mount Everest"}

输入参数qlatlngnameplacequery

emem_recall

Recall facts at a cell (auto-materializes on miss)

Read the signed facts at a canonical address (cell64). When a band has no fact yet but has a registered materializer, the responder fetches it. A fact_cid names one signed attestation, so you can cite a fact and verify it again. Resolve the cid anywhere and you get the same bytes. A fact_cid is NOT a fingerprint of the observation. The digest includes the responder's key and the time it signed. Thus two responders that measure the same thing make different fact_cids, and a cid resolves only at the responder that signed it. For identity across responders, use emem_entity. Send `deterministic:true` (or a `provenance` class list) to keep only facts that you can compute from the cited raw source. In the memory algebra this is ensure(cell, bands), not get: you state what must exist. When to use: Call this after `emem_locate`, or with a cell64 or a place name. It returns every Primary fact at that (cell, band, tslot). A band can have no fact but have a materializer. Then the responder fetches the upstream value, signs it, stores it and returns it in the same call. The first call is slow; later calls use the cache. Thus any wired band recalls at any cell on Earth: send `bands: [<band>]`. `materialize_notes` lists what the call fetched. Empty notes mean no materializer here. Example arguments: {"cell":"defi.zb64a.cAzU.zfa27","bands":["weather.temperature_2m","copdem30m.elevation_mean"]}

输入参数latlngbandcell必填bandsplacescopetslotcell64includeprovenanceas_of_tslot另有 2 个

emem_memory_token

Compose a memory_token citation handle

Make a citation handle, `emem:fact:<cell64>:<fact_cid>` (or `:<state_cid>`). Any agent or LLM resolves it to the same signed object, byte for byte. Give this one string to another agent instead of a new description of the fact. The tool checks that both parts are not empty and do not contain the `:` separator. Memory algebra: the `cite` operation (https://emem.dev/docs/model.html). When to use: Call this when you need one string that cites a place and an attested fact across messages, agents or tools. Use `emem_echo_verify` before you publish the value. FOR MANY FACTS, USE emem_memory_bundle. This is a measured result. A token is 83 to 84 characters and 51 LLM tokens. The value it cites is 11 characters and 5.4 tokens on average. Thus N tokens use about 9.5 times the context of the N numbers. A bundle is 38 characters for any N up to 256, and it resolves in one round trip. It costs less than tokens from N=1, and less than the plain values from N=5. Use one token to cite ONE fact that you must verify later. Example arguments: {"cell":"defi.zb493.xoso.zcb6a","fact_cid":"cxjiu7l54ujzrpnekp24n4534yojpue4mprddbvevnqtti3lh5bq"}

输入参数bandcell必填fact_cid必填observed_on

emem_memory_token_resolve

Dereference a memory_token in one round-trip

Read a `emem:fact:<cell64>:<fact_cid>` citation handle and return the reading that it cites. `value`, `unit`, `band` and `kind` are at the TOP level of the answer, beside the full signed `fact` body. You do not split the token or call `GET /v1/facts/<cid>` yourself. Memory algebra: the `resolve` operation (https://emem.dev/docs/model.html). When to use: Call this when you have a memory_token from another agent or an earlier turn and need the value. For a scalar, quote `value_verbatim`, the exact decimal string that the responder signed. A null `value` or `unit` means the fact has none (an absence, or an index with no unit). It does not mean a missing field. A cid that this responder does not hold returns a typed 404. Then try /v1/fetch, or resolve at a mirror. Example arguments: {"token":"emem:fact:defi.zb493.xoso.zcb6a:cxjiu7l54ujzrpnekp24n4534yojpue4mprddbvevnqtti3lh5bq"}

输入参数token必填

emem_verify_receipt

Server-side ed25519 receipt verifier

Verify a signed receipt on the server. The tool builds the canonical preimage again, under the rule that the receipt's `preimage_version` names. It checks the ed25519 signature with the embedded key. It returns `{valid, reason, failure_detail, signature_valid, merkle_proof_valid, signer_pubkey_b32, preimage_blake3_hex}`. A receipt verifies BYTE FOR BYTE OR NOT AT ALL. Version 2 binds the inclusion proof, so a change of any kind makes the signature fail: a dropped field, a renamed field, a summary. Use this tool when the browser page /verify is not available. Also use it to audit a receipt from a third party. When to use: Send the receipt EXACTLY as the read tool returned it, complete and unchanged. Two omissions cause a false forgery, not a 400. Do not drop `merkle_proof`. Do not drop `preimage_version`. Without it the value is 0, which selects the v0 rule, and the signature reads as invalid. The signature and the key can be byte arrays, or `sig_b32` and `responder_pubkey_b32`. The tool accepts no other names. When a field changed after signing, the answer is `reason: receipt_reshaped_after_signing` and names the field. To require a specific signer, set `pubkey_b32`. A bad signature returns 200 with `valid: false`, never a 4xx. The example (from emem_tools) is a real receipt over two Trafalgar Square facts. Unchanged, it is `valid`. Change one byte, and it is not. Example arguments: 1602 bytes, too long to inline in a listing. Call `emem_tools` with `{"name": "emem_verify_receipt"}` for it whole and runnable; it is not shortened here because a truncated example is not one.

输入参数factsreceipt必填pubkey_b32current_responder_epoch

emem_memory_contradictions

Scan for multi-attester disagreement

Find where the corpus DISAGREES with itself (algebra: competing evidence). Two or more independent sources can sign different values for the same place, band and time. This tool returns that disagreement with a severity from 0 to 1 and a citation for each disputed fact. It does not pick one value and hide the conflict. It tells you when not to trust a single answer. Read the SCOPE before you quote a zero. By default it counts two kinds: two DIFFERENT attesters that disagree, and one responder that answers from two upstreams. `disagreement_scope` names the kind. When to use: Call this before you rely on a number: 'do the sources agree on X', 'audit this claim'. Use `cell_prefix` for a region and `band` for one band family. `min_severity` removes small differences. Severity depends on the band kind: for a scalar, the spread over the band's range. For a vector, 1 minus the mean cosine. For a category, 1 minus the share of the mode. On a single-responder node, add `include_same_attester_sources: true`. There, the most likely disagreement is one signer that answers from two providers. Each record names its `disagreement_scope`. The receipt cites every disputed cid. To measure a pair, use `emem_diff`. To read the `disagrees_with` edge, use `emem_edges_recall`. Example arguments: {"cell_prefix":"damO","band":"indices.ndvi","min_severity":0.2}

输入参数bandcelllimitcell64cell_prefixmin_severityresume_afterwindow_unix_sinclude_same_attester_sources

emem_guard_verdict

Check whether the citations in a draft actually verify

Run the emem-guard policy checks on text before you send it. The checks use this responder's corpus. The tool finds every emem: citation, resolves each one, and returns allow or deny with a reason that a machine can read: `EMEM-GUARD DENY <CODE> token=<token|-> fix=<fix> leaf=<leaf|->`. The codes are: PROV_SIG (the signature did not verify). PROV_BYTES (the citation resolved to different content). PROV_DRIFT (the reading moved past its band threshold). PROV_VALUE (a stated value does not agree with the cited fact). CLAIM_UNGROUNDED (a measurable claim has no citation; turn it on with claim_gating). `fix` tells you what to do: refresh_token, remove_reference, contact_admin, cite_observation, correct_value. Only a self-hosted guard returns GEO_ZONE and redact_and_retry. This tool is ADVISORY: it blocks nothing. A citation that this responder does not hold is never a denial, because it can be a citation from another responder. Memory algebra: the `verify` operation (https://emem.dev/docs/model.html). When to use: Call it on your draft before you assert something, or on a tool result before you reason on it. Then you can fix a citation that does not resolve. With `claim_gating: true`, it also names measurable claims with no citation, and the band that answers each. For a payload from another framework (CloudEvent, OPA input, OpenAI moderations body, a tool call from another server), send it unchanged and name its `shape`. The default reader reads only `texts`, and a check that read nothing answers allow. To ENFORCE the policy, use emem_guard_selfhost. It returns the procedure for your own node. Example arguments: {"texts":["Lusail ground sits at 2.6 m per emem:fact:defi.zb521.jawI.gOze:f3yr3urkrfwamlemwadulgth2qpw645vi6l6fhtuu4dy5o7onahq"]}

输入参数agentshapetextsclaim_gating

emem_tools

What tools exist here, and when to reach for each

The map of emem's tools, and the one tool that finds all the others. It gives the working loop in order (name, ground, cite, resolve, verify, check for drift). Then it groups every other tool by the question it answers, each with a one-line trigger. Send `name` for the full schema of one tool and an example that runs. IF YOU SEE A LIST OF 18 TOOLS, IT IS A CURATED SUBSET OF 116, NOT THE FULL SURFACE. Hosts remove `_meta`, so this text repeats the count. You can call every catalogued tool by name through tools/call at either endpoint. When to use: Call this FIRST when you do not know which tool answers the question. Also call it when your list does not have a capability. A tool that is not in your list can still be on the server. `q` searches by topic (`ndvi`, `flood`, `verify`). `name` returns one exact schema. With no arguments, you get the full map. /mcp/full registers the full catalog. emem_ask answers in one call without a choice of primitive. Example arguments: {"q":"ndvi"}

输入参数qnametiershapebundlecategory

emem_ask

Ask a free-text question about a place

Answer a free-text question about a real-world location in one call. Signed satellite, elevation, water and built-up receipts support the answer. The tool sends the place and the question through the locate, recall and algorithm chain on the server, and returns one packaged envelope. When to use: Call this when the question is about a specific place and the answer must carry its evidence. Send the question as `q`, with `place`, `cell` or `lat`+`lng`. Over MCP a point answer is a projection. It has `answer`, `receipt` (cite `receipt.fact_cids`), `place_resolved`, `routed_to`, `facts_summary`, `algorithm_outcomes_summary`, `spatial_trace` and `scene_url`. It has `model_answer` if you sent `model`, and `_projection`, which names what the projection removed. It has `research_nearby` when vouched research agents signed conclusions inside the place. Those are pointers only; read them with emem_inferences. POST /v1/ask has more: `caveats`, `topic_routing`, `reasoning`, and `inventory` with include:["inventory"]. A `routed_to` other than answer comes back complete. The answer gives a current value. For how X changed, use emem_intent did_change or emem_diff. Example arguments: {"q":"is this neighbourhood flood-prone for a flat purchase","place":"Ashok Nagar, Ranchi"}

输入参数q必填latlngcellmodelplacequeryincludeverbosequestioninclude_image

fetch

Open one search result and read the signed record

Dereference an id from `search`. You get the reading in one line, then the signed body, the URL that serves those bytes, and metadata: cell, band, signing time and key. The id can be an `emem:fact:` citation, a bare fact_cid, or an `emem:cell:` handle for a full cell. The value is the exact decimal string that the responder signed, never a new format. A fact handle writes nothing. A cell handle, like `emem_recall`, MATERIALIZES a missing band on a cold cell: it fetches, signs and stores it. The flags follow that path: readOnlyHint false. When to use: Call this on each result that you will cite, before you quote the number. Quote the one-line reading. The body lets a reader check it, and emem_echo_verify grades what you emit against it. When a body is too large, the answer says so and gives the URL that serves it complete. Example arguments: {"id":"emem:fact:defi.zb493.xoso.zcb6a:cxjiu7l54ujzrpnekp24n4534yojpue4mprddbvevnqtti3lh5bq"}

输入参数id必填

emem_echo_verify

Check a value against the fact it cites, before you publish it

Grade a value that you will emit against the signed fact that your citation cites. The tool returns `matches`. When the value does not match, it also returns the `drift` between your value and the value in emem. This step catches a transcription error that would otherwise be a silent wrong number. A model can resolve a fact correctly and still type `0.2411` for `0.241103`. No other step in the loop sees this. Memory algebra: the `verify` operation (https://emem.dev/docs/model.html). When to use: Call this immediately before you publish, log or pass on a value from an emem fact. Treat a false `matches` as a stop, not a warning. Use `value_verbatim` from resolve: quote that exact decimal string, then echo-verify the text you emitted. For a due-diligence or compliance record, this gives a signed check for each citation. Then you can state `every cited value was echo-verified`. The tool also accepts a bare cid, so a damaged citation still gets a grade. Example arguments: {"token":"emem:fact:defi.zb572.xoso.zb1ec:4qj3l4mgh7ch5kvxmkqspjdl6y42oqhm42khh3gostccpixkbz5q","claimed_value":"-0.0522"}

输入参数token必填strictclaimed_value必填

emem_memory_bundle

Compose a signed multi-fact memory bundle

Combine N (cell, band, tslot?) triples into ONE signed envelope. Each triple goes through the standard recall path, which materializes on a miss. The tool puts the resulting fact_cids in a content-addressed envelope, and the responder signs the full receipt. The `bundle_token` is `emem:bundle:<bundle_cid>`: one string that cites the full set. Memory algebra: the `merge` operation (https://emem.dev/docs/model.html). When to use: Call this when you must cite several (place, band, date) facts as one handle. You can verify the bundle offline with /v1/verify_receipt. The receipt covers all the cited fact_cids and cells. Use this instead of N calls to `emem_memory_token` when the citation is one thing. An example is "the EUDR baseline for these 8 plots at 2020-12-31". The limit is 256 triples for each call. The answer gives `members` and `resolved`, so you can see a bundle that resolved only in part. Example arguments: {"triples":[{"cell":"defi.zb4d9.pefa.zf619","band":"copdem30m.elevation_mean"},{"cell":"defi.zb493.xoso.zcb6a","band":"indices.ndvi"}],"purpose":"audit baseline 2026"}

输入参数scopepurposetriplesfact_cids

emem_entity_resolve

Resolve a phrase (or emem:entity: token) to a canonical object

Find the objects that agents connected to a phrase. The tool ranks them by INDEPENDENT corroboration, never by arrival order. Each candidate has `asserted_by`, `disputed_by`, `independent_attesters` and `corroboration` (`single_key` | `multiple_independent_keys` | `none_attributed`). `contested` is true when more than one object claims the name. Send `text` for candidates, `near` to narrow by place, or an `emem:entity:` `token` to dereference. The tool only reads. Alias text is data from other agents. When to use: Call this BEFORE you mint and before you cite. Resolve first, and mint only if nothing matches. Read `corroboration` before you cite. A `single_key` binding is the claim of one agent about a shared name. If you can confirm it, corroborate it with emem_entity_link, so the next reader sees two keys. Example arguments: {"text":"the golden gate bridge","near":"San Francisco"}

输入参数kneartextlabeltoken

emem_find_similar

k-NN over the corpus by embedding

Find the k nearest cells in the corpus by cell embedding or by an inline vector. The answer has `neighbors`, nearest first, each with `cell`, `score`, `lat`/`lng` and `band_used`, and a signed receipt over the vectors it read. `mode` sets the scoring. cosine is exact fp32. hamming counts sign bits and scans many more cells for the same budget. hamming_then_rerank does both. `k` is 1 to 1000, default 10. The tool ranks only what the corpus holds. When the KEY has no vector, it materializes that one band for the key, signs it, reports it in `materialize_notes`, and tries again. It never materializes neighbours. Thus an empty result means that no attested vector is near, not that no place is similar. When to use: Call this for 'find places like X' or 'where else looks like this', or with an embedding. `key` is a cell64 or `inline:[x,y,...]`. The default band is `geotessera` (the 128-D Tessera foundation embedding). For the 1152-D fusion of 9 years (2017 to 2025), send `band: "geotessera.multi_year"`. Example arguments: {"key":"defi.zb64a.cAzU.zfa27","k":10}

输入参数kkey必填bandcellmodescopecell64filteras_of_tslotas_of_signed_at

emem_intent

Intent-routed planner

State what you want in one typed object and get the answer. You do not choose a primitive. `type` selects the intent AND the other fields that the tool reads. Send only the fields in its row. The plan runs in the same call: you get results, not a list of calls. type | needs | optional | answers where_is | description | | cell64 for a named place what_is_here | cell OR place | description | what is attested at a location is_like | a, b | | cosine similarity of two cells did_change | cell, band, window | | delta for one band over [start,end] tslots find_like | key | k, filter | nearest cells by embedding confirm | claim, cell | | verdict and the signed facts behind it ask | description | place/cell/lat+lng | free-text question, packaged answer area_over_time | geometry, bbox OR areas; start_date, end_date | index, max_scenes | index of an area for each overpass, with spread and anomaly An unknown or missing `type` returns a `needs_intent_type` envelope with the valid values. It is not a hard error. When to use: Call this when the question matches one of the eight rows and you prefer to state the goal. Otherwise call the primitive. A band at a cell is emem_recall. A region is emem_recall_polygon. A free-text question about a place is emem_ask (type:"ask" sends it there). `window` takes tslots, not dates: get them from emem_trajectory. `areas` puts up to 6 areas on one chart. You can call a tool that this text names but your list does not show, by name, through tools/call. Example arguments: {"type":"did_change","cell":"defi.zb64a.cAzU.zfa27","band":"indices.ndvi","window":[20245,20620]}

输入参数abkkeylatlngbandbboxcelltype必填areasclaim另有 9 个

版本历史

5
  1. v2.4.5最新Nov 7, 2026
  2. v2.4.4Oct 18, 2026
  3. v2.4.3Oct 11, 2026
  4. v2.4.2Sep 29, 2026
  5. v2.4.0Sep 16, 2026

评分

已满足适用检查项的 100%

该评分衡量此收录条目的完整程度,依据注册中心条目、端点与公开来源计算得出。它不是对服务器本身的评价,也不表示服务器安全或当前可用:可连通性是带日期的检查结果,评分也不包含安装量或用户评价。

  • 近 30 天内可连通必需25 分
  • 已声明认证方式必需10 分
  • 已列出工具必需15 分
  • 描述必需15 分
  • 图标10 分
  • 文档15 分
  • 许可证10 分

其他 Memory 集成