Skip to main content
Glama
SMGilliatt

Knowledge Assistant MCP Server

by SMGilliatt
README.md
# Knowledge Assistant MCP Server

A **multi-agent RAG (Retrieval-Augmented Generation)** MCP server built with **FastMCP** in Python. It answers questions from your documents using a coordinator, retriever, and synthesizer agents, and includes a **human-in-the-loop** step where you approve or request edits before finalizing answers.

## What it does

- **Query your knowledge base**: Ask questions in natural language; the server retrieves relevant chunks and proposes an answer with citations.
- **Multi-agent pipeline**: A coordinator decides whether to use the knowledge base, a retriever (RAG) fetches relevant documents, and a synthesizer produces a structured answer proposal.
- **Human-in-the-loop**: You review the proposed answer and either approve it or request edits before the answer is finalized.
- **Add documents**: Ingest text into the vector store (ChromaDB) so the assistant can answer from your own content.

**Use cases**: Internal knowledge assistant, FAQ over your docs, Q&A over notes or wikis, and similar RAG workflows that require a human approval step.

---

## Project Structure

```
knowledge-assistant-mcp/
├── src/
│   ├── server.py           # FastMCP app entry point
│   ├── config/
│   │   └── settings.py     # pydantic-settings (server name, API keys, model, RAG settings)
│   ├── routers/
│   │   ├── tools.py        # Register MCP tools
│   │   ├── resources.py    # Register MCP resources
│   │   └── prompts.py      # Register MCP prompts
│   ├── tools/              # Tool implementations
│   ├── resources/          # Resource implementations
│   ├── prompts/            # Prompt content (workflow with human-in-the-loop)
│   ├── app/                # Core logic: RAG, LLM, orchestrator (coordinator/retriever/synthesizer)
│   ├── models/             # Pydantic schemas (structured outputs)
│   └── utils/              # Helpers (e.g. Opik)
├── pyproject.toml
├── .env.sample
├── Dockerfile
└── README.md
```

---

## Setup

**Prerequisites:** Python 3.13, [uv](https://docs.astral.sh/uv/).

### Clone the repository

```bash
git clone https://github.com/YOUR_USERNAME/knowledge-assistant-mcp.git
cd knowledge-assistant-mcp
```

### Install dependencies with `uv`

```bash
uv sync
```

This creates a virtual environment (Python 3.13) and installs dependencies from `pyproject.toml`.

### Configure environment variables

```bash
cp .env.sample .env
```

Edit `.env` and set at least:

- **`GOOGLE_API_KEY`** (required): Used for Gemini (LLM and embeddings).  
  Get it from [Google AI Studio](https://aistudio.google.com/app/apikey).

Optional:

- **`OPIK_API_KEY`**: For observability (tracing). Get it from [Opik](https://www.comet.com/site/products/opik/).
- **`OPIK_PROJECT_NAME`**: Opik project name (default: `knowledge-assistant`).
- **`MODEL_NAME`**: Gemini model (default: `gemini-2.0-flash`).
- **`CHROMA_PERSIST_DIR`**: Directory for ChromaDB (default: `./chroma_data`).
- **`CHROMA_COLLECTION`**: Collection name (default: `knowledge_base`).
- **`RAG_TOP_K`**: Number of chunks to retrieve (default: `5`).
- **`EMBEDDING_MODEL`**: Google embedding model for RAG (default: `models/gemini-embedding-001`). Override if your API uses a different model.

### Run the server

**Stdio (for Cursor / Claude Desktop):**

```bash
uv run python -m src.server --transport stdio
```

**HTTP:**

```bash
uv run python -m src.server --transport http --port 8000
```

Or use the entry point:

```bash
uv run knowledge-assistant-mcp --transport stdio
```

You should see the FastMCP banner and the process waiting for connections; stop with **Ctrl+C**.

---

## Environment variables

Variables you can set in `.env`, and where to get API keys:

### Environment variables summary

| Variable            | Required | Description |
|---------------------|----------|-------------|
| `GOOGLE_API_KEY`    | Yes      | Google AI (Gemini) API key – [Google AI Studio](https://aistudio.google.com/app/apikey) |
| `OPIK_API_KEY`      | No       | Opik API key for observability – [Opik](https://www.comet.com/site/products/opik/) |
| `OPIK_PROJECT_NAME` | No       | Opik project name (default: `knowledge-assistant`) |
| `MODEL_NAME`        | No       | Gemini model (default: `gemini-2.0-flash`) |
| `CHROMA_PERSIST_DIR`| No       | ChromaDB persistence directory (default: `./chroma_data`) |
| `CHROMA_COLLECTION` | No       | ChromaDB collection name (default: `knowledge_base`) |
| `RAG_TOP_K`         | No       | Number of chunks to retrieve (default: `5`) |
| `EMBEDDING_MODEL`   | No       | Google embedding model for RAG (default: `models/gemini-embedding-001`) |

---

## Connecting from Cursor (or another MCP client)

Add this to your Cursor MCP settings (e.g. `.cursor/mcp.json`), replacing the path and API key as needed:

```json
{
  "mcpServers": {
    "knowledge-assistant": {
      "command": "uv",
      "args": [
        "--directory",
        "/absolute/path/to/knowledge-assistant-mcp",
        "run",
        "python",
        "-m",
        "src.server",
        "--transport",
        "stdio"
      ],
      "env": {
        "GOOGLE_API_KEY": "your-google-api-key-here"
      }
    }
  }
}
```

You can also rely on a `.env` file in the project directory and omit `env` or only set `ENV_FILE_PATH` if your client supports it.

---

## How to use

Once the server is running and connected (e.g. in Cursor):

1. **Add documents** (optional but needed for RAG answers)  
   Use the **add_documents** tool: pass `text` (the content to ingest) and optionally `source` (e.g. `"Context Engineering Book"`). The server chunks and embeds the text into ChromaDB. You can add more documents anytime.

2. **Ask a question**  
   Use the **query_knowledge_base** tool with your question. The server runs the multi-agent pipeline (coordinator → retriever → synthesizer) and returns a **proposed answer** with citations.

3. **Human-in-the-loop**  
   Review the proposal, then call **approve_or_edit_answer**:
   - To accept: `approved=True`, same `proposal_answer` as returned.
   - To request changes: `approved=False`, same `proposal_answer`, and set `user_feedback` to your requested edits. The server can then produce a revised answer.

You can also use **search_knowledge_base** to only search the vector store (no generated answer), and the **knowledge_assistant_workflow** prompt as a step-by-step guide. The resource **knowledge-assistant://server_info** exposes server metadata and RAG settings.

---

## Features

**Core:**

FastMCP server (`src/server.py`) with tools (`query_knowledge_base`, `approve_or_edit_answer`, `add_documents`, `search_knowledge_base`), one workflow prompt (`knowledge_assistant_workflow`) with a human-in-the-loop step (review proposal → approve or edit via `approve_or_edit_answer`), `uv`-based setup, and the structure above. No API keys in the repo; `.env.sample` and `.gitignore` are included.

**Additional:**

- **Multi-agent orchestration** – Coordinator, retriever (RAG), and synthesizer agents in `src/app/orchestrator.py`.
- **RAG with vector database** – ChromaDB + LangChain + Google embeddings; `search_knowledge_base` and `add_documents`; persistence via `CHROMA_PERSIST_DIR`.
- **MCP resource** – `knowledge-assistant://server_info` exposes server name, version, collection, and RAG settings.
- **Human-in-the-loop validation** – Workflow returns a proposal; the user approves or requests edits with `approve_or_edit_answer` before finalizing.
- **Structured outputs** – Pydantic models (`AnswerProposal`, `SearchResult`, `RetrievedChunk`, `SynthesisResult`) for synthesizer and API responses.
- **Observability (Opik)** – Optional tracing when `OPIK_API_KEY` is set.

---

## Docker

Build and run with Docker:

```bash
docker build -t knowledge-assistant-mcp .
docker run --rm -e GOOGLE_API_KEY=your-key -v $(pwd)/chroma_data:/app/chroma_data knowledge-assistant-mcp --transport stdio
```

For HTTP on port 8000:

```bash
docker run --rm -p 8000:8000 -e GOOGLE_API_KEY=your-key -v $(pwd)/chroma_data:/app/chroma_data knowledge-assistant-mcp --transport http --port 8000
```

---

## License

MIT (or your chosen license).

TDQS

A4.2/5.0

Scored across 4 tools

Disambiguation5/5

Each tool has a clearly distinct purpose: query_knowledge_base runs the full RAG pipeline and returns a proposed answer, search_knowledge_base performs raw retrieval only, approve_or_edit_answer handles the human-in-the-loop review step, and add_documents ingests new content. Although query and search both access the knowledge base, their outputs and workflows are fundamentally different and clearly described.

Naming Consistency5/5

All tool names follow a consistent verb_noun pattern in snake_case: query_knowledge_base, approve_or_edit_answer, add_documents, search_knowledge_base. The naming is uniform and predictable, with no mixed conventions or ambiguous verbs.

Tool Count5/5

With exactly 4 tools, the server is well-scoped for its purpose. Each tool addresses a distinct stage of the knowledge assistant workflow (ingestion, retrieval, synthesis, and review), and the count feels neither sparse nor bloated for the domain.

Completeness4/5

The core workflow is covered: add documents, search raw chunks, generate a proposed answer, and approve/request edits. However, there are minor gaps in document lifecycle management—no tools for deleting, updating, or listing documents—which could force workarounds in some use cases.

Maintenance

ActivityInactive
ResponsivenessNo issues