Api fetch wrapper
Wrap a public HTTP API (Open-Meteo weather as the demo) with credential handling, error normalisation, and a single retry on transient network failures. Demonstrates the production-shaped baseline for any "skill that calls an external service" — env-based secrets, structured error output, no leaked API keys in logs, and a deliberate retry policy. The Open-Meteo endpoint used here is keyless on purpose so the example runs without setup; replace `OPEN_METEO_URL` with your own host and add `process.env.MY_API_KEY` for an auth'd version.From its SKILL.md
npx -y skills add ChronoAIProject/Ornn --skill api-fetch-wrapperAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
4 things to look at
- reads credentialsReads from 1 credential source: `process.env.YOUR_API_KEY`.
- 19 stars19 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
- runs commandsInstructs the agent to run 3 commands, including `cd examples/api-fetch-wrapper` and 2 more.
- fetches URLsInstructs the agent to fetch 1 URL, including https://api.open-meteo.com.
What its file declares
Copied from the file, not written here
The file declares its own license as MIT. That is the author’s claim about this one file, and it is not the same thing as the license GitHub reports for the repository, which is listed with the other numbers below.
SKILL.md
2.4 KB, 455 tokens by cl100k_base, as published. Nobody here has run it
api-fetch-wrapper
The case that breaks first in production — a skill that hits an external service. This example covers the four things every such skill needs: secret handling, retry policy, error normalisation, and no-leak-on-failure logging.
Contract
Input (stdin, JSON):
{ "latitude": 52.52, "longitude": 13.41 }
Output (stdout, JSON):
{
"temperatureC": 18.4,
"windSpeedKmh": 12.6,
"fetchedAt": "2026-05-19T08:00:00.000Z"
}
Errors — written to stderr as {"error": "...", "cause": "..."} and exit code 1. Error messages NEVER include the raw upstream response body (it might echo a secret); they include the upstream status code and a short canonical reason.
Required environment
| Var | Purpose |
|---|---|
OPEN_METEO_URL | Optional override of the upstream host. Defaults to https://api.open-meteo.com. |
| (none for auth) | Open-Meteo is keyless. For an auth'd API, the same skeleton reads process.env.YOUR_API_KEY and passes it via Authorization header. |
Run locally
cd examples/api-fetch-wrapper
bun install
echo '{"latitude":52.52,"longitude":13.41}' | bun run src/index.ts
Adapt this
- Different API — replace the URL, query params, and response shape. The retry / error-mapping skeleton stays.
- API-key auth — read
process.env.YOUR_API_KEYonce at the top, pass it viaAuthorization: Bearer ${apiKey}, and ensure the key never appears in error messages. - Stronger retry — bump
MAX_ATTEMPTS, add exponential backoff with jitter, or distinguish 5xx (retry) vs 4xx (do not retry) explicitly. - Cache — wrap the fetch in a TTL cache when the upstream rate-limits.
What ships with it: 3 files
4.4 KB alongside SKILL.md, 1 of them executable
src/
- index.tsruns3.6 KB
- package.json282 B
- README.md470 B