{
"$type": "site.standard.document",
"description": "Most of my coding-agent skills so far have been for workflow automation — committing, deploying, reviewing. But I recently wrote two skills for",
"path": "/writing-coding-agent-skills-for-external-services/",
"publishedAt": "2026-04-23T06:26:00.000Z",
"site": "at://did:plc:bryys25pc2fnagnyxqgsglhd/site.standard.publication/3mn26bjkkmh23",
"tags": [
"AI",
"Tools"
],
"textContent": "Most of my coding-agent skills so far have been for workflow automation — committing, deploying, reviewing. But I recently wrote two skills for external services — betterstack-log-export and postmark-setup — and they turned out to work differently.\n\nWRITE SKILLS DURING THE TASK, NOT BEFORE\n\nbetterstack-log-export started when I was tracking down why a weekly email report was failing. I needed to filter Better Stack logs by time range and fields like from and level. I figured out the right approach — both the manual UI export and the curl/ClickHouse query — and set an in-session reminder to turn it into a skill.\n\npostmark-setup was even more direct. I was deploying DevSnoop and needed Postmark servers. I gave the agent my account token, told it to follow the pattern from my existing betterstack-source-setup skill, and the new skill was written and used in the same session.\n\nI wrote both during or right after the actual task, which meant I already knew what to encode instead of guessing at it.\n\nWHAT TO PUT IN THE SKILL\n\nMost of the time goes into deciding what belongs in the skill.\n\nFor betterstack-log-export, what mattered:\n\n * UI path for one-offs: Telemetry → filter view → gear → Download → NDJSON\n * curl path for repeatable queries: Integrations → Connect ClickHouse HTTP client\n * EU/US cluster split — which of my projects are on which cluster\n * Collection names — t337893_theblue_logs, t337893_theblue_s3, etc.\n * Credential locations: ~/.config/betterstack/eu.env and ~/.config/betterstack/us.env\n * Query pattern: UNION ALL over hot + archived logs — not obvious from the docs\n * JSONExtract patterns for nested fields (JSONExtractRaw for nested objects)\n * Concurrency limit: Standard tier allows 4 concurrent log queries, so retry on failures\n\nNone of this is in the Better Stack docs as a package. It's my account topology, my file layout, and the things I discovered by doing it once.\n\nFor postmark-setup, different knowledge but the same idea:\n\n * Create both dev and prod servers, not just one\n * Naming convention: <ProjectName> dev and <ProjectName> prod\n * The returned Server API token works as both SMTP username and password — not obvious\n * Update .env for dev, .env.kamal for prod\n * Remind about sender signature/domain verification in the Postmark UI\n\nThat last one is easy to forget. Without it in the skill, the agent finishes the API work, everything looks fine, and then email silently fails in production.\n\nINCLUDE BOTH THE UI PATH AND THE API PATH\n\nbetterstack-log-export covers two ways to get at logs:\n\n * Manual/one-off: filter in the UI and download NDJSON from the gear menu\n * Repeatable/scripted: query the ClickHouse HTTP API with curl\n\nI discovered the UI download first, before reaching for the API. It's faster when you just need to eyeball what happened. The curl path is for reproducible filters, row counts, or anything you might run again.\n\nAn agent that only knows the API will always reach for curl. Sometimes the right answer is downloading 200 rows from the UI and piping them through jq. Encoding both paths means the agent can pick the right one.\n\nKEEP CREDENTIALS OUTSIDE THE SKILL\n\nBoth skills store credentials under ~/.config/<service>/ and source them at runtime. Nothing in the skill body, nothing in the repo.\n\nsource ~/.config/betterstack/eu.env\n\nSkills are text files — they can end up in shared directories, version control, or another agent's context. Keeping credentials out means you don't have to think about it when you share or reorganize skills.\n\nThe pattern came from betterstack-source-setup, which predates the log-export skill. When I wrote postmark-setup, I followed the same layout: ~/.config/postmark/api.env, sourced at runtime.\n\nTRIM IT DOWN\n\nThe first version of betterstack-log-export was much longer than the current one. More explanation, more examples than the agent would ever need. Most of that was useful while I was figuring things out, but the agent at runtime just needs to know which cluster to hit, where the credentials are, and what SQL pattern to use.\n\nI trimmed it in the same session. The current version has one section each for the quick path, clusters, credentials, query pattern, and guardrails.\n\nWHAT THE AGENT CAN'T GET FROM DOCS\n\nThe agent can read Better Stack's API docs or Postmark's SMTP reference on its own. What it can't figure out is which cluster my project is on, what naming convention I use for servers, or that the returned API token doubles as the SMTP password. That's the knowledge that gets lost between sessions and re-discovered every time — unless a skill holds it.\n\nUSE THE SKILL IMMEDIATELY\n\npostmark-setup was used in the same session it was written — I set up DevSnoop's dev and prod servers with it right away. If the skill was wrong or incomplete, I'd have found out on the spot.\n\nbetterstack-log-export was used within a few sessions, running real queries against real log data. The JSONExtract patterns were refined once during actual use. The first version is a starting point — it gets better when you exercise it.",
"title": "Writing Coding-Agent Skills for External Services"
}