Standalone FastAPI microservice that indexes Cursor-style skill folders and provides semantic search over them. Framework-agnostic — works with any domain's skills (web frameworks, DevOps patterns, data pipelines, infrastructure, etc.). Used by AI agents in the OPL Crew platform to discover coding conventions, architectural patterns, and best practices at query time.
This repository is read-only for skill content: it indexes and queries SKILL.md files. To search marketplaces, install skills from GitHub, or delete installed skills, use the separate Skill Manager service (port 8091), which writes into a shared marketplace directory and calls this service’s /reload endpoint after changes.
AI agents need to find the right skill at the right time — but they don't know the exact skill name or filename upfront. A keyword search would fail when an agent asks "how do I containerize this app" but the relevant skill is named containerfile-generator. Embeddings solve this by converting both the query and skill content into vector representations that capture meaning, not just words.
How it works: At startup, the service reads every SKILL.md, splits it into chunks, and passes each chunk through a local embedding model (BAAI/bge-small-en-v1.5). The resulting vectors are stored in a LlamaIndex VectorStoreIndex. When an agent queries "app folder structure conventions", the query is embedded into the same vector space and the closest skill chunks are returned — even if no words overlap exactly.
Advantages over keyword/filename lookup:
- Intent matching — "how to deploy this app in a container" finds the containerfile skill, the compose skill, and the scaffold skill in ranked order, without needing exact terms
- Cross-skill discovery — a single query can surface relevant chunks from multiple skills across different domains (e.g., querying "appointment management" returns both the data model patterns skill and the API hooks reference skill)
- Language-agnostic queries — agents can describe what they need in natural language rather than constructing structured filters
- Zero-config for new skills — drop a
SKILL.mdinto the skills directory, trigger/reload, and it's immediately searchable by meaning — no keyword tagging required - Small and fast — the
bge-small-en-v1.5model is 33MB, runs on CPU, and indexes 30+ skills in under 5 seconds. No GPU or external API needed
Tag filtering is available as an optional narrowing mechanism on top of semantic search for cases where agents want to restrict results to a specific domain (e.g., tags: ["python"] or tags: ["devops"]).
- Semantic search over skill documents using LlamaIndex + HuggingFace embeddings (
BAAI/bge-small-en-v1.5) - Tag-based filtering via YAML frontmatter in
SKILL.mdfiles - Multi-directory indexing — combine skills from multiple sources (e.g., general + framework-specific)
- MCP endpoint at
/mcpfor direct agent integration via Model Context Protocol - Hot-reload in development — edit skills and query immediately
- Cache invalidation — content-hash-based; automatically re-indexes when skill files change
pip install -e .
SKILLS_BASE_DIR=./path/to/skills uvicorn src.main:app --port 8090podman build -t skills-service .
podman run -p 8090:8090 -v ./skills:/app/skills:ro skills-serviceThis service is a Git submodule of opl_ai_mono at skills-service/. The Skill Manager is a sibling submodule at skill-manager/ (writes marketplace skills; this service reads them).
Clone the mono repo with submodules:
git clone --recurse-submodules https://github.com/varkrish/opl-crew-mono.git opl_ai_mono
# If you already cloned without submodules:
cd opl_ai_mono && git submodule update --init skills-service skill-managerFrom the mono repo root, dev-compose.yml mounts this repo’s src/ for the skills container and mounts skill-manager/ for the manager. Optional overrides in .env:
SKILLS_SERVICE_DIR=./skills-service
SKILL_MANAGER_DIR=./skill-manager
FRAPPE_SKILLS_DIR=/path/to/your/.cursor/skills # framework skills (read-only mount)Then:
cd opl_ai_mono
podman compose -f dev-compose.yml --profile skills up -dFor backend-only dev compose under opl-ai-software-team/, see that repo’s compose.dev.yaml (may differ from the mono dev-compose.yml).
From opl_ai_mono root, use dev-compose.skills.yml to run only skills-service and skill-manager with the same shared marketplace volume:
cd opl_ai_mono
podman compose -f dev-compose.skills.yml up -dMCP for agents remains at http://localhost:8090/mcp (see src/main.py — api.mount("/mcp", ...)).
| Method | Path | Description |
|---|---|---|
| GET | /health |
Liveness check |
| GET | /health/ready |
Readiness (200 when index is built, 503 otherwise) |
| GET | /skills |
List all discovered skills with metadata |
| POST | /query |
Semantic search: {"query": "...", "top_k": 3, "tags": ["python"]} |
| POST | /reload |
Trigger background re-index (returns 202) |
| * | /mcp |
MCP SSE endpoint for agent tool integration |
# Find containerization patterns
curl -X POST http://localhost:8090/query \
-H "Content-Type: application/json" \
-d '{"query": "containerfile best practices", "top_k": 3}'
# Narrow to a specific domain using tags
curl -X POST http://localhost:8090/query \
-H "Content-Type: application/json" \
-d '{"query": "app scaffold folder structure", "top_k": 3, "tags": ["python"]}'Each skill is a directory containing a SKILL.md with YAML frontmatter. Skills are domain-agnostic — add skills for any technology or pattern:
skills/
app-scaffold/
SKILL.md
containerfile-generator/
SKILL.md
react-component-patterns/
SKILL.md
kubernetes-deployment/
SKILL.md
api-design-patterns/
SKILL.md
SKILL.md format:
---
name: app-scaffold
description: Canonical folder structure for the target framework
tags:
- python
- scaffold
- architecture
---
# App Scaffold
...skill content (patterns, templates, examples, rules)...Index skills from multiple sources by setting SKILLS_BASE_DIRS (colon-separated):
SKILLS_BASE_DIRS=/app/skills/general:/app/skills/team-specific:/app/skills/framework-specificThis lets you maintain a shared base of skills alongside team or project-specific ones.
| Variable | Default | Description |
|---|---|---|
SKILLS_BASE_DIR |
/app/skills |
Single skill directory |
SKILLS_BASE_DIRS |
— | Colon-separated list of skill directories (overrides SKILLS_BASE_DIR) |
SKILLS_INDEX_CACHE_DIR |
~/.crew-ai/skill_index_cache |
Persistent index cache location |
HF_HOME |
— | HuggingFace model cache directory |
HF_HUB_OFFLINE |
0 |
Set to 1 to use cached models without network access |
skills-service/
├── src/
│ ├── main.py # FastAPI app factory, REST routes, MCP mount
│ ├── discovery.py # Skill folder scanner, frontmatter parser
│ ├── indexer.py # LlamaIndex vector index builder + cache
│ ├── mcp_server.py # FastMCP tools (query_skills, list_skills, reload_index)
│ └── config.py # Pydantic settings from env vars
├── tests/
│ ├── test_api.py
│ ├── test_discovery.py
│ └── test_mcp_server.py
├── Containerfile # Production image (UBI9 + Python 3.11)
└── pyproject.toml # Dependencies
pip install -e ".[test]"
pytestMIT