extended-rlm
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@extended-rlmWhat have we recorded about project Phoenix?"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Extended RLM
extended-rlm is a self-learning knowledge layer for local LLM chat, built as a Model Context Protocol (MCP) server. It has two faces:
The engine (this repository): a Python MCP server that answers questions from plain Markdown files in a workspace, writes new knowledge back every turn, and stamps every answer with an explicit grounding verdict. Retrieval follows recursive language model (RLM) research (arXiv:2512.24601): cheap grep-like pre-filtering plus distillation by a small local "reader" model beats heavyweight RAG for project-scale corpora — no vector store on the default path.
A multi-agent knowledge stack: the same engine started N times, once per knowledge domain (a specialised knowledge agent, e.g.
extended-rlm-marketing,extended-rlm-lawyer), each with its own workspace/KB, all serving one LM Studio chat. The chat model routes each question to the agent whose domain matches — or answers directly when no domain matches.
Version: 0.2.0 (see CHANGELOG.md)
Licence: MIT
Transport: stdio (FastMCP) · Package:
src/extended_rlm/· Platform: Windows-first (PowerShell host scripts), engine itself is cross-platform Python 3.10+
Repository map (what precisely is inside)
extended-rlm\
├── src\extended_rlm\ the engine (Python package)
│ ├── server.py MCP server: 20 tools, agent identity/suffixing, bootstrap
│ ├── config.py layered config: defaults < config.yaml < env vars
│ ├── search.py ripgrep/grep search, keyword extraction/expansion, triggers
│ ├── chunker.py header-aware ~500-token chunking
│ ├── ranker.py TF-IDF-like ranking (INDEX 1.5x / trigger 2.0x boosts)
│ ├── reader_client.py OpenAI-compatible reader client, grounded distillation,
│ │ response cache, no-think prefill, session token counters
│ ├── kb_writer.py atomic topic/memory writes, INDEX maintenance, dedup,
│ │ supersedes, procedural-rule mirroring (F1)
│ ├── rules_digest.py [MAIN]-tagged rules -> MAIN-RULES.md digest (~1000-token cap)
│ ├── enforce.py action-time gates from topic frontmatter (F4)
│ ├── health.py KB drift diagnosis, claim verification, write log
│ ├── stats_log.py per-agent usage JSONL + stack-wide per-agent/TOTAL summary
│ ├── files.py workspace-scoped file tools + soft delete (.deleted\)
│ └── fileserver.py standalone localhost download server (one per agent)
├── scripts\
│ ├── start-chat.ps1 one-command stack launcher (agents, reader, LM Studio,
│ │ system-prompt pinning, stats markers)
│ ├── stop-chat.ps1 session token summary (chat vs readers, per agent) + shutdown
│ ├── new-agent.ps1 create + register a new knowledge agent (scaffolds workspace)
│ └── watch-chat-speed.ps1 live tok/s monitor
├── host\lmstudio\ LM Studio host integration
│ ├── system-prompt.md condition-neutral bootstrap prompt (routing mandate +
│ │ get_session_rules_* bootstrap order)
│ ├── enable-layer.ps1 register one agent in ~\.lmstudio\mcp.json (env wiring)
│ ├── disable-layer.ps1 remove all extended-rlm* entries (OFF condition)
│ ├── setup-filesystem.ps1 filesystem MCP server (present in both conditions)
│ ├── chat-model-load.config.json pinned chat-model load config (context/seed/KV cache)
│ └── README.md step-by-step Windows host setup
├── COMMON-RULES.md engine-wide behaviour rules served to EVERY agent's chat
│ session (routing, query-first, capture, stats duties)
├── extended-rlm.json stack config: chat model, reader backend, agent registry
├── docs\
│ ├── creating-a-new-agent.md agent lifecycle guide (scaffold -> seed -> verify)
│ ├── authoring-erlm-knowledge.md FULL spec for authoring a new agent's knowledge
│ │ data (for frontier-LLM KB generation)
│ ├── msc-experiment-environment.md experiment configuration record (pre-freeze)
│ ├── EVALUATION-RUN-GUIDE.md ON/OFF evaluation procedure
│ ├── GROUNDING_AND_HIERARCHY.md grounding-verdict contract
│ ├── RECONCILIATION-recorded-retrievable-enforced.md F1-F4 design note
│ ├── KNOWLEDGE_BASE_SETUP_GUIDE.md turning any workspace into a structured KB
│ └── WEBSITE_GUIDE.md optional docs website from the KB
├── tests\ 182 tests, no network / no live reader needed
├── examples\ RULES.example.md, .env.example
├── config.example.yaml per-workspace tuning template
└── start_server.bat single-server launcher (legacy/bare-engine mode)A knowledge workspace (one per agent) lives OUTSIDE this repo and contains only data:
AGENT.md (domain + routing lists), RULES.md (strict rules), PRINCIPLES.md (behaviour
principles), auto-generated MAIN-RULES.md (session digest), and .kb\ (INDEX.md, topics,
code_examples, memory). The complete authoring specification is
docs/authoring-erlm-knowledge.md.
Related MCP server: Inkstone
MCP tool surface (20 tools per agent)
In multi-agent mode every tool name gets the agent suffix (ask_knowledge_base_lawyer, …) and
its description is prefixed with [agent: <name> | domain: <domain>] — the routing signal.
Session bootstrap
Tool | Purpose |
| Binding session rules: the agent's |
Retrieval
Tool | Purpose |
| MANDATORY first step for any in-domain question: grounded answer with |
| KB structure (files, sizes, Tier-1 memory, reader status). |
| Clear the reader response cache. |
| Session token usage for ALL connected agents + TOTAL (computed from the shared stats dir — one call covers the whole stack). |
| Reset this agent's in-memory counters. |
Writing (self-learning)
Tool | Purpose |
| Atomic topic write + INDEX row, dedup, |
| Tier-1 behavioural memory ( |
| Append a strict rule (→ RULES.md) or behaviour principle (→ PRINCIPLES.md); |
Enforcement, health, accuracy
Tool | Purpose |
| Action-time gates from topic |
| KB drift: oversized topics, INDEX orphans/broken rows, dead links, staleness. |
| Live-ping the reader endpoint; concrete failure reason on error. |
| Confirm a cited file+snippet still exists (stale-KB detector). |
| Recent KB-related git activity. |
| KB writes since last digest + the stack-wide token block (end-of-turn summary). |
Workspace files
Tool | Purpose |
| Workspace-scoped file access; writes to RULES.md/PRINCIPLES.md auto-regenerate the MAIN digest. |
| Soft delete — moved to |
| Clickable localhost download link served by the per-agent fileserver. |
Architecture
LM Studio chat (one local model, e.g. Qwen3.5-9B)
│ system prompt (pinned into model defaults by start-chat.ps1):
│ bootstrap order + routing mandate
│
├── MCP: extended-rlm-marketing ──► workspace A (own RULES/PRINCIPLES/.kb)
├── MCP: extended-rlm-lawyer ──► workspace B │
├── MCP: <any further agents> ──► workspace ... │ all agents share
└── MCP: filesystem (workspace file access) ▼ ONE reader:
small local LLM (Ollama or the
LM Studio model itself) distills
top-ranked chunks into grounded,
cited answersPer query: keyword extraction/expansion → ripgrep across the knowledge tiers →
header-aware chunking (+ trigger-matched topics) → ranking (INDEX/trigger boosts) →
reader distillation → answer + Grounding: GROUNDED | PARTIAL | NOT-FOUND + token stats.
Session bootstrap & the [MAIN] rules digest
RULES.md(strict rules) andPRINCIPLES.md(behaviour principles) are canonical and unlimited; the agent updates them at runtime (record_rule, direct edits).Entries/sections tagged
[MAIN]are compiled — deterministically, no LLM — intoMAIN-RULES.md, hard-capped at ~1000 tokens. Only this digest (plusAGENT.mdandCOMMON-RULES.md) is loaded into chat sessions; everything untagged stays retrievable on demand. At ≥90% budget the engine demands consolidation: move a cohesive rule set into a KB guideline topic, leave a one-line[MAIN]summary + pointer.Routing failure modes are defended on three channels: the system prompt is pinned into the chat model's LM Studio defaults (every new chat gets it), the
ask_knowledge_basedescription itself declares the call mandatory for in-domain questions, and KB answers produced before the bootstrap carry a corrective banner.
Token accounting
Every reader call is appended to logs\reader-usage-<agent>.jsonl (shared stats dir, session
marker from start-chat.ps1). Any single agent's get_kb_session_stats therefore reports
every agent + TOTAL — one call per turn, no arithmetic for the chat model, robust to MCP
process restarts. stop-chat.ps1 prints the full session summary (chat model vs readers,
per agent, cache hits) from LM Studio engine logs + the JSONL files.
The grounding verdict contract
Verdict | Meaning | Calling model's action |
| Fully answered from the KB | Rely on it; do not re-derive |
| Some parts | Escalate only the missing parts: files, then cited web |
| Nothing relevant | Escalate whole question, then capture the result into the KB |
The self-learning loop (F1–F4): recorded, retrievable, enforced
# | Guarantee | Mechanism |
F1 | Procedural rules become retrievable | procedural |
F2 | Retrieval survives re-phrasing |
|
F3 | Recorded ⇒ confirmed retrievable | verify-on-write re-runs the real pipeline for a paraphrase; warns |
F4 | Action-time enforcement |
|
Quick start (multi-agent stack, Windows + LM Studio)
conda create -n GenAI_FA python=3.12; conda activate GenAI_FA
git clone <this-repository> extended-rlm; cd extended-rlm
pip install -e .[dev]
# 1. Declare agents in extended-rlm.json (or create one interactively):
.\scripts\new-agent.ps1 -Name finance -Domain "Corporate finance for ...: budgeting, cash-flow, ..."
# 2. Launch everything (mcp.json, workspaces, reader, LM Studio, system prompt):
.\scripts\start-chat.ps1
# 3. In LM Studio: enable the agents + 'filesystem' in the chat's Program panel. Chat.
# 4. End the session with the token summary:
.\scripts\stop-chat.ps1Single-workspace (bare engine, canonical tool names): start_server.bat --path C:\path\to\ws
or .\scripts\start-chat.ps1 -Workspace C:\path\to\ws.
Configuration
Resolution order: built-in defaults → workspace config.yaml
(template) → environment variables. Secrets only via environment.
Key environment variables (full list in src/extended_rlm/config.py):
Variable | Default | Purpose |
| cwd | Workspace root (equivalent to |
| unset | Agent identity; tool-name suffix + description tag (AGENT.md |
| unset | Path to the engine-wide COMMON-RULES.md served by |
| unset | Per-agent usage JSONL; its parent dir is the shared stack-stats dir |
| auto | Stable download-server port for this agent |
|
| Reader endpoint (any OpenAI-compatible |
|
|
|
| unset | Suppress Qwen3/3.5 reader thinking via assistant prefill (fast path) |
|
| Reasoning-reader headroom / HTTP timeout (s) |
|
|
|
|
| Verdict line behaviour |
|
| Tier-1 memory search |
|
| Action-time gates |
| unset | Explicit config YAML path |
Stack-level settings (chat model + pinned load config, reader backend ollama/lmstudio,
agent registry) live in extended-rlm.json and are applied by
start-chat.ps1.
Evaluation: the ON/OFF switch
Designed for a controlled experiment (MSc project): same base model, same workspaces, same
prompts and sampler settings; the single manipulated factor is the set of extended-rlm*
entries in mcp.json.
ON:
start-chat.ps1(default) registers the configured agents.OFF:
start-chat.ps1 -Condition OFFremoves them; the model runs stock (filesystem MCP stays in both conditions).The system prompt is condition-neutral and pinned into the model defaults; the pinned load config freezes context length, seed, and KV-cache quantisation.
Measures: task correctness, cross-session consistency, rule-following, factual accuracy, token cost (per-answer stats line,
get_kb_session_stats,stop-chat.ps1summary).Full procedure: docs/EVALUATION-RUN-GUIDE.md; environment record: docs/msc-experiment-environment.md.
Tests
pytest # 182 tests, no network, no live reader needed
ruff check src/Distillation, grounding, verify-on-write, enforcement, the [MAIN] digest, stats aggregation, bootstrap banner, and file tools are all exercised with fake clients and pure functions.
Security notes
Secrets (
READER_API_KEY) come from the environment only; never from config files.The engine writes only inside the knowledge tiers (
RULES.md,PRINCIPLES.md,.kb\, memory dir) and the workspace file tools are path-jailed to the workspace (soft delete only).The download fileserver binds to
127.0.0.1and serves only workspace files.
Licence
MIT, see LICENSE.
Credits
Recursive language model (RLM) research: arXiv:2512.24601
This server cannot be deployed
Maintenance
Related MCP Connectors
Personal wiki and memory layer for AI assistants. Persistent, structured memory across sessions.
Personal context for every AI: search, read, and write back to your private Markdown library.
- KumbukaOAuthai.kumbuka
Governed, auditable knowledge your team curates for its AI assistants, self-hostable
Self-hostable shared brain for you and your AI agents — docs, flows, meetings, decisions, rationale
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceA local knowledge base server that connects to AI assistants, turning markdown files into a semantically searchable memory layer via OpenAI embeddings and SQLite.10 npm1MIT
- AlicenseNot gradedqualityDmaintenanceAutomatically extracts and indexes knowledge from AI sessions and files using local LLMs, enabling semantic search and memory management.12 npmMIT
- FlicenseAqualityDmaintenanceEnables indexing local documents (PDF, Markdown, text, code) into a knowledge base and querying them via semantic search using local embeddings, all running privately on your machine.4-
- AlicenseNot gradedqualityAmaintenanceLocal-first memory and retrieval for private project knowledge. Enables indexing files, searching, and asking questions about project documents using local embeddings and LLM.6AGPL 3.0