Enables storage and semantic search of facts, and interactive 3D visualization of embeddings via MCP tools.
SaferSkills independently audited MCP Knowledge Viz (MCP Server) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
A knowledge-base chatbot with semantic search and interactive embedding visualisation, built as a hybrid of REST microservices (browser UI) and a proper MCP stdio server (Claude Desktop / Cursor integration).
Store facts in natural language, ask questions, and explore the embedding space in 2D (matplotlib) or interactive 3D (Plotly) — all backed by ChromaDB and SentenceTransformers.
Service architecture
The system has two independent access paths that share the same business logic:
| Layer | Transport | Use case |
|---|---|---|
REST servers (run_all.sh) | HTTP | Browser chatbot UI |
MCP stdio server (mcp_tools.py) | stdin/stdout JSON-RPC | Claude Desktop, Cursor, any MCP client |
Both layers delegate to `kb_core.py` — the single module that owns the ChromaDB client and the SentenceTransformer embedder. Neither layer duplicates data-access logic.
kb_core.py talks to ChromaDB. REST endpoints and MCP tools are thin wrappers.mcp_tools.py calls kb_core directly; the REST servers do not need to be running for an MCP client to use the tools.EmbeddingPayload, VisualizationRequest, ReducedEmbeddings).Module structure
QnA request flow
Visualization flow
MCP tools flow
plantuml -tsvg docs/architecture/uml/*.puml -o ../images
plantuml -tpng docs/architecture/uml/*.puml -o ../imagesCentral data service. Also serves the chatbot browser UI.
| Method | Endpoint | Description |
|---|---|---|
GET | /chatbot | Browser UI (two-column layout) |
POST | /add_fact | Embed and store a fact in ChromaDB facts collection |
POST | /add_query | Embed and store a query in ChromaDB queries collection |
POST | /search | Semantic search — returns top-k facts + distances. Body: {"query": "...", "n_results": 5} |
GET | /get_all_embeddings | Return all facts + queries with raw embeddings (used by Viz server) |
Thin HTTP wrapper. Calls the KB server; no direct DB access.
| Method | Endpoint | Description |
|---|---|---|
POST | /ask | Stores query via /add_query, fetches matches via /search, returns ranked results |
Generates embedding plots via PCA dimensionality reduction.
| Method | Endpoint | Query params | Returns | |
|---|---|---|---|---|
GET | /visualize_embeddings | dimensions (2\ | 3), show_radius, radius_neighbors, figure_width, figure_height, dpi | image/png (matplotlib) |
GET | /visualize_embeddings_3d | show_radius, radius_neighbors, figure_width, figure_height, dpi | image/png (matplotlib 3D) | |
GET | /visualize_embeddings_interactive | show_radius, radius_neighbors | application/json (Plotly figure) |
mcp_tools.py is a FastMCP stdio server. Configure it in your MCP client and the three tools below appear automatically — no REST servers needed.
| Tool | Arguments | Description |
|---|---|---|
add_fact | text: str | Embed and persist a fact in ChromaDB |
ask | query: str, n_results: int = 5 | Semantic search; also records the query for visualisation |
visualize_embeddings | show_radius: bool = true, radius_neighbors: int = 3 | Returns a Plotly 3D figure as a JSON string |
Copy mcp.json.example to mcp.json, fill in your absolute paths, then copy the mcpServers block into your client's config file:
~/Library/Application Support/Claude/claude_desktop_config.json~/.cursor/mcp.json// mcp.json.example — fill in your local paths
{
"mcpServers": {
"knowledge-viz": {
"command": "/path/to/your/project/.venv/bin/python",
"args": ["-m", "mcp_servers.mcp_tools"],
"cwd": "/path/to/your/project"
}
}
}mcp.jsonis gitignored because it contains absolute local paths. Always editmcp.json.examplefor committed changes.
git clone <repository-url>
cd mcp-knowledge-viz
python -m venv .venv
source .venv/bin/activate # Windows: .venv\Scripts\activate
pip install -r requirements.txtchmod +x run_all.sh
./run_all.shStarts three servers:
| Server | Port | Role |
|---|---|---|
| Knowledge Base | 8000 | Data + chatbot UI |
| QnA | 8001 | Question answering |
| Visualization | 8002 | Embedding plots |
Open http://127.0.0.1:8000/chatbot in your browser.
| Parameter | Default | Range | Effect |
|---|---|---|---|
dimensions | 2 | 2 or 3 | PCA target dimensions |
show_radius | true | bool | Draw search-radius circle / sphere around latest query |
radius_neighbors | 5 | 1–50 | Neighbour count used to compute the radius |
figure_width | 16 | float | Matplotlib figure width (inches) |
figure_height | 10 | float | Matplotlib figure height (inches) |
dpi | 160 | int | Matplotlib output resolution |
n_results | 5 | 1–50 | Facts returned per search |
mcp-knowledge-viz/
├── app/
│ ├── static/
│ │ ├── chatbot.css # Two-column layout, vis viewport
│ │ └── chatbot.js # Fetch facts/QnA, Plotly 3D, spinner
│ └── templates/
│ └── chatbot.html # Bootstrap 5 two-column UI
├── docs/
│ └── architecture/
│ ├── images/ # Generated SVG + PNG diagrams
│ └── uml/ # PlantUML sources
├── mcp_servers/
│ ├── kb_core.py # ★ Shared ChromaDB + embedder logic
│ ├── knowledge_base_server.py # REST :8000 — delegates to kb_core
│ ├── qna_server.py # REST :8001 — HTTP wrapper
│ ├── visualization_server.py # REST :8002 — delegates to visualization/
│ ├── mcp_tools.py # ★ MCP stdio server (add_fact, ask, visualize)
│ └── visualization/
│ ├── models.py # Pydantic models
│ ├── kb_client.py # HTTP client → KB server
│ ├── reducer.py # PCA 2D/3D
│ ├── renderer.py # matplotlib (2D/3D static PNG)
│ ├── plotly_renderer.py # Plotly interactive 3D JSON
│ └── service.py # Orchestrator
├── chroma_db/ # Persistent vector store (gitignored)
├── mcp.json # Local MCP config (gitignored)
├── mcp.json.example # Template — commit this, not mcp.json
├── run_all.sh # Start all three REST servers
└── requirements.txt| Concern | Library |
|---|---|
| REST framework | FastAPI + uvicorn |
| Vector store | ChromaDB (persistent) |
| Embeddings | SentenceTransformers all-MiniLM-L6-v2 |
| Dimensionality reduction | scikit-learn PCA |
| 2D/3D static plots | matplotlib |
| Interactive 3D plots | Plotly (JS CDN + Python) |
| MCP server | mcp[cli] FastMCP |
| HTTP client | httpx |
| Frontend | Bootstrap 5, vanilla JS |
~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.