Infinite Skills. Finite Context.
skills.rs is a unified MCP server that aggregates multiple upstream MCP servers and high-level Skills into a single, unified registry. It exposes 3 focused MCP tools to prevent context-window bloat while enabling unbounded tool/skill discovery and skill lifecycle management.
- π Unified Discovery - Search across all tools and skills from one interface
- π¦ Progressive Disclosure - Load skill content on-demand to save tokens (99% token reduction)
- π€ AI Agent CLI - Drop-in replacement for mcp-cli with enhanced features
- π Agent Skills Compatible - Import skills from Vercel skills.sh ecosystem (
skills add owner/repo) - π‘οΈ Sandboxed Execution - Safe execution with presets (dev, standard, strict, isolated, network, filesystem, wasm)
- π· WebAssembly Support - Run WASM bundled tools with memory/CPU limits
- πΎ Persistence - SQLite-based storage for registry and execution history
- β Validation - Comprehensive skill validation and dependency checking
- π Security - Multi-backend sandboxing with per-tool/server configuration
- π Production-Ready - Fully tested, documented, and hardened
-
CLI Mode (AI Agent Integration)
- Direct tool discovery and execution from command line
- Compatible with mcp-cli workflows
skills list,skills tool,skills exec,skills grepskills skill create,skills skill edit,skills skill delete,skills skill show
-
Server Mode (MCP Protocol)
- Run as MCP server exposing meta-tools
search,exec,manage- Aggregate multiple upstream MCP servers
- Create, update, delete skills via unified manage tool
# Install directly from GitHub (recommended)
cargo install --git https://github.com/labiium/skills
# Install skills.rs from Crates.io
cargo install skillsrs
# Or clone and build from source
git clone https://github.com/labiium/skills
cd skills
cargo build --releaseAfter installation, skills.rs will automatically use system-appropriate directories:
- Linux:
~/.local/share/skills,~/.config/skills - macOS:
~/Library/Application Support/skills,~/Library/Preferences/skills - Windows:
%APPDATA%\labiium\skills
View your paths with:
skills pathsSkills.rs supports both project-local and global configuration.
Initialize a project-local setup in the repo root:
skills initThis creates:
.skills/config.yaml.skills/skills/.skills/skills.db
skills will automatically discover the nearest .skills/config.yaml by walking up from the current directory.
Minimal .skills/config.yaml:
paths:
data_dir: ".skills"
skills_root: ".skills/skills"
database_path: ".skills/skills.db"
# Global sandbox defaults - all fields are optional!
# Sensible defaults are applied automatically:
# backend: timeout, timeout_ms: 30000, memory: 512MB, network: false
sandbox:
backend: timeout
timeout_ms: 30000
allow_read: []
allow_write: []
allow_network: false
max_memory_bytes: 536870912
max_cpu_seconds: 30
use_global:
enabled: false
upstreams: []
# ^ Add MCP servers here (see "Adding MCP Servers" section above)To disable sandboxing entirely:
sandbox:
backend: noneYou can override sandbox settings for specific MCP servers or tools using presets or fine-grained options:
upstreams:
# Uses default sandbox (timeout, 512MB, no network)
- alias: filesystem
transport: stdio
command: ["npx", "-y", "@modelcontextprotocol/server-filesystem", "."]
# Network-enabled preset for web tools
- alias: brave-search
transport: stdio
command: ["npx", "-y", "@modelcontextprotocol/server-brave-search"]
sandbox_config:
preset: network # One-liner configuration!
# Filesystem access with custom paths
- alias: custom-files
transport: stdio
command: ["./my-file-server"]
sandbox_config:
preset: filesystem
allow_read:
- /home/user/projects
- /tmp
allow_write:
- /tmp
# Untrusted tool - strict isolation (Linux bubblewrap)
- alias: untrusted
transport: stdio
command: ["./untrusted-mcp"]
sandbox_config:
preset: strict
timeout_ms: 5000 # Override preset default
# Least trusted tool - maximum Docker isolation
- alias: external-plugin
transport: stdio
command: ["./third-party-plugin"]
sandbox_config:
preset: isolated
docker:
image: "alpine:latest"
memory_limit: 134217728 # 128MB
cpu_quota: 0.25 # Quarter CPU
network_mode: "none" # Complete isolation
# WASM tool execution
- alias: wasm-tool
transport: stdio
command: ["wasm-mcp-runtime"]
sandbox_config:
preset: wasm
max_memory_bytes: 134217728 # 128MB for WASMAvailable Presets:
| Preset | Backend | Timeout | Memory | Network | Use Case |
|---|---|---|---|---|---|
default |
timeout | 30s | 512MB | β | Balanced (applied automatically) |
development |
timeout | 60s | 1GB | β | Local dev, trusted code |
standard |
timeout | 30s | 512MB | β | Production (same as default) |
strict |
bubblewrap | 10s | 256MB | β | Untrusted code, maximum security (Linux) |
isolated |
docker | 10s | 256MB | β | Least trusted code, container isolation |
network |
restricted | 30s | 512MB | β | API clients, web search |
filesystem |
restricted | 30s | 512MB | β | File editors, with path controls |
wasm |
wasm | 30s | 256MB | β | WebAssembly execution |
Configuration Precedence:
Global Defaults β Server Override β Tool Override
Global config is stored in the system config directory (varies by platform). To force using global config (ignore project .skills/config.yaml):
skills --global listYou can also point at a specific file:
skills --config /path/to/config.yaml listIf you want to use global upstreams/skills in addition to project ones, set in .skills/config.yaml:
use_global:
enabled: trueThis overlays project settings on top of the global config and appends project upstreams to the global list.
Environment Variable:
export SKILLS_PATH=/custom/skills
skills serverCommand-Line Override:
skills server --path /custom/skillsTo see the directories in use on your machine, run:
skills pathsStdio mode (for MCP clients):
skills server stdio
# or simply
skills server # stdio is the default modeHTTP mode (for testing):
skills server http --bind 127.0.0.1:8000MCP servers provide tools that skills.rs can aggregate and make available through its unified interface. In the configuration, MCP servers are defined under the upstreams key.
Add this to your .skills/config.yaml:
upstreams:
- alias: filesystem
transport: stdio
command: ["npx", "-y", "@modelcontextprotocol/server-filesystem", "."]Then verify it's working:
# List all available tools from all MCP servers
skills list
# You should see filesystem tools like:
# - filesystem/read_file
# - filesystem/write_file
# - filesystem/list_directoryupstreamsis the configuration key for MCP servers- Each upstream needs an
alias(how you'll reference it) and acommandto start the server transport: stdiois the most common transport (others:sse,websocket)- Multiple MCP servers can be added to the same
upstreamslist
upstreams:
- alias: filesystem
transport: stdio
command: ["npx", "-y", "@modelcontextprotocol/server-filesystem", "."]
- alias: brave-search
transport: stdio
command: ["npx", "-y", "@modelcontextprotocol/server-brave-search"]
env:
BRAVE_API_KEY: "${BRAVE_API_KEY}"
- alias: fetch
transport: stdio
command: ["uvx", "mcp-server-fetch"]For detailed MCP configuration options (environment variables, SSE transport, health checks), see OPERATIONS.md.
For a step-by-step tutorial, see TUTORIAL.md.
Skills.rs can replace mcp-cli while adding production features. Same workflow, better capabilities.
| Feature | mcp-cli | skills.rs |
|---|---|---|
| Token Reduction | 99% | 99% |
| CLI Interface | β | β |
| Persistence | β | β |
| Sandboxing | β | β |
| Per-Tool/Server Sandboxing | β | β |
| Sandbox Presets | β | β |
| WebAssembly Support | β | β |
| Skills | β | β |
| MCP Server Mode | β | β |
# List all servers and tools
skills list # Like: mcp-cli
skills list -d # With descriptions: mcp-cli -d
# Search for tools
skills grep "*file*" # Like: mcp-cli grep "*file*"
# Get tool schema
skills tool filesystem/read_file # Like: mcp-cli filesystem/read_file
# Execute a tool
skills tool filesystem/read_file '{"path": "./README.md"}'
# Like: mcp-cli filesystem/read_file '{"path": "./README.md"}'
# With JSON output
skills tool filesystem/read_file '{"path": "./README.md"}' --json
# Raw text only
skills tool filesystem/read_file '{"path": "./README.md"}' --raw# Create a new skill from file
skills skill create my-skill \
--description "My custom skill" \
--skill-md ./SKILL.md \
--uses-tools brave_search,grep
# Create skill with inline content
echo "# My Skill\n\nInstructions here" | skills skill create my-skill --content -
# Or provide content directly
skills skill create my-skill --content "# My Skill\n\nStep 1: Do this"
# Edit a skill - sed-like replacement
skills skill edit my-skill --replace "old text" --with "new text"
# Append to SKILL.md
skills skill edit my-skill --append "## Troubleshooting\n\nCommon issues..."
# Replace entire content from file
skills skill edit my-skill --skill-md ./updated-SKILL.md
# Or from stdin
cat ./updated-SKILL.md | skills skill edit my-skill --content -
# Show skill content
skills skill show my-skill
# Show specific file from skill
skills skill show my-skill --file helper.py
# Delete a skill (with confirmation)
skills skill delete my-skill
# Force delete without confirmation
skills skill delete my-skill --forceYou have access to MCP servers via the `skills` CLI.
Commands:
- `skills list` - List all servers and tools
- `skills list <server>` - Show server's tools
- `skills list -d` - Include descriptions
- `skills tool <server>/<tool>` - Get tool schema
- `skills tool <server>/<tool> '<json>'` - Execute tool
- `skills grep "<pattern>"` - Search by pattern
- `skills skill create <name> --description "..."` - Create a skill
- `skills skill edit <skill-id>` - Edit/update a skill
- `skills skill delete <skill-id>` - Delete a skill
- `skills skill show <skill-id>` - Display skill content
Workflow:
1. Discover: `skills list` or `skills grep "<pattern>"`
2. Inspect: `skills tool <server>/<tool>`
3. Execute: `skills tool <server>/<tool> '<json>'`
4. Manage: `skills skill create/edit/delete/show`Fast discovery over unified registry (tools + skills)
{
"q": "search the web",
"kind": "any",
"limit": 10
}Fetch full schema and signature for a callable without executing it
{
"id": "skill://web-researcher@1.0@abc123",
"describe": true,
"format": "json_schema"
}Execute a callable with validation and policy enforcement
{
"id": "skill://web-researcher@1.0@abc123",
"arguments": {"query": "latest AI news"},
"timeout_ms": 30000
}Unified skill lifecycle management: create, get, update, delete
Create a skill:
{
"operation": "create",
"name": "web-researcher",
"version": "1.0.0",
"description": "Research topics using web search",
"skill_md": "# Web Researcher\n\n...",
"uses_tools": ["brave_search"],
"bundled_files": [["script.py", "print('hello')"]]
}Get skill content (progressive disclosure):
{
"operation": "get",
"skill_id": "web-researcher",
"filename": "helper.py"
}Update a skill:
{
"operation": "update",
"skill_id": "web-researcher",
"name": "web-researcher",
"version": "1.1.0",
"description": "Updated description",
"skill_md": "# Updated content..."
}Delete a skill:
{
"operation": "delete",
"skill_id": "web-researcher"
}A skill is a package of agent instructions and optional bundled tools. Skills use progressive disclosure to minimize token usage:
Level 1: Metadata (name, description, tags) - always available
Level 2: SKILL.md (instructions) - loaded on demand
Level 3: Additional files - loaded progressively
Level 4: Execution - when agent is ready
.skills/
config.yaml # Project configuration
skills/ # Skills directory
my-skill/
SKILL.md # Instructions with YAML frontmatter (required)
scripts/ # Executable scripts (optional)
references/ # Reference docs (optional)
assets/ # Binary assets (optional)
skills.db # SQLite database
cache/ # Cache files
logs/ # Log files
---
name: web-researcher
description: Research topics using web search and summarization
version: 1.0.0
allowed-tools:
- brave_search
- filesystem_read
tags:
- web
- research
---
# Web Researcher
## Purpose
Research topics using web search and save findings.
## Steps
1. Call `brave_search` with the query
2. Read top 3 results using `filesystem_read`
3. Summarize findings
4. Save summary to file
## Tools Used
- `brave_search` - Search the web
- `filesystem_read` - Read web content
## Expected Output
A markdown file with research summary.skills.rs is fully compatible with the Agent Skills format pioneered by Vercel. You can import and use skills from the growing ecosystem of Agent Skills repositories.
Agent Skills is an open standard for packaging AI agent instructions and tools. A skill is a directory containing:
- SKILL.md with YAML frontmatter (required)
- scripts/ for bundled executables (optional)
- references/ for supporting documents (optional)
- assets/ for additional files (optional)
Import skills directly from GitHub repositories:
# Import all skills from a repository
skills add vercel-labs/agent-skills
# Import specific skill(s)
skills add wshobson/agents --skill monorepo-management
# Import from full GitHub URL
skills add https://github.com/owner/repo --skill skill-name
# Import multiple skills
skills add vercel-labs/agent-skills --skill web-design-guidelines --skill vercel-react-best-practices
# Specify git ref (branch, tag, or commit)
skills add owner/repo --skill my-skill --git-ref v1.0.0
# Force overwrite existing skills
skills add owner/repo --forceAdd Agent Skills repositories to your config.yaml for automatic synchronization:
agent_skills_repos:
# Import specific skills from Vercel's repository
- repo: "vercel-labs/agent-skills"
skills:
- "web-design-guidelines"
- "vercel-react-best-practices"
# Optional: specify git ref
# git_ref: "main"
# Import all skills from a repository
- repo: "wshobson/agents"
# Omit 'skills' to import all
# Full GitHub URL with version pinning
- repo: "https://github.com/owner/repo"
skills:
- "monorepo-management"
git_ref: "v1.0.0"Skills are automatically synced on server startup and can be manually synced with:
skills syncSync behavior:
- β Adds new skills from configured repositories
- π Updates existing skills when commit SHA changes
- ποΈ Removes skills from repositories deleted from config
- π Validates all skills against Agent Skills specification
Here's a minimal Agent Skill (SKILL.md):
---
name: pdf-processing
description: Extract text and tables from PDF files using Python tools
license: MIT
compatibility: Works best with Claude and GPT-4
metadata:
author: your-name
version: "1.0.0"
allowed-tools: Bash(python3) Read Write
---
# PDF Processing
Extract and process content from PDF files.
## Purpose
This skill helps you extract text, tables, and metadata from PDF documents.
## Steps
1. Use the `extract.py` script to process the PDF
2. Parse the extracted text
3. Save results to a structured format
## Tools Used
- `python3` - Run the extraction script
- File system tools for reading/writing
## Expected Output
JSON file containing extracted text and tables.With optional scripts/extract.py:
#!/usr/bin/env python3
import sys
import json
# PDF extraction logic hereskills.rs supports all Agent Skills features:
| Feature | Supported | Notes |
|---|---|---|
| YAML frontmatter | β | Full spec compliance |
| Name validation | β | Lowercase, hyphens, 1-64 chars |
| Field constraints | β | Description β€1024, compatibility β€500 |
| scripts/ | β | Python, Bash, Node.js |
| references/ | β | Progressive disclosure |
| assets/ | β | Progressive disclosure |
| allowed-tools | β | Maps to tool_policy.allow |
| Recursive discovery | β | Finds skills in nested directories |
| Mixed formats | β | Agent Skills + skills.rs formats coexist |
skills.rs automatically detects skill format:
- Has
SKILL.md: Agent Skills format (YAML frontmatter + markdown) - No
SKILL.md: Not a valid skill
Skills are seamlessly converted to the unified internal format and available through the MCP tools.
Agent Skills leverage progressive disclosure to minimize token usage:
Level 1 (always loaded): Name, description, metadata
Level 2 (on-demand): SKILL.md content
Level 3 (on-demand): references/, assets/ files
Level 4 (execution): scripts/ bundled tools
Use get_content to load additional content:
{
"skill_id": "pdf-processing",
"filename": "references/guide.md" // optional
}While fully compatible, skills.rs adds enterprise features:
| Feature | skills.sh | skills.rs |
|---|---|---|
| Skill import | β | β |
| GitHub shorthand | β | β |
| Config-based sync | β | β |
| Auto cleanup | β | β |
| MCP server mode | β | β |
| Sandboxing | β | β |
| Per-Tool/Server Sandboxing | β | β |
| Sandbox Presets | β | β |
| WebAssembly Support | β | β |
| SQLite persistence | β | β |
| Tool validation | β | β |
| Risk assessment | β | β |
# Import skills
skills add <owner/repo> [--skill <name>] [--git-ref <ref>] [--force]
# Sync from config
skills sync
# List all skills (including Agent Skills)
skills list
# Search for skills
skills grep "*pdf*"
# Get skill schema
skills tool local/pdf-processing
# Show system paths
skills pathsUnlike Vercel's skills.sh, skills.rs does not send telemetry data. All skill operations are local and private.
skills.rs supports multiple sandboxing backends:
| Backend | Security Level | Platform | Use Case |
|---|---|---|---|
none |
All | Development only | |
timeout |
π‘ Basic | All | Basic timeout enforcement |
restricted |
π Medium | Unix | Resource limits, temp dir isolation |
bubblewrap |
π’ High | Linux | Container isolation (recommended for Linux) |
docker |
π’ High | All (requires Docker) | Container isolation (cross-platform) |
wasm |
π΅ High | All | WebAssembly runtime with WASI |
Zero-config (uses defaults):
upstreams:
- alias: my-server
transport: stdio
command: ["./my-mcp-server"]
# No sandbox_config needed - uses secure defaults!Development:
sandbox:
preset: development # 60s timeout, 1GB RAM, network enabledProduction (Linux with bubblewrap):
sandbox:
preset: strict # bubblewrap, 10s timeout, 256MB, no networkMaximum isolation (Docker, cross-platform):
sandbox:
preset: isolated # Docker container, 10s timeout, 256MB, no networkLeast trusted tools (explicit Docker config):
upstreams:
- alias: untrusted-external-tool
transport: stdio
command: ["./potentially-risky-mcp-server"]
sandbox_config:
preset: isolated
docker:
image: "alpine:latest" # Minimal attack surface
memory_limit: 134217728 # 128MB
cpu_quota: 0.25 # Quarter CPU
network_mode: "none" # Complete network isolation
auto_remove: true # Clean up after executionWebAssembly bundled tool:
skills/my-skill/
SKILL.md
tool.wasm # WASM bundled toolThe WASM module should export:
fn run(input_ptr: i32, input_len: i32) -> i32- Execute with JSON inputmemoryexport - For data transfer
Arguments and results are passed as JSON strings via WASM linear memory.
Choose the right preset for your use case:
# Development - minimal restrictions
sandbox_config:
preset: development
# Production - balanced security (default)
sandbox_config:
preset: standard
# High security - untrusted code (Linux bubblewrap)
sandbox_config:
preset: strict
# Maximum isolation - least trusted code (Docker, cross-platform)
sandbox_config:
preset: isolated
# Network tools - web search, APIs
sandbox_config:
preset: network
# File tools - with path restrictions
sandbox_config:
preset: filesystem
allow_read:
- /home/user/projects
allow_write:
- /tmp
# WASM execution - memory-safe
sandbox_config:
preset: wasm
max_memory_bytes: 134217728 # 128MBNo configuration = secure defaults automatically applied:
- Backend:
timeout - Timeout: 30 seconds
- Memory: 512 MB
- Network: Disabled
- CPU: 30 seconds
β
Resource Limits - CPU, memory, file descriptors
β
Timeout Enforcement - Prevents runaway scripts
β
Per-Tool/Server Sandboxing - Different security levels per component
β
Preset-Based Configuration - Easy security profiles (dev, standard, strict, isolated)
β
Docker Sandboxing - Cross-platform container isolation
β
Path Traversal Protection - Validates all file paths
β
Circular Dependency Detection - Prevents infinite loops
β
Environment Sanitization - Removes dangerous env vars
β
Network Blocking - Per-server network access controls
β
WASM Isolation - Memory-safe WebAssembly execution
β
Execution Auditing - All executions logged to database
All data is persisted to SQLite:
- Callable Registry - Tools and skills with metadata
- Execution History - Complete audit trail
- Server State - Configuration and runtime state
persistence:
enabled: true
database: "./data/skills.db"
prune_after_days: 30Query execution history:
let history = persistence.get_execution_history(&callable_id, 100).await?;# All tests (70+ passing)
cargo test --workspace --all-features
# Unit tests only
cargo test --workspace --lib
# Integration tests
cargo test --test integration_test
# WASM and sandbox tests
cargo test --test wasm_sandbox_test
# Specific crate
cargo test -p skillsrs-skillstore- β 70+ tests passing
- β Unit tests for all core functionality
- β 7 integration tests for full lifecycle
- β 33 WASM and sandbox configuration tests
- β Sandbox backend tests (all 5 backends)
- β Validation tests
- β Persistence tests
| Operation | Time | Notes |
|---|---|---|
| Skill search | <10ms | Tantivy index |
| Registry lookup | <1ms | HashMap |
| Content loading | ~1ms | Single file read |
| Bundled tool (Python) | 50-200ms | Interpreter startup |
| Persistence save | ~2ms | SQLite insert |
Tested at scale:
- 100 skills: No degradation
- 1,000 callables: <1ms lookup
- 10,000 execution records: <10ms query
FROM rust:1.70 AS builder
WORKDIR /app
COPY . .
RUN cargo build --release
FROM debian:bookworm-slim
RUN apt-get update && apt-get install -y \
python3 bash bubblewrap ca-certificates \
&& rm -rf /var/lib/apt/lists/*
COPY --from=builder /app/target/release/skills /usr/local/bin/skills
COPY config.yaml /etc/skills/config.yaml
EXPOSE 8000
CMD ["skills", "http", "--config", "/etc/skills/config.yaml"]docker build -t skills:latest .
docker run -p 8000:8000 -v ./skills:/var/lib/skills skills:latest- OS: Linux (recommended), macOS, Windows
- CPU: 1+ cores
- RAM: 512MB+ (1GB+ recommended)
- Disk: 100MB+ for binary, varies for skills
- Dependencies:
- Python 3.8+ (for .py bundled tools)
- Bash 4.0+ (for .sh bundled tools)
- bubblewrap (for container sandboxing on Linux)
- Docker (for Docker sandboxing backend)
- wasmtime compatible system (for WASM backend)
- PROMPT_CLI.md - System prompt for AI agents using
skillsCLI (~300 Tokens) - PROMPT_MCP.md - System prompt for AI agents using skills.rs as MCP server (~390 Tokens but may not be necessary)
- TUTORIAL.md - Step-by-step tutorial for getting started with skills.rs and MCP servers
- QUICKSTART.md - Quick getting started guide
- OPERATIONS.md - Complete operations guide (deployment, configuration, CLI usage)
- MCP_GUIDE.md - Detailed guide for configuring and using MCP servers
- CHANGELOG.md - Version history and changes
- config.example.yaml - Full configuration reference
βββββββββββββββββββββββββββββββββββββββββββ
β MCP Client (Agent) β
ββββββββββββββββ¬βββββββββββββββββββββββββββ
β MCP Protocol
ββββββββββββββββΌβββββββββββββββββββββββββββ
β SkillsServer (3 MCP Tools) β
ββββ¬βββββββ¬βββββββ¬βββββββ¬ββββββββββββββββββ
β β β β
ββββΌβββ βββΌβββ ββΌββββ ββΌβββββββββ
βReg. β βSrchβ βRun β βSkillStorβ
ββββ¬βββ ββββ¬ββ βββ¬βββ ββββ¬βββββββ
β β β β
β β ββββΌβββ β
β β βSdbx β β
β β βββββββ β
ββββΌββββββββΌββββββββββββββΌβββββββ
β Persistence (SQLite) β
ββββββββββββββββββββββββββββββββββ
Contributions welcome! Please:
- Fork the repository
- Create a feature branch
- Add tests for new features
- Ensure all tests pass:
cargo test --workspace - Submit a pull request
Apache License, Version 2.0 (LICENSE)
- Issues: GitHub Issues
- Discussions: GitHub Discussions
- Documentation: See
docs/directory
Built with π¦ Rust | Powered by the MCP Protocol