API key handling (the shared convention)
June 22, 2026 · View on GitHub
Skills that call external APIs (literature search, web synthesis, …) all use the same key convention so a user sets each key once and every skill in the project reuses it.
This page is the authoring reference. The installed reference implementation is the
literature-search skill (tools/lit/keys.py), and its SKILL.md
documents the convention for runtime. Consuming skills reach it through that sibling skill
(<lit> keys / <lit> keys --init) — an installed SKILL.md never links docs/ (it isn't installed).
The project key file
<repo root>/keys.env (nearest .git ancestor of the working dir, else the CWD)
- One file per project, shared by every skill in it. Set a key once; all skills see it.
- Sits inside the repo, so it MUST be gitignored (
keys.env).0600permissions. - Plain
KEY=VALUElines;#comments; blank lines ignored.
# agent-loop-skills API keys (shared across skills in this project).
S2_API_KEY=xxxxxxxx
OPENALEX_EMAIL=me@example.com
OPENROUTER_API_KEY=
BGPT_API_KEY=
Rules
- Precedence: a real OS environment variable always wins over the file (so CI and power users can
just
export). The file fills in whatever the environment doesn't. - All keys optional: a missing key degrades the corresponding feature gracefully — the skill keeps running on whatever is available, down to built-in web search.
- Secrets never enter the conversation: the user fills the file themselves (in their editor). Skills only ever read presence as booleans, never the values.
- One file, many skills:
--initappends a skill's missing keys to the shared file and never overwrites existing values, so skills coexist in one file.
Onboarding flow (what a skill does at setup)
The literature-search skill exposes this as <lit> keys [--init]; a skill with its own keys mirrors it:
… keys— report which keys are already present (the shared file may be populated by a prior skill). If what you need is there, you're done.… keys --init— create the file if absent and append slots for this skill's keys. Prints the path.- Ask the user to open the file and paste the keys they want, then say when done. In-session
shortcut:
! $EDITOR ./keys.env. … keysagain — report live vs degraded tiers, and proceed. Never block on keys.
Adopting the convention in a new skill
- Copy the reference implementation
../loops/literature-search/tools/lit/keys.pyinto the new skill'stools/. - Edit only the
KEYSregistry — the(ENV_VAR_NAME, "description — where to get it")list for that skill's services. Leave the engine untouched. - In the skill's CLI: default
--env-filetokeys.default_env_path(), callkeys.load_env_file(args.env_file)before doing any work, and expose akeyssubcommand that runskeys.ensure_template(...)on--initand printskeys.status().
The engine is standard-library only and Python ≥3.9, so it runs anywhere the skill does with no installs.