Security
GHSA-9x7v-2vjj-xghg: a read-only OAuth token could write memories over SSE, Streamable HTTP and prompts/get. Thanks to @gigio1023 for the report.
The write scope check from GHSA-2r68-g678-7qr3 lived in the FastAPI JSON-RPC shim only. SSE and Streamable HTTP authenticated the token, dropped its scope and dispatched straight into MemoryServer.call_tool, so a read token could call memory_store, memory_update and memory_delete. The learning_session prompt stored a memory without going through call_tool at all. The transports now record the granted scope on each request, and call_tool and learning_session refuse writes without write, per message. The readOnlyHint classification moved onto MemoryServer so the shim and the transports share it.
This affects only servers running with MCP_OAUTH_ENABLED=true. stdio and API-key callers are unchanged. If you run OAuth with read-only clients, upgrade.
The mcp SDK floor rises from 1.8.0 to 1.9.2, the first release that hands the per-message request to handlers.
Also in this release
- Hybrid sync: Cloudflare tombstones stay authoritative (#1502), and pulled memories skip semantic dedup on the receiving device (#1504).
- Export/import round trip now covers every store and reports rejected memories (#1520, @massimiliano1991).
- Delta-sync first sync installs the peer baseline and re-embedding clears
embedding_pendingin the right store partition (#1522). regenerate_embeddings.pywrites vectors into their store partition and skips soft-deleted memories (#1521).- ONNX loader log lines are sanitised (#1540, @massimiliano1991).
- Belief noise filter no longer drops long but substantive insights.
Full entry: https://github.com/doobidoo/mcp-memory-service/blob/v12.0.1/CHANGELOG.md