@vauban-org/preste
v0.66.2
Published
Preste — sovereign agentic CLI with OODA/ReAct/Plan patterns, local MCP server for Claude Code/Desktop integration, and Ed25519 auto-attestation on every run. BYOK, standalone, no infra.
Downloads
299
Maintainers
Readme
preste
Every agent run. Signed. Forever.
preste is the first agentic CLI that combines BYOK provider routing, three loop patterns, a local MCP server, and automatic Ed25519 cryptographic attestation on every single run — in a single MIT-licensed binary.
npm install -g @vauban-org/preste
preste setup # connect your LLM in 60 seconds
preste agent run BUILDER --task "scaffold a /api/ping route"
# ✓ attestation saved → ~/.preste/attestations/b0c520a4....jsonWhy preste?
| Feature | preste | Hermes | OpenClaw | Claude Code | |---|:---:|:---:|:---:|:---:| | BYOK — any LLM provider | ✅ | ✅ | ✅ | ❌ | | Standalone — no server required | ✅ | ✅ | ✅ | ❌ | | OODA / ReAct / Plan loops | ✅ (3) | ❌ (1) | ❌ (1) | ❌ | | Ed25519 attestation — every run | ✅ | ❌ | ❌ | ❌ | | Local MCP server (IDE delegation) | ✅ | ❌ | ❌ | — | | Starknet on-chain anchor | ✅ | ❌ | ❌ | ❌ | | SKILL.md (agentskills.io standard) | ✅ | ❌ | ❌ | ❌ | | IETF draft conformance | ✅ | ❌ | ❌ | ❌ |
Quick start
npm install -g @vauban-org/preste
preste setup
preste agent run BUILDER --task "list the TypeScript files in src/ and count them"
preste attest list # see your signed certificates
preste attest verify <runId>Real output:
[BUILDER › OODA › deepseek-v4-flash]
step 1 list_directory src/
step 2 list_directory src/routes/
step 3 ✓ done
There are 27 TypeScript files in packages/cli/src/.
✓ attestation saved ~/.preste/attestations/b0c520a4....json (kid=f33f00c0…)
3.7 s · 3 steps · 3389 in / 207 out tokensInstallation
npm install -g @vauban-org/preste # global
pnpm add @vauban-org/preste # per-projectRequires Node.js ≥ 18.
Onboarding
preste setupInteractive wizard. Tests connectivity before saving to ~/.preste/config.yaml.
| Provider | Default model | Notes |
|---|---|---|
| LiteLLM (sovereign) | deepseek-v4-flash | Self-host. Recommended. |
| Groq | llama-3.3-70b-versatile | Free tier. Fast fallback. |
| OpenAI | gpt-4o | Standard. |
Resolution order (first wins): ~/.preste/config.yaml → LITELLM_URL → GROQ_API_KEY → OPENAI_API_KEY.
Agent run
preste agent run <TYPE> --task "<description>"Types: ARCHITECT · BUILDER · TESTER · SCRIBE · SYNERGY
Loop patterns (--pattern):
| Pattern | What it does | Pick when |
|---|---|---|
| ooda (default) | Structured function-calling loop | Files, shell, HTTP |
| react | Text-based Thought → Action → Observe | Heavy reasoning |
| plan | Upfront plan → sequential execution | Multi-step tasks |
# OODA — structured tool calls (default)
preste agent run BUILDER --task "scaffold a retry helper with exponential backoff"
# ReAct — reasoning-first
preste agent run ARCHITECT --task "review circuit-breaker in src/router/" --pattern react
# Plan-then-Execute
preste agent run TESTER --task "write edge-case tests for the quota manager" --pattern plan
# One-shot — no loop, just an LLM answer
preste agent run SCRIBE --task "summarise this doc" --one-shot --context "$(cat notes.md)"
# With episodic memory
preste agent run SYNERGY --task "weekly trend analysis" --recall --remember| Flag | Default | Description |
|---|---|---|
| --task <text> | required | Task description |
| --pattern ooda\|react\|plan | ooda | Loop pattern |
| --context <text> | — | Extra context injected into system prompt |
| --one-shot | false | Single LLM call, no tools |
| --max-steps <n> | 20 | Max loop iterations |
| --recall | false | Inject relevant past memories before run |
| --remember | false | Save this run to episodic memory |
| --no-attest | false | Skip attestation |
| --json | false | JSON output |
Mobile observe + steer via sovereign relay
Pair your phone with a running preste --remote session through a
zero-knowledge relay. Both sides dial OUT to the relay (NAT-friendly).
The relay forwards opaque ciphertext frames PC ↔ phone and never
decrypts them — X25519 + AES-256-GCM, ephemeral keys per session.
# 1. Start preste with the Vauban-hosted relay (or your own).
preste --remote --relay https://relay.preste.vauban.tech
# 📡 remote-control — observe + steer this session from your phone
# http://0.0.0.0:3113/remote/stream
# token: <hex>
#
# 🌍 relay — pair your phone from anywhere
# scan the QR with preste.vauban.tech (PWA) :
# [ASCII QR]
# preste-pair://eyJ2IjoxLCJyZWxheVVybCI6Imh0dHBzOi8v...Open preste.vauban.tech on your phone
(install as a PWA — works iOS/Android/desktop), scan the QR, and observe
the live transcript. Tap-to-veto each tool call. Voice STT mic to inject,
TTS to read back the assistant.
Self-host the relay (production / regulated workloads) :
# 1-command docker-compose with Caddy auto-TLS :
git clone https://github.com/vauban-org/command-center
cd command-center/packages/preste-relay
cp docker-compose.example.yml docker-compose.yml
cp Caddyfile.example Caddyfile
# Edit Caddyfile : replace relay.example.com with your domain.
docker-compose up -dCert auto-provisioned by Let's Encrypt + rotated by Caddy. The relay
itself : ~300 lines of pure Node http + crypto, MIT, no runtime deps.
See packages/preste-relay/README.md for the
protocol spec + the K8s ingress patterns Vauban uses for the public relay.
Cryptographic attestation
Every preste agent run auto-generates a signed RunCertificate. No flag. No opt-in. No server.
# List all certificates
preste attest list
# Verify offline — no network, no Vauban infra
preste attest verify <runId>
# ✓ valid · owned by local key
# Anchor the Poseidon hash on Starknet
preste attest anchor <runId> # dry-run (computes hash only)
preste attest anchor <runId> --network sepolia # real transaction (needs STARKNET_PRIVATE_KEY)Certificate JSON (excerpt):
{
"runId": "b0c520a458aefcee87654ac0e479279c",
"agentId": "BUILDER",
"status": "completed",
"stepCount": 3,
"pattern": "ooda",
"provider": { "name": "litellm", "model": "deepseek-v4-flash" },
"usage": { "inputTokens": 3389, "outputTokens": 207 },
"signatureAlg": "Ed25519",
"signaturePubkey": "f33f00c09dc3179f…",
"signature": "3b6e8a…"
}Anchor dry-run output:
{
"runId": "b0c520a458aefcee87654ac0e479279c",
"poseidonHash": "0x2eaaaa012a1beb050a5d6236cfe80b53daeb7577db9d458f030740cbe3e93fc",
"dryRun": true
}How it works:
- First run generates
~/.preste/ed25519.key(chmod 600). Your key. Never leaves your machine. - Canonical JSON via JCS (RFC 8785) + Poseidon Merkle root over loop steps.
- Signed with Ed25519. Cert saved to
~/.preste/attestations/<runId>.json. - Third parties verify with the embedded SPKI pubkey — zero Vauban infrastructure.
Conforms to IETF draft-vauban-skill-attestation-00.
Regulatory fit: Provides the tamper-evident traceability substrate for AI Act Art. 14 (human oversight) and EU AI Office guidance on high-risk AI. Auditable 5 years later from the JSON file alone.
MCP server — let your IDE delegate to preste
preste serve --mcp turns the binary into a local MCP server. Claude Code,
Claude Desktop, Cursor, Continue.dev spawn it and call agent runs directly —
each producing a signed RunCertificate.
preste serve --mcp # stdio (IDE-spawned)
preste serve --http --port 3200 # HTTP (StreamableHTTP)Wire into Claude Code (~/.claude.json):
{
"mcpServers": {
"preste": {
"type": "stdio",
"command": "preste",
"args": ["serve", "--mcp"]
}
}
}Tools exposed:
| Tool | Purpose |
|---|---|
| preste_agent_run | Execute OODA / ReAct / Plan agent |
| preste_agent_models | List models on your LLM provider |
| preste_skills_list | List installed SKILL.md skills |
| preste_attest_verify | Verify Ed25519 RunCertificate |
| preste_attest_list | Enumerate local attestations |
| preste_attest_anchor | Poseidon hash + optional Starknet tx |
Skills (SKILL.md)
preste supports the agentskills.io standard.
preste skills install starknet-validator
preste skills run starknet-validator --task "check validator health"
preste skills validate ./my-skill/SKILL.md # lint your own skills
preste skills create my-skill --tier verified # scaffold from templateTiers: official (Vauban-signed) · verified (community-reviewed) · unverified
Marketplace (P9)
Cryptographically signed skill marketplace. Every package ships a proof.json
ProofClaim ; install refuses any package whose signature does not verify
(no --no-verify opt-out). Full reference : docs/skills-marketplace.md.
# Search the marketplace.
preste skills search "starknet" --registry https://skills.vauban.tech
# Install a specific version (slug@version).
preste skills install [email protected] --registry https://skills.vauban.tech
# Publish your own (after staging SKILL.md + script.ts + proof.json).
preste skills publish --path ./my-skill --registry https://skills.vauban.techBearer for publish lives in ~/.preste/auth.yaml (key registry_token).
Registry URL resolution : --registry > PRESTE_SKILLS_REGISTRY env > https://skills.vauban.tech.
Persona
preste persona set --name "Senior Rust Engineer" --tone concise --language en
preste persona set --domain "distributed systems" --domain "ZK proofs"
preste persona show
preste persona resetStored at ~/.preste/persona.yaml, injected into every agent system prompt.
Episodic memory
preste memory recall "circuit breaker implementation"
preste memory store --content "Decided to use sliding window for rate limiting" --type decision
# Or during agent run
preste agent run BUILDER --task "..." --recall --rememberMemory lives at ~/.preste/memory/episodic.jsonl. Recall uses RRF-scored
retrieval (cosine + recency + importance).
Session memory
preste uses three-stage memory within a conversation session:
| Stage | Scope | Storage | |---|---|---| | Working memory | Last 6 turns verbatim | In-process (configurable) | | Episodic | Older turns, LLM-compacted | In-process snapshot | | Long-term | Compaction summaries across sessions | Brain (optional, BYOK) |
In-session commands:
/compact # compress older turns now (automatic at 70% context fill)
/save # persist the session snapshot
preste cmd-chat --resume <snapshot> # restore a prior sessionEnabling Brain long-term storage (optional):
# ~/.preste/config.yaml
brain:
api_key: bk_... # from brain.vauban.tech
brain_id: <uuid> # auto-detected on first run if omittedWhen configured, compaction summaries are archived to Brain after each /compact. The next session restores them as ## Long-term context in the system prompt.
Without Brain config: identical behaviour to 0.24 -- zero errors, zero prompts.
Commands reference
| Command | Description |
|---|---|
| preste setup | Interactive BYOK onboarding |
| preste agent run <TYPE> | Run OODA / ReAct / Plan agent |
| preste agent list | List agent types |
| preste agent models | List models on the configured provider |
| preste skills list | List installed skills |
| preste skills install <name> | Install from CC backend or marketplace (with --registry) |
| preste skills publish | Publish a signed skill package to the marketplace (P9) |
| preste skills search <query> | Search CC backend or marketplace (with --registry) |
| preste skills run <name> | Execute a local skill |
| preste skills validate <path> | Lint a SKILL.md |
| preste skills create <name> | Scaffold a new skill |
| preste attest verify <runId> | Verify cert offline |
| preste attest list | List all local certs |
| preste attest anchor <runId> | Poseidon hash + Starknet anchor |
| preste serve --mcp | Local MCP server (stdio) |
| preste serve --http | Local MCP server (HTTP) |
| preste persona show\|set\|reset | Manage agent persona |
| preste memory recall <query> | Search episodic memory |
| preste memory store | Write to episodic memory |
| preste cmd-chat --resume <snap> | Restore session from snapshot |
| /compact (in-session command) | Compress older turns |
| /save (in-session command) | Persist session snapshot |
Environment variables
| Variable | Description |
|---|---|
| LITELLM_URL | Sovereign LiteLLM base URL |
| LITELLM_API_KEY | LiteLLM API key (optional) |
| LITELLM_MODEL | Model override. Default: deepseek-v4-flash |
| GROQ_API_KEY | Groq API key |
| OPENAI_API_KEY | OpenAI API key |
| CC_SERVICE_URL | CC server URL (for --server mode) |
| CC_SERVICE_TOKEN | Bearer token for CC server (cc:read scope) |
| STARKNET_PRIVATE_KEY | Private key for preste attest anchor --network |
| STARKNET_ACCOUNT | Starknet account address |
| PRESTE_SKILLS_REGISTRY | Skill marketplace URL (default https://skills.vauban.tech) |
| PRESTE_HOME | Override ~/.preste storage prefix (config, skills, attestations) |
| PRESTE_ALLOW_MAINNET_RECEIPT | Lift the Sepolia-only gate for zkpay receipts ; set to literal "1" only (operator burden per ADR-ECO-022 v2) |
Programmatic API
import { runAgentRun, runAttestVerify } from '@vauban-org/preste';
const result = await runAgentRun({
agentType: 'BUILDER',
task: 'scaffold a health-check route for /api/ping',
pattern: 'ooda',
maxSteps: 10,
});
console.log(result.content);
// → "Here is the health-check route..."
const verify = await runAttestVerify({ runIdOrPath: result.runId });
console.log(verify.valid); // true — Ed25519 signature verifiedArchitecture
Single esbuild bundle (~423 KB), no runtime server dependency.
- Loop:
@vauban-org/agent-sdkAgentLoop(minimal-loop, function-calling) - Attestation:
node:cryptoEd25519 + Poseidon felt252 (starknet.js) - MCP:
@modelcontextprotocol/sdkStdio + StreamableHTTP transports - Config: YAML (
yamllib), Zod-validated schemas - Memory: JSONL append-only at
~/.preste/memory/episodic.jsonl
Exit codes
| Code | Meaning |
|---|---|
| 0 | Success |
| 1 | Validation failure (invalid cert, agent error) |
| 2 | Strict mode failure |
| 3 | Fatal (network error, unrecoverable I/O) |
Contributing
PRs welcome. pnpm install && pnpm build && pnpm test
License
MIT — Vauban · Command Center
