muninn-local-mcp
by wolfcao
README.md
# Muninn Local MCP
A local-first [Model Context Protocol](https://modelcontextprotocol.io) (MCP) server that gives AI agents (such as [OpenCode](https://opencode.ai)) persistent, project-scoped memory powered by [ChromaDB](https://www.trychroma.com) and [Ollama](https://ollama.ai) embeddings.
All data stays on your machine — no external API calls, no cloud storage.
> **Note:** This project is adapted from [muninn-mcp](https://github.com/calclavia/muninn-mcp) and modified to run fully locally using Ollama + ChromaDB instead of cloud services.
## Features
- **Persistent memory** — store and recall context across sessions via vector search
- **Project isolation** — each git project gets its own memory namespace, automatically
- **Global memory** — share cross-project knowledge (tooling, patterns, decisions)
- **Local embeddings** — vectors generated by a local Ollama model, zero data leaves your machine
- **MCP-native** — works with any MCP-compatible client (OpenCode, Claude Desktop, etc.)
- **Zero-config defaults** — sensible defaults that work out of the box
## Prerequisites
- **Python** >= 3.11
- [**uv**](https://docs.astral.sh/uv/) — Python package manager
- [**Ollama**](https://ollama.ai) running locally with the `mxbai-embed-large` model:
```bash
ollama pull mxbai-embed-large
```
## Installation
```bash
git clone https://github.com/wolfcao/muninn-local-mcp.git
cd muninn-local-mcp
uv sync
```
## Configuration
### Environment Variables
| Variable | Default | Description |
|---|---|---|
| `MUNINN_DATA_DIR` | `~/.config/opencode/muninn` | ChromaDB data directory |
| `MUNINN_OLLAMA_URL` | `http://localhost:11434` | Ollama service URL |
| `MUNINN_EMBED_MODEL` | `mxbai-embed-large` | Embedding model name |
| `MUNINN_PROJECT_ID` | _(auto from git root)_ | Force a specific project ID |
### OpenCode Integration
Add the server to your `opencode.json`:
```json
{
"mcp": {
"muninn": {
"type": "stdio",
"command": "uv",
"args": [
"--directory",
"/path/to/muninn-local-mcp",
"run",
"python",
"-m",
"muninn_local"
]
}
}
}
```
### Standalone
Run the MCP server directly:
```bash
python -m muninn_local
```
## MCP Tools
Muninn exposes 7 tools, split between **project-scoped** and **global** memory.
### Project Memory
| Tool | Parameters | Description |
|---|---|---|
| `memory_write` | `text`, `memory_type`, `tags` | Store a project-scoped memory |
| `memory_search` | `query`, `top_k` | Semantic search within current project |
| `memory_list` | `limit`, `offset` | List memories (newest first) |
| `memory_delete` | `memory_id` | Delete a specific memory |
### Global Memory
| Tool | Parameters | Description |
|---|---|---|
| `global_memory_write` | `text`, `memory_type`, `tags` | Store a cross-project memory |
| `global_memory_search` | `query`, `top_k` | Semantic search across all projects |
| `global_memory_list` | `limit` | List global memories (newest first) |
### Memory Types
The `memory_type` parameter accepts: `summary`, `decision`, `next-steps`, `code-pattern`, `note` (default).
## How Project Isolation Works
Muninn automatically identifies the current project by resolving the git repository root (`git rev-parse --show-toplevel`) and hashing the path with SHA256. The resulting fingerprint becomes the `project_id`, ensuring each project's memories are isolated in their own ChromaDB collection.
## Architecture
| Layer | Module | Responsibility |
|---|---|---|
| Entry | `__main__.py` / `server.py` | MCP FastMCP server |
| Business | `memory.py` (`MemoryManager`) | Memory CRUD operations |
| Storage | `chroma_store.py` (`ChromaStore`) | ChromaDB persistence wrapper |
| Embedding | `embeddings.py` (`OllamaEmbedder`) | Vector generation via Ollama API |
| Config | `config.py` (`Config`) | data_dir / ollama_url / embed_model |
| Identity | `project.py` | git root → auto project_id |
## Notes
1. **Ollama must be running** — the server depends on a local Ollama instance for embedding generation.
2. **Data is persistent** — ChromaDB stores data in `~/.config/opencode/muninn/chroma/`. Deleting this directory wipes all memories.
3. **Path-sensitive project IDs** — cloning or forking to a different path generates a new `project_id`, so memories won't carry over. Override with `MUNINN_PROJECT_ID` if needed.
## License
MIT
TDQS
A4/5.0
Scored across 7 tools
Disambiguation5/5
Tools are clearly separated by scope (global vs. project-specific) using consistent prefixes, and each tool performs a distinct operation (list, search, write, delete). No ambiguity between tools.
Naming Consistency5/5
All tool names follow a consistent pattern: scope prefix (global_memory_ or memory_) followed by a verb (list, search, write, delete). Naming is predictable and uniform.
Tool Count5/5
With 7 tools covering both global and project memory operations (list, search, write, delete), the count is well-scoped and appropriate for a focused memory store server.
Completeness4/5
The tool surface is mostly complete for both scopes, but the global scope lacks a delete operation, which is a minor gap. CRUD operations are otherwise covered.
Maintenance
ActivityInactive
ResponsivenessNo issues