Lexomni MCP
Lexomni MCP is a local knowledge-management server that indexes Markdown and PDF documents into a SQLite FTS5 index so an agent can search, read and note-take inside a _lexomni workspace.
Discover documents —
lexomni_listSourceslists all MDs (user/,agent/) and PDFs (books/) in the workspace, reporting the resolved workspace path, a count, and a warning when it is empty or the index is missing/out of date.Build or refresh the index —
lexomni_buildIndexis the only tool that indexes; it is incremental (skips unchanged files by size + mtime, drops deleted docs), and accepts optionalsources(user/agent/books) andforceto reindex everything.Keyword search —
lexomni_searchDocsperforms literal FTS5 searches over indexed chunks (query ≥ 2 chars, optionalsourcesfilter,limit1–50, default 10) and returns snippets,docId,chunkIndex, source and relative path; it never indexes, so new or changed files require a rebuild.Read document content —
lexomni_readDocreturns a chunk of an indexed document bydocId(≥ 3 chars), with optionalchunkIndex(defaults to 0) andmaxChars(200–20000) to cap response size.Write agent notes —
lexomni_writeNotecreates or updates Markdown files in_lexomni/agent/withfilename,content, and optionalmode(overwritedefault, orappend), limited to 1 MiB per note.Work safely in a configurable workspace — resolution follows
LEXOMNI_WORKSPACE, then the project root (CLAUDE_PROJECT_DIRor the client's first root), then an upward search for_lexomnistopping at the repo root; reads never create folders.Rely on enforced security limits — path traversal, absolute paths, null bytes and symlinks are blocked or ignored, writes are confined to
_lexomni/agent/(verified on real disk path), and PDFs are parsed in sandboxed, read-only Node processes with resource limits.Support multilingual workflows indirectly — the server never translates; the agent expands queries (e.g. "arquitetura em camadas" → "layered architecture") and keeps a living glossary at
_lexomni/agent/glossary.md.
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., "@Lexomni MCPsearch my documents for 'clean architecture'"
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.
Lexomni MCP
MCP (Model Context Protocol) server for local knowledge management with Markdown and PDF indexing using SQLite FTS5.
Author: PagansDev (Paulo Gabriel Neves Santos) | Repository: github.com/PagansDev/lexomni-mcp
English
Usage
Requires Node.js 20.16 or newer.
As a local MCP server
Configure your MCP client (e.g.,
.mcp.jsonfor Claude Code,.cursor/mcp.jsonfor Cursor). Pin an exact version:
"lexomni": {
"command": "npx",
"args": ["-y", "lexomni-mcp@0.2.0"],
"env": { "LEXOMNI_WORKSPACE": "_lexomni" }
}A relative LEXOMNI_WORKSPACE keeps a versioned config file portable across machines. Projects set up with @satlab/protocol get this entry from satlab-protocol init, and satlab-protocol update keeps it current.
Add your documents:
_lexomni/user/- User markdown (guidelines, architecture, etc.)_lexomni/agent/- Agent notes (written bylexomni_writeNote)_lexomni/books/- PDFs (books, documentation, etc.)
Ask the agent to run
lexomni_buildIndex. Searches only return what has been indexed.
How the workspace is resolved
LEXOMNI_WORKSPACE, when set. An absolute path is used as is; a relative one is resolved against the project root.The project root is
CLAUDE_PROJECT_DIR(set by Claude Code), otherwise the first root reported by the MCP client, otherwise the current directory.Without
LEXOMNI_WORKSPACE, the server looks for a_lexomnifolder from the project root upwards and stops at the repository root (the first folder containing.git). If none is found, the workspace is<project root>/_lexomni.
Reading never creates folders: user/, agent/, books/ and index/ are created only when lexomni_writeNote or lexomni_buildIndex writes. lexomni_listSources and lexomni_searchDocs always report the workspace they used and return a warning when it is empty, when the index does not exist, or when it is out of date.
Available Tools
Agent handles parameters on its own
lexomni_listSources
Lists all documents (MD and PDF) in the workspace.
Parameters: none
Example:
{
"workspace": "/path/to/project/_lexomni",
"count": 5,
"docs": [...]
}lexomni_buildIndex
Indexes documents into SQLite FTS5 for fast search. This is the only tool that indexes, and it is incremental: documents whose size and modification time did not change are skipped, and documents removed from the workspace are dropped from the index.
Parameters:
sources(optional): array of["user", "agent", "books"]. Limits what is indexed and what can be removed.force(optional): reindex everything, changed or not.
Example:
{ "ok": true, "docsIndexed": 1, "indexed": 1, "skipped": 11, "removed": 0 }lexomni_searchDocs
Keyword search across indexed documents. It never indexes: new or changed files appear only after the next lexomni_buildIndex, and the response carries a warning until then.
The query is literal text. Each word is matched as typed, so hyphens, quotes and colons are safe (third-party, CVE-2024-4367); FTS5 operators such as OR, NEAR or * are not interpreted.
Parameters:
query(required): string, min 2 characterssources(optional): filter by sourcelimit(optional): max results (1-50, default 10)
Example:
{
"query": "clean architecture",
"workspace": "/path/to/project/_lexomni",
"hits": [
{
"docId": "user:user/guidelines.md",
"chunkIndex": 0,
"snippet": "...about [clean] [architecture]...",
"source": "user",
"relPath": "user/guidelines.md"
}
]
}lexomni_readDoc
docId (required)
Type: string Purpose: unique identifier of the document in the index.
Constraint: at least 3 characters. Typical source: taken from a hit returned by lexomni_searchDocs.
chunkIndex (optional) Type: integer Minimum: 0 Purpose: which chunk (piece) of the document to read. If omitted: usually defaults to the first chunk (0), depending on implementation.
maxChars (optional) Type: integer Range: 200–20000 Purpose: maximum number of characters of text to return for that chunk, useful to limit response size.
lexomni_writeNote
filename (required) Type: string Purpose: name of the markdown file to create or update in the agent’s notes area.
Constraint: at least 1 character.
content (required) Type: string Purpose: markdown content to write into the file.
Constraint: at least 1 character.
mode (optional) Type: string Allowed values: "overwrite" – replaces the existing file content entirely. "append" – appends content to the end of the existing file. Default: "overwrite" if not specified.
Security
Path traversal blocked (no
../, absolute paths or null bytes in note names)Write access limited to
_lexomni/agent/, checked against the real path on diskSymbolic links are ignored when indexing and refused when writing notes, so a symlink inside the workspace cannot expose or overwrite files outside it
PDFs are parsed only by
lexomni_buildIndex, each one in a separate, sandboxed Node process (read-only access to the package and that PDF, no writes, no child processes, 100 MB / 512 MB / 60 s limits), with pdf.js string evaluation disabledNotes are limited to 1 MiB
Runtime dependencies are bundled and releases are published from CI with provenance
See SECURITY.md for the supply chain policy, risky components and how to report a vulnerability.
Architecture
_lexomni/ # In user's project
user/ # Guidelines, architecture (read-only)
agent/ # Agent notes (writable)
books/ # PDFs (read-only)
index/ # SQLite FTS5 (generated)
lexomni.sqliteMultilingual Strategy
Lexomni does not translate text internally. To find docs in PT and EN for e.g. :
Agent expands queries before searching:
"arquitetura em camadas" → also searches "layered architecture"
"fila" → also searches "message queue", "job queue"
Living glossary at
_lexomni/agent/glossary.md:Agent learns new terms via web search
Improves search quality over time
Development
npm run build # Bundle into dist/ (index.js, pdf.worker.mjs, sql-wasm.wasm)
npm run dev # Watch mode
npm start # Run built server
npm test # Tests
npm run lint # Lint
npm run typecheck # TypecheckTo run a local build from a clone, point the MCP client to it:
"lexomni-local": {
"command": "node",
"args": ["/path/to/lexomni-mcp/dist/index.js"],
"env": { "LEXOMNI_WORKSPACE": "_lexomni" }
}Related MCP server: Hoard
License
Available Tools
5 toolslexomni_buildIndexB
Generates/updates the SQLite FTS5 index from MDs and PDFs in _lexomni.
| Name | Required | Description | Default |
|---|---|---|---|
| sources | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries full responsibility for behavioral disclosure. It reveals that the tool writes/updates an index but does not disclose whether existing indexes are replaced, whether the operation is expensive, whether file reading can fail, or whether special permissions are needed. This is a thin disclosure for a mutation-like tool.
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 a single efficient sentence with no filler. The core action and resource are stated upfront, and the source location is included without unnecessary detail.
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 tool with no annotations and no output schema, the description leaves too much unsaid: the meaning of `sources`, the side effects of rerunning, and the recommended workflow alongside `lexomni_searchDocs` are all missing. It is barely more useful than the tool name alone.
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 0%, and the description does not explain the `sources` parameter at all. The enum values (`user`, `agent`, `books`) are somewhat self-explanatory, but an agent is left to guess whether they refer to directories, categories, or something else, and what omitting `sources` means.
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 names a specific verb ('Generates/updates') and resource ('SQLite FTS5 index'), with a clear input scope ('MDs and PDFs in _lexomni'). This clearly separates it from sibling tools like lexomni_searchDocs, lexomni_readDoc, and lexomni_writeNote.
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 implies the tool is used to build or refresh searchable indexes over documents, which suggests it should be run before searching. However, it never explicitly states when to run it, when not to run it, or how it relates to the sibling `lexomni_searchDocs` tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
lexomni_listSourcesA
Lists available MDs (user/agent) and PDFs (books) in the _lexomni workspace.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the behavioral transparency burden. The verb 'Lists' implies a read-only operation, and the workspace scope is stated, but return format and any limitations are not disclosed.
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 a single sentence that front-loads the action and scope with no unnecessary detail. Every word contributes to understanding the tool's purpose.
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 zero-parameter listing tool, the description is sufficiently complete: it states what is listed, the categories, and the workspace. Without an output schema, the phrase 'Lists available...' reasonably implies the return value.
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 tool has zero parameters, and the input schema is complete by default. The description does not need to explain parameter semantics, so the baseline score of 4 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 uses the specific verb 'Lists' and identifies the resource types (MDs and PDFs) and scope (_lexomni workspace). This clearly distinguishes it from sibling tools like lexomni_searchDocs and lexomni_readDoc.
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 implies a discovery/listing use case, but it does not explicitly state when to use this tool versus alternatives. Sibling names suggest different operations, yet the description provides no direct usage guidance or exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
lexomni_readDocB
Reads a chunk of an indexed document (by chunkIndex).
| Name | Required | Description | Default |
|---|---|---|---|
| docId | Yes | ||
| maxChars | No | ||
| chunkIndex | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden of behavioral disclosure. It states that reading occurs, but does not explain chunk indexing semantics, behavior when chunkIndex is omitted or out of range, whether results are capped by maxChars, or what the response looks like. These are significant gaps for a tool with no output schema.
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 a single, direct sentence with no filler or redundancy. 'Reads a chunk of an indexed document (by chunkIndex)' conveys the core operation efficiently and the key selection mechanism is front-loaded.
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 tool with no annotations, no output schema, and three parameters with zero schema descriptions, this one-liner is insufficient. It does not explain chunk semantics, the role of maxChars, required preconditions like an existing index, or the return structure. An agent would need to guess or inspect external documentation to invoke it correctly in non-trivial cases.
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 0%, so the description must compensate for the schema's lack of explanatory text. It only clarifies chunkIndex; docId and maxChars are left to inference from their names and schema constraints. The agent gets no explanation of how maxChars interacts with chunking or what docId refers to.
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 operation (reads) and the target (a chunk of an indexed document, selected by chunkIndex). This distinguishes it from sibling tools like lexomni_buildIndex, lexomni_searchDocs, and lexomni_writeNote, which have different verbs and resources.
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?
No guidance is given about when to use this tool or what prerequisites exist, such as 'the document must first be indexed via lexomni_buildIndex'. There is no mention of alternatives or exclusions, leaving the agent to infer usage context from the word 'indexed'.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
lexomni_searchDocsB
Searches indexed documents by keyword (FTS).
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | ||
| query | Yes | ||
| sources | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden of behavioral disclosure. It only states that the tool searches indexed documents by keyword; it does not disclose the return format, result ordering, pagination/limit behavior, or that searchable content depends on a pre-built index. 'Indexed documents' hints at a prerequisite but is not sufficient.
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 a single, front-loaded sentence with no wasted words. It states the action (Searches), the object (indexed documents), and the method (keyword FTS) in an efficient, scannable way.
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?
Given three parameters, no annotations, and no output schema, the description is far too minimal. It leaves critical operational details undefined: what 'sources' does, how 'limit' behaves, and what the result looks like. An agent can call it with just 'query', but cannot reliably predict results or apply filters correctly.
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 0% and the description only mentions 'keyword', which maps to the required query parameter. It says nothing about 'limit' (maximum results) or 'sources' (filtering by user/agent/books), leaving those parameters unexplained in both schema and description. The description does not compensate for the low 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 uses a specific verb ('Searches') and resource ('indexed documents') with a clear method ('by keyword (FTS)'). It is distinct from sibling tools like readDoc (direct retrieval), listSources (listing sources), buildIndex (building an index), and writeNote (writing), so an agent can tell search apart from them.
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 no guidance on when to use this tool versus alternatives, no exclusions, and no context about prerequisites (e.g., needing to build the index first). Sibling tools are known but never referenced, so the agent must infer when keyword search is the right choice from the name alone.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
lexomni_writeNoteB
Creates/updates a markdown file in _lexomni/agent (agent memory).
| Name | Required | Description | Default |
|---|---|---|---|
| mode | No | overwrite | |
| content | Yes | ||
| filename | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description is the only behavioral disclosure. It correctly identifies the tool as a mutation that creates or updates a markdown file in a scoped location, but it does not disclose that the default mode is overwrite, how append behaves, side effects, or failure modes.
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?
A single, front-loaded sentence with no filler. The verb, object, location, and purpose are stated in order, making the core meaning immediately visible.
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 simple three-parameter write tool, the description plus schema is enough to make a plausible call. Yet with no annotations or output schema, it lacks a bit of surrounding context such as overwrite semantics and how this write relates to the other lexomni tools like buildIndex.
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 0% and the description adds no meaning for filename, content, or mode. The schema shows the parameter names and the mode enum, so the description does not compensate for the missing parameter-level guidance.
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?
States a specific action (creates/updates), a concrete resource (markdown file), and a precise location (_lexomni/agent). This clearly distinguishes it from the read/search/list/index siblings.
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 phrase 'agent memory' implies this is for persisting agent notes, and sibling names imply alternatives such as reading or searching. However, there is no explicit statement of when to choose this tool over alternatives or when not to use it.
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.
5 tool updates
v0.0.0-dev- First observed
lexomni_buildIndex - First observed
lexomni_listSources - First observed
lexomni_readDoc - First observed
lexomni_searchDocs - First observed
lexomni_writeNote
TDQS
Scored across 5 tools
Each tool has a clearly distinct function: listing sources, building the index, searching, reading a chunk, and writing a note. There is no overlap or confusion between tool purposes.
All tools follow a consistent lexomni_verbNoun pattern (listSources, buildIndex, searchDocs, readDoc, writeNote). The naming is uniform and predictable.
Five tools is well-scoped for a document indexing and retrieval server. Each tool earns its place, covering the essential operations without unnecessary bloat.
Core workflows are covered: list sources, build index, search, read chunks, and write agent notes. A minor gap is the lack of a way to enumerate chunks or retrieve document structure, but this is workable for the intended use case.
Maintenance
Related MCP Connectors
Personal knowledge base MCP server with semantic search, auto-categorization, metadata extraction
MCP server for querying Forkast documentation
Serve a folder of Markdown notes as an MCP server: hybrid search, reading, and sourced answers.
Markdown-based note-taking with a hosted MCP server. Your notes serve you and your AI.
Related MCP Servers
- AlicenseAqualityAmaintenanceMCP Server for local knowledge management. Semantic + keywords + tags886 PyPI22MIT
- AlicenseNot gradedqualityDmaintenanceLocal MCP server for indexing personal knowledge into SQLite with hybrid search, chunk-level citations, memory tools, and agent orchestration.4MIT
- AlicenseAqualityCmaintenanceMCP server that indexes Markdown, Word, HTML, and PDF documents into a SQLite knowledge graph with CJK+Latin full-text search and cross-document reference tracking. Runs drift audits to surface stale policies, conflicting research claims, superseded ADRs, and undocumented code exports.108MIT
- FlicenseNot gradedqualityCmaintenanceMCP server that enables full-text search and link navigation over Markdown files as a knowledge graph.-