Skip to content

RootMind 2.5.0

Choose a tag to compare

@github-actions github-actions released this 25 Oct 11:20
· 20 commits to main since this release
035145c

Added

  • Command line for the running service (#35): rootmind status, folders list|add|remove, index [--full] [--folder N] [--wait], search, ask, config llm, mcp tokens list and remote-access on|off|status, each with --json, in the rootmind command and in the backend executable (rootmind-backend). They find the service of the account like the app does (service status, then a check that the service's own process listens on the port), read the REST token from its protected file and say clearly when the account cannot read it. API keys and the ngrok authtoken come from a file or stdin, never from an argument, and no secret is printed, not even masked. --url and --token-file (or RLM_URL and RLM_TOKEN_FILE) point the commands at another REST API; plain http:// only to loopback. The README has a new "Command line" section.
  • Named MCP tokens with a folder scope (#35): rootmind mcp tokens create <name> [--folders a,b] --out FILE, list and revoke (and GET/POST/DELETE /mcp/tokens). The token is shown once (written to a new file, mode 0600 on Linux) and stored only as its SHA-256 in config.yaml; its folders limit what its searches, reads, listings and statistics see. A new or revoked token takes effect with the next request, without a restart. The existing data/api_token.txt is the token named default, so existing clients keep working.
  • Serving MCP to other machines: mcp_http.network in config.yaml makes the service's MCP process also listen on another address, with TLS (tls_cert, tls_key), on a loopback port for a reverse proxy, or with plain HTTP only when insecure_http: true. It requires mcp_http.allowed_hosts (checked against the Host header) and accepts only named tokens unless allow_default_token is set; the loopback listener is unchanged. mcp_http.allowed_origins extends the Origin allowlist. New guide docs/SERVER.md ("Run RootMind on a server": a dedicated account with lingering, folders, tokens, TLS or Caddy/nginx, clients) and a threat model for server use in SECURITY.md.
  • rescan_minutes per folder (rootmind folders add --rescan-minutes N) re-scans that folder every N minutes, for mounted network shares where changes made on other machines raise no event.
  • Optional tracing of the question loop (#48, part 1), off by default. One span per model call (purpose, tokens, stop reason, tool requests, duration) and per tool call (arguments, result size, the documents a search returned, the window a read returned). scripts/run_evals.py --trace <folder> writes a JSONL file and a readable Markdown summary per eval run, and each run in the results carries its trace_id. tracing.local: true in config.yaml writes the same files under logs/traces/ in the data folder. tracing.langfuse: true (or run_evals.py --langfuse) exports to Langfuse with the new optional extra rootmind-backend[tracing] and the LANGFUSE_* environment variables. With tracing off, the loop makes no tracing calls and loads no tracing code. Traces contain questions and document text but never API keys; SECURITY.md lists what they hold and where they go.
  • Each release now updates RootMind's entry in the official MCP Registry (io.github.cgaeking/rootmind, the rootmind.mcpb bundle) automatically (#49). A new job at the end of release.yml renders server.json from the template packaging/mcpb/server.json with the version, the release's download URL and the SHA-256 of the published rootmind.mcpb (scripts/registry_server_json.py, checked against SHA256SUMS.txt), validates it against the vendored schema and with mcp-publisher validate, and publishes it with a pinned, checksum-verified mcp-publisher through GitHub OIDC (no stored secret). Prereleases are not published; dry runs render and validate only. A registry failure leaves the GitHub release as it is and can be re-run. scripts/check_versions.py also checks the template's name, schema and placeholders.
  • Evals: a LangGraph baseline (#48, part 2). scripts/run_evals.py --agent langgraph runs the 16 cases with RootMind's tools (same executors, so identical tool results), the same system prompt, model endpoint and scoring in LangChain's stock agent (langchain.agents.create_agent, LangGraph). It lives in backend/evals/baselines/langgraph/ with its own exactly pinned environment (langchain 1.4.7, langgraph 1.2.17, langchain-openai 1.7.2); the backend and its lock file do not depend on LangChain. --compare A.json B.json prints two live results side by side. Measured with granite4.1:8b through Ollama, 3 runs per case: both agents 98%, 15 of 16 cases every run, about the same tool calls, tokens and latency; table and caveats in backend/evals/README.md. Hosted models were not compared.
  • examples/langchain_mcp/: RootMind's MCP server as tools in a LangChain agent through langchain-mcp-adapters, with an offline test against the real stdio server.

Changed

  • rootmind mcp-http --host with an address other than loopback now needs --tls-cert and --tls-key, or --insecure-http for plain HTTP.
  • The get_statistics tool counts only the documents of the folders the request may see.
  • rootmind index now asks the running service to index. It still indexes in its own process with the new --local, with a global --config, when RLM_HOME is set, or when the account has no RootMind service; --connector is now also spelled --folder, and --json prints the result.

Fixed

  • Sources of an answer that names a search hit by its document id instead of its file name: the answer now cites that document, not every document the search returned (#47).
  • Evals: the live checks failed correct answers that used typographic characters, which granite4.1:8b does in most answers (a narrow no-break space in "1.1 kg", non-breaking hyphens in "2026-04-30"). Unicode spaces, hyphens, dashes, curly quotes and Markdown emphasis now count as their plain forms, and c14 accepts "not contain", "not available" and "cannot be determined" as "not found" (#47). Measured results for the local model in backend/evals/README.md and the README changed accordingly.
  • When the model ended a turn with an empty reply (no text, no tool call), typically right after a successful search, that empty turn became the answer ("The model stopped without producing an answer"). Seen with granite4.1:8b through Ollama in the eval runs for #47. The agent now asks once more for the final answer from the results so far, for every provider; the retry counts against the iteration limit, and in the last iteration the existing final call takes its place. If the second reply is empty too, the answer says so clearly. Empty replies with a refusal or content-filter stop reason are reported as before.
  • Search hits got a page, slide or sheet (and a suggested read window) only when the whole query occurred word for word in the document (#55). Models search with several words ("Ultralight 1P tent target weight"), so most hits had no location, and answers cited none or a wrong one (in the #47 eval traces "Page 1" for a fact on page 2). The position now comes from the full-text match itself: the place in the shown snippet where the most query terms occur together on one page, slide or sheet.
  • A read_document call for a window that earlier reads of the same question already returned now carries a note that the text is already in the conversation, with a wider window to read instead. In the #47 traces a local model re-read 30–150-character windows of one invoice eight times until the iteration limit (48k tokens instead of about 5k). The text is still returned.

Downloads

File What it is
RootMind-Setup-x64.exe The Windows app with its background service (41.9 MB). Installs for all users of the computer and sets up the service for your account; needs one administrator approval, no Python.
RootMind-amd64.deb The Linux app for Ubuntu and Debian: sudo apt install ./RootMind-amd64.deb. On its first start it sets up its background service as systemd user services of your account; no root needed for that.
RootMind-x86_64.rpm The same for Fedora and openSUSE Tumbleweed: sudo dnf install ./RootMind-x86_64.rpm (openSUSE: sudo zypper install ./RootMind-x86_64.rpm).
RootMind-x86_64.AppImage The same as an AppImage for other distributions, without installation: chmod +x RootMind-x86_64.AppImage, then run it (needs FUSE 2, libfuse2).
rootmind.mcpb RootMind for Claude Desktop: double-click it and Claude Desktop installs it. Needs RootMind installed with Serve MCP over HTTP on (the default).
rootmind-backend-windows-x64.zip The backend on its own for Windows, for the command line and servers. Not needed for the app.
rootmind-backend-linux-x64.tar.gz The backend on its own for Linux (x86-64, glibc 2.35 or later), for the command line and servers. Not needed for the app.
SHA256SUMS.txt SHA-256 checksums of these files.

Verify the download

The binaries are not code-signed yet. On the first start, Windows SmartScreen may show "Windows protected your PC" (choose More info, then Run anyway), and Smart App Control, when it is on, may block them; it has no exception for a single app. Check the files before you run them. The hash must match the line for the file in SHA256SUMS.txt:

(Get-FileHash .\RootMind-Setup-x64.exe -Algorithm SHA256).Hash.ToLower()
sha256sum --check --ignore-missing SHA256SUMS.txt
gh attestation verify RootMind-Setup-x64.exe --repo cgaeking/rootmind

Every file has a build provenance attestation that ties it to this repository and to the workflow run that built it.

Code signing policy

See CODE_SIGNING.md: the binaries are not code-signed yet; what will be signed, team roles and the privacy policy.