Api skill builder
Skill aditya-m-bharadwaj/APIskillBuilderSkill/.claude/skills/api-skill-builder
Bootstrap a new "<vendor>-api-skill" project — a safe, cross-platform single-file Python CLI that mediates a third-party REST API, plus a matching Claude skill that drives it under explicit AI-safety constraints (token never enters AI context; every mutation passes through a six-tier safety classifier; every mutation is recorded in a local audit log). Trigger when the user asks to "build a CLI / skill for <some API>", "wrap the <X> API safely", or to mirror the linode-api-skill pattern for a new vendor.From its SKILL.md
npx -y skills add aditya-m-bharadwaj/APIskillBuilderSkill --skill api-skill-builderAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 0 stars0 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.
SKILL.md
30.0 KB, ~7.4k tokens by cl100k_base, as published. Nobody here has run it
API Skill Builder — bootstrap a vendor-API CLI + Claude skill with AI-safety baked in
This skill takes you from "I want to drive the <X> REST API safely from a Claude session" to a published alpha that:
- never lets the AI read the API credential,
- classifies every endpoint into a six-tier risk taxonomy and refuses to send a mutation without the matching operator-supplied flag,
- stores the credential in the strongest OS-native secret store available, with file fallback at mode
0600, - writes an append-only audit log of every mutation,
- ships with cross-platform installers, MIT license, full doc set, CI, issue/discussion templates, and a tracked project-memory layer.
The canonical reference implementation is linode-api-skill at https://github.com/aditya-m-bharadwaj/linode-api-skill. Whenever this skill says "mirror the pattern", read the corresponding file there and adapt it. Do not invent variations of the safety contract — copy it.
Hard rules (non-negotiable for every generated skill)
When you generate a new <vendor>-api-skill repo, the resulting tool MUST satisfy all of these. If a target API makes one of them impossible (e.g. mandatory query-string auth), surface the conflict to the operator and stop — do not silently weaken the contract.
- The API credential never enters the AI's context. Not via env, not via
cat, not via argv, not via dialog stdout the AI can see. Entry path is<bin> setup(TTY-only, hidden prompt) or<bin> gui-setup(native OS password dialog, AI-runnable but renders out-of-band of any pipe the AI reads). - Storage is OS-native first, file fallback at mode
0600only. macOS Keychain → Linux Secret Service (libsecret) → file at~/.<vendor>-api-skill/token(mode0600, refuses to read if broader). Single-string-secret backends only — if the vendor uses a key+secret pair, store the pair as one URL-encoded or JSON blob in one keystore entry. - Verify before store. A new credential is validated against a known-good read endpoint (
whoami-equivalent for the API) BEFORE replacing whatever is already in the keystore. A bad credential never overwrites a working one. - Six-tier safety classifier with required-flag matrix. Every mutation passes through
classify(method, path)which returns one of:read,mutating,destructive,billable,financial,privilege. The CLI itself enforces the required flags; the matrix is the same aslinode-api-skill's. Unrecognized endpoints fall through to the strictest applicable default (GET → read, DELETE → destructive, anything else → mutating). - Append-only audit log of every mutation.
~/.<vendor>-api-skill/audit.log, mode0600, one JSON line per mutation, with timestamp / user / action / target / parameter metadata — never the token, never request body values, never generated secrets. - Path / argument hardening. Validate paths against a tight regex; reject
../.traversal segments and URL-encoded%-sequences pre-classification. Refuse--body @filepaths that resolve inside the config dir. Strip a leading API-version prefix (e.g./v4,/v3) at the boundary if the docs canonically include it. - Stdlib-only Python, single file.
bin/<vendor>-api-skillis one Python 3.8+ file using only the stdlib. Norequests, noclick, nopydantic, nokeyring. This eliminates supply-chain risk on a privileged tool. - Every mutation needs human confirmation in chat AND the machine
--yesflag.--yesalone is never enough; the AI must obtain explicit human confirmation in chat before sending. - MIT license, AI-authorship disclosure, commit-trailer convention.
AUTHORS.mddiscloses the model that wrote the code. Commits carryPrompted-By: <operator>+Co-Authored-By: <model>trailers. Seelinode-api-skill/CONTRIBUTING.mdfor the exact format. - Threat model documented.
SECURITY.mdlists what the tool defends and what it does NOT defend; reporting goes through GitHub private security advisories.
The build process
Follow these steps in order. Do not skip "in-flight" steps to land a partial alpha — the safety contract is most useful when complete.
Step 0 — Confirm scope with the operator
Before writing code, agree on:
- API name and slug. Slug is
<vendor>-api-skill(kebab-case, no doubling). Used as the binary name, repo name, and Claude skillname:field. - Auth model. Bearer token?
apikey+secretpair? OAuth? HMAC-signed requests? This shapes the token storage andgui-setupflow. - API base URL and version. e.g.
https://api.linode.com/v4,https://api.porkbun.com/api/json/v3, etc. Note whether the canonical docs paths include the version segment (you'll want to strip it at the boundary if so — see_strip_v4inlinode-api-skill). - The "billable" endpoints. Which paths cost real money when called? Get a list from the operator or the vendor's pricing page. These are the ones that need
--i-understand-billing. - The "financial" and "privilege" prefixes (if any). Some APIs don't have these tiers — that's fine; leave the prefix lists empty.
Step 1 — Init the repo
mkdir ~/Code/<slug>
cd ~/Code/<slug>
git init -b main
Drop in the LICENSE (MIT, copyright "<slug> contributors"), .gitignore (mirror linode-api-skill), and the dir skeleton:
.claude/
├── skills/<slug>/SKILL.md ← the runtime skill (will be authored after the CLI exists)
├── commands/{resume,save}.md ← project-level slash commands
└── settings.json ← graphify PreToolUse hook (installed by `graphify claude install`)
.github/
├── workflows/{ci,codeql}.yml
├── ISSUE_TEMPLATE/{bug_report,feature_request,config}.{md,yml}
├── DISCUSSION_TEMPLATE/{q-and-a,ideas,show-and-tell}.yml
└── FUNDING.yml
bin/<slug> ← the CLI (Python 3.8+, stdlib only)
tests/test_classify.py ← offline classifier tests
docs/
├── README.md
├── progress/{TEMPLATE.md,YYYY-MM-DD-initial-alpha.md}
├── decisions/{TEMPLATE.md,NNNN-*.md}
└── settings.local.json.template ← harness deny-rules template
install.sh
install.ps1
AUTHORS.md
CHANGELOG.md
CLAUDE.md
CONTRIBUTING.md
LICENSE
README.md
SECURITY.md
Step 2 — Design the safety classifier
Author the classifier table in bin/<slug> with five collections (mirror linode-api-skill line ~620+):
_FINANCIAL_PREFIXES— tuple of path prefixes under which any non-GET isfinancial. Leave empty()if the API has no money-movement endpoints._PRIVILEGE_PREFIXES— tuple of path prefixes under which any non-GET isprivilege(token/user/oauth management)._BILLABLE_EXACT— set of(METHOD, normalized_path)tuples that allocate a paid resource._MUTATING_EXACT— set of(METHOD, normalized_path)for explicitly-mutating-but-free endpoints (clearer than relying on the default)._DESTRUCTIVE_EXACT— optional, for non-DELETE destructive endpoints (e.g.POST /…/disable).
Implement _normalize_path(path) — strips the API-version prefix if applicable, then maps numeric segments to {id} for table lookup. Implement classify(method, path) returning (tier, [required_flags], explanation).
Test the classifier offline for every entry. Cross-check each _BILLABLE_EXACT entry against the vendor's pricing page — over-cautious is safe; under-cautious is dangerous.
Step 3 — Implement token storage
Mirror the storage layer from linode-api-skill (look for _kc_get_macos, _kc_set_macos, _kc_get_linux, _file_get, _file_set):
- macOS:
security add-generic-password -U(in-place update, no delete-then-add race). - Linux:
secret-tool store/secret-tool lookup(libsecret). Falls through to file if not present. - Windows / fallback: file at
~/.<slug>/token, mode0600. Refuse to read if POSIX mode is broader than0600.
For multi-part credentials (apikey + secret), serialize as one JSON blob before storage so each backend stays a single-string store. Encode/decode at the boundary; the rest of the CLI sees one opaque string and decodes inside _request.
Step 4 — Implement gui-setup and setup
setupreads viagetpass(hidden prompt) from a TTY. AI agents cannot run this. The install script'scurl … | shinvocation re-attaches stdin to/dev/ttyso it still works when invoked through a pipe.gui-setuppops a native OS password dialog:- macOS:
osascriptwithdisplay dialog "..." with hidden answer. - Linux: try
zenity --password, fall back tokdialog --password. - Windows: PowerShell
Get-Credential(returns aSecureString; convert to plain inside the PS one-liner and emit to stdout).
- macOS:
- The dialog process's stdout is captured into Python memory via
subprocess.run(..., capture_output=True). The token bytes never re-enter stdout that any pipe / observer can see. - Validate the captured token by calling the API's
whoami-equivalent BEFORE writing it to the keystore (Step 3 contract). - On rotation: tell the user to revoke the old token at the vendor's dashboard. Local replacement does not invalidate the old token server-side.
Step 5 — Implement named commands + generic api gateway
- Named commands for the most common, highest-value workflows. For a domain registrar (Porkbun), this is
domains,dns-list <domain>,dns-create,dns-delete <id> --confirm-id,pricing, etc. Each named command performs the classification check inline and audits on success. - Generic
apicommand for full API coverage:<slug> api <METHOD> <path> [--data …] [--body @file] [--query k=v] [--paginate] [--dry-run] [--json] [--yes] [--confirm-id …] [--i-understand-billing] [--allow-financial] [--allow-privilege]. Filter outAuthorization-header overrides in--header-style flags. Refuse--body @filepaths that resolve inside the config dir. - Audit-log every non-read call after success (or after a 4xx that did mutation work).
Step 6 — Write tests
tests/test_classify.py loads bin/<slug> via importlib.machinery.SourceFileLoader (no install needed) and exercises:
- One test per
_BILLABLE_EXACT/_FINANCIAL_PREFIXES/_PRIVILEGE_PREFIXESentry — assert classification and flags. _normalize_path: numeric segments →{id}, string segments preserved, version-prefix stripping, edge cases (/v40/fooand/foo/v4/barshould NOT be stripped)._validate_path: traversal rejection, URL-encoded%rejection, ASCII path-char whitelist.- Method case-insensitivity.
- Default fallback: unknown GET → read, unknown DELETE → destructive, anything else → mutating.
- Platform helpers (
_has_display,_platform).
Aim for ≥25 tests; ≥30 once you've covered all classifier-table entries.
Step 7 — Author the runtime SKILL.md
Author .claude/skills/<slug>/SKILL.md. Use linode-api-skill/.claude/skills/linode-api-skill/SKILL.md as the template. Sections to mirror:
- Frontmatter (
name,description). - Hard rules.
- How the safety classifier works (the same six-tier table).
- Named commands table.
- Generic
apigateway examples for each tier. - Resource-category checklist (one row per major API category — what to confirm with the user before calling).
- Token management workflows (add, rotate, remove, diagnose).
- Workflow recipes (the 4–8 most common multi-step operations for this vendor).
- Things you should NOT do.
- When something goes wrong (error → action table).
Step 8 — Author the supporting docs
For each, copy the corresponding file from linode-api-skill and rewrite for the new vendor:
README.md— install one-liners, token management, classifier reference, common workflows, file map, uninstall. Status banner at top:Status: v0.1.0-alpha.1.AUTHORS.md— AI-authorship attribution + AI-generated-code disclaimer.SECURITY.md— threat model: defended vs. not-defended, hardening recommendations, private-advisory reporting link.CONTRIBUTING.md— stdlib-only rule, classifier-extension procedure, test pattern, full commit-message format (Prompted-By + Co-Authored-By trailers).CHANGELOG.md— one[0.1.0-alpha.1]entry describing the alpha; future work goes under[Unreleased].CLAUDE.md— project-level hard rules for any AI agent in the repo. Defers to.claude/skills/<slug>/SKILL.mdas authoritative.
Step 9 — .github/ metadata
Copy from linode-api-skill/.github/:
workflows/ci.yml— 3 OS × Python 3.8–3.12 matrix (exclude macOS 3.8/3.9 — runner images don't ship them). Steps:py_compile,unittest discover tests, smoke<slug> classifyon a read and a destructive path. Separateshellcheck install.shjob on Ubuntu.workflows/codeql.yml— GitHub's CodeQL static analysis. Matrix overpython(the CLI is Python; rules catch path-traversal, injection, weak crypto, etc.) andactions(lints the workflow files themselves for token-scope and untrusted-input issues). Triggers on push tomain, PR tomain, and a weekly cron.build-mode: none— the CLI is stdlib-only so there's nothing to compile. Pair with "Code scanning" enabled in repo settings (Step 14). The canonical template lives in this skill's own repo atAPIskillBuilderSkill/.github/workflows/codeql.yml; for a generated vendor skill, copy it and addpythonalongsideactionsin the language matrix.ISSUE_TEMPLATE/{bug_report,feature_request}.mdandconfig.yml—config.ymldisables blank issues and points contact links at the private security advisory page,SECURITY.md, and Discussions.DISCUSSION_TEMPLATE/{q-and-a,ideas,show-and-tell}.yml.FUNDING.yml— fill ingithub: [<operator-username>]; comment out the rest.
Step 10 — Memory layer
Set up the same docs/ layer that linode-api-skill uses:
docs/README.md— human-facing index of the memory layer.docs/progress/TEMPLATE.mdanddocs/progress/YYYY-MM-DD-initial-alpha.md— seed entry covering this scaffolding session.docs/decisions/TEMPLATE.mdand ADRs0001-N. At minimum write:0001-stdlib-only-python.md— why no requests/click/keyring.0002-safety-classifier-six-tiers.md— the tier taxonomy.0003-cross-platform-token-storage.md— backend selection.0004-ai-safe-token-entry-gui-dialog.md— the out-of-band entry pattern.0005-prompted-by-trailer-convention.md— commit-trailer rationale.0006-monolithic-cli-file.md— single-file rationale.0007-versioning-semver.md— SemVer with-alpha.N.- One ADR per vendor-specific decision (auth flow, version-prefix, billable-list source).
docs/settings.local.json.template— harness deny-rules template using~/paths (NOT/Users/<operator>).
Step 11 — Project-level slash commands + graphify
.claude/commands/resume.md— readsdocs/progress/(most recent),graphify-out/GRAPH_REPORT.md, three most recentdocs/decisions/. Adapt fromlinode-api-skill/.claude/commands/resume.md..claude/commands/save.md— writes a newdocs/progress/YYYY-MM-DD-<slug>.md, optionally creates an ADR, routes reusable cross-project concepts to~/.claude/vault/zettel/concepts/. Adapt fromlinode-api-skill/.claude/commands/save.md.- After at least one code file exists, run
graphify update .once to populategraphify-out/. Install the post-commit hook:graphify hook install. Install the Claude PreToolUse hook:graphify claude install(writes.claude/settings.json).
Step 12 — Install scripts
install.sh(POSIX) — verify Python 3.8+, clone the repo (or use existing checkout), symlinkbin/<slug>into${LINODE_CTL_PREFIX:-~/.local/bin}(rename the env var to match the vendor slug). Optionally install the Claude skill into~/.claude/skills/<slug>/. Re-attach stdin to/dev/ttyfor the optional immediate-setup prompt socurl … | shstill works.install.ps1(Windows) — Python check,.cmdshim onPATH,icacls-locked-down ACL for the file fallback if used.- Verify with
shellcheck install.shbefore commit.
Step 13 — Initial commit
One commit with the entire alpha. Subject form: feat: initial public alpha (v0.1.0-alpha.1). Body: 1-sentence summary + bullet list of every major surface (CLI commands, classifier tiers, storage backends, install scripts, skill, docs). Trailers:
Prompted-By: <operator name> <operator email> # from `git config user.name`/`user.email`
Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]> # actual model id you are running as
Do NOT bypass hooks (--no-verify, --no-gpg-sign). Do NOT commit if the operator has not explicitly told you to — draft the message and stop.
Step 14 — Push and configure the GitHub repo
After the operator authorizes the push and the commit lands on origin/main, configure the GitHub repo. These settings are the alpha default; the operator can tighten them later (e.g. add branch protection) once the project has external contributors.
About panel (top of the repo page):
- Description — one sentence covering what the tool does and the safety pitch. Form: "
<vendor>-api-skill— a safe, single-file Python CLI mediating the<Vendor>API, plus a matching Claude skill. Credential never enters AI context; every mutation is classifier-gated and audit-logged." - Website — leave blank, or point to the canonical reference (
https://github.com/aditya-m-bharadwaj/linode-api-skill). - Topics — pick ~12 from:
claude-code,claude-skill,claude-agent-sdk,ai-safety,ai-agents,api-wrapper,cli,python,<vendor>(e.g.linode,porkbun),<vendor>-api,credential-management,audit-log,safety-classifier.
Features (Settings → General → Features):
| Feature | Default | Why |
|---|---|---|
| Issues | on | issue templates ship in .github/ISSUE_TEMPLATE/ |
| Discussions | on | discussion templates ship in .github/DISCUSSION_TEMPLATE/ |
| Wikis | on | enabled by default; the in-repo docs/ memory layer is canonical, but leaving wikis on costs nothing and gives external contributors a low-friction surface |
| Projects | on | enabled by default; same reasoning — no cost, optional surface for issue triage |
| Sponsorships | on | .github/FUNDING.yml is in place |
| Preserve this repository | on if eligible (Arctic Code Vault opt-in) | free, no downside |
Pull Requests (Settings → General → Pull Requests):
- Allow squash merging: on.
- Allow merge commits / rebase merging: off for a solo alpha.
- Always suggest updating PR branches: on.
- Allow auto-merge: on.
- Automatically delete head branches: on.
Code security (Settings → Code security):
- Private vulnerability reporting: enable — this is what
SECURITY.mdandISSUE_TEMPLATE/config.ymldirect reporters to. - Dependabot alerts: enable — catches
actions/*version bumps even though the CLI has no Python deps. - Dependabot security updates: enable.
- Secret scanning (free on public repos): enable.
- Push protection (blocks pushes containing detected secrets): enable.
- Code scanning (CodeQL): enable. The workflow ships at
.github/workflows/codeql.yml(Step 9) and analyzes the Python CLI and the workflow files themselves. Even on a stdlib-only single-file CLI, CodeQL catches path-traversal, command-injection, weak-crypto, and untrusted-input-into-action patterns that the classifier doesn't see. The weekly cron also re-scans against updated rule packs.
Branch protection (Settings → Branches):
- For a solo v0.x alpha: skip. The operator pushes directly to
mainper the established pattern. - Revisit once external contributors arrive: enable "Require a pull request before merging" + "Require status checks to pass" (CI green) on
main.
Pages / Webhooks / Actions secrets: leave as default. No docs site is published; no secrets are needed by CI.
Bootstrap the wiki. The wiki is a separate git repository (<repo>.wiki.git) that GitHub provisions only after a first page is saved through the web UI. You (the AI) cannot create this repo via gh or any other automated path — gh repo create <slug>.wiki fails with "The repository <slug>.wiki cannot end in .wiki" because GitHub reserves the .wiki suffix for auto-provisioned wiki repos. Cloning <slug>.wiki.git returns "Repository not found" until the operator has saved a page.
→ Stop here and ask the operator to bootstrap the wiki manually. Direct them to:
- Open
https://github.com/<owner>/<slug>/wikiin a browser. - Click "Create the first page" and save anything (the default "Welcome to the wiki!" body is fine — it will be overwritten in a moment).
- Confirm back to you that the page saved.
Only after the operator confirms can you proceed. Then clone the now-existing wiki repo, replay starter pages over GitHub's placeholder, and push:
# In the project root, AFTER the operator has saved the first wiki page:
git clone https://github.com/<owner>/<slug>.wiki.git wiki
echo 'wiki/' >> .gitignore # main repo never tracks the nested .git
cd wiki
# GitHub-provisioned wikis default to the `master` branch, not `main`.
# Don't fight it; commit on master so push succeeds without surgery.
# Author / copy in the starter pages (this overwrites GitHub's auto Home.md):
# ... write Home.md, _Sidebar.md, _Footer.md, Getting-Started.md, etc.
git add -A
git commit -m "wiki: initial seed (v0.1.0-alpha.1 surface)"
git push -u origin master
The minimum-viable starter page set (mirror the APIskillBuilderSkill wiki):
Home.md— landing page with the safety pitch in one paragraph + navigation._Sidebar.md— right-side nav (Concepts / Reference / Contribute / Links)._Footer.md— short repo / license footer.Getting-Started.md— install, prerequisites, first invocation.How-It-Works.md— conceptual overview of how the CLI + runtime skill relate.Hard-Rules.md— annotated version of the safety contract.Six-Tier-Safety-Classifier.md— tier table + classification logic.Build-Process.md— annotated build/use steps if relevant for downstream users.ADR-Index.md— one-line summaries linking to eachdocs/decisions/<NNNN>-*.mdfile.FAQ.md— open questions and deliberate non-goals.Roadmap.md— near / medium / long-term + explicitly out-of-scope items.Contributing-to-the-Wiki.md— clone-edit-push workflow + page conventions.
Page conventions: filenames are Page-Name.md at the wiki root (no subdirectories — GitHub wikis are flat); internal links use [[Page Name]]; links from wiki to the main repo use absolute https://github.com/<owner>/<slug>/blob/main/... URLs because the two repos are separate. Wiki pages summarize and link to canonical content in docs/; they do not replace it. When the wiki and docs/ disagree, docs/ wins.
Add a "Contributing to the wiki" section to the generated project's CONTRIBUTING.md describing the local workflow and the docs/ vs. wiki split — so a future contributor knows how to clone, edit, push, and where canonical content lives.
Run this step right after the first push lands. The default GitHub presets for a brand-new repo are not what the safety contract assumes — at minimum, private vulnerability reporting must be on (or SECURITY.md's instructions are a dead link), and the description / topics must be set so users discover the project at all.
After configuring, paste the live About-panel description and the comma-separated topic list back to the operator for verification.
Step 15 — Live smoke test (if a token is available)
If the operator provides a scoped test credential, exercise the alpha end-to-end before declaring v0.1 done:
- Install via the published
curl … | shone-liner against a sandbox prefix (LINODE_CTL_PREFIX=/tmp/...-style) so you don't pollute the operator's real install. <slug> gui-setupvia the OS dialog. Confirmwhoamiworks.- Inventory all existing resources and record them so you can verify nothing got touched.
- Exercise one workflow per tier:
read— list a resource type.mutating— a reversible change (e.g. toggle a setting).destructive— delete a test-tagged resource only.billable— create the cheapest possible resource, tagged for cleanup.financial/privilege—--dry-runonly, do not actually call.
- Verify the safety contract: try a billable call without
--i-understand-billing(expect refusal); try a destructive call with mismatched--confirm-id(expect refusal). - Clean up all test-tagged resources via the named cleanup command.
- Confirm pre-existing resources are untouched.
- Review the audit log — every mutation should appear, no secrets should appear.
Any defects surfaced by the smoke test are blockers for v0.1, not follow-up issues. Land the fixes (with tests and the corresponding CHANGELOG / SKILL.md / docs updates in the same commit) before tagging.
Safety guarantees the generated skill MUST provide
A reader looking at the generated repo for the first time should be able to verify the following by reading the code, with no external trust:
- The token is never in argv. Search
bin/<slug>for the token variable name — it should only appear in: storage read/write helpers, theAuthorizationheader construction, and the verify-before-store call. - The token is never in stdout / stderr / log files / audit entries. Search for the token variable name in
print,_emit,_audit,logger, etc. — should appear in none. - The OS-dialog stdout is captured into Python memory by
subprocess.run(..., capture_output=True)and never re-printed. The CLI prints success metadata (Authenticated as: <username>) and nothing else from that call. - Every mutation is guarded by an
if not args.yes: raise CtlError(...)check OR the genericapicommand's flag-check loop. There are no code paths that POST/PUT/PATCH/DELETE without classification + flag gating. - The audit log only records body keys for generic
apicalls — not values. Grep_audit(...)calls; the onlybody_keys=...shape is keys-only.
Things you should NOT do
- Do not import third-party Python packages. Stdlib only. Even
keyringis out — the CLI's storage layer is intentionally re-implemented against the OS-native CLIs (security,secret-tool,cmdkey). - Do not support an
LINODE_TOKEN-style environment variable as the primary credential path. The operator can opt-in via documented escape hatches, but the default is keystore-only. - Do not invent a "lighter" safety classifier with fewer tiers because the target API "seems mostly free". Even free APIs have privilege escalation (issuing scoped tokens), and the tier system is the operator's mental model — don't change it across vendors.
- Do not add a fancy interactive prompt for token entry beyond
setup(TTY) andgui-setup(OS dialog). No browser-based OAuth flows, no QR codes, noexpectscripts. The TTY/dialog out-of-band requirement is the contract. - Do not auto-classify unrecognized endpoints as
read. The default fallback for non-GET ismutating; for DELETE,destructive. Conservative is correct. - Do not publish to PyPI yet. The default install path is the one-liner
curl … | shfrom raw.githubusercontent.com, which can't smuggle in a dependency. If PyPI publishing is added later, switch the version string to PEP 440 (0.1.0a1instead of0.1.0-alpha.1). - Do not create the generated repo as a "monorepo" of multiple vendors. One vendor = one repo. The skill is independent per vendor; cross-vendor sharing happens at the doc level (this skill).
Reference implementation
https://github.com/aditya-m-bharadwaj/linode-api-skill is the canonical implementation. When in doubt, read the corresponding file there. Specifically:
| Concern | File |
|---|---|
| Safety classifier | bin/linode-api-skill lines ~620–740 |
| Token storage | bin/linode-api-skill _kc_* and _file_* helpers |
| GUI dialog | bin/linode-api-skill _has_display, _prompt_token_gui, _confirm_gui |
| Audit log | bin/linode-api-skill _audit |
| Verify-before-store | cmd_setup and cmd_gui_setup (call /profile before persisting) |
| Path validation | PATH_RE and _validate_path |
| Header / body hardening | _request (filters Authorization); _load_body (refuses paths under CONFIG_DIR) |
| Skill template | .claude/skills/linode-api-skill/SKILL.md |
| Memory layer | docs/ and .claude/commands/{resume,save}.md |
| CI | .github/workflows/ci.yml |
| Install scripts | install.sh, install.ps1 |
| Commit-trailer convention | CONTRIBUTING.md §"Commit message format" |
Open issues / things the build process does not yet automate
These are honest gaps you should surface to the operator rather than fake:
- Pricing introspection. This skill assumes you'll get the billable-endpoint list from a human or the vendor's pricing page. There's no automatic mapping from an OpenAPI spec to "this endpoint costs money".
- OAuth-flow APIs. The
setup/gui-setuppattern assumes a paste-once-and-store credential. For APIs requiring OAuth dance + refresh tokens, you'll need additional design (similar in spirit togh auth loginbut adapted). - Live smoke testing across all tiers. Step 14 prescribes the methodology but the actual recipe is per-vendor — you need to know which resource is cheapest, which can be safely deleted, etc.
- Generator tooling. This skill is markdown that guides an AI to build. There is no
api-skill-builder scaffold <slug> <spec.json>CLI. Building one is reasonable future work; for now, follow the steps by hand.
What ships with it
Read from the repository
Just SKILL.md. No reference files, no scripts.