Skip to content

ha1tch/molu

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 

Repository files navigation

molu — Design Draft 01

Version: draft-01
Status: pre-implementation
Author: haitch
Date: 2026-06-11
Repository: github.com/ha1tch/molu


What molu is

molu is an MCP sidecar for xolu. It connects to a running xolu instance, reads its live schema, and exposes the operational model of that xolu instance as MCP tools that an AI agent can use to perform business operations in natural language.

Related projects

xolu (github.com/ha1tch/xolu) is the storage engine molu drives. It provides a multi-model embedded database — documents, graph, timeseries, blobs, FSMs, events, sequences — accessible over a REST API. xolu is the system of record. molu never stores anything; all persistent state lives in xolu.

nolu (github.com/ha1tch/nolu) is the distributed coordination layer for xolu. It manages multi-instance topology, replication, and load balancing across a partially-known network of xolu nodes. molu connects to a single xolu instance; in a nolu-coordinated deployment, nolu decides which xolu instance molu talks to.

MCP (Model Context Protocol, modelcontextprotocol.io) is the open protocol that defines how AI models communicate with external tools and data sources. MCP standardises the tool call and resource access patterns that Claude and other models use to interact with the world. molu implements the MCP server role using the official Go SDK (github.com/modelcontextprotocol/go-sdk), making xolu's operational model available to any MCP-compatible agent.

The three projects form a stack:

AI agent  ←→  MCP  ←→  molu  ←→  xolu  ←→  nolu (optional)
                    understand   store    coordinate
                    and act

molu is the layer that understands what the data means and knows how to act on it. xolu stores it. nolu coordinates it across nodes.

Claude / AI agent
      │  MCP protocol (stdio or SSE)
      ▼
    molu
      │  HTTP (xolu REST API)
      ▼
    xolu
      │
      ▼
  SQLite + graph + timeseries + blobs + FSMs

molu is stateless. All persistent state lives in xolu. molu holds no database, no knowledge base, no vector index. Its operational knowledge is derived entirely from the live xolu instance it is connected to.


What makes this post-RAG

Traditional RAG: corpus → chunk → embed → rank → inject → generate. The corpus is static or slow-moving. The retrieval is read-only. The agent consumes knowledge.

molu is different on every axis:

  • No corpus. The xolu schema is a live executable specification, not a document collection. Entity types, REF relationships, FSM definitions, sequences, event subscriptions — these describe exactly what exists and exactly what can happen to it.

  • No chunking or ranking. The schema is complete and precise. molu reads it in full at startup and refreshes it on change. There is no relevance ranking problem because the schema is structured, not unstructured.

  • Read-write. molu executes writes, commits, FSM walks, sequence increments. "Prepare a new invoice for John Doe" causes real mutations with real consequences.

  • Live ETL. molu translates natural language intent into structured xolu operations in real time. The schema changing is immediately reflected in molu's behaviour.

  • Agentic. A single natural language request may require multi-step planning: entity lookup, REF resolution, FSM state assessment, commit construction, result verification. molu plans and executes that sequence autonomously.

The grounding that makes this reliable is structural: xolu's schema is formal and machine-readable. molu doesn't infer the operational model from documentation — it reads it directly from the running system.


Architecture

Components

molu/
├── cmd/molu/           — entry point, config, startup
├── pkg/xolu/           — xolu HTTP client (typed, generated from xolu API)
├── pkg/schema/         — live schema reader and semantic map builder
├── pkg/planner/        — natural language → operation plan
├── pkg/executor/       — operation plan → xolu API calls
├── pkg/mcp/            — MCP server (tools, resources, prompts)
└── pkg/config/         — configuration

Startup sequence

  1. Connect to xolu instance (OLU_URL, OLU_API_KEY)
  2. Read all registered schemas from GET /api/v1/schemas
  3. Read FSM definitions from GET /api/v2/fsm/def
  4. Read sequences from GET /api/v2/gen/seq
  5. Read event subscriptions from GET /api/v2/event
  6. Build semantic map (entity types, field names, REF graph, FSM topology, generator names)
  7. Register MCP tools derived from the semantic map
  8. Begin serving MCP connections

Schema refresh

molu subscribes to xolu's entity.updated and schema-change events via /api/v2/event to receive push notifications when the schema changes. On notification, it re-reads the affected schema and rebuilds the relevant parts of the semantic map. MCP tool definitions are updated without requiring a restart.

If xolu's event system is not yet available (pre-v2), molu falls back to polling GET /api/v1/schemas on a configurable interval (MOLU_SCHEMA_POLL_INTERVAL, default 30s).


The semantic map

The semantic map is molu's internal representation of the xolu instance it is connected to. It is built from the live schema and held in memory.

type SemanticMap struct {
    // Entity types indexed by name and by likely natural language aliases
    Entities    map[string]*EntityDef

    // REF graph: which entities reference which
    RefGraph    *RefGraph

    // FSM definitions by entity type
    Machines    map[string][]*MachineDef

    // Generator definitions
    Generators  map[string]*GeneratorDef

    // Event subscriptions
    Events      map[string]*EventDef

    // Tenant context
    Tenant      string
}

type EntityDef struct {
    Name       string
    Schema     map[string]interface{}   // raw JSON Schema
    Fields     []*FieldDef
    REFFields  []*REFFieldDef           // fields with format:ref
    FSMs       []*MachineDef            // machines bound to this type
    Sequences  []*GeneratorDef          // sequences used by this type
}

The semantic map enables:

  • Entity resolution: "customer" → customer entity type
  • Field resolution: "name" → name field, "date" → invoice_date
  • REF resolution: "for customer John Doe" → lookup customer where name = "John Doe", return {"type":"REF","entity":"customer","id":42}
  • FSM resolution: "prepare" → FSM initial state or draft input, "approve" → approved transition input
  • Generator resolution: "invoice number" → invoice_number sequence

MCP tool surface

molu exposes a small set of high-level tools rather than a thin mechanical mapping of every xolu endpoint. The tools are shaped for agent use — they accept intent, not API parameters.

Core tools

find Find entities matching a natural language description.

{
  "name": "find",
  "description": "Find entities in xolu matching a description",
  "inputSchema": {
    "query": "string — natural language description of what to find",
    "entity_type": "string? — optional hint for entity type",
    "limit": "integer? — max results, default 10"
  }
}

Example: find("customer named John Doe") → resolves to GET /api/v1/customer?name=John+Doe or an OQL query.

get Retrieve a specific entity by type and ID.

{
  "name": "get",
  "description": "Retrieve a specific entity",
  "inputSchema": {
    "entity_type": "string",
    "id": "integer"
  }
}

create Create a new entity, optionally with an FSM machine.

{
  "name": "create",
  "description": "Create a new entity in xolu",
  "inputSchema": {
    "entity_type": "string",
    "data": "object — field values for the new entity",
    "start_machine": "string? — FSM definition name to bind"
  }
}

update Update an existing entity.

{
  "name": "update",
  "description": "Update an existing entity",
  "inputSchema": {
    "entity_type": "string",
    "id": "integer",
    "changes": "object — fields to update",
    "version": "integer? — for optimistic concurrency"
  }
}

perform The primary agentic tool. Accepts a natural language description of a business operation and executes it. molu plans and executes the full sequence of xolu calls required.

{
  "name": "perform",
  "description": "Perform a business operation described in natural language",
  "inputSchema": {
    "instruction": "string — natural language description of what to do",
    "context": "object? — additional context (current entity, tenant, etc.)"
  }
}

Example: perform("prepare a new invoice for customer John Doe")

molu's planner:

  1. Identifies intent: create invoice
  2. Identifies subject: customer John Doe → calls find("John Doe", "customer")
  3. Determines initial state: invoice FSM has initial state draft
  4. Determines sequence: invoice_number sequence exists
  5. Constructs commit payload: new invoice entity + FSM machine creation
  6. Executes: POST /api/v1/commit with entity data and machine binding
  7. Returns: created invoice with ID, invoice number, and initial FSM state

walk Advance an FSM machine by input name or natural language description of the desired transition.

{
  "name": "walk",
  "description": "Advance an entity's state machine",
  "inputSchema": {
    "entity_type": "string",
    "id": "integer",
    "transition": "string — input name or natural language description",
    "payload": "object? — transition payload"
  }
}

query Execute an OQL or Sulpher query directly for cases where natural language grounding is insufficient.

{
  "name": "query",
  "description": "Execute an OQL or Sulpher query against xolu",
  "inputSchema": {
    "language": "oql | sulpher",
    "query": "string"
  }
}

describe Return molu's current understanding of the xolu schema — useful for the agent to orient itself before performing complex operations.

{
  "name": "describe",
  "description": "Describe the xolu schema: entity types, relationships, FSMs",
  "inputSchema": {
    "entity_type": "string? — describe a specific type, or all if omitted"
  }
}

MCP resources

molu exposes the semantic map as MCP resources, allowing the agent to read the schema directly:

molu://schema                  — all entity types
molu://schema/{entity_type}    — specific entity type schema
molu://fsm/{definition_id}     — FSM definition
molu://fsm/machine/{id}        — machine state and history
molu://gen                     — all generators

The planner

The planner is the core of molu. It takes a natural language instruction and the semantic map and produces an OperationPlan — a sequence of xolu API calls that realises the intent.

type OperationPlan struct {
    Steps    []OperationStep
    Atomic   bool            // if true, wrap in /commit
    Explain  string          // human-readable plan summary
}

type OperationStep struct {
    Kind     StepKind        // Lookup, Create, Update, Walk, Query, Generate
    Entity   string
    ID       int64
    Data     map[string]interface{}
    FSMInput string
    Payload  map[string]interface{}
    DependsOn []int          // step indices this step depends on
}

The planner uses the semantic map for grounding and Claude (via the Anthropic API) for natural language understanding. The planning call is a structured output request: given the instruction, the semantic map summary, and the available operation types, produce a JSON plan.

This is the component where molu is most agentic: the planner may make intermediate tool calls (e.g. looking up John Doe's customer ID before constructing the invoice creation step) before producing the final plan.

Planning strategy

Simple single-entity operations (create, update, find) are planned without an LLM call using pattern matching against the semantic map. This keeps latency low for common cases.

Complex multi-step operations (involving REF resolution, FSM walks, atomic commits, sequence assignment) use a structured LLM call with the semantic map as context.

The planner never executes speculatively. It produces a plan, presents it to the executor, and the executor performs the actual xolu API calls. Plan and execution are cleanly separated.


The executor

The executor takes an OperationPlan and executes it against xolu. It handles:

  • Step ordering based on DependsOn relationships
  • Result propagation (John Doe's ID from the lookup step feeds into the REF field of the create step)
  • Atomic commit construction when plan.Atomic is true
  • Error handling and partial failure reporting
  • Response normalisation for MCP return values
type Executor struct {
    client  *xolu.Client
    smap    *SemanticMap
    logger  zerolog.Logger
}

func (e *Executor) Execute(ctx context.Context, plan *OperationPlan) (*ExecutionResult, error)

Configuration

# Required
MOLU_XOLU_URL=http://localhost:7070     # xolu instance URL
MOLU_XOLU_API_KEY=                      # xolu API key (if auth enabled)
MOLU_XOLU_TENANT=                       # default tenant (empty = tenant 0)

# MCP transport
MOLU_TRANSPORT=stdio                    # stdio | sse
MOLU_SSE_ADDR=:8090                     # for sse transport

# Planner
MOLU_ANTHROPIC_API_KEY=                 # for LLM-backed planning
MOLU_PLANNER_MODEL=claude-sonnet-4-6    # model for planning calls
MOLU_PLANNER_SIMPLE_THRESHOLD=1        # steps below this use pattern matching

# Schema
MOLU_SCHEMA_POLL_INTERVAL=30s          # fallback polling if events unavailable
MOLU_SCHEMA_CACHE_TTL=5m               # how long to cache schema reads

# Observability
MOLU_LOG_LEVEL=info
MOLU_LOG_FORMAT=console                # console | json

Module

module github.com/ha1tch/molu

go 1.22

require (
    github.com/modelcontextprotocol/go-sdk  v1.6.1
    github.com/rs/zerolog                   v1.x
    github.com/ha1tch/xolu                  v0.9.8  // HTTP client only
)

molu imports xolu only for the HTTP client types — it does not embed xolu's storage layer. The dependency is on the API contract, not the implementation.


Non-goals for draft-01

  • molu does not generate or run code
  • molu does not have its own storage
  • molu does not implement authentication (delegates to xolu)
  • molu does not support multiple simultaneous xolu instances (one molu ↔ one xolu)
  • molu does not cache entity data (always reads through to xolu)
  • molu does not implement the /api/v2 FSM or event endpoints until xolu implements them

Open questions

  1. Planner grounding quality. How well does the semantic map ground natural language requests against arbitrary xolu schemas? This needs empirical testing with real schemas before the planner design can be finalised.

  2. Ambiguity handling. "Prepare a new invoice for John Doe" is unambiguous if exactly one customer named John Doe exists. If zero or multiple exist, molu must ask for clarification. The tool response format for disambiguation requests needs design.

  3. Tenant awareness. Multi-tenant xolu instances require molu to know which tenant to operate in. Should tenant be a per-connection config, a per-request parameter, or derived from the agent's identity?

  4. Write safety. Should molu require explicit confirmation for destructive operations (delete, FSM terminal state)? Or trust the agent to confirm before calling? The answer affects the tool design significantly.

  5. Schema coverage. xolu /api/v2 endpoints (FSM, event, gen, meta) are not implemented yet. molu's design accounts for them but the initial implementation targets /api/v1 only.


Draft 01. Pre-implementation. Subject to revision as xolu v1.0 approaches and the /api/v2 subsystems are built.

About

MCP sidecar for xolu, allows MCP-enabled agents to drive a xolu operational database server and the domains it describes after learning from its schema

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors