Implementation Guide
A checklist for implementing a Skills Protocol-compliant runtime. This guide covers MVP requirements and recommended best practices.
Overview
To implement a Skills Runtime, you need:
- Transport — JSON-RPC 2.0 over HTTP
- Storage — Skill registry and blob storage
- Methods — Implement 8 core methods
- Runtime — Sandbox execution environment
- Safety — Permission enforcement and resource limits
- Testing — Verify protocol compliance
Transport layer
Requirements
- HTTP endpoint (typically
/rpc) handling POST requests - JSON-RPC 2.0 compliance
- Parse
jsonrpc,id,method,paramsfields - Return
resulton success,erroron failure - Preserve request
idin responses
- Parse
Implementation example
from flask import Flask, request, jsonify
app = Flask(__name__)
@app.route('/rpc', methods=['POST'])
def rpc_endpoint():
payload = request.json
method = payload.get('method')
params = payload.get('params', {})
id_ = payload.get('id')
try:
result = handle_method(method, params)
return jsonify({
"jsonrpc": "2.0",
"id": id_,
"result": result
})
except Exception as e:
return jsonify({
"jsonrpc": "2.0",
"id": id_,
"error": {
"code": -32603,
"message": str(e)
}
})
def handle_method(method, params):
if method == "list_skills":
return list_skills(params)
elif method == "execute_skill":
return execute_skill(params)
# ... etc
Storage
Skills registry
Skills are stored as directories with the following structure:
/skills_root/
<skill_name>/
skill.toml
SKILL.md
code/
resources/
- Load skills on startup or on-demand
- Support skill versioning (latest-by-default pattern)
- Validate
skill.tomlformat - Index for fast lookup by name and namespace
Blob storage
Blobs are stored as files with unique IDs:
/blobs/
blob_abc123.txt
blob_def456.json
blob_ghi789.csv
- Generate unique blob IDs (e.g., random or UUID-based)
- Store MIME type metadata with each blob
- Support reading full or partial content
- Implement TTL or cleanup policy
Methods
Discovery (3 methods)
-
list_skills
- Filter by namespace
- Support
detaillevels (names, summary) - Pagination with cursor
- Deterministic sort order
-
describe_skill
- Parse and return
skill.tomlmanifest - Extract SKILL.md frontmatter
- Support
detaillevels (manifest, summary, full) - Handle version parameter
- Parse and return
-
read_skill_file
- Read arbitrary files from skill directory
- Enforce path restrictions (no
../escapes) - Return error for non-existent files
Execution (2 methods)
-
execute_skill
- Load skill's entrypoint module
- Create sandbox with resource limits
- Mount
input_blobs - Enforce
timeout_ms - Capture output, logs, created blobs
- Return structured result
-
run_code
- Accept Python code (MVP)
- Mount requested skills
- Mount input blobs
- Provide
runtimehelpers - Same result format as
execute_skill
Blobs (2 methods)
-
create_blob
- Store content with MIME type
- Generate unique blob ID
- Return blob ID and size
-
read_blob
- Support sampling modes:
sample_head,sample_tail,full - Respect
max_byteslimit - Return truncation flag
- Include MIME type in response
- Support sampling modes:
Bootstrap (1 method)
- load_skills_protocol_guide
- Return canonical guide content
- Consistent across all runtime instances
Runtime environment
Sandbox creation
- Create isolated execution environment (process, container, or VM)
- Run as non-root user
- Enforce CPU limits (e.g., 1 core)
- Enforce memory limits (e.g., 512MB - 4GB)
- Enforce wall-clock time limits
- Clean
/workspace/after execution
Resource mounting
- Mount skills as read-only at
/skills/<name>/ - Create writable
/workspace/directory - Mount blobs (either as files or via helper functions)
Environment setup
- Sanitize inherited environment
- Inject only declared secrets from
permissions.secrets - Prevent access outside skill and workspace directories
- Optionally enforce network restrictions based on
permissions.network
Helper library
-
Provide
runtime.blobsmodule:-
read_text(blob_id: str) -> str -
write_text(content: str) -> str -
write_json(obj: dict) -> str
-
-
Provide
runtime.logmodule:-
info(msg: str) -
error(msg: str)
-
Entrypoint execution
- For
execute_skill: Import skill'sruntime.entrypointand callexport(args) - For
run_code: Save code as module, import, and call entrypoint - Capture return value (must be JSON-serializable, ≤ 4KB)
- Capture stdout/stderr
Safety & security
Permission enforcement
- Respect
permissions.secrets— Only inject listed secrets - Respect
permissions.network— Restrict outbound connections to allowlisted domains - Validate
input_blobsare accessible by requesting skill
Path restrictions
- Prevent
read_skill_filefrom escaping skill directory - Prevent code from accessing files outside
/skills/and/workspace/ - No filesystem access outside sandboxed environment
Resource limits
- Enforce CPU time limits
- Enforce memory limits
- Enforce wall-clock time (timeout)
- Handle timeout gracefully (return error status, not protocol error)
Input validation
- Validate JSON-RPC structure
- Validate required parameters
- Validate parameter types
- Return protocol-level error for invalid input
Testing
Unit tests
- Test each method in isolation
- Test error cases (missing params, invalid skill, etc.)
- Test skill discovery (listing, filtering, sorting)
Integration tests
- Execute a simple skill
- Execute custom code with mounted skills
- Create and read blobs
- Verify sandbox isolation
Compliance tests
- Verify JSON-RPC 2.0 responses
- Verify response formats match spec
- Verify deterministic sorting in
list_skills - Verify output size limits (4KB for output, 2KB for logs)
Security tests
- Verify path restrictions in
read_skill_file(e.g., reject../) - Verify sandbox cannot escape environment
- Verify secrets are only injected when declared
- Verify non-root execution
- Verify timeout enforcement
Minimal MVP implementation
To get started, implement:
1. Transport: Flask (or equivalent) with JSON-RPC 2.0
2. Storage: Directory-based skill registry + file-based blob storage
3. Methods: All 8 methods (even if simplified)
4. Runtime: Python subprocess sandbox with basic limits
5. Safety: Path validation, non-root execution
6. Testing: Basic integration tests
Then iterate to add:
- Container-based sandboxing (Docker)
- Advanced permission enforcement
- Network restriction capabilities
- Multi-language support
Example architecture
┌─────────────────────────────────────┐
│ HTTP Server (Flask) │
│ /rpc endpoint │
└──────────────┬──────────────────────┘
│
┌──────────────▼──────────────────────┐
│ RPC Handler │
│ (routes to methods) │
└──────────────┬──────────────────────┘
│
┌──────────┼──────────┐
│ │ │
▼ ▼ ▼
┌────────┐ ┌──────────┐ ┌────────┐
│Discovery│ │Execution │ │ Blobs │
│Methods │ │Methods │ │Methods │
└────────┘ └──────────┘ └────────┘
│ │ │
▼ ▼ ▼
┌─────────────────────────────────────┐
│ Storage Layer │
│ Skills Blobs Metadata │
└─────────────────────────────────────┘
│ │
▼ ▼
┌────────────────────────────────────┐
│ Sandbox Execution Engine │
│ (process/container isolation) │
└────────────────────────────────────┘