HTTP API (JSON-RPC 2.0)
JSON-RPC 2.0 protocol specifications, endpoint routing, live vs gated methods, and error formats for @memofs/server.
@memofs/server exposes a standard JSON-RPC 2.0 interface over HTTP. Both deployment targets (Node.js and Cloudflare Workers) implement the exact same routing, method registry, and response structures.
Endpoints & Routing
| Method | Path | Description |
|---|---|---|
GET | /health, / | Liveness health check. Returns {"ok":true,"name":"memofs-server","version":"0.1.0"}. |
POST | /, /rpc | JSON-RPC 2.0 request dispatcher. Supports single requests and batch request arrays. |
OPTIONS | * | CORS preflight handler. Active when allowedOrigins is configured. |
Request Headers
Content-Type: application/json(Required forPOST)Authorization: Bearer <token>(Required whenrequireAuth: true)x-project-id: <projectId>(Optional project scoping header when resolved by proxy)
JSON-RPC Request Format
Every POST request must supply a JSON-RPC 2.0 object:
{
"jsonrpc": "2.0",
"id": 1,
"method": "recall",
"params": {
"query": "how is authentication configured?",
"limit": 3
}
}Successful Response Format
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"items": [
{
"id": "chunk_auth_1",
"text": "Tokens are verified in src/auth/verify.ts using RSA256.",
"score": 0.92
}
]
}
}Error Response Format
{
"jsonrpc": "2.0",
"id": 1,
"error": {
"code": -32601,
"message": "Method not found"
}
}Complete Method Catalog
1. Live (Read-Only) Methods
Read-only methods are always enabled and execute concurrently without locking:
| Method Name | Input Parameters | Return Value | Description |
|---|---|---|---|
health | {} | MemoFSHealthResult | Liveness and active capability probe (MemoFS.health). |
recall | { query: string, limit?: number, filter?: RecallFilter } | RecallResult | Hybrid semantic and lexical memory retrieval (MemoFS.recall). |
context | MemoryContextInput | MemoryContextResult | Progressive-disclosure prompt briefing (MemoFS.context). |
memory.readCore | {} | string | Content of .memofs/memory/core.md (MemoFS.core.read). |
memory.readNotes | {} | string | Content of .memofs/memory/notes.md (MemoFS.notes.read). |
memory.readConversations | { limit?: number } | ConversationEntry[] | Chronological conversation logs (MemoFS.conversations.read). |
memory.listRecent | { limit?: number } | RecentMemoryResult | Recent memory write audit log (MemoFS.listRecentMemories). |
memory.validate | { strict?: boolean } | ValidateMemoryResult | Canonical file and graph integrity check (MemoFS.validate). |
graph.listNodes | ListGraphInput | { items: GraphNodeInput[], nextCursor?: string } | Paginated entity nodes (MemoFS.graph.listNodes). |
graph.listEdges | ListGraphInput | { items: GraphEdgeInput[], nextCursor?: string } | Paginated relationship edges (MemoFS.graph.listEdges). |
graph.neighbors | GraphNeighborsInput | GraphNeighborsResult | 1-hop connected graph neighborhood (MemoFS.graph.neighbors). |
graph.path | GraphPathInput | GraphPathResult | Shortest path between two entities (MemoFS.graph.path). |
snapshots.list | {} | SnapshotRecord[] | List available checkpoint snapshots (MemoFS.snapshots.list). |
2. Gated (Mutating) Methods
Mutating methods alter memory files. To prevent race conditions, they are gated on the Concurrency Layer:
| Method Name | Input Parameters | Return Value | Description |
|---|---|---|---|
memory.write | WriteMemoryInput | WriteMemoryResult | Writes a classified, durable memory (MemoFS.writeMemory). |
memory.recordNote | TimestampedNoteInput | WriteMemoryResult | Appends a timestamped entry to notes (MemoFS.notes.record). |
memory.updateCore | { content: string } | void | Overwrites core memory rules (MemoFS.core.update). |
memory.appendConversation | ConversationEntry | void | Appends a conversation turn (MemoFS.conversations.append). |
graph.upsertNodes | { nodes: GraphNodeInput[] } | { nodes: GraphNodeInput[] } | Upserts knowledge graph entities (MemoFS.graph.upsertNodes). |
graph.upsertEdges | { edges: GraphEdgeInput[] } | { edges: GraphEdgeInput[] } | Upserts knowledge graph relationships (MemoFS.graph.upsertEdges). |
consolidate | ConsolidateMemoryInput | ConsolidateMemoryResult | Merges duplicates and supersedes facts (MemoFS.consolidate). |
snapshots.create | SnapshotMemoryInput | SnapshotMemoryResult | Creates an immutable checkpoint (MemoFS.snapshots.create). |
snapshots.restore | { id: string } | void | Restores memory state from checkpoint (MemoFS.snapshots.restore). |
The Concurrency Write Gate
When a mutating method is called without an injected concurrency layer, the dispatcher immediately returns HTTP status 503 Service Unavailable with JSON-RPC error code -32000:
{
"jsonrpc": "2.0",
"id": 1,
"error": {
"code": -32000,
"message": "Concurrent writes require the concurrency layer. This method is read-only until it is injected.",
"data": {
"httpStatus": 503,
"reason": "concurrency_layer_required"
}
}
}Enabling Mutating Writes
To enable writes in your server deployment, provide a concurrencyLayer with an acquire implementation:
import { handleRuntimeRequest } from "@memofs/server";
const response = await handleRuntimeRequest(request, {
runtime: memofs,
concurrencyLayer: {
// Serializes concurrent calls for the same project
acquire: async (projectId, task) => {
return await myDistributedMutex.run(projectId, task);
},
},
});When injected, the dispatcher executes mutating handlers inside acquire, guaranteeing that concurrent operations on the same project are serialized and safe.