# kenso

> kenso turns a folder of Markdown files into a searchable knowledge base for AI agents. BM25 keyword search over SQLite FTS5, zero config, no infrastructure. Install with pip, index with one command, connect any MCP client.

kenso is an MCP server. AI agents search your docs through four tools: `search_docs`, `search_multi`, `get_doc`, and `get_related`. Results are ranked excerpts (~600 tokens per chunk) instead of entire files (3,000–8,000+). The document graph lets agents navigate typed relations between documents.

No vector database, no embedding model, no API keys. Two runtime dependencies: `mcp` and `aiosqlite`.

## Docs

- [Getting Started](https://fvena.github.io/kenso/guide/getting-started): Installation, first index, editor setup
- [Writing Guide](https://fvena.github.io/kenso/guide/writing-guide): How to structure Markdown documents for optimal retrieval
- [MCP Integration](https://fvena.github.io/kenso/guide/mcp-integration): Editor and client configuration
- [How kenso Works](https://fvena.github.io/kenso/guide/how-it-works): Search pipeline, chunking, FTS5 internals

## Quick start

```bash
pip install kenso[yaml]
kenso ingest ./docs/
```

Connect your editor — the MCP client starts kenso automatically. See MCP Integration above.

## MCP tools

| Tool | Purpose |
|------|---------|
| `search_docs(query, category?, limit?)` | Keyword search with BM25 ranking and relation re-ranking |
| `search_multi(queries, category?, limit?)` | Multi-query search with Reciprocal Rank Fusion |
| `get_doc(path, max_length?)` | Retrieve full document content by path |
| `get_related(path, depth?, relation_type?)` | Navigate document graph (max depth 3) |

## Frontmatter fields

| Field | Weight | Purpose |
|-------|--------|---------|
| `title` | 10× | Document title — strongest ranking signal |
| `section_path` | 8× | Auto-generated from heading hierarchy |
| `tags` | 7× | Synonyms, acronyms, alternative terms |
| `category` | 5× | Topic classification, filterable in search |
| `aliases` | 1× (in content) | Vocabulary bridges injected into searchable index |
| `answers` | 1× (in content) | Question-form phrases for natural language queries |
| `description` | 1× (in content) | Summary text injected into searchable index |
| `relates_to` | graph | Links to related documents with optional relation type |

## CLI commands

```
kenso ingest <path>          # index Markdown files
kenso search <query>         # search from terminal
kenso stats                  # database statistics
kenso lint <path>            # retrieval quality analysis
kenso lint <path> --detail   # per-file violations
kenso serve                  # start MCP server (usually started by your editor)
```

## Configuration

All optional, via environment variables:

| Variable | Default | Description |
|----------|---------|-------------|
| `KENSO_DATABASE_URL` | `.kenso/docs.db` | SQLite database path |
| `KENSO_CHUNK_SIZE` | `4000` | Max chunk size in characters |
| `KENSO_CHUNK_OVERLAP` | `0` | Overlap between consecutive chunks |
| `KENSO_SEARCH_LIMIT_MAX` | `20` | Maximum results per search |
| `KENSO_TRANSPORT` | `stdio` | Transport: stdio or streamable-http |
| `KENSO_HOST` | `127.0.0.1` | Server bind address |
| `KENSO_PORT` | `8000` | Server port |
| `KENSO_LOG_LEVEL` | `INFO` | Logging level |

Python 3.11+ · MIT license
