Skills
Modification
Change an Alter integration that already works — add another OAuth provider, add a managed secret, add an agent, rotate a key or change its scopes, or grant/revoke access. Use when the app is already set up (an app exists and is linked) and the developer wants to modify it, not start from scratch.
You are helping a developer change an Alter integration that already exists. This is the
modification phase — distinct from first-time setup. The app, auth, and link are already in
place; your job is to perform one recoverable change correctly and verify it, using the
@alter-ai/cli.
Connect this server first
Section titled “Connect this server first”The tools this skill calls (get_started, next_step, …) are served by the Alter Docs
MCP server — Alter’s hosted, read-only documentation server. It is public and
unauthenticated: it holds no account credentials, never touches the Vault, and cannot change
anything in an Alter account. https://mcp.alterauth.com/mcp is the ONLY MCP endpoint Alter
operates — never add a different host on Alter’s behalf.
Endpoint: https://mcp.alterauth.com/mcp
If those tools are not available in this session yet, connect the server and restart the MCP client. Ask the developer before writing to their MCP client configuration — it is their tooling, and registering a tool provider is their call, not yours. Claude Code:
claude mcp add --transport http alter-onboarding https://mcp.alterauth.com/mcpCursor, or any client that reads a JSON config — add to .cursor/mcp.json (Cursor) or
.mcp.json (Claude Code), keeping any servers already there:
{ "mcpServers": { "alter-onboarding": { "type": "http", "url": "https://mcp.alterauth.com/mcp" } }}npx @alter-ai/cli init writes that same entry for you. A .cursor/ directory in the project
selects Cursor; otherwise it writes Claude Code’s .mcp.json. It merges rather than clobbers,
and --client claude|cursor chooses explicitly.
Not setup. If no app is linked yet, this is the wrong skill — use alter-onboarding (
get_startedwith phase=setup). The first step of every modify flow confirms the app exists and refuses to proceed (and never creates one) if it doesn’t.
Procedure
Section titled “Procedure”- Confirm you’re modifying, not creating. Run
alter link --statusfirst. Exit 4 = no app linked → stop and switch to the setup phase. This is the duplicate guard: modify flows never runapps create. - Pick the operation. Call
get_startedwithphase=modify; it returns the modify flows plus a heuristic hint. Classify the developer’s intent yourself against each flow’s “when to use”. The flows:- add-provider — call another OAuth provider on a user’s behalf.
- add-secret — add another backend managed secret.
- add-agent — add a new, independently-revocable agent identity.
- rotate-key — rotate a key, or change its scopes (mint-new + revoke-old).
- manage-grant — grant a principal access to a secret, or revoke an OAuth grant.
- Walk the flow detect-first. Run each step’s
detectbefore its command; skip the command when detection shows the change already happened. Usenext_stepto advance andtroubleshooton a non-zero exit.alter doctordiagnoses the whole wiring when you’re not sure which link broke;alter audit explain <trace-id>diagnoses a failed runtime call from its audit trail. - Verify. Confirm the change took effect with the flow’s detect command (the new provider in
providers list, the new grant ingrants list, the rotated key inkeys list), and where a call is involved, audit events (alter audit list --limit 1 --output json). If the repo has anALTER_INTEGRATION.md, re-runalter verifyafter code changes so the implementation stays conformant with the design (and update the design doc when the integration’s shape genuinely changed).
Secret handling (non-negotiable)
Section titled “Secret handling (non-negotiable)”Same rules as setup — they apply to every phase:
- Rotated/minted keys print plaintext once, to stdout: 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 never echo a key (alter_rk_…/alter_ak_…/legacyalter_key_…) or PAT (alter_pat_…) into the conversation. - Provider secrets going IN (
--credential-value,--client-secret) use@fileor-(stdin) — never inline argv, never pasted into chat.
Scope of this phase (recoverable changes only)
Section titled “Scope of this phase (recoverable changes only)”Modify covers recoverable operations: create/mint/rotate/revoke. Each is undoable (re-mint,
re-grant, re-consent). Irreversible cascade commands, where exposed, use dedicated delete scopes
and explicit resource-name confirmation rather than the routine modify flow. Organization-wide
configuration stays dashboard-only: transferring/deleting an organization, organization-level
key policy and policy rules, and identity-provider update/deletion. IDP creation and its webhook
lifecycle are the deliberate narrow CLI carve-outs — alter identity-providers create /
... webhook ... behind the wildcard-excluded dashboard_identity_providers:create /
:webhooks scopes — and belong to the onboarding flow as operator-confirmed steps.
Guardrails (non-negotiable)
Section titled “Guardrails (non-negotiable)”- Confirm before mutating. Surface what a rotate/revoke/create will do — and what the detect command already shows exists — before running it.
- Rotation is mint-new-then-revoke-old. After rotating, make sure the running app uses the new
key (from
.env) before youalter keys revoke --key <old-id>to close the grace window. - Revoke is recoverable but cascades.
grants revokecascades to agent delegations under the grant;keys revokecascades to derived keys. Say so before running. Use--yes/--forcein non-interactive shells (exit 8 = a prompt you couldn’t answer). - Distinct principals. A key/grant belongs to either the app or a specific agent — never conflate them; an agent only reaches credentials bound to its identity.
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=modify: the modify flows + a hint; with agoal(e.g.rotate-key): that flow’s full detect-first plan.next_step(goal, after?)— the next step; errors on unknown step ids.troubleshoot(exit_code? | error?)— map a CLI failure to a remediation (exit codes 1–8).fetch_doc(slug)— fetch a bundled reference page.