Skip to main content
Glama
neryams

journal-rag

by neryams

journal-rag

Source-control-friendly hybrid retrieval over team markdown journals. Heading-chunked BM25 + local vector embeddings fused via Reciprocal Rank Fusion (RRF), with regex as an escape hatch. A per-user daemon shares models and workspace indexes across MCP clients.

Embeddings run locally via @huggingface/transformers (default model: Qwen3-Embedding-0.6B) — no API keys, no external calls.

Each consuming repo commits journal-rag.config.json and markdown under docs/journal/ (or other configured folders). This package is the shared engine.

Per-repo config

Create journal-rag.config.json at the repo root:

{
  "sources": ["docs/journal"],
  "cachePath": ".journal-rag/index.json",
  "embeddingModel": "onnx-community/Qwen3-Embedding-0.6B-ONNX"
}

Field

Required

Default

Description

sources

yes

Directories containing markdown journals

cachePath

no

.journal-rag/index.json

BM25 chunk index cache path

embeddingModel

no

onnx-community/Qwen3-Embedding-0.6B-ONNX

Hugging Face model ID for local embeddings

The vector cache (vectors.json) is stored in the same directory as cachePath.

Add to .gitignore:

.journal-rag/

Related MCP server: mnemonic

Build & install (once per machine)

cd c:/repos/journal-rag
npm install          # runs prepare → build
npm link             # puts journal + journal-mcp on your PATH

npm link registers two global commands:

Command

What it runs

journal

CLI (search, list, get, …)

journal-mcp

MCP stdio server (for editor config)

journal-daemon

Shared local daemon (normally started automatically)

Re-run npm run build (or npm link again) after pulling server changes. Alternative to link: npm install -g . from this repo (same effect).

CLI (any teammate)

From a repo root with config:

journal search "HttpFacade singleton"        # hybrid BM25 + vector (default)
journal search "HttpFacade singleton" --bm25 # BM25-only (no embedding)
journal list --filter dialog
journal get docs/journal/2026-04-21_vapp-http-facade-and-singleton-sweep.md
journal index --rebuild

After npm link in this repo, journal search "..." works globally.

Set JOURNAL_RAG_WORKSPACE to an absolute repo root only when you must run the CLI from a subdirectory.

The first run downloads the embedding model (~614 MB, quantized int8) to the Hugging Face cache directory. Subsequent runs load from cache. Embedding inference uses DirectML on Windows, Core ML on macOS, and CPU elsewhere. Indexing uses single-document batches to stay within the memory limits of 6 GB GPUs. DirectML sessions disable memory-pattern optimization and use sequential execution as required by ONNX Runtime. Partial vectors are checkpointed every 100 chunks so an interrupted build can resume.

Each editor still launches a small stdio MCP proxy because stdio cannot be shared between clients. The proxy automatically connects to one per-user daemon over a Windows named pipe or Unix socket. The daemon canonicalizes the path to journal-rag.config.json; Cursor, ChatGPT, and other clients using the same config therefore share one workspace runtime, vector build, and model instance. No administrator-level service installation is required.

Diagnostic logs

The MCP proxy and daemon write daily JSONL logs and retain them for 14 days:

  • Windows: %LOCALAPPDATA%\journal-rag\logs

  • macOS: ~/Library/Logs/journal-rag

  • Linux: $XDG_STATE_HOME/journal-rag/logs or ~/.local/state/journal-rag/logs

Set JOURNAL_RAG_LOG_DIR to override the directory. Logs include process IDs, canonical config paths, daemon startup and request failures, vector-build timing, selected execution device, model-load timing, and process memory after model loading. Query text and journal content are not logged.

MCP tools

Tool

Purpose

search_journal

Hybrid BM25 + vector search with RRF fusion (query, k). Falls back to BM25-only if vector index is unavailable.

write_entry

Create a new journal entry (title, content). Auto-generates dated filename, incrementally updates the vector index.

get_entry

Full file by path or filename

list_entries

Browse metadata (filter optional)

search_regex

Exact / path / symbol lookup

Editor setup

Use stdio — spawn Node with dist/server.js.

Put MCP config in the workspace, not your user profile

The server resolves journal-rag.config.json by walking up from its working directory. That file lives at each consuming repo's root (next to docs/journal/), not in journal-rag itself.

If you add the server to a global / user-level editor profile, the spawn cwd is usually wrong (home dir, editor install dir, last random folder, etc.) and the server cannot find config — even if you hardcode "cwd": "C:/repos/my-repo", that breaks the moment you open a second repo workspace.

Do this instead: commit workspace-level MCP config inside each repo that has journals. Teammates run npm link once (see above) so journal-mcp is on PATH — no machine-specific paths in the committed JSON.

Cursor

.cursor/mcp.json at the repo root (e.g. my-repo/.cursor/mcp.json) — safe to commit:

{
  "mcpServers": {
    "journal": {
      "command": "journal-mcp",
      "cwd": "${workspaceFolder}",
      "env": {
        "JOURNAL_RAG_WORKSPACE": "${workspaceFolder}"
      }
    }
  }
}

${workspaceFolder} resolves to the repo you opened. journal-mcp comes from npm link in the journal-rag repo.

VS Code (Copilot agent mode)

Same idea: .vscode/mcp.json in the repo, not User settings:

{
  "servers": {
    "journal": {
      "type": "stdio",
      "command": "journal-mcp",
      "cwd": "${workspaceFolder}"
    }
  }
}

JetBrains AI Assistant / Junie

Configure MCP at project scope (.idea / project settings), not the IDE default profile. Open the repo as the project root. Command: journal-mcp (after npm link).

If journal-mcp is not found

Ensure npm's global bin dir is on your PATH (npm bin -g). On Windows that is usually %APPDATA%\\npm. Then re-run npm link from journal-rag. Fallback for a single machine only: "command": "node", "args": ["<absolute-path>/journal-rag/dist/server.js"].

Fallback

If an editor cannot set cwd per workspace, set env JOURNAL_RAG_WORKSPACE to the absolute path of the consuming repo root in that workspace's MCP config.

Design notes

  • Corpus is small (~tens of files); BM25 over heading chunks matches how journals are written.

  • Vector embeddings (local, via Transformers.js) add semantic recall for paraphrased or conceptual queries.

  • Reciprocal Rank Fusion (RRF, k=60) merges BM25 and vector rankings without needing score normalization.

  • Index caches are optional and gitignored; markdown in git is the source of truth.

  • Vector cache is incremental — only new/changed chunks are re-embedded on rebuild.

  • Vector index builds take a machine-wide lock, so MCP servers opened for different workspaces do not run expensive embedding jobs concurrently. The lock has a heartbeat and is recovered after a crashed or killed process.

  • The daemon owns workspace runtimes keyed by canonical config path. MCP stdio processes contain no model or index state and only forward tool calls.

Available Tools

5 tools
get_entryA

Return the full markdown of one journal file by relative path or filename.

ParametersJSON Schema
NameRequiredDescriptionDefault
pathYesRelative path (e.g. docs/journal/2026-04-21_topic.md) or filename

TDQS

A4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the behavioral disclosure burden. It conveys read-only retrieval and the return shape ('full markdown'), but it doesn't disclose behavior for missing files, ambiguous bare filenames, or path resolution roots. Adequate but with gaps.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

One concise sentence that front-loads the action and scope, with no filler or redundancy.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple one-parameter retrieval tool, the definition plus the schema specify the input and the returned content ('full markdown'), which is enough for basic invocation. It doesn't fully specify edge-case behavior, but that is a modest gap at this complexity.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, and the schema already explains the path parameter with an example. The description mostly restates the same addressing idea and adds no new parameter-level semantics beyond that.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description identifies a specific verb ('Return'), a specific resource ('full markdown of one journal file'), and the addressing method ('by relative path or filename'). This clearly distinguishes it from the list, search, and write sibling tools.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It clearly implies when to use it: when you need the complete markdown of a single known journal entry addressed by path or filename. It doesn't explicitly discuss exclusions or alternatives like search_journal, but the retrieval context is clear.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_entriesA

List journal files with title, date, and section headings. Optional filter substring on path/title.

ParametersJSON Schema
NameRequiredDescriptionDefault
filterNoCase-insensitive substring filter

TDQS

A3.5/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the burden of behavioral disclosure. It conveys that the tool returns journal file titles, dates, and section headings, and that filtering applies to path/title. However, it does not mention ordering, pagination, result limits, or how section headings are derived, leaving some behavioral ambiguity.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two short sentences, front-loads the core behavior, and includes the key optional parameter without unnecessary detail. Every part earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a read-only list tool with a single optional parameter, the description provides the essential call details: what is returned and how filtering works. It is somewhat incomplete because it does not contrast with sibling search tools, but the low complexity and clear output fields keep the gap small.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema already documents 'filter' as a case-insensitive substring filter, so the baseline is 3. The description adds meaningful scope by specifying the filter applies to path/title, which goes beyond the schema's generic wording. This clarifies the parameter's actual effect.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the action ('List') and the resource ('journal files'), and specifies the returned metadata: title, date, and section headings. It does not explicitly differentiate itself from siblings like search_journal or search_regex, but the focus on listing file metadata is reasonably distinct.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides no guidance on when to use this tool versus alternatives such as search_journal, get_entry, or search_regex. The optional filter is mentioned but there is no explicit indication of when listing with a substring filter is preferable to content or regex search.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

search_journalA

Hybrid BM25 + vector semantic search over team markdown journals (heading-chunked). Returns ranked hits with file#heading citations.

ParametersJSON Schema
NameRequiredDescriptionDefault
kNo
queryYesSearch terms or phrase

TDQS

A4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden. It discloses the hybrid retrieval algorithm (BM25 + vector), the chunking strategy (heading-chunked), and the return format (ranked hits with file#heading citations), which effectively communicates read-only behavior and result structure. It omits details like pagination or authentication, but for a search tool the core behavior is transparent.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is composed of two concise, information-dense sentences with no filler. The core mechanism and resource are front-loaded, followed by the output format, making every word useful.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple two-parameter tool with no output schema, the description covers the key aspects needed to invoke it correctly: the search scope, the retrieval method, and the return format. It does not describe the exact structure of a hit beyond file#heading citations, but this is acceptable given the tool's simplicity.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 50%: 'query' has a description and 'k' has default/min/max but no description. The tool description adds no explicit parameter-level guidance; however, 'Returns ranked hits' combined with k's default of 8 implies k controls result count. The description only marginally compensates for the missing k description.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb ('search'), a specific resource ('team markdown journals'), and the method ('Hybrid BM25 + vector semantic search'), while also noting the heading-chunked indexing and citation-style output. This clearly distinguishes it from sibling tools, especially search_regex, by indicating semantic rather than regex-based search.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage for semantic/fuzzy search over journals and contrasts with the existence of search_regex, but it does not explicitly say when to use this tool versus alternatives. There is no 'use search_regex for regex patterns' or similar guidance, leaving the decision to inference.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

search_regexA

Regex search across journal chunks (escape hatch for symbols, paths, exact identifiers).

ParametersJSON Schema
NameRequiredDescriptionDefault
kNo
patternYesJavaScript regex pattern (case-insensitive)

TDQS

A3.7/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden. It makes the search behavior and scope clear and implicitly identifies the operation as non-mutating, but it does not disclose output shape, match limits, or behavior on invalid patterns. This is acceptable but incomplete.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single front-loaded sentence states the action and resource, then adds a compact parenthetical with high-value selection guidance. There is no wasted wording.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Without an output schema or annotations, the description should explain what the tool returns and clarify the k parameter's role. Neither is provided, leaving an agent uncertain about result format and how to configure search depth. This is a meaningful gap for a tool that is otherwise simple.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is only 50%: pattern is described, but k has no semantic description beyond numeric bounds. The tool description reinforces pattern's purpose but says nothing about k, so an agent must guess whether k means top-k results, page size, or something else.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly names the operation as regex search over journal chunks and adds an explicit escape-hatch purpose: symbols, paths, and exact identifiers. This distinguishes it from the likely keyword-based search_journal sibling without opening any schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The 'escape hatch' phrasing plus the concrete use cases tell an agent when to reach for this tool rather than a normal search. It does not explicitly name search_journal as the default alternative or state when not to use it, so it stops short of full routing guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

write_entryA

Create a new markdown journal entry. Filename is generated from today's date and the title slug. Returns the file path. The vector index is incrementally updated (only new chunks are embedded).

ParametersJSON Schema
NameRequiredDescriptionDefault
titleYesEntry title (used for H1 heading and filename slug)
contentYesFull markdown content of the journal entry (should start with # Title)

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden. It discloses key behavioral details: filename generation from date and title slug, return value (file path), and the vector index side effect. It does not mention duplicate-title collision behavior, but the provided details are substantial.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three tight sentences with no filler. The core action is front-loaded, followed by filename behavior, return value, and the vector index side effect. Every sentence earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a two-parameter create tool with no output schema, the description covers the return value, file naming, and an important side effect. It could mention what happens on filename collision, but the essentials an agent needs to call it correctly are present.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3. The description adds a bit of context by noting the date is part of the generated filename, but most parameter meaning is already present in the schema descriptions.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the action ('Create a new markdown journal entry') and names the resource. It is distinct from the sibling read/search/list tools, so an agent can tell it apart without extra inference.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description makes the intended use obvious: creating a new journal entry. It does not explicitly name alternatives or exclusions, but the contrast with read/search/list siblings is clear enough for a straightforward create operation.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections. Dates show when Glama detected each change.

  1. 5 tool updatesv0.1.0
    • First observedget_entry
    • First observedlist_entries
    • First observedsearch_journal
    • First observedsearch_regex
    • First observedwrite_entry

TDQS

A4/5.0
Disambiguation5/5

Each tool has a clearly distinct role: semantic/full-text search, regex-based search, listing, full-entry retrieval, and entry creation. Even though search_journal and search_regex can both find text, their purpose and query syntax are clearly separated, so an agent should not confuse them.

Naming Consistency5/5

All tool names follow a consistent lowercase verb_noun pattern: search_journal, get_entry, list_entries, search_regex, write_entry. The naming is predictable and immediately conveys the action and target.

Tool Count5/5

Five tools is a well-scoped set for a journal RAG server. There is one tool for semantic search, one for regex search, one for listing, one for retrieving full entries, and one for creating new entries—each earns its place without redundancy.

Completeness4/5

The tool surface covers the core journal workflow: create entries, list them, retrieve them, and search them semantically or by regex. Update and delete capabilities are absent, but for a journal/RAG-oriented server these are often intentionally not needed, so this is a minor gap rather than a significant one.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Connectors

Related MCP Servers

  • F
    license
    Not graded
    quality
    C
    maintenance
    Hybrid semantic search (dense vector + BM25) over local knowledge bases and codebases, exposed as MCP tools for AI agents to search and list knowledge bases.
    -
  • A
    license
    Not graded
    quality
    B
    maintenance
    MCP server for on-device hybrid search over markdown knowledge bases, combining BM25, vector embeddings, and LLM reranking with link graph and time decay.
    17
    MIT
  • A
    license
    A
    quality
    C
    maintenance
    A local MCP server enabling hybrid search over documents, memory, and knowledge graphs for retrieval-augmented generation, with tools for SQLite, semantic memory, and entity-relationship queries.
    4
    1
    MIT
  • A
    license
    Not graded
    quality
    C
    maintenance
    An MCP server that provides a unified hybrid-search interface over Slack, wikis, code, and databases, enabling agents and humans to query scattered knowledge with exact and semantic search.
    MIT

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/neryams/workspace-docs-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server