Skillz
Self-extending MCP server - build and execute custom AI tools at runtime
Installation
npx skillzAsk AI about Skillz
Powered by Claude Β· Grounded in docs
I know everything about Skillz. Ask me about installation, configuration, usage, or troubleshooting.
0/500
Reviews
Documentation
π Skillz - Self-Extending MCP Server
Build and execute custom tools at runtime. Let your AI create its own tools.
Install β’ Configure β’ Features β’ Examples β’ Documentation
π― Why Skillz?
Traditional MCP servers have a fixed set of tools. Skillz lets your AI create new tools on the fly.
β Traditional MCPπ Fixed Tool Set β¬οΈ Deploy & Restart β±οΈ Time Consuming |
β Skillzπ§ Dynamic Tools β‘ Instant π Zero Downtime |
Example: "Build me a tool that fetches weather data" β AI writes the code β Tool is instantly available.
No deployments. No restarts. Just ask.
β‘ Installation
# Install WASM target (required for building tools)
rustup target add wasm32-wasip1
# Install Skillz from crates.io
cargo install skillz
β οΈ Important: Make sure
~/.cargo/binis in your PATH so your editor can find theskillzexecutable.
Or build from source:
git clone https://github.com/Algiras/skillz.git
cd skillz/mcp-wasm-host
cargo install --path .
β Support Skillz
If you find Skillz useful, please consider supporting its development:
Your support enables new features and improvements!
π§ Editor Configuration
Cursor IDE
Add to ~/.cursor/mcp.json:
{
"mcpServers": {
"skillz": {
"command": "skillz"
}
}
}
2. Configure MCP Client
Add the following to your MCP settings file (e.g., ~/Library/Application Support/Claude/claude_desktop_config.json):
{
"mcpServers": {
"skillz": {
"command": "/Users/YOUR_USERNAME/.cargo/bin/skillz"
}
}
}
[!TIP] If you encounter a
spawn skillz ENOENTerror, it means your client can't find the binary. Using the absolute path (usually~/.cargo/bin/skillz) fixes this!
Note: If
skillzisn't in your PATH, use:~/.cargo/bin/skillz
HTTP Server Mode (v0.4.0+)
Run Skillz as an HTTP server for web integrations:
# Start HTTP server on port 8080
skillz --transport http --port 8080
# Custom host binding
skillz --transport http --host 0.0.0.0 --port 3000
# Enable hot reload (watch tools directory for changes)
skillz --hot-reload
# HTTP server with hot reload
skillz --transport http --port 8080 --hot-reload
Endpoints:
GET /sse- Server-Sent Events stream for real-time updatesPOST /message- Send JSON-RPC messages
Connect with curl:
# Establish SSE connection
curl -N http://localhost:8080/sse -H 'Accept: text/event-stream'
# Send a message (in another terminal)
curl -X POST http://localhost:8080/message \
-H 'Content-Type: application/json' \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'
π― Features
π Core Capabilities
| Feature | Description |
|---|---|
| π¦ WASM Tools | Compile Rust β WebAssembly at runtime |
| π¦ Rust Crates | Add serde, regex, anyhow, etc. to WASM tools! |
| π Script Tools | Python, Node.js, Ruby, Bash, or any language |
| π MCP Integration | Import external stdio MCP servers, expose tools under namespaces |
| π·οΈ Tool Annotations | Hints for clients (readOnly, destructive, idempotent) |
| β‘ Code Execution | Compose multiple tools via code (98% token savings!) |
| π¦ Dependencies | Auto-install pip/npm/cargo packages per tool |
| π³ Docker Services | Define & manage Docker services tools depend on |
| πΎ Persistence | Tools survive server restarts |
| π Sandbox | Optional bubblewrap/firejail/nsjail isolation |
| π Shareable | Each tool has its own directory with manifest.json |
| π Dynamic Guide | Built-in skillz://guide resource updates automatically |
| π Tool Import | Import tools from GitHub repos or Gists |
| βοΈ Pipelines | Chain tools together declaratively |
| π HTTP Transport | Run as HTTP server with SSE for web apps |
| π¬ Elicitation | Scripts can request user input via MCP protocol |
| π§ Memory | Persistent key-value storage with TTL support |
| π¦ Resources | Tools can list and read server resources |
| π Secrets | Forward SKILLZ_* env vars to tools |
| π Tools/Call | Tools can call other registered tools |
| π‘ Streaming | Progressive output via stream chunks |
| π Logging/Progress | Scripts can send logs and progress updates |
| π₯ Hot Reload | Watch tools directory, auto-reload on changes |
| π¦ Versioning | Auto-backup on update, rollback to any version |
| π Subscriptions | Subscribe to resource updates, get notified on changes |
| π listChanged | Hot reload emits MCP list changed notifications |
| π― _meta Support | Progress tokens forwarded from MCP requests |
| β Cancellation | Handle cancellation requests for running tools |
| π‘ Built-in Prompts | 6 native prompts for creating tools via MCP protocol |
| π Progressive Disclosure | Tools appear only when their skill is activated |
| π¦ Skill Bundles | Activate multiple skills with @bundle-name |
| π Skill Dependencies | Skills can declare dependencies, auto-activated |
| π€ LLM Discovery | suggest_skill uses sampling to recommend skills |
| π Git Skill Repos | Clone skill repos from GitHub with add_skill_repo |
| π Knowledge Skills | SKILL.md files as prompts (Claude Skills compatible) |
π Available Tools (15 Core)
| Tool | Description |
|---|---|
build_tool | Compile Rust code β WASM tool (with crate dependencies) |
register_script | Register script tool (Python, Node.js, etc.) with deps |
call_tool | Execute any tool (WASM, Script, Pipeline, or MCP) |
list_tools | List all available tools |
delete_tool | Remove a tool and clean up |
import_tool | Import tools from Git repos or GitHub Gists |
import_mcp | Register external MCP servers under a namespace |
execute_code | Run code that composes multiple tools |
pipeline | Create, list, delete pipeline tools (action-based) |
memory | Persistent storage for tools (store, get, list, delete, stats) |
version | List versions, rollback to previous, view version info |
services | Define & manage Docker services for tools |
activate_skill | Enable a skill (or @bundle) to make its tools visible |
deactivate_skill | Hide a skill's tools to reduce noise |
suggest_skill | LLM-powered skill recommendations |
add_skill_repo | Clone skill repositories from Git (GitHub, etc.) |
π Skill Repositories
Import skills from Git repositories (compatible with Claude Skills format):
# First, activate dev tools
activate_skill(name="dev")
# Import a skill repository
add_skill_repo(url="https://github.com/kepano/obsidian-skills")
# β "Added repo 'obsidian-skills' with 3 skills: obsidian-markdown, obsidian-bases, json-canvas"
# Import awesome-claude-skills (23+ skills!)
add_skill_repo(url="https://github.com/ComposioHQ/awesome-claude-skills", branch="master")
# β "Added repo 'awesome-claude-skills' with 23 skills: mcp-builder, webapp-testing, ..."
Supported repo layouts:
skills/skill-name/SKILL.md(kepano/obsidian-skills style)skill-name/SKILL.mdat root (ComposioHQ/awesome-claude-skills style)
Skills appear as prompts - use prompts/get(name="skill-name") to retrieve knowledge.
π Progressive Disclosure
Tools are organized into skills that can be activated/deactivated:
# See what's available
suggest_skill(context="I want to build an MCP server")
# β "Suggested skills: dev, mcp-builder"
# Activate skills
activate_skill(name="dev") # Enable developer tools
activate_skill(name="@dev-full") # Enable bundle: dev + sys + memory
# Create a tool (it's hidden by default)
register_script(name="my-tool", code="...")
activate_skill(name="my-tool") # Now it's visible
# Hide when done
deactivate_skill(name="my-tool")
Virtual Skills:
| Skill | Tools |
|---|---|
dev | register_script, build_tool, import_mcp, add_skill_repo, etc. |
sys | pipeline, services, call_tool_internal |
memory | memory |
Bundles (~/.gemini/skills/bundles.json):
{
"@dev-full": ["dev", "sys", "memory"],
"@creators": ["dev"]
}
π‘ Quick Examples
π₯ See Skillz in Action
π¦ Build a WASM Tool (Rust)
build_tool(
name: "fibonacci",
description: "Generates Fibonacci numbers",
code: "fn main() {
let (mut a, mut b) = (0u64, 1);
for _ in 0..20 { print!(\"{} \", a); (a, b) = (b, a + b); }
}",
annotations: {"readOnlyHint": true}
)
π Import an External MCP Server
# Register a stdio MCP server - all its tools become available under a namespace
import_mcp(
name: "time",
command: "uvx",
args: ["mcp-server-time"],
description: "Time utilities from MCP server"
)
# Now use its tools with the namespace prefix
call_tool(tool_name: "time_get_current_time", arguments: {"timezone": "UTC"})
# Use MCP tools in pipelines!
pipeline(
action: "create",
name: "world_clock",
steps: [
{ name: "ny", tool: "time_get_current_time", args: { timezone: "America/New_York" } },
{ name: "london", tool: "time_get_current_time", args: { timezone: "Europe/London" } },
{ tool: "word_counter", args: { text: "NY: $ny.datetime, London: $london.datetime" } }
]
)
Note: Only stdio MCP servers are supported (command + args). HTTP/SSE servers are not yet supported.
> **π€ For LLMs & Advanced Users**
> See [docs/LLM_GUIDE.md](docs/LLM_GUIDE.md) for detailed technical specifications, JSON-RPC protocols, script templates, and advanced usage examples.
---
## π§ Environment Variables
| Variable | Description | Example |
|----------|-------------|---------|
| `TOOLS_DIR` | Where tools are stored | `~/.skillz/tools` |
| `SKILLZ_ROOTS` | Workspace roots (colon-separated) | `/home/user/project:/data` |
| `SKILLZ_SANDBOX` | Sandbox mode | `bubblewrap`, `firejail`, `nsjail` |
| `SKILLZ_SANDBOX_NETWORK` | Allow network in sandbox | `1` |
| `SKILLZ_*` | **Forwarded to tools** (for secrets) | `SKILLZ_OPENAI_KEY=sk-...` |
**Root Priority:** MCP client roots > `SKILLZ_ROOTS` env > cwd
### π Secrets via Environment Variables
All `SKILLZ_*` prefixed env vars are forwarded to script tools:
```bash
# Set secrets in your shell
export SKILLZ_OPENAI_KEY="sk-..."
export SKILLZ_API_TOKEN="your-secret"
export SKILLZ_DEBUG="1"
Access in tools via context.environment:
env = request["params"]["context"]["environment"]
api_key = env.get("SKILLZ_OPENAI_KEY")
Note: Only
SKILLZ_*vars are forwarded. Other env vars are not exposed to tools for security.
π³ Docker Services
Tools can declare dependencies on Docker services (databases, caches, etc.). When a tool runs, Skillz checks if required services are running and injects connection environment variables.
Define a Service
services(
action: "define",
name: "postgres",
image: "postgres:15",
ports: ["5432"],
env: {"POSTGRES_PASSWORD": "dev"},
volumes: ["data:/var/lib/postgresql/data"],
healthcheck: {
cmd: "pg_isready -U postgres",
interval: "2s",
retries: 15
}
)
Manage Services
# List all defined services
services(action: "list")
# Start a service
services(action: "start", name: "postgres")
# Check status (running, ports, health)
services(action: "status", name: "postgres")
# View logs
services(action: "logs", name: "postgres", tail: 100)
# Stop/remove services
services(action: "stop", name: "postgres")
services(action: "remove", name: "postgres")
# Cleanup unused services
services(action: "prune")
Tools with Service Dependencies
Register a tool that requires services:
register_script(
name: "user_manager",
description: "Manage users in PostgreSQL",
interpreter: "python3",
requires_services: ["postgres"], # Tool requires postgres to be running
dependencies: ["psycopg2-binary"],
code: """
import json, sys, os
import psycopg2
request = json.loads(sys.stdin.readline())
args = request["params"]["arguments"]
# Connection details injected by Skillz
conn = psycopg2.connect(
host=os.environ["POSTGRES_HOST"], # Auto-injected
port=os.environ["POSTGRES_PORT"], # Auto-injected
user="postgres",
password="dev",
dbname="postgres"
)
# ... your code
"""
)
When calling user_manager, Skillz will:
- Check if
postgresservice is running - If not running, return a helpful error with fix command
- If running, inject
POSTGRES_HOSTandPOSTGRES_PORTenv vars
Volume Types
| Type | Syntax | Description |
|---|---|---|
| Named | data:/path | Docker-managed volume, prefixed with skillz_ |
| Bind | /host/path:/container/path | Mount host directory into container |
π Security
Platform Support
π‘οΈ Sandbox Modes (Linux Only)
Enable sandboxing via environment variable:
| Sandbox | Security Level | Features |
|---|---|---|
| π’ bubblewrap | Medium | Namespace isolation |
| π‘ firejail | High | seccomp + namespaces |
| π΄ nsjail | Very High | Most restrictive |
Configuration:
# Bubblewrap (namespace isolation)
export SKILLZ_SANDBOX=bubblewrap
# Firejail (seccomp + namespaces)
export SKILLZ_SANDBOX=firejail
# nsjail (most restrictive)
export SKILLZ_SANDBOX=nsjail
# Allow network in sandbox
export SKILLZ_SANDBOX_NETWORK=1
π See SECURITY.md for full details.
π οΈ Development
git clone https://github.com/Algiras/skillz.git
cd skillz
cargo build --release
cargo test
π€ Contributing
See CONTRIBUTING.md for guidelines.
π License
MIT License - see LICENSE
π Links
| Resource | Link |
|---|---|
| π¦ Crates.io | crates.io/crates/skillz |
| π Documentation | algiras.github.io/skillz |
| π» GitHub | github.com/Algiras/skillz |
| π MCP Spec | modelcontextprotocol.io |
Built with β€οΈ for AI-powered development
