Marchyo ships a bring-your-own-key (BYOK) AI desktop. Enabling marchyo.ai
installs per-user AI clients wired to OpenRouter (an OpenAI-compatible
aggregator), adds task-based model routing, a local OpenViking context
layer, MCP tools, and a set of Agent Skills surfaced to every client.
Your API key never enters the Nix store: it is supplied through a
sops-nix secret (or any runtime file) and
read at startup.
Quick start
{
# owner is required: the sops-nix default is a root-only 0400 file under
# /run/secrets, which the desktop user's AI clients cannot read.
sops.secrets."openrouter-api-key".owner = "your-username";
marchyo.ai = {
enable = true;
openrouter.apiKeyFile = config.sops.secrets."openrouter-api-key".path;
};
}
Clients
- aichat — terminal chat client, also bound to
Super+A (floating terminal).
- pi — Armin Ronacher’s minimal coding agent, wired to OpenRouter via a
registered provider (
~/.pi/agent/settings.json + an extension).
- claude-code — installed for convenience, but it speaks the Anthropic
API and is not wired to OpenRouter; authenticate it separately.
Options
| Option | Default | Description |
|---|
marchyo.ai.enable | false | Enable BYOK AI tooling |
marchyo.ai.openrouter.apiKeyFile | null | Runtime path to the API key (required) |
marchyo.ai.openrouter.baseUrl | https://openrouter.ai/api/v1 | OpenAI-compatible base URL |
marchyo.ai.openrouter.defaultModel | anthropic/claude-sonnet-4 | Model used when routing is off |
marchyo.ai.tooling.enable | true | Install aichat / pi / claude-code |
marchyo.ai.routing.enable | true | Task→model routing (see below) |
marchyo.ai.context.enable | false | OpenViking local context layer |
marchyo.ai.skills.enable | true | Install Agent Skills to all clients |
marchyo.ai.mcp.enable | true | Wire MCP tools (mcp-nixos) into clients |
marchyo.ai.local.enable | false | Local inference — not yet implemented |
Model routing
marchyo.ai.routing maps task buckets to a primary OpenRouter model plus a
fallback chain (consumed as OpenRouter’s native models array, which auto-fails
over on errors/rate-limits). Defaults pin the frontier/reasoning buckets and lean
on openrouter/auto and the :nitro/:floor variant suffixes elsewhere so
quarterly model churn is absorbed. Slugs are starting points — verify them
against OpenRouter’s live model list and adjust. Every default is overridable:
marchyo.ai.routing.tasks.frontier.model = "openai/gpt-5.5";
marchyo.ai.routing.tools.aichat = "frontier"; # which bucket aichat uses
Buckets: frontier, everydayCoding, fast, reasoning, summarize,
longContext, budget, local (placeholder). The resolved policy is exported to
~/.config/marchyo/ai-routing.json, and each bucket is available as an aichat
role (aichat -r frontier).
Context / memory (OpenViking)
marchyo.ai.context.enable installs the OpenViking ov
CLI — a local context database for AI agents. Data stays under
~/.openviking/workspace (configurable via context.workspacePath); embeddings
are pointed at OpenRouter. The key is injected into ~/.openviking/ov.conf at
activation (never in the store). Index your skills with
ov add-resource ~/.claude/skills.
Only the ov CLI is packaged (not the separate openviking-server), so
context.service.enable is not wired yet.
Skills
marchyo.ai.skills installs Marchyo Agent Skills (SKILL.md) — marchyo-config
and nix-build-debug — to every client in skills.clients. claude-code
(~/.claude/skills) and pi (~/.pi/agent/skills) consume the Agent Skills
standard natively; aichat gets each skill as a role. Add more skills by dropping
<name>/SKILL.md dirs under modules/home/ai-skills/skills/.
marchyo.ai.mcp wires mcp-nixos into
claude-code (merged into ~/.claude.json), giving grounded NixOS package/option
lookups (no hallucinated attr names). It runs via uvx (uv is installed).
Supplying the key with sops-nix
age-keygen -o ~/.config/sops/age/keys.txt and record the public key.
- Add a
.sops.yaml, then sops secrets/ai.yaml containing
openrouter-api-key: sk-or-v1-....
- Declare the secret and point Marchyo at its path:
{
sops.defaultSopsFile = ./secrets/ai.yaml;
sops.age.keyFile = "/var/lib/sops-nix/key.txt";
# owner so the desktop user can read it (default is root-only 0400).
sops.secrets."openrouter-api-key".owner = "your-username";
marchyo.ai = {
enable = true;
openrouter.apiKeyFile = config.sops.secrets."openrouter-api-key".path;
};
}
The sops NixOS and Home Manager modules are wired into Marchyo’s defaults — you
only declare the secret and provide your age key.
Local inference
marchyo.ai.local.enable is declared but not implemented; enabling it fails an
assertion. Use OpenRouter for now. Last modified on June 24, 2026