Skip to main content

Ingestion

The public ingestion API is CaptureMemory. It accepts arbitrary JSON-compatible content, stores a typed primary MemoryRecord, and can create linked entity or semantic records when interpretation is enabled.

CaptureMemory replaces the older one-method-per-shape API at the daemon boundary. Use source_kind to describe whether the content is an event, tool output, observation, working state, or agent turn.


CaptureMemory

rpc CaptureMemory(CaptureMemoryRequest) returns (CaptureMemoryResponse);

Captures a memory candidate for interpretation, validation, storage, and graph linking. The server always returns the primary record that was stored. When entity resolution or relation extraction creates additional records or edges, those are returned in the same response.

Request fields

sourcestring

Actor, service, or system that produced the content. SDKs default this to the client name when omitted.

source_kindstring

Shape of the captured content. Common values are event, tool_output, observation, working_state, and agent_turn.

contentgoogle.protobuf.Valuerequired

Arbitrary JSON-compatible content to capture. This is the raw evidence Membrane interprets and stores.

contextgoogle.protobuf.Value

Optional JSON-compatible execution context, such as agent ID, session ID, thread ID, or project metadata.

reason_to_rememberstring

Human-readable reason this content should be retained. This helps LLM-backed interpretation choose durable facts and entities.

proposed_typestring

Optional requested memory type: episodic, working, semantic, competence, plan_graph, or entity. When omitted, Membrane infers the primary type from source_kind and content.

summarystring

Short summary for the primary record and interpretation metadata.

tagsstring[]

Free-form labels for filtering, observability, and prompt projection.

scopestring

Visibility scope. Scoped records are returned only to trust contexts that include the same scope. Unscoped records are visible to all allowed callers.

sensitivitystring

Sensitivity classification: public, low, medium, high, or hyper. SDKs default to low.

timestampstring

RFC 3339 timestamp. SDKs default to the current UTC time.

Response fields

primary_recordMemoryRecord

The primary typed memory record created from the capture request.

created_recordsMemoryRecord[]

Additional records created during interpretation and resolution, usually entity records.

edgesGraphEdge[]

Graph edges materialized during capture, such as mentions_entity, mentioned_in, references_record, and referenced_by.


Examples

capture, err := m.CaptureMemory(ctx, ingestion.CaptureMemoryRequest{
Source: "build-agent",
SourceKind: "tool_output",
Content: map[string]any{
"tool": "go test",
"args": []string{"./..."},
"result": "auth package passed",
},
Context: map[string]any{"thread_id": "session-001"},
ReasonToRemember: "Keep successful test context for future auth work",
Summary: "Auth package tests passed",
Tags: []string{"auth", "tests"},
Scope: "project-auth",
Sensitivity: schema.SensitivityLow,
})
if err != nil {
log.Fatal(err)
}
fmt.Println(capture.PrimaryRecord.ID)
import { MembraneClient, Sensitivity, SourceKind } from "@bennettschwartz/membrane";

const client = new MembraneClient("localhost:9090", { apiKey: "your-key" });

const capture = await client.captureMemory(
{
tool: "go test",
args: ["./..."],
result: "auth package passed",
},
{
source: "build-agent",
sourceKind: SourceKind.TOOL_OUTPUT,
context: { thread_id: "session-001" },
reasonToRemember: "Keep successful test context for future auth work",
summary: "Auth package tests passed",
tags: ["auth", "tests"],
scope: "project-auth",
sensitivity: Sensitivity.LOW,
}
);

console.log(capture.primary_record.id);
from membrane import MembraneClient, Sensitivity, SourceKind

client = MembraneClient("localhost:9090", api_key="your-key")

capture = client.capture_memory(
{
"tool": "go test",
"args": ["./..."],
"result": "auth package passed",
},
source="build-agent",
source_kind=SourceKind.TOOL_OUTPUT,
context={"thread_id": "session-001"},
reason_to_remember="Keep successful test context for future auth work",
summary="Auth package tests passed",
tags=["auth", "tests"],
scope="project-auth",
sensitivity=Sensitivity.LOW,
)

print(capture.primary_record.id)

Content Shapes

content is intentionally flexible. These conventions give the interpreter enough structure to produce useful typed records and graph links.

Event

{
"ref": "thread-7:turn-12",
"event_kind": "agent_reply",
"text": "Explained the auth retry strategy"
}

Use source_kind: "event" for discrete occurrences, user messages, agent replies, errors, or status changes.

Tool Output

{
"tool_name": "go test",
"args": { "packages": ["./pkg/..."] },
"result": { "exit_code": 0, "stdout": "ok ./pkg/auth" }
}

Use source_kind: "tool_output" for tool invocations. Membrane stores the tool details in the episodic payload and can later consolidate repeated successful patterns into competence records or plan graphs.

Observation

{
"subject": "user",
"predicate": "prefers_language",
"object": "Go"
}

Use source_kind: "observation" for subject-predicate-object facts. These usually become semantic records, with entity links when subjects or objects resolve to known entities.

Working State

{
"thread_id": "session-001",
"state": "executing",
"next_actions": ["run tests", "review output"],
"context_summary": "Refactoring auth middleware"
}

Use source_kind: "working_state" for resumable task state.


Entity And Graph Linking

When interpretation is configured, Membrane can extract mentions, resolve them to existing entity records, create new entity records, and write graph edges. Entity records use the entity memory type and the EntityPayload shape:

{
"kind": "entity",
"canonical_name": "auth middleware",
"primary_type": "Service",
"types": ["Service", "Concept"],
"aliases": [{ "value": "auth layer", "kind": "nickname" }],
"identifiers": [{ "namespace": "repo_path", "value": "pkg/auth" }],
"summary": "Authentication middleware used by the API service"
}

Capture responses include both the created entity records and the edges connecting them to the primary record.