Skip to main content

Module http

Module http 

Source
Expand description

HTTP/JSON transport for Solo. Local-only by default — binds to 127.0.0.1:<port> and serves the same operations the MCP server exposes:

Episode operations:

  • POST /memory — remember (body: { content, source_type?, source_id? })
  • POST /memory/search — recall (body: { query, limit? })
  • GET /memory/{id} — inspect
  • DELETE /memory/{id}?reason=… — forget

Maintenance:

  • POST /memory/consolidate — trigger a consolidation pass
  • POST /backup — encrypted online backup

Derived-layer (v0.4.0+; queries against the Steward’s outputs):

  • GET /memory/themes?window_days=N&limit=K
  • GET /memory/facts_about?subject=X&predicate=Y&since_ms=N&until_ms=N&include_as_object=B&limit=K
  • GET /memory/contradictions?limit=K
  • GET /memory/clusters/{cluster_id}?full_content=true (v0.5.0+)

Document operations (v0.7.0+):

  • POST /memory/documents — ingest a file
  • POST /memory/documents/search — vector search over chunks
  • GET /memory/documents — paginate documents
  • GET /memory/documents/{id} — inspect one document
  • DELETE /memory/documents/{id} — soft-delete a document

There’s no auth at this layer. The threat model is local-machine single-user; binding to 127.0.0.1 keeps the surface off the LAN. A future commit can add bearer-token auth + LAN binding.

§Lifecycle

serve_http(addr, server, shutdown) binds to addr, runs axum with with_graceful_shutdown(shutdown), returns when shutdown fires or the listener errors. solo http-serve invokes this from inside a OneShotContext, so writer + reader pool + lockfile stay live for the server’s lifetime and clean up properly afterwards.

Structs§

ApiError
AuditPrincipal
v0.8.0 P4: extractor that pulls the authenticated principal’s subject (JWT sub or "bearer") out of request extensions for the audit log. None when no AuthenticatedPrincipal is present (unauthenticated loopback deployments).
MaybePrincipal
v0.10.0: extractor that lifts the full AuthenticatedPrincipal out of request extensions for the /v1/tenants handler. Distinct from AuditPrincipal (which only carries subject: Option<String>) — the tenant-list handler needs the tenant_claim and claims fields to distinguish bearer (claims = Null) from OIDC (claims = JWT object) principals.
SoloHttpState
HTTP-side application state. v0.8.0 P2 swapped per-handler `WriteHandle
TenantExtractor
Axum extractor that resolves the request’s target tenant, then lazy-opens the tenant via the registry.

Constants§

MCP_STREAM_EVENT_INIT
Initial event name emitted by GET /mcp when an SSE client connects. Used by browser-based MCP clients (e.g. the AI SDK’s experimental_createMCPClient with the SSE transport) to confirm the stream is live before they begin polling for server-initiated notifications. v0.10.2 keeps the stream idle after this event — server-initiated notifications come in v0.10.3+.
STREAM_HEARTBEAT_SECS
Heartbeat interval for /v1/graph/stream. Fires unconditionally every 30 seconds — easier to reason about than “fire 30s after the last event”, and keeps proxies happy without code that races a reset on every invalidate.
TENANT_HEADER
HTTP header that routes a request to a specific tenant. Optional; absent → state.default_tenant.

Functions§

openapi_spec
Build the OpenAPI 3.1 spec describing Solo’s HTTP transport. Public so the smoke test + future client-codegen tooling can produce the same document without spinning up the server.
router
Convenience wrapper: no auth (loopback-only deployments).
router_with_auth
Build the router with optional bearer-token auth (v0.7.x legacy shape).
router_with_auth_config
Build the router with a config-driven auth block (v0.8.0 P3+).
serve_http
Bind + serve (v0.7.x legacy shape). shutdown is awaited inside axum’s with_graceful_shutdown; resolving it triggers a clean drain. bearer_token = None runs unauthenticated (loopback default); Some(t) requires Authorization: Bearer t on every request except GET /health + GET /openapi.json.
serve_http_with_auth_config
Bind + serve with a config-driven auth block (v0.8.0 P3+). auth = None runs unauthenticated. See router_with_auth_config for the auth-mode semantics.