agent-skills
Retrieval-only MCP server that turns any knowledge source (Obsidian vault, notes, reference sets) into searchable Qdrant-backed skills, exposing list_skills, search_vault, and search_skill tools for agents to query via stdio or SSE.
README
agent-skills
Modular RAG skills for a self-hosted LLM agent, backed by Qdrant.
Most "chat with your Obsidian vault" projects embed a vector store inside the Obsidian app and stop there. This is a different shape. Any knowledge source (an Obsidian vault, a folder of notes, a reference set) becomes a skill the agent can search, all behind one interface. It targets a standalone agent (Ollama, an agent gateway, an MCP client) instead of living inside the note-taking app.
The Obsidian vault indexer is the main worked example. It is one skill, not the whole project.
The core idea: a skill is three things
skill = (Qdrant collection) + (manifest: where the docs live + how to chunk) + (retrieval hook)
Everything downstream is generic. Adding a knowledge skill is a manifest, not a rewrite:
NOTES = SkillManifest(name="work_notes", source_glob="~/notes/work/**/*.md")
register(NOTES) # chunk -> embed -> upsert
retrieve(NOTES.name, q) # embed query -> search -> context block
Architecture
sources ingestion Qdrant agent
vault / ----> chunk + embed ----> one collection ----> gateway / MCP
notes / (via Ollama) per skill injects context,
reference sets then answers
What the vault skill handles
The Obsidian loader (agent_skills/vault.py) does not treat notes as flat text:
- YAML frontmatter is parsed into payload metadata, not embedded as prose.
[[wikilinks]]are flattened to their display text for the embedding, and kept as alinkslist in the payload for graph-aware retrieval.#tags(inline and frontmatter) become filterable payload metadata.- Image embeds (
![[...]]) are dropped before embedding. - Incremental sync: each note is SHA-256 hashed, only changed notes are re-embedded, deleted notes are purged. The collection is not wiped per run.
- Deterministic chunk IDs (
uuid5(path:index)) so edits overwrite cleanly instead of duplicating.
Quickstart
pip install -r requirements.txt
# 1. bring up Qdrant locally
docker run -p 6333:6333 -v $(pwd)/qdrant_storage:/qdrant/storage qdrant/qdrant
# 2. pull an embedding model in Ollama
ollama pull nomic-embed-text
# 3. set VAULT_PATH in agent_skills/config.py, then index
python examples/index_vault.py sync
# 4. query
python examples/index_vault.py ask "how did I configure the network?"
Add your own skill
- Copy
examples/register_notes.py. - Write a
SkillManifestpointing at your docs. register()it. It is now a collection the agent queries like any other.
Plug into an agent (MCP)
examples/mcp_server.py exposes retrieval as MCP tools (list_skills,
search_vault, search_skill), so an MCP client can query the knowledge. The
surface is read-only: it retrieves, it does not write or take actions.
pip install "mcp[cli]"
python examples/mcp_server.py # stdio, for local MCP clients
For a local client (Claude Code, Cursor, Claude Desktop), point its MCP config at the script:
{
"mcpServers": {
"agent-skills": {
"command": "python",
"args": ["/absolute/path/to/examples/mcp_server.py"]
}
}
}
For a networked gateway, switch the transport to sse at the bottom of
mcp_server.py and point the gateway at http://<host>:8000/sse. The agent
calls search_vault(...), the tool returns a context block, and the gateway
feeds it into the model's context.
Config
Everything lives in agent_skills/config.py: Ollama URL, embedding model and
dimension, Qdrant host/port, chunk size and overlap. Swap the embedder freely,
but keep EMBED_DIM matched to the model or the upsert will reject.
Notes
- Local-first. Embeddings run on your own Ollama host; nothing leaves the network.
- Retrieval only. This gives an agent knowledge to reason over. It does not hand the agent tools to act on the world.
- Not an Obsidian plugin. It reads the vault as files; it does not run in the app.
- Early stage: the code is organized and syntax-clean, but run it against a live Qdrant and Ollama before relying on it.
License
MIT. See LICENSE.
Recommended Servers
playwright-mcp
A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.
Magic Component Platform (MCP)
An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.
Audiense Insights MCP Server
Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.
VeyraX MCP
Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.
graphlit-mcp-server
The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.
Kagi MCP Server
An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.
E2B
Using MCP to run code via e2b.
Neon Database
MCP server for interacting with Neon Management API and databases
Exa Search
A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.
Qdrant Server
This repository is an example of how to create a MCP server for Qdrant, a vector search engine.