ep-mcp
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@ep-mcpsearch my ExpertPack for how multi-pack routing works"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
ep-mcp
Expertise-as-a-Service over the Model Context Protocol.
An MCP server that turns any ExpertPack into a live, queryable knowledge service. Any MCP-compatible agent (Claude Desktop, Cursor, Windsurf, Claude.ai, custom hosts) can connect and retrieve high-quality, provenance-rich domain expertise via standardized tools.
π expertpack.ai Β· π¦ ExpertPack Framework Β· π Architecture
97.6% retrieval hit rate / 0 full misses on a 22-question benchmark against a production v4.1 atomic-conceptual pack (658 chunks). Prior v4.0 baseline on the same pack and eval set: 65.1%.
Features
Schema-aware hybrid retrieval: BM25 + vector search (sqlite-vec), metadata boosting, MMR re-ranking, adaptive threshold filtering, length penalty
requires:expansion (schema v4.1 atomic-conceptual): When a top-K atom's frontmatter declaresrequires: [B, C], the referenced atoms are auto-appended to results as additionalSearchResults flaggedrequires_expanded=True. Directional (AβB does not imply BβA), transitive up to 2 hops, capped at 3 atoms and 3,500 cumulative tokens, appended after themax_resultsslice so it never displaces top-K.Intent-aware routing: Automatic query classification (ENTITY/HOW/WHY/WHEN/GENERAL) adjusts vector/BM25 fusion weights per query β no LLM required
Query embedding cache: SQLite-backed cache keyed by
(model, dimension, sha256(query))β warm query latency drops from ~4s (live Gemini API) to ~1msDeep graph traversal: Optional multi-hop BFS expansion over knowledge graph edges with per-hop score decay and drift prevention
Reserved-slot graph merge: Configurable protected slots in the final top-K reserved for graph-expanded neighbors so related files surface even against dominant core results
BM25 fallback mode: Embedding provider outage degrades gracefully to lexical-only search (coverage + density + path + length scoring) instead of a hard error
Cross-encoder reranker: Optional second-pass precision reranker (disabled by default, ~70ms warm latency when enabled)
Provenance-first: Every result includes
id,content_hash,verified_at,source_fileReconstruct mode (RFC-003): Opt-in
reconstruct=true/reconstruct: trueenriches results withfragment_id,line_range,original_markdown, span-levelcontent_hash,excerpt,stale, and byte offsets so agents can prove exactly what source text grounded an answerEP-native chunking: Files are treated as atomic retrieval units (split at
##/###only for oversized content). Split chunks keep the original span ascontent/span_hash, carry a computedline_range, and record aheading_path(0.7.0+)Heading paths (0.7.0+): every hit carries
heading_path(e.g.["Routing", "Setup", "Ports"]) so an H3 hit keeps its H2 parent;ep_read(path, section=..., neighbors=true)reads just that section plus its previous/next siblingsFreshness (0.7.0+, ExpertPack Core 4.2): hits and
ep_readcarryverified_age_days,age_stale(verified_atolder than the file'srefreshor the manifestfreshness.refresh_cycle),expiredandexpires_at(volatile TTL).stalekeeps its old meaning β index drift (file changed since indexing, reconstruct mode only). Optional down-rank viaretrieval.freshness_penalty(default0.0= off)Skills over MCP (0.7.0+, opt-in): set
mcp.skills.enabled: truein a pack'smanifest.yamlto declare theio.modelcontextprotocol/skillsextension (SEP-2640). Each pack becomes one skill atskill://{slug}/SKILL.md(generated) with every non-on_demandfile served verbatim atskill://{slug}/{path};skills/list/skills/getpublish the manifest with SHA-256 digests, sizes,ttlMsandcacheScope. Host support is still thin, so theep_*tools remain the primary pathFrontmatter aware: Strips metadata for embedding, extracts
type,tags,requires, etc. for boosting/expansion/filteringIncremental indexing: Content-hash based staleness detection β only re-embeds changed files
Multi-pack support: Path-based routing at
/packs/{slug}/mcpGraph-aware retrieval: optional post-retrieval expansion via
_graph.yamladjacency, including accepted ontology/entity nodes when graph export provides themcontext_prefix(RFC-004): sidecar situating strings are prepended at index time for embed + BM25 only; returned/reconstruct text stays the original atom bodyTier / navigation filter:
retrieval_strategy: navigation,_index.md,source-coverage.md, andcontext.on_demandfiles are excluded from the RAG pool (still readable viaep_read/ resources)Tools:
ep_searchβ primary hybrid retrieval toolep_readβ load a whole atom by path or provenance id (consume-loop step 2)ep_list_topicsβ browse pack structure and available content typesep_graph_traverseMulti-pack stdio support: All tools accept a
packparameter for routing when multiple packs are configured. Single-pack configs makepackoptional (defaults to the only configured pack).
Resources:
ep://{slug}/manifestep://{slug}/authorityep://{slug}/filesep://{slug}/file/{+path}(raw content with frontmatter)skill://{slug}/SKILL.md,skill://{slug}/{+path}(only whenmcp.skills.enabled: true)
Transports: Streamable HTTP (primary, cloud-ready), stdio (local dev)
stdio multi-pack support (0.6.0+): When using
--transport stdiowith multiple packs configured, all tools accept an optionalpackparameter (slug string) to specify which pack to query. For single-pack configurations, thepackparameter is optional and defaults to the only configured pack. This allows MCP hosts (Cursor, Claude Desktop) to use a single stdio process for multiple packs instead of requiring one process per pack.
HTTP endpoint:
GET /search(for non-MCP HTTP clients)Golden retrieval eval (0.7.0+):
tests/eval/β YAML query sets (expectedbest-first,must_not,category) scored as recall@1/3/5, MRR and must_not violations per pack and category. Skipped in the default run;pytest tests/eval -m golden --golden <dir> --packs-root <dir>withEP_EVAL_TODAY=2026-10-20and optionalEP_EVAL_MIN="recall@5=0.9,mrr=0.7", orpython tests/eval/golden_eval.py --golden <dir> --today 2026-10-20Auth: API key (Phase 1), designed for OAuth 2.1 (Phase 2)
Related MCP server: KaaS
Quick Start
Installation
git clone https://github.com/brianhearn/ep-mcp.git
cd ep-mcp
pip install -e .[dev]Configuration
Create config.yaml with at minimum:
server:
host: "127.0.0.1"
port: 8000
log_level: "info"
# Required for public Host headers (SDK v2 DNS-rebinding protection).
# See DEPLOYMENT.md β omit and Streamable HTTP returns 421.
mcp_allowed_hosts:
- "localhost"
- "localhost:*"
- "127.0.0.1"
- "127.0.0.1:*"
packs:
- slug: "my-pack"
path: "/path/to/your/expertpack"
api_keys:
- "your-secret-key-here"
embedding:
provider: "gemini" # "gemini" (default) or "azure-openai"
model: "gemini-embedding-001"For the full configuration reference β embedding providers, retrieval tuning (mmr_lambda, min_score, default_max_results, graph expansion, reranker, requires: expansion, etc.), production systemd setup, and deployment gotchas β see DEPLOYMENT.md.
Running
ep-mcp serve --config config.yamlThe server builds/updates the SQLite index (FTS5 + sqlite-vec) on startup. 0.5.0 requires a rebuild of existing indexes (index_features=context_prefix_v1+nav_filter_v1); startup does this automatically, or delete <pack>/.ep-mcp/ first.
The GET /search HTTP endpoint is available at:
GET /search?q=<query>&pack=<slug>&n=10
Add &reconstruct=true to include original markdown spans and provenance blocks for verification.
with header Authorization: Bearer <key>.
Environment Variables
Only the key for your configured embedding provider is required.
Variable | Required | Description |
| If | Gemini embedding API key |
| If | Azure OpenAI resource endpoint |
| If | Azure OpenAI API key |
| Optional | Per-pack API key override (uppercase slug, hyphensβunderscores) |
| Optional | Deploy target for |
| Optional | Remote source path for |
| Optional | Remote site-packages path for |
Tech Stack
Language: Python 3.12+
MCP Framework: official
mcpSDK v2 (MCPServer, spec 2026-07-28, dual-era with 2025 clients)Storage: SQLite with FTS5 + sqlite-vec
Embeddings: Gemini (default), configurable Azure OpenAI / OpenAI providers
Web: Starlette + Uvicorn (for Streamable HTTP)
CLI: Click
See pyproject.toml for exact dependencies.
Project Structure
See ARCHITECTURE.md for detailed module breakdown, retrieval pipeline, indexing strategy, and design decisions.
Related
expertpack.ai β Framework website, community packs, and documentation
ExpertPack β Schema framework, validation tools, Obsidian compatibility, community packs
ExpertPacks β Published knowledge packs (private)
EasyTerritory MCP (future) β Domain-specific layer built on top of this repo +
ezt-designerpack
License
Apache 2.0 Β© 2026 Brian Hearn
Author
Brian Hearn β Built in 3 days (April 10β11, 2026).
This server cannot be deployed
Maintenance
Related MCP Connectors
Remote MCP server exposing SMI Aware tools, resources, and skills over Streamable HTTP.
Agent-native MCP server over the public saagarpatel.dev corpus. Read-only, stateless.
Serve a folder of Markdown notes as an MCP server: hybrid search, reading, and sourced answers.
Turn a GitHub repo or docs site into agent-ready context: pack it or search it, over MCP.
Related MCP Servers
- FlicenseNot gradedqualityAmaintenanceExposes a compiled Markdown knowledge base to any MCP-capable coding agent through a single ask tool, returning cited answers grounded in full wiki articles over stdio or streamable HTTP.-
- FlicenseNot gradedqualityAmaintenanceExposes a compiled Markdown knowledge base to MCP-capable coding agents through a single ask tool that returns cited, Markdown-formatted answers grounded in whole wiki articles rather than embedded fragments. Runs locally over stdio or remotely over streamable HTTP with optional bearer-token authentication.-
- FlicenseNot gradedqualityAmaintenanceExposes a compiled Markdown knowledge base to MCP-capable coding agents through a single ask tool that returns cited answers grounded in whole wiki articles rather than embedded fragments. Supports local stdio and remote streamable-HTTP transports, with optional bearer-token authentication on the network transport.-
- AlicenseNot gradedqualityCmaintenanceEnables MCP-capable agents to search and answer over a local hybrid-retrieval knowledge base as tools, covering querying, grounded answering, index stats, corpus listing, and adding a website. Runs over stdio for local clients or HTTP for remote ones.MIT