lekton-sync
CLI tool to sync markdown documents and prompt definitions to a Lekton instance.
It scans a directory for .md files and prompt YAML files, calls the Lekton sync APIs to compute the delta, and uploads only the content that has changed.
Installation
Docker
Build a minimal container image from the repository root:
Run it by mounting the documentation workspace and passing the usual environment variables:
This image contains only the lekton-sync binary in a distroless runtime, so it fits well in documentation CI pipelines without installing Rust toolchains on the runner.
Tagged releases can also publish a ready-to-use Docker image via GitHub Actions:
Usage
| Argument | Default | Description |
|---|---|---|
ROOT |
. |
Root directory to scan for markdown files and prompt definitions |
--archive-missing |
— | Archive documents present in Lekton but not found locally |
--dry-run |
— | Show what would be done without making any changes |
--config <PATH> |
<ROOT>/.lekton.yml |
Path to config file |
-v, --verbose |
— | Verbose output |
Environment variables
| Variable | Required | Description |
|---|---|---|
LEKTON_TOKEN |
Yes | Service token for authentication |
LEKTON_URL |
Yes* | Base URL of the Lekton server |
*Can also be set via url in .lekton.yml.
Document format
Each markdown file must have a YAML front matter block. Files without front matter are skipped.
title: My Document
slug: optional/custom-slug # defaults to file path relative to root
access_level: public # defaults to "public"
service_owner: my-team # optional
tags: [guide, onboarding] # optional
order: 10 # optional, for ordering within a section
is_hidden: false # optional
Document body...
The slug is derived from the file path relative to the root directory (e.g. docs/guides/intro.md → docs/guides/intro), unless overridden by the slug field in the front matter.
Prompt format
Prompt definitions are loaded from prompts/*.yaml by default. This directory can be changed via .lekton.yml.
name: Code Review
description: Review a patch before merge
owner: platform-team
access_level: developer
status: active
publish_to_mcp: true
default_primary: true
context_cost: medium
tags:
variables:
- name: diff
description: Unified diff to inspect
required: true
prompt_body: |
Review the following diff:
{{diff}}
Supported prompt fields:
| Field | Required | Description |
|---|---|---|
name |
No | Human-readable prompt name. Defaults to the file slug segment. |
description |
Yes | Short description shown in Lekton. |
owner |
Yes* | Owning team or service. Falls back to default_service_owner if configured. |
access_level |
No | Falls back to default_access_level, then public. |
status |
No | Prompt lifecycle status. Defaults to active. |
tags |
No | Optional tags array. |
variables |
No | Optional variable descriptors (name, description, required). |
publish_to_mcp |
No | Publish this prompt to MCP discovery/context. Defaults to false. |
default_primary |
No | Include in the default MCP context unless hidden by the user. Defaults to false. |
context_cost |
No | Prompt context weight hint. Defaults to medium. |
slug |
No | Overrides the slug derived from the prompt file path. |
lekton-import |
No | Set to false to skip the prompt. |
prompt_body |
Yes | Raw prompt body uploaded to Lekton. |
The prompt slug is derived from the path relative to the prompt directory and prefixed with prompts/ by default (for example prompts/code-review.yaml → prompts/code-review).
Configuration file
Place a .lekton.yml file in the root directory (or pass --config) to set project-level defaults:
url: https://lekton.example.com
default_access_level: internal
default_service_owner: platform-team
slug_prefix: protocols/my-service
prompts_dir: prompts
prompt_slug_prefix: prompts
archive_missing: false
| Field | Description |
|---|---|
url |
Base URL of the Lekton server (overridden by LEKTON_URL) |
default_access_level |
Fallback access level when not set in front matter |
default_service_owner |
Fallback service owner when not set in front matter |
slug_prefix |
Prefix prepended to every document slug |
prompts_dir |
Directory containing prompt YAML files, relative to ROOT |
prompt_slug_prefix |
Prefix prepended to every prompt slug |
archive_missing |
Archive documents not found locally (overridden by --archive-missing) |
Example
# Preview what would change
# Sync and archive documents/prompts no longer present locally
GitHub Actions example
- name: Sync docs to Lekton
run: |
docker run --rm \
-e LEKTON_URL="${{ secrets.LEKTON_URL }}" \
-e LEKTON_TOKEN="${{ secrets.LEKTON_TOKEN }}" \
-v "${{ github.workspace }}:/workspace" \
docker.io/${{ secrets.DOCKERHUB_USERNAME }}/lekton-sync:${{ github.ref_name }} \
--archive-missing /workspace/docs
License
AGPL-3.0