StepLock
An MCP server gatekeeper runtime that enforces step-by-step AI skill execution with output verification.
AI agents skip steps. They mis-sequence workflows. They accept incorrect output and keep going. StepLock fixes that by sitting between your agent and its skill definitions — delivering one step at a time, requiring submitted output, and running verification scripts before advancing. Reliable, auditable execution regardless of LLM compliance.
How it works
Agent ──► StepLock (MCP) ──► Step 1 instruction
│
Agent submits output
│
Verification script runs
│
✔ Pass → next step ✗ Fail → guidance returned, agent retries
StepLock exposes four MCP tools to the agent:
| Tool | Purpose |
|---|---|
list_skills |
Discover available skills by name and description |
start_skill |
Begin execution — returns session ID, first step, and available helpers |
submit_step_output |
Submit output for the current step and receive the next |
run_helper_script |
Run a helper script declared on the current step |
Quick start
VS Code / Copilot
Add to .vscode/mcp.json (workspace-scoped) or open MCP: Open User Configuration from the Command Palette:
{
"servers": {
"steplock": {
"type": "stdio",
"command": "uvx",
"args": ["steplock"]
}
}
}
Verify the server is running: open Copilot Chat → Select tools → confirm list_skills, start_skill, submit_step_output, and run_helper_script are listed.
Defining a skill
my-skill/
├── SKILL.yaml
├── steps/
│ ├── step1.md
│ └── step2.md
└── scripts/
├── verify_step1.py
└── get_context.py
SKILL.yaml
name: my-skill
description: When and why to use this skill.
steps:
- id: step-1
instruction: steps/step1.md # file path or inline string
verify: scripts/verify_step1.py # optional
on_fail: retry # retry | abort (default: abort)
helpers: # optional list of helper scripts
- scripts/get_context.py
- id: step-2
instruction: steps/step2.md
# no verify — output is accepted immediately
Verification scripts receive the agent's submitted output via stdin and exit with:
0— output accepted, execution advances- non-zero — output rejected; anything printed to stdout/stderr is returned to the agent as guidance
Helper scripts are utility scripts the agent can run during a step via run_helper_script to gather context or perform preparatory work. They are declared per-step with the helpers list and identified by filename without extension. They receive optional string arguments via sys.argv and return stdout, stderr, and exit_code.
Registering skills
StepLock discovers skills through two merged sources, each supporting auto-discovery:
| Location | Created automatically | Auto-discovery | Purpose |
|---|---|---|---|
~/.steplock/ |
Yes — on first run | ✔ Recursively scans subdirectories | User-wide skills |
./.steplock/ |
No | ✔ Recursively scans subdirectories | Project-local skills |
Auto-discovery
Place skill directories directly inside either location. StepLock recursively scans for SKILL.yaml files:
.steplock/
├── skills-registry.yaml # explicit paths (optional)
├── my-skill/
│ └── SKILL.yaml
└── skill-pack/
├── skill-a/
│ └── SKILL.yaml
└── skill-b/
└── SKILL.yaml
Explicit registry (optional)
# ~/.steplock/skills-registry.yaml (or ./.steplock/skills-registry.yaml)
skills:
- /home/user/my-skills/my-skill
- /home/user/my-skills/another-skill
Registry entries can be:
- Skill directories — containing a
SKILL.yamlfile - Folder paths — recursively scanned for
SKILL.yamlfiles
Deduplication
If the same skill name appears in multiple locations, the project-local entry (./.steplock/) takes precedence over the user-wide entry (~/.steplock/). Filesystem paths are never exposed to the agent — only skill names.
Skill definition reference
| Field | Required | Description |
|---|---|---|
name |
✔ | Unique skill name exposed to the agent |
description |
✔ | When and why the agent should use this skill |
steps[].id |
✔ | Unique step identifier |
steps[].instruction |
✔ | File path (relative to skill dir) or inline string |
steps[].verify |
— | Path to a verification script |
steps[].on_fail |
— | retry or abort (default: abort) |
steps[].helpers |
— | List of helper script paths (relative to skill dir) |
Backward compatibility: a single-step skill with no verify behaves identically to an Anthropic-model skill. Existing skills adopt with zero changes.
Development setup
git clone https://github.com/l0kifs/steplock-ai-skill-executor.git
cd steplock-ai-skill-executor
uv sync
Connect to VS Code / Copilot from a local checkout — add to .vscode/mcp.json:
{
"servers": {
"steplock": {
"type": "stdio",
"command": "uv",
"args": ["run", "python", "-m", "steplock.entry_points.main"],
"cwd": "${workspaceFolder}"
}
}
}
Run tests:
uv run pytest tests/ -v # Run all tests
uv run pytest tests/e2e/ -v # E2E tests only
uv run pytest tests/unit/ -v # Unit tests only
Tests use an in-memory transport — no running server instance required.
Contributing
Bug reports and pull requests are welcome. Before opening a PR:
- Fork the repo and create a feature branch
- Run
uv run pytest— all tests must pass - Run
uv run ruff check src/— no lint errors - Open a pull request with a clear description of the change
For larger features, open an issue first to discuss the approach.
License
MIT © Sergei Konovalov
Metadata
Release files for steplock 0.3.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| steplock-0.3.0.tar.gz | 13.4 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| steplock-0.3.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 33.8 kB
Release files / steplock-0.3.0.tar.gz
| Download URL | steplock-0.3.0.tar.gz |
|---|---|
| Size | 13.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
edc3bf57865c28748e5cf9ac6fabaad80a9e17e92e412f35dc473432376e3a08
|
|
BLAKE2b-256 checksum How to use checksums |
fa4141b49ce3f98876b8680a4d4a378448180975912a6ac64f9e4119a23a2f80
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jun 11, 2026.
Transparency logRelease files / steplock-0.3.0-py3-none-any.whl
| Download URL | steplock-0.3.0-py3-none-any.whl |
|---|---|
| Size | 20.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
6a9fdab81fe8b41a43bf3016a8d703ff7945211cee61837174eaba1e733b73f9
|
|
BLAKE2b-256 checksum How to use checksums |
87236f3e5fac20c2636ec568cd50e95c5a0211c510c0ac6a726c448e04281bb4
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jun 11, 2026.
Transparency log