LexiconLocal
This server exposes two MCP tools that let agents search a local knowledge base and read matching documents.
Search the Lexicon: query curated project notes, in-place repo docs, and archived Claude Code / Codex / ChatGPT session transcripts.
Hybrid retrieval: combine exact lexical matching (FTS5) with semantic vector search, and see which leg matched (
fts,vector, or both).Confidence scoring: each result includes an absolute
confidencescore so you can tell whether the corpus truly covers the topic or not.Filter results: restrict by project (old/alias names resolve to current project), source type (
lexicon,repo-doc,transcript,codex-memory,claude-memory,claude-project,archive-doc), and date range (before/after).Control result count: request 1–50 results per search.
Read documents: open the full indexed document by its path, or centre on one chunk with configurable surrounding context.
Click on "Install 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., "@LexiconLocalsearch past sessions and repo docs for how we fixed the flaky test suite"
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.
Lexicon Local
A local, offline second brain for your coding agents.
Every session you have with a coding AI — Claude Code, Codex, ChatGPT, Claude web — and every Markdown file across every repo you work on, captured automatically, indexed locally, and searchable by the next agent before it starts guessing.
"It's a second brain for my AI coding assistants — everything they and I have ever figured out gets captured automatically, and any new session can search all of it before it starts guessing."
Nothing leaves your machine. The only network call is to Ollama on localhost.
What it does
Captures — a Claude Code
SessionEndhook archives each transcript the moment a session ends; a nightly job sweeps up Codex sessions; account exports from ChatGPT and Claude web are dropped in and parsed. Your repos' own.mdfiles are indexed in place, never copied.Indexes — one SQLite file holding two search engines: FTS5 for exact words,
sqlite-vecfor meaning. Chunked, deduplicated by content hash, credentials redacted on the way in.Searches — hybrid lexical + semantic retrieval fused with reciprocal rank fusion, curated notes boosted over raw transcripts, and an absolute confidence score so an agent can tell "we have this" from "we have nothing" instead of bluffing with the least-bad match.
Serves — an MCP server any agent can call (
lexicon_search,lexicon_read), a CLI, and a read-only local web UI for you.Distils — raw transcripts are searchable from day one; curated
overview.md/decisions.md/log.mdnotes are written per project when it is worth the pass.lexicon distillranks the backlog.Watches itself — preflight proves the embedder works by actually embedding something; a weekly golden-query suite asserts search quality against the live index; a watchdog notices when the nightly job has stopped.
Related MCP server: cc-history
The two-repo model
This repository is the code. Your knowledge lives in a separate repo — ~/Lexicon by default — that the code manages but never owns, and that you never publish.
~/Lexicon/ # your data — a git repo with no remote
├── INDEX.md # every project: one-liner, aliases, repo path
├── config.yaml # what gets indexed
├── projects/<name>/ # curated notes: overview.md, decisions.md, log.md
├── topics/ # cross-project learnings
├── private/ # never indexed
├── archive/ # raw transcripts and exports — non-destructive, gitignored
└── index/ # the SQLite index — disposable, gitignoredThe index is derived. Delete it and lexicon index --full rebuilds it from the files. The files are the truth.
Install
Requirements: macOS or Linux, Python 3.12+, uv, and Ollama running locally.
git clone https://github.com/alexeymohr/LexiconLocal.git
cd LexiconLocal
uv sync
ollama pull nomic-embed-textFirst run
uv run lexicon init # scaffolds ~/Lexicon; prints the next steps
# edit ~/Lexicon/config.yaml: point source_roots at the directory that CONTAINS your repos
uv run lexicon preflight # proves Ollama, the model, the DB, and the registrations
uv run lexicon index --full # first index; later runs are incremental
uv run lexicon report # what got indexed, and whether the importer is healthy
uv run lexicon search "how did we handle X"Then wire up the agents:
uv run python scripts/register_mcp.py # Claude Code, Codex, Claude Desktop
./scripts/install_agents.sh # macOS: nightly capture + weekly quality guardand add the SessionEnd hook so transcripts are captured without anyone remembering to — lexicon init prints the exact JSON to paste into ~/.claude/settings.json. Finally, paste the convention block from ~/Lexicon/CONVENTION.md into each repo's CLAUDE.md or AGENTS.md so agents know to look before they leap.
Three doors
Door | For | Command |
MCP server | agents, in any repo | registered once; tools |
CLI | you, in a terminal |
|
Web UI | you, in a browser |
|
Platform honesty
The indexer, search, MCP server and web UI are portable Python and should run anywhere SQLite and Ollama do. The unattended automation is macOS-specific: the nightly and weekly jobs use launchd, notifications use osascript, and the launch-agent health check reads Background Task Management. On Linux you still get capture through the SessionEnd hook; the scheduled jobs need a cron equivalent nobody has written yet.
This has been run on exactly one machine. The first install on a second one will find something. Please open an issue when it does.
Calibration honesty
Several constants were measured, not derived — the static ranking boosts, the L2 confidence bounds, the absent-topic median threshold, the exact-scan cutoff for project-scoped vector search. They are right for the corpus they were measured on and are starting points for yours. docs/OPERATIONS.md says which ones and how to re-measure. The golden-query suite (scripts/golden_queries.py) is how you find out whether they still hold; its corpus-specific half is a YAML file you own.
Privacy
Everything local. No cloud APIs, no telemetry.
What "local" is enforced to mean. The embedding host must be loopback and is refused before a request is made; Ollama traffic sets
trust_env=False, so aHTTP_PROXYorALL_PROXYin your environment cannot route it elsewhere; and models whose tag marks them as hosted (model:cloud,model:120b-cloud) are refused. Note what that does not prove: loopback addressing means the request reaches Ollama on this machine, not that Ollama performed the inference here. For assurance beyond LexiconLocal's reach, Ollama's ownOLLAMA_NO_CLOUD=1disables its cloud features server-wide. LexiconLocal will not set it for you — your Ollama configuration is yours.private/,.envfiles, keys, and the PII files inside account exports are never indexed. Credential-shaped strings are redacted on ingest.Your data repo has no remote. This code repo is public — and ships with a leak guard (
scripts/leak_guard.py, wired in byscripts/install_hooks.sh) that derives the names of your projects from your Lexicon at commit time and refuses to let them into a commit or a push. If you contribute, install the hooks first.
Documentation
docs/ARCHITECTURE.md— the design and the reasoning behind itdocs/CONFIGURATION.md— every key inconfig.yamldocs/OPERATIONS.md— what runs unattended, what each failure means, what was calibrated
Changes
CHANGELOG.md — what changed in each release, and which changes
are breaking.
License
MIT. See LICENSE.
Available Tools
2 toolslexicon_readA
Read an indexed document, or one chunk of it with surrounding context. Use after lexicon_search to expand a promising result: pass that result's path and chunk_ord.
| Name | Required | Description | Default |
|---|---|---|---|
| path | Yes | Document path exactly as returned by lexicon_search | |
| chunk_ord | No | Chunk ordinal to centre on. Omit for the whole document. | |
| context_chunks | No | Chunks of context each side |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full transparency burden. It discloses the core behavior: reading a whole document or a centred chunk with surrounding context, and it clarifies that path must come from lexicon_search. It does not explicitly state read-only/no side effects, but the verb 'Read' strongly implies it, and the chunk/context semantics are well described.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences with no filler. The action and scope appear first, and the follow-up sentence provides the exact usage pattern with the sibling tool. Every clause earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a three-parameter tool with an output schema and a single sibling, the description is complete. It explains what the tool does, when to use it, how to connect it to lexicon_search, and how the chunking parameters behave. No critical information is missing for correct invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema covers 100% of parameters and already explains path provenance, chunk_ord as the centre, the whole-document option, and context_chunks as each-side context. The description adds orchestration context (use after search) but does not significantly add parameter-level meaning beyond what the schema provides, so the baseline of 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb ('Read') and resource ('an indexed document, or one chunk of it with surrounding context'), and clearly distinguishes it from the sibling tool by describing the read operation that follows search. It is immediately obvious that this tool is for expanding an existing search result, not for searching.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly states when to use the tool: 'Use after lexicon_search to expand a promising result.' It also tells the agent exactly how to invoke it, by passing the path and chunk_ord from that result, which effectively routes the agent between lexicon_read and lexicon_search.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
lexicon_searchA
Search the Lexicon: curated project notes, in-place repo documentation, and archived Claude Code / Codex / ChatGPT session transcripts. Hybrid lexical (FTS5) plus semantic (local embeddings) search. Use before re-solving a nontrivial problem to find prior work, past decisions, and approaches that already failed.
Reading the results: score is ordinal and only orders one result set against another in the same query -- it says nothing about whether the Lexicon actually covers the topic. confidence does: it is absolute, runs 0.15-1.00, and is comparable across queries. At or above 0.80 the corpus genuinely covers the point; between 0.60 and 0.80 treat the result as partial or tangential and verify before relying on it. If most results sit below that, the honest answer is that the Lexicon does not cover this -- say so instead of stretching a weak hit. matched_by shows which leg found it: fts is an exact lexical match, vector a semantic one, and both together is the strongest signal.
| Name | Required | Description | Default |
|---|---|---|---|
| after | No | ISO date lower bound, YYYY-MM-DD | |
| limit | No | Max results | |
| query | Yes | What to look for. Quote exact identifiers, paths, error strings or symbols to force an exact lexical match. | |
| before | No | ISO date upper bound, YYYY-MM-DD | |
| project | No | Restrict to one project. Historical and alias names resolve to the current project (a renamed repo's old name resolves to its new one). | |
| source_type | No | lexicon = curated notes; repo-doc = docs in a live repo; transcript = archived sessions (Claude Code, Codex, Claude/ChatGPT web); codex-memory / claude-memory = distilled memory stores; claude-project = Claude project briefs and their attached docs. |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description takes full responsibility for behavioral disclosure and does so thoroughly. It explains the meaning of the score field (ordinal, query-relative), the confidence field (absolute, comparable, with actionable thresholds 0.80 and 0.60-0.80), and the matched_by field, including what signals the strongest match. This goes well beyond a basic statement of behavior.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long but every section earns its place: purpose, when to use, and a compact but essential guide to interpreting results. The confidence threshold guidance is front-loaded after the purpose and prevents wasted effort on weak hits. No filler or tautology is present.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description is effectively complete for a search tool. It covers what is searched, when to search, how to interpret the returned fields, and how to handle the 'corpus not covered' case. The schema handles parameter details and an output schema exists, so the description must focus on decision-making semantics, which it does.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the input schema already documents all six parameters adequately. The description reinforces the query technique of quoting exact identifiers, paths, or error strings, but adds no new parameter-level semantics beyond what the schema provides. This matches the baseline of 3 for full schema coverage.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly identifies the action ('Search the Lexicon') and the specific resource scope ('curated project notes, in-place repo documentation, and archived session transcripts'). It is clear that this tool searches rather than reads, but it does not explicitly mention or differentiate the sibling tool lexicon_read, so it misses the full 5.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives an explicit when-to-use directive: 'Use before re-solving a nontrivial problem to find prior work, past decisions, and approaches that already failed.' It provides clear context for when the tool is appropriate, but does not state exclusions or contrast with lexicon_read, so it stops short of a 5.
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.
2 tool updates
v0.3.0- First observed
lexicon_read - First observed
lexicon_search
TDQS
lexicon_search and lexicon_read have clearly distinct roles: one finds relevant results across the corpus, the other expands a specific indexed document. There is no overlap or ambiguity between the two.
Both tools follow the same lexicon_ prefix with an action verb in snake_case: lexicon_search and lexicon_read. This creates a clean, predictable naming pattern.
Two tools is minimal, but for a read-only local knowledge retrieval server, search-and-read is the core interaction loop. It is slightly thin compared to typical server scopes, but each tool earns its place.
The search-to-read workflow is complete for consuming the Lexicon, including clear guidance on interpreting result confidence. Missing are corpus-level operations like listing indexed documents or ingesting new content, but those appear outside this server's stated purpose.
Maintenance
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
Token-efficient search for coding agents over public and private documentation.
Project memory, semantic code search, and grounded agent context.
Shared memory for coding agents. Stop re-explaining your codebase every session.
Persistent memory for AI agents. Search, store, and recall across sessions.
Related MCP Servers
- AlicenseBqualityCmaintenanceProvides local, agentic semantic recall over Claude Code session history, enabling the agent to search past discussions semantically, expand turns, and grep transcripts.512MIT
- AlicenseNot gradedqualityCmaintenanceProvides local-first, cross-session memory for Claude Code, enabling semantic search across past sessions to retrieve procedures, decisions, or answers without exposing secrets.Apache 2.0
- AlicenseAqualityAmaintenanceEnables coding agents to query local notes, decisions, docs, and code with hybrid retrieval (BM25 + embeddings + reranking) and get path:line citations. It provides tools like rag_query for full-corpus search and search_knowledge for project-scoped knowledge recall.21MIT
- FlicenseNot gradedqualityBmaintenanceEnables coding agents to search locally indexed repositories with hybrid semantic and lexical retrieval, returning exact source citations with file paths and line ranges.-
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
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/alexeymohr/LexiconLocal'
If you have feedback or need assistance with the MCP directory API, please join our Discord server