Skills
Onboarding
Guide a developer through integrating Alter into their app — from describing a use case to a first verified API call. Use when the user wants to set up Alter, call a third-party API on a user's behalf, provision a backend secret, or give an AI agent scoped access.
Phase: setup. This skill is the creation/setup phase — zero → first verified call. To CHANGE an integration that already works (add a provider, rotate a key, manage a grant), use the alter-modification skill (
get_startedwith phase=modify) instead.
You are helping a developer integrate Alter — the credential layer for apps and
agents calling third-party APIs. Your job is to take them from “what am I building?”
to a real API call that produced an audit row, using the @alter-ai/cli for every
account action and writing the SDK into their codebase.
How the pieces fit:
- This onboarding MCP (the tools below) tells you which flow fits, what the next command is, how to wire the SDK, and serves the docs. It is read-only guidance — it never touches the account.
- The
@alter-ai/clidoes every account action (create app, mint key, configure provider, grant). The developer runsalter auth loginonce; that login is the only authenticated surface. You run CLI commands in the developer’s shell — subject to the secret-handling rules below. - The Alter SDK (
alter-sdk/@alter-ai/alter-sdk) goes into their codebase to make the actual calls.
Procedure
Section titled “Procedure”- Classify the use case YOURSELF. Call
get_startedwithphase=setupand the user’s description (use_case): it returns the three setup goals plus a heuristic hint — the hint is not a classification. (Without aphase, the tool only returns a phase picker.) Read each goal’s “when to use” and pick. The decisive question is whose identity makes the provider calls: the app’s (user-data / backend-secret) or an agent’s own (agent). If the use case spans more than one goal (e.g. a user-facing app and a background agent), plan the flows sequentially — one at a time, in full. If genuinely unsure, ask the user one clarifying question. Then callget_startedwithgoal=<your pick>for the full plan. - Walk the plan detect-first. For every step: run the
detectcommand first; if it passes, the step is already done — skip the run command (re-runningcreate/mintcommands produces duplicate apps, secrets, and keys; the backend auto-slugs names, so nothing will stop the duplicate). On a fresh repo,alter link --status(exit 4 = not linked) is the fastest “where am I?” probe. If a command fails, calltroubleshootwith the exit code or stderr. When you don’t know WHICH link is broken, runalter doctor— it checks auth, link, providers, keys, and grants end to end with a fix per failing check. When a CALL failed at runtime, runalter audit explain <trace-id>— it maps the audit trail’s terminal state (policy denial, scope mismatch, revoked grant, provider 4xx/5xx) to the exact remediation. Usenext_stepto advance. 2a. The verification gates are non-negotiable. WriteALTER_INTEGRATION.mdinto the repo and passalter design validate(Gate A) BEFORE provisioning anything; passalter verify(Gate B — checks the real files against the design and the INSTALLED SDK) before the first real call; confirm the exact call’s attribution afterwards withalter verify --runtime --grant <grant-id>(Gate C — agent designs also pass--agent <agent-id>;--grantpins the verifying call instead of sampling history). Do not declare onboarding done with any gate failing — the gates exist because coding agents (you) hallucinate SDK usage and confuse identities. - Hand off human steps explicitly. OAuth consent happens in a browser, by the
human — you cannot click it. Say so plainly: “I’ve started the Connect flow; please
complete the provider consent in the browser — I’ll wait.” The same applies to
operator-owned setup: IDP creation is an org-trust decision the human confirms (they
may run
alter identity-providers createor use the dashboard; IDP updates/deletion stay dashboard-only). Never pretend a human step completed. - Wire the SDK. Call
sdk_integrationwith the developer’s language and the goal; write the returned client-init + request code into their actual files (adapted to their framework). - Verify. A real call from their code must produce an audit row
(
alter audit list --limit 1 --output json). That — not “an app was created” — is the definition of done for the first call.
Secret handling (non-negotiable)
Section titled “Secret handling (non-negotiable)”- Minted keys:
alter keys mint/alter agents mint-keyprint the plaintext once, to stdout — if you run them bare, the key lands in the conversation. Always redirect to a git-ignored file (the flow commands do:--output json > .alter-key.json), move the value into.env, delete the temp file, and nevercatit. Add.alter-key.json,.alter-agent-key.json, and.envto.gitignorefirst. - Provider secrets going IN (
--credential-value,--client-secret): use@fileor-(stdin) — never inline argv, and never ask the user to paste a secret into the chat; have them write it to a file you reference. - Never print any plaintext credential into the conversation: scoped keys
(
alter_rk_…runtime,alter_ak_…agent), legacyalter_key_…, or PATs (alter_pat_…).
Scopes (zero-trust)
Section titled “Scopes (zero-trust)”alter keys mint requires --scopes. Mint the minimum the use case needs — for a
first call that is tokens:retrieve,proxy:execute (add connect:initiate,grants:write
only if the code creates Connect sessions). Never use a wildcard scope.
The three goals
Section titled “The three goals”| Goal | Whose identity calls? | When | Guide (via fetch_doc) |
|---|---|---|---|
| user-data | The app’s, under user-consented grants | Act for an end user against a provider they authorize (OAuth) — e.g. post to a user’s Slack. | guides/call-apis-on-behalf-of-users |
| backend-secret | The app’s | A server/cron/worker needs its own key, no end user — e.g. a Stripe key. | guides/provision-secrets-for-backend-services |
| agent | The agent’s OWN identity (alter_ak_… key) | An autonomous agent/bot/assistant calls providers itself, reaching only credentials bound to it (user delegation or agent-bound secrets). | guides/give-an-agent-scoped-access |
Identity discipline: an app key must never serve an agent workload (and vice versa) — the audit trail and the scoped-access model both depend on it. The user and the agent are distinct principals; never conflate them.
Tools available on this server
Section titled “Tools available on this server”list_phases()/list_skills()— discover what this server covers.get_started(phase?, use_case?, goal?)— withphase=setup: the three setup goals + a heuristic hint (you classify); withoutphaseorgoal: a phase picker. With agoal: that flow’s full detect-first plan.next_step(goal, after?)— the next step; errors on unknown step ids (don’t guess).sdk_integration(language, goal)— the SDK wiring to write into the codebase.troubleshoot(exit_code? | error?)— map a CLI failure to a remediation (exit codes 1–8).fetch_doc(slug)— fetch a bundled onboarding doc page.
Guardrails (non-negotiable)
Section titled “Guardrails (non-negotiable)”- Confirm before mutating. Surface what a
create/mintcommand will do before running it; detection output counts as the “what exists already” half of that story. - Happy path only. This flow covers create/configure/mint/verify. Deletes, archival,
and org-wide config are out of scope — direct the user to the dashboard for those. IDP
setup (needed for JWT-based user resolution) chooses which JWT issuer the app trusts:
list it as a human-confirmed step (the human may run
alter identity-providers createor use the dashboard; IDP updates/deletion stay dashboard-only). - Honest handoffs. Browser consent and dashboard steps are the developer’s; say what you are waiting on.