MemoFSMemoFS
Self-Hosting

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

MethodPathDescription
GET/health, /Liveness health check. Returns {"ok":true,"name":"memofs-server","version":"0.1.0"}.
POST/, /rpcJSON-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 for POST)
  • Authorization: Bearer <token> (Required when requireAuth: 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 NameInput ParametersReturn ValueDescription
health{}MemoFSHealthResultLiveness and active capability probe (MemoFS.health).
recall{ query: string, limit?: number, filter?: RecallFilter }RecallResultHybrid semantic and lexical memory retrieval (MemoFS.recall).
contextMemoryContextInputMemoryContextResultProgressive-disclosure prompt briefing (MemoFS.context).
memory.readCore{}stringContent of .memofs/memory/core.md (MemoFS.core.read).
memory.readNotes{}stringContent of .memofs/memory/notes.md (MemoFS.notes.read).
memory.readConversations{ limit?: number }ConversationEntry[]Chronological conversation logs (MemoFS.conversations.read).
memory.listRecent{ limit?: number }RecentMemoryResultRecent memory write audit log (MemoFS.listRecentMemories).
memory.validate{ strict?: boolean }ValidateMemoryResultCanonical file and graph integrity check (MemoFS.validate).
graph.listNodesListGraphInput{ items: GraphNodeInput[], nextCursor?: string }Paginated entity nodes (MemoFS.graph.listNodes).
graph.listEdgesListGraphInput{ items: GraphEdgeInput[], nextCursor?: string }Paginated relationship edges (MemoFS.graph.listEdges).
graph.neighborsGraphNeighborsInputGraphNeighborsResult1-hop connected graph neighborhood (MemoFS.graph.neighbors).
graph.pathGraphPathInputGraphPathResultShortest 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 NameInput ParametersReturn ValueDescription
memory.writeWriteMemoryInputWriteMemoryResultWrites a classified, durable memory (MemoFS.writeMemory).
memory.recordNoteTimestampedNoteInputWriteMemoryResultAppends a timestamped entry to notes (MemoFS.notes.record).
memory.updateCore{ content: string }voidOverwrites core memory rules (MemoFS.core.update).
memory.appendConversationConversationEntryvoidAppends 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).
consolidateConsolidateMemoryInputConsolidateMemoryResultMerges duplicates and supersedes facts (MemoFS.consolidate).
snapshots.createSnapshotMemoryInputSnapshotMemoryResultCreates an immutable checkpoint (MemoFS.snapshots.create).
snapshots.restore{ id: string }voidRestores 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.

On this page