mirror of
https://gitea.ingwaz.work/Ingwaz/openbrain-mcp.git
synced 2026-06-15 22:07:08 +00:00
Scope memories by API token and add shared-token e2e coverage
This commit is contained in:
41
README.md
41
README.md
@@ -10,7 +10,7 @@ OpenBrain is a Model Context Protocol (MCP) server that provides AI agents with
|
||||
- 🏠 **Local Embeddings**: No external API calls - uses ONNX runtime with all-MiniLM-L6-v2
|
||||
- 🐘 **PostgreSQL + pgvector**: Production-grade vector storage with HNSW indexing
|
||||
- 🔌 **MCP Protocol**: Streamable HTTP plus legacy HTTP+SSE compatibility
|
||||
- 🔐 **Multi-Agent Support**: Isolated memory namespaces per agent
|
||||
- 🔐 **Shared Memory by Token**: Agents using the same API token share memory visibility while retaining source-agent provenance
|
||||
- ♻️ **Deduplicated Ingest**: Near-duplicate facts are merged instead of stored repeatedly
|
||||
- ⚡ **High Performance**: Rust implementation with async I/O
|
||||
|
||||
@@ -20,8 +20,8 @@ OpenBrain is a Model Context Protocol (MCP) server that provides AI agents with
|
||||
|------|-------------|
|
||||
| `store` | Store a memory with automatic embedding generation, optional TTL, and automatic deduplication |
|
||||
| `batch_store` | Store 1-50 memories atomically in a single call with the same deduplication rules |
|
||||
| `query` | Search memories by semantic similarity |
|
||||
| `purge` | Delete memories by agent ID or time range |
|
||||
| `query` | Search memories by semantic similarity, optionally filtering by source agent |
|
||||
| `purge` | Delete memories visible to the current API token, optionally filtering by source agent or time range |
|
||||
|
||||
## Quick Start
|
||||
|
||||
@@ -127,8 +127,8 @@ If you want prod e2e coverage without leaving a standing CI key on the server, t
|
||||
### Deduplication on Ingest
|
||||
|
||||
OpenBrain checks every `store` and `batch_store` write for an existing memory in
|
||||
the same `agent_id` namespace whose vector similarity meets the configured
|
||||
dedup threshold.
|
||||
the same API-token scope and same source `agent_id` whose vector similarity
|
||||
meets the configured dedup threshold.
|
||||
|
||||
Default behavior:
|
||||
|
||||
@@ -165,10 +165,12 @@ Recommended target file in A0:
|
||||
### External Memory System
|
||||
- **Memory Boundary**: Treat OpenBrain as an external MCP long-term memory system, never as internal context, reasoning scratchpad, or built-in memory
|
||||
- **Tool Contract**: Use the exact MCP tools `openbrain.store`, `openbrain.query`, and `openbrain.purge`
|
||||
- **Namespace Discipline**: Always use the exact `agent_id` value `openbrain`
|
||||
- **Shared Access Model**: Memory visibility is determined by the API token in the MCP client config, not by `agent_id`
|
||||
- **Source Labels**: Use `agent_id` on `openbrain.store` and `openbrain.batch_store` only as a provenance label for the storing agent when that label is useful
|
||||
- **EXTRAS First**: Before calling `openbrain.query`, check the `[EXTRAS]` section for pre-loaded memories or handoff facts related to the same topic. If the needed context is already present, do not query OpenBrain again.
|
||||
- **Session Cache**: If the same topic was already queried earlier in the current conversation and the result is still in context, reuse that result instead of querying again unless the user references new external information or the prior result is clearly insufficient.
|
||||
- **Retrieval First**: Before answering requests that may depend on prior sessions, project history, user preferences, ongoing work, named people, named projects, deployments, debugging history, or handoff context, call `openbrain.query` only when `[EXTRAS]` and the current conversation do not already provide the needed context.
|
||||
- **Query Scope**: Do not send `agent_id` with `openbrain.query` for normal retrieval. Use `source_agent_id` only when you intentionally want to filter results by the agent that originally stored them.
|
||||
- **Query Strategy**: Use noun-heavy search phrases with exact names, tool names, acronyms, hostnames, and document names; query first with `(threshold=0.15, limit=8)`, then retry once with `(threshold=0.05, limit=10)` only if the first pass returns zero useful results
|
||||
- **Storage Strategy**: When a durable fact is established, call `openbrain.store` without asking permission and store one atomic fact whenever possible
|
||||
- **Storage Content Rules**: Store durable, high-value facts such as preferences, project status, project decisions, environment details, recurring workflows, handoff notes, stable constraints, and correction facts
|
||||
@@ -177,7 +179,7 @@ Recommended target file in A0:
|
||||
- **Metadata Usage**: Use metadata when helpful for tags such as `category`, `project`, `source`, `status`, `aliases`, and `confidence`
|
||||
- **Miss Handling**: If `openbrain.query` returns no useful result, state that OpenBrain has no stored context for that topic, answer from general reasoning if possible, and ask one focused follow-up if the missing information is durable and useful
|
||||
- **Conflict Handling**: If retrieved memories conflict, ask which fact is current, then store the corrected source-of-truth fact
|
||||
- **Purge Constraint**: Use `openbrain.purge` cautiously because it is coarse-grained; it deletes by `agent_id` and optionally before a timestamp, not by individual memory ID
|
||||
- **Purge Constraint**: Use `openbrain.purge` cautiously because it is coarse-grained; it deletes memories visible to the current API token and can optionally narrow by `source_agent_id` and `before`, but not by individual memory ID
|
||||
- **Correction Policy**: For ordinary corrections, prefer storing the new source-of-truth fact instead of purging unless the user explicitly asks for cleanup or reset
|
||||
- **Source Tagging**: Every `openbrain.store` call MUST include `"source_agent"` in metadata, set to the Agent Instance ID defined in the active project's identity file (e.g., `"source_agent": "ingwaz-a0"`). This enables tracing facts back to the originating agent instance.
|
||||
```
|
||||
@@ -259,17 +261,22 @@ legacy SSE endpoints for older MCP clients that still use the deprecated
|
||||
2024-11-05 HTTP+SSE transport.
|
||||
|
||||
Header roles:
|
||||
- `X-Agent-ID` is the memory namespace. Keep this stable if multiple clients
|
||||
should share the same OpenBrain memories.
|
||||
- `X-Agent-Type` is an optional client profile label for logging and config
|
||||
clarity, such as `agent-zero` or `codex`.
|
||||
- If two clients use the same API token, they can read and write the same
|
||||
OpenBrain memories.
|
||||
- `X-Agent-ID` is an optional source-agent label for logs and store provenance.
|
||||
It does not control memory visibility.
|
||||
- `X-Agent-Type` is an optional client-program label such as `agent-zero`,
|
||||
`codex`, or `claude-code`. It does not select transport server-side; the URL
|
||||
path does that.
|
||||
- `agent_id` on `store` and `batch_store` is provenance. `source_agent_id` on
|
||||
`query` and `purge` is an optional provenance filter.
|
||||
|
||||
### Example: Codex Configuration
|
||||
|
||||
```toml
|
||||
[mcp_servers.openbrain]
|
||||
url = "https://memory.example.com/mcp"
|
||||
http_headers = { "X-API-Key" = "YOUR_OPENBRAIN_API_KEY", "X-Agent-ID" = "openbrain", "X-Agent-Type" = "codex" }
|
||||
http_headers = { "X-API-Key" = "YOUR_OPENBRAIN_API_KEY", "X-Agent-ID" = "codex-desktop", "X-Agent-Type" = "codex" }
|
||||
```
|
||||
|
||||
### Example: Agent Zero Configuration
|
||||
@@ -281,7 +288,7 @@ http_headers = { "X-API-Key" = "YOUR_OPENBRAIN_API_KEY", "X-Agent-ID" = "openbra
|
||||
"url": "https://memory.example.com/mcp/sse",
|
||||
"headers": {
|
||||
"X-API-Key": "YOUR_OPENBRAIN_API_KEY",
|
||||
"X-Agent-ID": "openbrain",
|
||||
"X-Agent-ID": "agent-zero",
|
||||
"X-Agent-Type": "agent-zero"
|
||||
}
|
||||
}
|
||||
@@ -290,7 +297,8 @@ http_headers = { "X-API-Key" = "YOUR_OPENBRAIN_API_KEY", "X-Agent-ID" = "openbra
|
||||
```
|
||||
|
||||
Agent Zero should keep using the legacy HTTP+SSE transport unless and until its
|
||||
client runtime supports streamable HTTP. Codex should use `/mcp`.
|
||||
client runtime supports streamable HTTP. Codex should use `/mcp`. If both
|
||||
clients use the same API token, they already share memory visibility.
|
||||
|
||||
### Example: Store a Memory
|
||||
|
||||
@@ -303,7 +311,7 @@ client runtime supports streamable HTTP. Codex should use `/mcp`.
|
||||
"name": "store",
|
||||
"arguments": {
|
||||
"content": "The user prefers dark mode and uses vim keybindings",
|
||||
"agent_id": "assistant-1",
|
||||
"agent_id": "agent-zero",
|
||||
"ttl": "7d",
|
||||
"metadata": {"source": "preferences"}
|
||||
}
|
||||
@@ -322,7 +330,6 @@ client runtime supports streamable HTTP. Codex should use `/mcp`.
|
||||
"name": "query",
|
||||
"arguments": {
|
||||
"query": "What are the user's editor preferences?",
|
||||
"agent_id": "assistant-1",
|
||||
"limit": 5,
|
||||
"threshold": 0.6
|
||||
}
|
||||
@@ -340,7 +347,7 @@ client runtime supports streamable HTTP. Codex should use `/mcp`.
|
||||
"params": {
|
||||
"name": "batch_store",
|
||||
"arguments": {
|
||||
"agent_id": "assistant-1",
|
||||
"agent_id": "codex",
|
||||
"entries": [
|
||||
{
|
||||
"content": "The user prefers dark mode",
|
||||
|
||||
Reference in New Issue
Block a user