factum-mcp
1.2.4
dotnet tool install --global factum-mcp --version 1.2.4
dotnet new tool-manifest
dotnet tool install --local factum-mcp --version 1.2.4
#tool dotnet:?package=factum-mcp&version=1.2.4
nuke :add-package factum-mcp --version 1.2.4
Factum MCP Server
Your personal knowledge base with AI-powered fact management and semantic search
Factum is an MCP (Model Context Protocol) server that helps you store, organize, and query your personal knowledge. Use it to capture facts, approve staging entries, and build a growing repository of verified information with hybrid search (keyword + semantic).
๐ Quick Start
Option 1: .NET Global Tool (Recommended)
# Install
dotnet tool install -g factum-mcp
# Run
factum-mcp
Option 2: Manual Download (No .NET Required)
- Download the latest
factum-mcp-v*.zipfrom Releases - Extract to
C:\Tools\factum-mcp\ - Run
factum-mcp.exe
Option 3: Build from Source
# Clone and build
git clone https://github.com/romansource/factum-mcp
cd factum-mcp
dotnet build -c Release
# Run
dotnet run --project src/factum-mcp.csproj --no-build
๐ Embedding Setup (Optional)
Factum works with keyword-only search by default. For semantic search, configure an OpenAI-compatible embedding API:
๐ Local/Private (Recommended)
{
"Embedding__BaseUrl": "http://your-server:11434/v1",
"Embedding__ApiKey": "",
"Embedding__Model": "all-minilm:22m"
}
๐ก
your-servercan belocalhost,192.168.1.100, or any IP on your network.
๐ Ensure port11434is open on the embedding server if accessing remotely.
โ๏ธ Cloud/High-Quality
{
"Embedding__BaseUrl": "https://api.openai.com/v1",
"Embedding__ApiKey": "sk-...",
"Embedding__Model": "text-embedding-3-small"
}
๐งช Testing/Offline
Omit Embedding__BaseUrl โ Factum auto-fallbacks to keyword-only search.
โ ๏ธ Critical: If you change
Embedding__ModelorBaseUrl, runrebuild_embeddingsto re-embed all facts. Mixing embeddings from different models breaks semantic search.
โจ Key Features
| Feature | Description |
|---|---|
| ๐๏ธ Markdown Storage | Facts stored in plain Markdown for easy reading and editing |
| โ Enforced Staging | Propose โ Review โ Approve workflow prevents memory pollution |
| ๐ Hybrid Search | BM25 keyword + semantic embeddings for best results |
| ๐งฉ 11 MCP Tools | Search, retrieve, propose, approve, decline, update, list staging, quality check, summaries, rebuild embeddings |
| ๐ SQLite Backend | Local SQLite database for fast, reliable storage |
| ๐ Semantic IDs | Auto-generated IDs from fact descriptions for easy referencing |
| โก Embedding Cache | Skip re-embedding unchanged facts (saves time + API calls) |
| ๐ Auto-Reindex | File watcher auto-reloads facts.md changes (no restart needed) |
| ๐ Zero-Config Fallback | Auto-switches to keyword-only search if embedding server unreachable |
| ๐ก๏ธ Model Safety | EmbeddingModelIdentifier prevents silent corruption when switching models |
| ๐ Auto-Detect Dimensions | No manual config; detects vector dimensions on first run |
| ๐ Professional Logging | ILogger + relative file logging (logs/factum-.log) |
| ๐ฏ Token Budgeting | retrieve_relevant_facts guarantees context fits your LLM prompt |
๐ Configure MCP Client
Add the following to your MCP client's configuration (e.g., Cline's settings.json, OpenCode's mcp.json):
{
"mcpServers": {
"factum": {
"command": "factum-mcp",
"cwd": "${workspaceFolder}"
}
}
}
๐งฉ Available Tools
Because Factum implements the tools/list MCP capability, your client will automatically discover these tools and their input schemas:
search_facts: Search the knowledge base using BM25 + semantic vector similarity.retrieve_relevant_facts: Token-budgeted retrieval to fetch relevant facts while adhering to context limits.propose_fact: Propose a new fact for review. Goes to staging and is NOT searchable until approved.approve_fact: Approve a staging fact to move it to permanent, searchable storage.decline_fact: Reject a staging fact. Removes it permanently so it will never be auto-approved.list_staging_facts: List all facts pending approval in staging.update_fact: Propose an update to an existing fact (creates a staging entry for review).evaluate_fact_quality: Check for redundancy and quality before proposing a new fact.get_memory_summary: Provide a compact statistical breakdown and topic summary.generate_project_summary: Generate a comprehensive overview of the entire knowledge base.rebuild_embeddings: Re-embed all approved facts. Required after changing model or BaseURL.
๐ Staging Workflow: Drafts Before Publishing
Think of staging like a "drafts" folder โ the AI can suggest facts, but nothing becomes part of your permanent knowledge base until you approve it.
The Full Cycle
1. AI proposes a fact โ saved as a draft (not visible to the AI in conversation)
2. You review the draft โ either via the MCP tool or by opening the file
3. You either:
โ
Approve โ the fact becomes permanent and searchable
โ Decline โ the fact is permanently removed
Step-by-Step Example
You speak naturally. The LLM agent calls the tool behind the scenes:
user: Can you remember that git rebase is for linear history and merge is for shared branches?
The tool returns a structured review card:
๐ New Fact Proposed
โโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Description: Git Rebase vs Merge
Text:
Use git rebase for linear history on topic branches.
Use git merge for integrating shared branches.
โโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ ๏ธ REVIEW REQUIRED โ not searchable until approved
Staging ID: staging:a1b2c3d4
Actions:
โ approve_fact(id="staging:a1b2c3d4")
โ decline_fact(id="staging:a1b2c3d4")
You review and approve (after the 10-second delay):
user: approve_fact(id="staging:a1b2c3d4")
โ โ
Fact approved: fact:git/rebase-vs-merge
Or decline it if it's wrong:
user: decline_fact(id="staging:a1b2c3d4")
โ โ
Fact declined and removed
How to Review
You have two options:
| Method | How |
|---|---|
| MCP Tool (recommended) | Run list_staging_facts to see a JSON list of all pending facts with their IDs, descriptions, and text |
| File review | Open facts_staging.md in any text editor to read the raw Markdown |
Why the 10-Second Delay?
The system enforces a minimum 10-second wait between proposing and approving. This prevents the AI from auto-approving its own suggestions and gives you time to review.
What Happens to Unapproved Facts?
Staging facts accumulate in facts_staging.md until you approve or decline them. They are never visible to the AI during conversation, never returned in search results, and never included in memory summaries.
Config Options
{
"Staging": {
"RequireManualApproval": true, // Enforce review before approval
"MinApprovalDelaySeconds": 10 // Minimum seconds before approval allowed
},
"AutoProposal": { // Configuration for agent auto-proposing
"Enabled": true,
"RequireApproval": true, // Set false to bypass staging (use with caution)
"MinQualityScore": 70, // Only propose high-quality facts
"RepetitionWindowSeconds": 300, // Detect repeated topics in 5-min window
"RepetitionThreshold": 3, // Propose after 3 similar queries
"MaxProposalsPerSession": 20, // Rate limiting
"MaxProposalsPerHour": 50, // Hourly rate limiting
"CooldownSeconds": 30, // Minimum seconds between proposals
"TriggerOnLowRelevanceSearch": true,
"TriggerOnRepeatedQuery": true,
"TriggerOnLongResponse": false,
"IncludePatterns": [],
"ExcludePatterns": [],
"ExcludeTools": []
}
}
๐ค Auto-Proposal (Optional)
Factum can proactively suggest facts based on usage patterns. Configure via AutoProposal section:
{
"AutoProposal": {
"Enabled": true,
"RequireApproval": false, // Set false to bypass staging (use with caution)
"MinQualityScore": 70, // Only propose high-quality facts
"RepetitionWindowSeconds": 300, // Detect repeated topics in 5-min window
"RepetitionThreshold": 3, // Propose after 3 similar queries
"MaxProposalsPerSession": 20, // Rate limiting
"TriggerOnLowRelevanceSearch": true
}
}
๐ฏ Use Cases
| Setting | Behavior |
|---|---|
Enabled: false |
Passive mode (default) โ only propose when explicitly asked |
Enabled: true, RequireApproval: true |
Active assistant โ suggests facts, you review before approval |
Enabled: true, RequireApproval: false |
Highly proactive โ auto-saves high-quality facts directly (audit via auto_proposed: true frontmatter) |
๐ How Repetition Detection Works
- Factum tracks semantic hashes of queries/fact content per session
- If similar content (โฅ85% similarity) appears โฅ3 times in 5 minutes โ auto-propose
- Quality gate ensures only clear, non-redundant facts are proposed
โ ๏ธ Warning:
RequireApproval: falsebypasses the staging workflow. Use only if you trust the auto-proposal logic or plan to reviewfacts.mdregularly.
๐ Hybrid Search Explained
Factum uses a hybrid search algorithm combining:
- BM25 Keyword Scoring (40%): Fast, exact phrase matching.
- Cosine Similarity (60%): Semantic similarity using OpenAI-compatible embeddings, cached locally in SQLite.
(Falls back seamlessly to keyword-only search if the embedding server is unavailable).
๐ Facts File Format
Facts are stored in Markdown with frontmatter:
---
id: fact:async/await:patterns
description: Async/Await Patterns
created: 2026-03-30
---
Always await async calls to avoid deadlocks. Use ConfigureAwait(false) in libraries. CancellationToken for cleanup. Task.Run only for CPU-bound work; I/O is already async.
File Locations
| File | Purpose | Git Track? |
|---|---|---|
facts.md |
Approved/permanent facts | โ Yes (if sharing team knowledge) |
facts_staging.md |
Facts pending approval | โ No (personal workflow) |
factum.db |
SQLite database (with embeddings) | โ No (regenerated from facts.md) |
Recommendation: Add to .gitignore for personal use:
facts.md
facts_staging.md
factum.db
โ๏ธ Configuration
Configure via appsettings.json or environment variables:
| Variable | Default | Description |
|---|---|---|
Paths__Database |
factum.db |
SQLite database path |
Paths__FactsFile |
facts.md |
Approved facts file |
Paths__StagingFile |
facts_staging.md |
Staging facts file |
Embedding__BaseUrl |
(omitted) | OpenAI-compatible API base URL. If set + reachable โ enable semantic search. |
Embedding__ApiKey |
(omitted) | API key for cloud providers (omit for local Ollama). |
Embedding__Model |
nomic-embed-text |
Embedding model name. |
Embedding__TimeoutSeconds |
30 |
Request timeout in seconds. |
Retrieval__HybridWeight__bm25 |
0.4 |
BM25 weight in hybrid search (0-1) |
Retrieval__HybridWeight__embedding |
0.6 |
Embedding weight in hybrid search (0-1) |
Staging__RequireManualApproval |
true |
Require minimum delay before approval |
Staging__MinApprovalDelaySeconds |
10 |
Minimum seconds before approval |
AutoProposal__Enabled |
true |
Enable automated fact proposals |
AutoProposal__RequireApproval |
true |
Require manual approval before facts become searchable |
AutoProposal__MinQualityScore |
70 |
Minimum quality score (0-100) for auto-proposal |
AutoProposal__RepetitionWindowSeconds |
300 |
Time window in seconds to track repeated queries |
AutoProposal__RepetitionThreshold |
3 |
Number of similar queries within window to trigger proposal |
AutoProposal__SimilarityThreshold |
0.85 |
Similarity threshold (0-1) for considering queries the same |
AutoProposal__MaxProposalsPerSession |
20 |
Maximum auto-proposals per session |
AutoProposal__MaxProposalsPerHour |
50 |
Maximum auto-proposals per hour |
AutoProposal__CooldownSeconds |
30 |
Minimum seconds between auto-proposals |
AutoProposal__TriggerOnLowRelevanceSearch |
true |
Trigger when search results have low relevance |
AutoProposal__TriggerOnRepeatedQuery |
true |
Trigger when a query is repeated multiple times |
AutoProposal__TriggerOnLongResponse |
false |
Trigger after long LLM responses |
AutoProposal__IncludePatterns |
[] |
Patterns that must match description to propose |
AutoProposal__ExcludePatterns |
[] |
Patterns that skip auto-proposal if matched |
AutoProposal__ExcludeTools |
[] |
Tool names that never trigger auto-proposal |
๐งช Testing
The project includes an integration test suite with 40 tests covering all 11 MCP tools:
# Run integration tests
dotnet run --project integration_tests/integration_tests.csproj
Tests use a temporary directory with a fresh SQLite database and BM25 index, then clean up on exit. They validate both happy paths and error handling (missing params, invalid IDs, empty results).
Learn more about Target Frameworks and .NET Standard.
This package has no dependencies.
| Version | Downloads | Last Updated |
|---|