@techsologic/unolock-agent
v2.0.5
Published
UnoLock Agent CLI and local runtime
Readme
UnoLock Agent
This repository is the dedicated home for UnoLock's local agent client.
UnoLock was built to protect you. Now it can protect both you and your agent.
UnoLock Agent is currently in alpha. It is available for evaluation and early testing, but it is not ready for broad production rollout yet.
Start With The Skill
For skill-aware agents, the primary starting point is the UnoLock agent-access skill:
- skills/unolock-agent-access/SKILL.md
https://github.com/TechSologic/unolock-agent/blob/main/skills/unolock-agent-access/SKILL.md
That skill is the agent-facing onboarding layer.
This repo ships one shared skill plus thin host manifests, so OpenClaw and Claude Code can load the same skill natively.
Plugin files in this repo:
- shared skill: skills/unolock-agent-access/SKILL.md
- OpenClaw manifest: openclaw.plugin.json
- Claude Code manifest: .claude-plugin/plugin.json
Why Use UnoLock For An Agent
UnoLock Agent is not only about protecting secrets.
It gives an agent a safer place to keep and use:
- secrets
- durable memory
- structured notes
- checklists
- space-scoped working data
- selected local file backups through UnoLock sync
Compared to local memory files or plaintext secret storage, UnoLock gives the agent:
- encrypted storage
- controlled access to only the Spaces it should use
- persistence beyond a single local machine or process
- safer recovery from host loss, reset, or replacement
- a stronger access model than reusable API keys or plaintext config secrets
Security Requirement
UnoLock Agent is built for customers who want the strongest practical protection for AI-accessed secrets.
For normal customer use, the strongest deployment uses a production-ready:
- TPM
- vTPM
- Secure Enclave
- or equivalent platform-backed non-exportable key store
If the host cannot provide one of those, UnoLock Agent can still fall back to a lower-assurance software provider. When that happens, UnoLock reports the reduced assurance clearly and makes the reduced-assurance tradeoff visible instead of pretending it met UnoLock's preferred key-storage requirements.
That tradeoff is intentional. Agentic Safe Access exists to keep AI access as close as possible to UnoLock's normal device-bound security model without pretending every host can satisfy the same storage guarantees.
Intended Environment
UnoLock Agent is designed to work across a wide range of agent environments.
The strongest deployments are environments that can provide device-bound, non-exportable key storage in a normal user-controlled session. That includes:
- desktop AI assistants
- local AI hosts such as Claude Desktop or Cursor
- user-controlled workstations, laptops, and VMs with TPM/vTPM access
- macOS hosts that can use either Secure Enclave or a non-exportable Keychain-backed key
- Windows or WSL hosts that can use either TPM-backed keys or the non-exportable Windows CNG fallback
Other environments may still work, but they may only be able to provide lower assurance. That commonly includes:
- fully headless background agents
- remote sandboxes
- plain containers without hardware-backed key access
These environments are harder to support because they often cannot satisfy UnoLock's preferred requirement for device-bound, non-exportable key storage in a normal user-controlled session.
Official GitHub repository:
https://github.com/TechSologic/unolock-agent- Releases:
https://github.com/TechSologic/unolock-agent/releases
Agent-first onboarding site:
https://unolock.ai/index.htmlhttps://unolock.ai/install-mcp.htmlhttps://unolock.ai/connect-agent.htmlhttps://unolock.ai/agent-explanation-kit.html
Recommended customer install source:
- OpenClaw: install
@techsologic/unolock-agent-plugin - Claude Code: install
@techsologic/unolock-agent, export the shared skill bundle, then start withclaude --plugin-dir ... - Claude Desktop and Cursor: use MCP config with
unolock-agent mcp - other skill-capable hosts: load
skills/unolock-agent-access/SKILL.md - CLI-only hosts: use direct local
unolock-agent; prefer a GitHub Release binary there, withnpm install -g @techsologic/unolock-agentas a practical Node/npm path - source installs only when the plugin, SKILL, and direct packaged CLI paths are not the right fit yet
If you are new to UnoLock itself, start with these docs first:
- UnoLock Knowledge Base:
https://docs.unolock.com/index.html - Agentic Safe Access:
https://docs.unolock.com/features/agentic-safe-access.html - Access Keys & Safe Access:
https://docs.unolock.com/features/multi-device-access.html - Spaces:
https://docs.unolock.com/features/spaces.html - Connect an AI Agent to a Safe:
https://docs.unolock.com/howto/connecting-an-ai-agent.html
Prerequisite:
- Free and Inheritance can share their single included Safe space with one extra Agent Key.
- Sovereign and HighRisk are still the right tiers for broader multi-Space and collaboration-heavy agent workflows.
The current agent runtime proves the hardest integration seam first:
- live local
/startflow compatibility - ML-DSA signature verification
- ML-KEM encapsulation
- AES-GCM callback decryption
The agent client does not create Safes.
Safe creation remains a human/browser responsibility, matching the product model:
- human admin creates a Safe
- human admin creates an agent access key for that Safe
- UnoLock Agent registers to the existing Safe
- UnoLock Agent later authenticates and uses the shared Safe API surface for agent memory, notes, checklists, and secrets
Quick start
Run this from the repo root after the local server is up on http://127.0.0.1:3000:
./scripts/bootstrap.sh
./scripts/run_local_probe.sh
./scripts/run_stdio_mcp.sh
./scripts/run_local_e2e_readonly.shFor host configuration and implementation details, see:
- Install Guide
- macOS Quick Start
- Supported Environments
- MCP Host Config
- Support Matrix
- Tool Catalog
- Claude Desktop example
- Claude Code plugin install example
- Cursor example
- OpenClaw MCP example
- OpenClaw plugin config example
- Manual skill install example
Best path by host:
- OpenClaw: install
@techsologic/unolock-agent-plugin. - Claude Code: install
unolock-agent, rununolock-agent install-skill ..., then start withclaude --plugin-dir .... - Claude Desktop and Cursor: configure the host to run
unolock-agent mcp. - Other skill-capable hosts: load the shared SKILL.md manually.
- CLI-only hosts: use direct
unolock-agentcommands.
For direct agent use, install the CLI once, then run unolock-agent directly.
npm install -g @techsologic/unolock-agentunolock-agent register 'https://safe.example/#/agent-register/...' 1
unolock-agent status
unolock-agent list-spaces
unolock-agent list-notes
unolock-agent list-files
unolock-agent sync-add ./SOUL.md
unolock-agent sync-statusOnly if a host needs the explicit host-command form, use:
unolock-agent mcp- The host writes JSON-RPC to
stdinand reads JSON-RPC fromstdout. - The
mcpsubcommand uses the same local UnoLock runtime as the CLI. - On a fresh host, the first start can take longer because local cryptographic code may need to be compiled or prepared.
UnoLock keeps the user PIN in process memory and keeps the current Space selected across normal CLI and host-driven use.
The same executable also supports explicit CLI commands, for example:
unolock-agent register 'https://safe.example/#/agent-register/...' 1
unolock-agent status
unolock-agent list-spaces
unolock-agent list-notes
unolock-agent create-note "Todo" "Buy milk"
unolock-agent list-files
unolock-agent sync-add ./SOUL.md
unolock-agent sync-restore ./SOUL.mdUse the explicit mcp subcommand only for hosts that require that command shape. Running unolock-agent with no arguments prints usage.
Plugin Installs
This repo now uses one shared skills/ directory for skill-capable hosts. Use native host install surfaces first when they exist.
OpenClaw:
openclaw plugins install @techsologic/unolock-agent-pluginSee examples/openclaw-plugin-config.json.
Claude Code native skill install:
npm install -g @techsologic/unolock-agent
unolock-agent install-skill /absolute/path/to/unolock-agent-plugin
claude --plugin-dir /absolute/path/to/unolock-agent-pluginFor a concrete Claude Code setup example that starts from the normal CLI install, see examples/claude-code-plugin-install.sh.
Generic manual skill hosts:
npm install -g @techsologic/unolock-agent
unolock-agent install-skill /absolute/path/to/unolock-agent-pluginFor hosts that only accept a manual skill file or skill directory, see examples/manual-skill-install.sh.
Other Agent Hosts
Use these host-specific examples:
- OpenClaw best path: native plugin install via examples/openclaw-plugin-config.json
- Claude Code best path: local skill install via examples/claude-code-plugin-install.sh
- Claude Desktop best path: MCP config via examples/claude-desktop-config.json
- Cursor best path: MCP config via examples/cursor-mcp.json
- generic skill hosts best path: manual skill install via examples/manual-skill-install.sh
Once the local UnoLock Agent is running, the normal flow is:
- call normal UnoLock tools
- provide the one-time Agent Key URL and PIN together when UnoLock asks for setup
- let UnoLock keep and use the current Space by default for normal work
If you prefer manual install from source:
git clone https://github.com/TechSologic/unolock-agent.git
cd unolock-agent
python3 -m pip install --user -e .
unolock-agent-probe
unolock-agent --help
unolock-agent mcp
python3 -m unolock_mcp tpm-diagnose
unolock-agent-tpm-check
unolock-agent-self-test
python3 -m unolock_mcp config-checkFor normal customer and agent onboarding, use the normal UnoLock commands and follow UnoLock's directions.
macOS support is still alpha. UnoLock Agent now prefers Secure Enclave when it works cleanly and otherwise falls back to a non-exportable macOS Keychain key for broader compatibility. If you are evaluating it on Apple Silicon, start with:
The first liboqs-python run may build or locate liboqs under your home directory. That can take a few minutes, so agents should not assume the first startup is hung just because it is slower than later launches.
For the best customer experience, prefer GitHub Release binaries over source installs. Source installs still depend on the local liboqs-python / liboqs environment.
Preferred Customer Install
Use the best current host path directly instead of walking through every fallback:
For an agent-first public onboarding flow, send users or agents to:
https://unolock.ai/index.html
OpenClaw should install:
openclaw plugins install @techsologic/unolock-agent-pluginClaude Code should install:
npm install -g @techsologic/unolock-agent
unolock-agent install-skill /absolute/path/to/unolock-agent-plugin
claude --plugin-dir /absolute/path/to/unolock-agent-pluginIf the host can load skills but has no native install path, point it at:
https://github.com/TechSologic/unolock-agent/blob/main/skills/unolock-agent-access/SKILL.md
Use the standalone direct CLI path only when the host cannot use plugins or skills, or when you need exact CLI commands.
When using the direct CLI path, prefer the standalone GitHub Release binaries instead of installing from Git.
That avoids most of the Python packaging and source-build overhead for customers.
If your host environment is already Node/npm-oriented and you need the direct CLI path, install the CLI globally:
npm install -g @techsologic/unolock-agent
unolock-agent --versionThe direct CLI npm package is only:
- the normal UnoLock executable package
The separate plugin npm package is:
@techsologic/unolock-agent-plugin
The unolock-agent executable is not itself the plugin.
Current CLI Surface
The main end-user CLI commands today are:
- registration and auth:
register,set-pin - Space selection:
list-spaces,get-current-space,set-current-space - notes and checklists:
list-records,list-notes,list-checklists,get-record,create-note,update-note,append-note,rename-record,create-checklist,set-checklist-item-done,add-checklist-item,remove-checklist-item - Cloud files:
list-files,get-file,download-file,upload-file,rename-file,replace-file,delete-file - sync:
sync-list,sync-status,sync-add,sync-run,sync-enable,sync-disable,sync-remove,sync-restore - diagnostics:
tpm-diagnose,tpm-check,self-test - MCP host mode:
mcp
Advanced local daemon controls also exist:
unolock-agent statusunolock-agent startunolock-agent stopunolock-agent toolsunolock-agent call <tool> --args '{...}'
For normal CLI use, the daemon is auto-started as needed.
Sync Model
UnoLock sync is intentionally narrow right now:
- one sync job maps one local file to one Cloud archive in one Space
- sync is currently one-way from local file to UnoLock Cloud
- restore is explicit and manual with
sync-restore - sync requires UnoLock Cloud files and therefore does not work on Safe tiers that do not support Cloud files
- sync config is stored in a reserved Space note so a clean reinstall or new agent registration can adopt the same sync jobs later
This is a small important-file backup feature, not recursive directory sync or general-purpose bidirectional sync.
Project home:
https://github.com/TechSologic/unolock-agent
After install, run UnoLock directly:
unolock-agent --helpUse the CLI for normal registration and Safe access work.
Update Policy
UnoLock Agent should not replace itself in the middle of an active session or write flow.
The intended update model is:
- UnoLock reports update status
- the install channel applies updates
- the UnoLock process restarts between tasks so in-memory PINs and sessions can be re-established cleanly
Check update status with:
unolock-agent check-update --jsonOr, through the MCP itself, call:
unolock_get_update_status
Preferred channel behavior:
- global npm install
- preferred low-friction npm path
- update with
npm install -g @techsologic/unolock-agent@latest, then restart UnoLock
- direct GitHub Release binary
- replace the binary manually, then restart the UnoLock MCP
- Python package install
- upgrade the package in that environment, then restart the UnoLock MCP
For the best user experience, do updates between tasks, not while a setup flow, authentication flow, or sensitive write flow is active.
Standalone config
Normal setup should not require this section. When the MCP runs outside the main UnoLock monorepo, it can usually derive its UnoLock runtime config from the UnoLock Agent Key URL. Environment variables and config files are advanced overrides for custom deployments or broken metadata, not part of the normal agent flow.
Advanced override example:
{
"base_url": "https://api.unolock.example",
"transparency_origin": "https://safe.unolock.example",
"signing_public_key_b64": "BASE64_SERVER_PQ_SIGNING_PUBLIC_KEY"
}For normal UnoLock cloud-service use, the MCP can derive the API origin and PQ validation key from the user-provided Agent Key URL automatically. UnoLock remains client-side encrypted, no identity is linked to a Safe, and the design tries to minimize unnecessary metadata and correlation exposure. If you want to force the same normal cloud deployment without waiting for an Agent Key URL, this also works:
{
"base_url": "https://api.safe.unolock.com"
}the MCP will derive https://safe.unolock.com, fetch /unolock-client.json, and read the published serverPQValidationKey. If that deployment metadata file is unavailable, it falls back to the transparency bundle.
Use this command to verify what the MCP resolved:
python3 -m unolock_mcp config-checkTPM provider selection:
- default:
UNOLOCK_TPM_PROVIDER=auto - force software provider:
UNOLOCK_TPM_PROVIDER=software - force Linux TPM/vTPM provider:
UNOLOCK_TPM_PROVIDER=linux - force best macOS provider:
UNOLOCK_TPM_PROVIDER=mac - force best Windows provider:
UNOLOCK_TPM_PROVIDER=windows
On WSL2, auto now prefers the Windows TPM helper provider when powershell.exe can create TPM-backed keys on the Windows host, and falls back to a non-exportable Windows CNG key when TPM-backed creation is unavailable. This has been validated locally with live registration and authentication. If neither Windows path works, auto falls back to the software provider with loud reduced-assurance warnings.
On macOS, auto now tries the Secure Enclave provider first and then falls back to a non-exportable Keychain-backed provider. Secure Enclave remains the higher-assurance path, but the Keychain path is there to reduce launch-context friction on real Macs.
Current capabilities
The working path today is the local probe:
- GET
/start?type=access - verify
PQ_KEY_EXCHANGE - verify the server ML-DSA signature
- encapsulate to the server ML-KEM public key
- POST the PQ callback response
- decrypt the next encrypted callback
On the current local stack this is already returning the next callback successfully.
The package now also exposes a real stdio MCP server with:
- single active UnoLock auth-flow state machine
- generic
/startflow bootstrap after PQ negotiation - generic flow continuation
- generic authenticated
/apiaction calls - convenience wrappers for
GetSpacesandGetArchives - note and checklist projection from UnoLock
Recordsarchives - write-support MVP for notes and checklists with version-aware conflict handling
- daemon-backed file sync configuration, status, push-to-Cloud, and manual restore
Python/source installs additionally expose these entry points:
unolock-agent-probe- run the packaged local probe
unolock-agent- run the CLI and print usage with no arguments
- use
unolock-agent mcpfor stdio MCP mode
unolock-agent-tpm-check- run the fail-fast production-readiness TPM check
unolock-agent-self-test- run the one-shot UnoLock Agent readiness check
Current MCP tools:
unolock_set_agent_pinunolock_registerunolock_list_spacesunolock_get_current_spaceunolock_set_current_spaceunolock_list_recordsunolock_list_filesunolock_list_notesunolock_list_checklistsunolock_get_fileunolock_get_recordunolock_download_fileunolock_rename_fileunolock_replace_fileunolock_delete_fileunolock_create_noteunolock_update_noteunolock_append_noteunolock_upload_fileunolock_rename_recordunolock_create_checklistunolock_set_checklist_item_doneunolock_add_checklist_itemunolock_remove_checklist_itemunolock_sync_listunolock_sync_statusunolock_sync_addunolock_sync_rununolock_sync_enableunolock_sync_disableunolock_sync_removeunolock_sync_restoreunolock_get_update_status
Low-level flow and raw API debug tools are hidden by default. Enable them only for debugging with UNOLOCK_MCP_ENABLE_ADVANCED_TOOLS=1.
- the software provider is the final fallback when the host cannot provide a production-grade provider, and the MCP surfaces that reduced assurance clearly
- once authenticated, the MCP can read UnoLock notes/checklists and project them into plain-text agent-friendly DTOs while keeping the stored Quill/checklist formats unchanged
- the MCP can now create notes and checklists and perform version-aware note/checklist updates, note appends, and checklist updates within the agent's allowed Spaces
- the MCP now keeps one current Space and uses it as the default for normal read, write, and Cloud file operations
- the first-party local daemon auto-starts for normal CLI and stdio MCP use and supports version handoff during upgrades without transferring authenticated session state
- registration status now reports a
recommended_next_actionandguidancefield so an agent can tell whether it should ask for an agent key URL, ask for a PIN, start registration, or authenticate - after the MCP process restarts, the agent stays registered but must ask the user for the PIN again before re-authenticating
- registration state now remembers which TPM provider created the agent key and will tell the host to re-register or force the old provider if there is a provider mismatch
- the MCP can diagnose the active TPM/vTPM provider and give host advice when no working TPM/vTPM is detected
- sync config is stored in reserved Space notes, while runtime state stays local for digests, timestamps, and event dedupe
- sync can adopt existing reserved sync notes after a clean reinstall or new agent registration in the same Spaces
Read and write support:
unolock_list_recordsacceptskind,pinned, andlabelunolock_list_notesandunolock_list_checklistsare convenience wrappersunolock_list_spacesmarks the current Space, andunolock_get_current_space/unolock_set_current_spacemanage that defaultunolock_list_filesexposes onlyCloudarchives;LocalandMsgarchives are intentionally excludedunolock_list_spacesreturns space metadata plus record counts and Cloud file counts- normal read and write tools use the current Space automatically and include the
space_idthey actually used in their responses - read/list/get responses include
writable,allowed_operations,version,read_only, andlocked - write tools use cache-first optimistic writes with 5-minute in-memory archive TTLs
- archive rereads happen only on cache miss, cache expiry, or upload conflict
- write conflicts return stable structured reasons such as
write_conflict_requires_reread unolock_upload_filecreates aCloudarchive and uploads encrypted multipart chunks like the web client pathunolock_download_filereconstructs multipart Cloud archives part by part before writing plaintext to the local filesystemunolock_rename_fileupdates only Cloud file metadata and keeps the archive in placeunolock_replace_filereuses the existing Cloud archive ID while replacing file contentsunolock_delete_fileremoves the Cloud archive when the Agent Key is writableunolock_sync_addwrites reserved sync configuration in the target Spaceunolock_sync_statusmerges reserved sync configuration with local runtime stateunolock_sync_runpushes local changes to the bound Cloud archiveunolock_sync_restorerestores the bound Cloud archive back to the watched path or an explicit output pathunolock_sync_removeandunolock_sync_restoreaccept either a sync id or the watched local file path
Current bootstrap limitation:
- to finish
DecodeKeyandClientDataKey, the MCP still needs the bootstrap AIDK material for the access - if the Agent Key URL does not include that bootstrap secret, the MCP will stop with a clear blocker instead of faking progress
- that keeps the implementation aligned with UnoLock's current AIDK/CDMK hierarchy instead of bypassing it
Testing with a local Safe
When you need a real Safe for local testing, use the UnoLock browser Playwright harness from a full UnoLock checkout under client/e2e-playwright.
That harness already covers:
- Safe creation
- virtual WebAuthn registration in Chromium
- Safe open/lifecycle flows
This keeps the boundary clean:
- browser tests create and manage test Safes
agent-mcponly probes or authenticates against an existing Safe
For local agent bootstrap, the create-safe harness can now emit a registration artifact:
E2E_AGENT_BOOTSTRAP_OUTPUT_FILE=/tmp/unolock-agent-bootstrap.json \
npm --prefix client/e2e-playwright run test:create-safe
cat /tmp/unolock-agent-bootstrap.jsonThat artifact includes:
- the generated UnoLock Agent Key URL
- the access ID used for the agent registration
- the bootstrap secret encoding needed by the MCP
- whether the browser had to fall back to the current access because the Safe tier could not create another device access
- with the default Playwright settings, the local test PIN is
0123
Current local fallback behavior:
- if the Safe tier permits another device access, the harness creates a dedicated AI-marked access
- if the tier blocks new device accesses, the harness issues an agent registration URL for the current authenticated access instead
- the current-access fallback exists for local/dev testing and is not the preferred long-term product shape
For a full local regression run:
./scripts/run_local_e2e_readonly.shThat script:
- creates a fresh local Safe and agent bootstrap artifact with Playwright
- registers the MCP against that new agent key
- authenticates and reads spaces/records
- simulates an MCP restart
- re-authenticates with the PIN and verifies access again
Package layout
unolock-agent/
docs/
scripts/
src/
unolock_mcp/
api/
auth/
crypto/
domain/
mcp/
tpm/
transport/
tests/Separation of concerns
src/unolock_mcp/tpm/- TPM DAO and provider implementations
src/unolock_mcp/crypto/- PQ session negotiation
- callback AES-GCM helpers
- AWS Encryption SDK helpers
- Safe keyring management
src/unolock_mcp/transport//startand/apiHTTP transport- callback DTO handling
src/unolock_mcp/auth/- agent registration and access clients
- local compatibility probe
- single-flow auth state and local registration state
src/unolock_mcp/api/- authenticated Safe API client
src/unolock_mcp/domain/- domain objects and DTOs
src/unolock_mcp/mcp/- MCP tool surface only
Notes
- Server-side interop probes can still live under
server/safe-server/scripts/when they are validating server behavior directly. - Production agent auth is intended to use TPM/vTPM or equivalent device-backed storage. The software provider is the lower-assurance fallback when stronger host key protection is not available. If you want to load UnoLock as a plugin, use the shared plugin installs above.
