Skip to content

AI (BYOK)

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.

{
# 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;
};
}
  • 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.
Option Default Description
marchyo.ai.enable false Enable BYOK AI tooling
marchyo.ai.provider "openrouter" AI service provider (enum; "openrouter" is the only value for now — reserved for future providers)
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.routing.tasks.<bucket> pinned defaults Per-bucket { model; fallbacks; } — primary OpenRouter slug plus fallback chain
marchyo.ai.routing.tools { aichat = "everydayCoding"; pi = "everydayCoding"; } Which task bucket each OpenRouter-backed client defaults to
marchyo.ai.context.enable false OpenViking local context layer
marchyo.ai.context.workspacePath ".openviking/workspace" OpenViking workspace dir, relative to $HOME
marchyo.ai.context.service.enable false Run the OpenViking HTTP server as a per-user systemd service
marchyo.ai.context.embeddingModel openai/text-embedding-3-small OpenRouter embedding model slug used by OpenViking
marchyo.ai.skills.enable true Install Agent Skills to all clients
marchyo.ai.mcp.enable true Wire MCP tools into MCP-capable clients
marchyo.ai.mcp.nixos.enable true Enable the mcp-nixos server (run via uvx)
marchyo.ai.local.enable false Local inference — not yet implemented

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). Both aichat and pi default to the everydayCoding bucket (marchyo.ai.routing.tools). The resolved policy is exported to ~/.config/marchyo/ai-routing.json, and each bucket is available as an aichat role (aichat -r frontier).

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.

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).

  1. age-keygen -o ~/.config/sops/age/keys.txt and record the public key.
  2. Add a .sops.yaml, then sops secrets/ai.yaml containing openrouter-api-key: sk-or-v1-....
  3. 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.

marchyo.ai.local.enable is declared but not implemented; enabling it fails an assertion. Use OpenRouter for now.