TL;DR
- Claude's Max and Team plans include a monthly API credit at no extra cost. Claude Code can't spend it, but OpenCode can, once you register an API key. The official pages don't mention third-party clients, but on my machine the credit went down when I used OpenCode.
- The credit is $100 a month on Max 5x and $200 on Max 20x. Team gets a per-seat pool, capped at $500. It resets every month and doesn't roll over. Pro isn't eligible.
- It isn't added automatically. You get it by linking a Console organization in claude.ai.
- In OpenCode you register a Console API key. Anthropic doesn't allow signing in to OpenCode with a Pro/Max account.
- The second half is a paste-ready prompt, plus the pitfalls, for moving your Claude Code setup (
CLAUDE.md, subagents, skills, MCP, hooks) to OpenCode.
The whole thing in three steps:
# 1. In claude.ai, link a Console organization under Settings > Billing, then create an API key in the Console
# 2. Register the key in OpenCode (you paste it at the prompt)
opencode auth login anthropic --method key
# 3. Check that it works
opencode run --model anthropic/claude-haiku-5-5 "Reply with exactly one word: pong"
Tested on macOS 27.0.1, OpenCode v2.0.27 and Claude Code 2.1.296. The quotes from official pages and my own runs are both as of Oct 12, 2026.
Why I moved to OpenCode
On the night of Oct 11, 2026, in the last push on a hackathon project, Claude Code hit its weekly limit. I logged in again with a Console account, and this time it said Credit balance is too low. Since the next day, Oct 12, I've been on OpenCode v2.0.27 with an API key.
Monthly API credits for Max and Team plans are rolling out from Oct 7, 2026 (Platform release notes). Interactive Claude Code can't use them; the API can. This post covers how to connect OpenCode, and the pitfalls I hit moving my Claude Code setup to V2.
Connect OpenCode to the credit
What the credit covers
The table below is what the Help Center and the Platform docs say.
| How you use it | Credit |
|---|---|
| Interactive Claude Code (terminal, IDE, desktop, web) | Not eligible |
claude -p or the Agent SDK, run by you with an API key from the linked organization |
Eligible |
| Claude API, Console Playground | Eligible |
| Bedrock, Vertex AI, Foundry | Not eligible |
| Third-party clients such as OpenCode (with a Console API key) | Not mentioned (it went down on my machine) |
The monthly amount is $100 on Max 5x and $200 on Max 20x; Team gets a per-seat pool (capped at $500). It renews every month with no carry-over. A plan can link only one Console organization, and you can't change it yourself later (it goes through support).
Logging in to Claude Code with a Console account doesn't get you this credit either. The docs say that if an organization holds only this credit, you get Credit balance too low · Add funds: ….
1. Link a Console organization
- Open Settings > Billing in claude.ai (Team owners: Organization settings > Billing).
- Under API credits, click "Link organization" and pick an organization or create a new one.
- Read the Supplemental Credit Terms and link.
On the plan side you need to be the subscriber (Max) or an Owner or Primary Owner (Team). On the Console side you need one of the Owner, Admin or Billing roles. A new subscription can link only after 7 days. If you're eligible but "API credits" doesn't show up, the rollout may not have reached you yet (the Help Center says it's rolling out over several days). Once linked, the Console's Settings > Billing shows the amount and expiry under Promotional credits. Pick the organization you actually work in.
2. Create an API key
In the Console's Settings → API keys, press Create key, choose a name and an expiry, and set Linked account to yourself. The key starts with sk-ant- and is shown only once, when you create it. Keys in the linked organization draw from the same balance, even across different workspaces.
3. Register it in OpenCode
curl -fsSL https://opencode.ai/v2/install | bash # if you're on V1: opencode upgrade --major
opencode auth login anthropic --method key
Paste the key at the prompt (this needs an interactive terminal). In the TUI, use /connect and pick Anthropic. Each time you register a key, another saved account is added, and the newest one becomes active. If you already had a different key registered, check with opencode auth list and switch to the linked organization's key with opencode auth switch anthropic <label> (Providers).
Warning: Don't sign in to OpenCode with a Pro/Max subscription. Anthropic's legal page doesn't allow third-party developers to route users' requests through Free, Pro or Max plan credentials. OpenCode's own V1 docs say of using Pro/Max models in OpenCode: "Anthropic explicitly prohibits this". They also say the plugin for it was removed in 1.3.0. An old step that says to pick "Claude Pro/Max" is still on the same page, but it doesn't work.
Using a Console API key that you set up in your own development environment, on the other hand, is not restricted, according to the legal page. I couldn't find a sentence saying it works with any client, though.
Warning: Don't put
ANTHROPIC_API_KEYin~/.zshrceither. If you approve a key found in the environment, Claude Code runs on that key instead of your subscription. Interactive mode isn't eligible for this credit, so you can end up withCredit balance is too low. Withclaude -p, a key in the environment is always used, with no approval step (Authentication, error reference).
If you'd rather pass the key as an environment variable, you can set it for OpenCode's background server only (opencode service set env ANTHROPIC_API_KEY sk-ant-...). I don't use this.
4. Check that it works
$ opencode auth list
Anthropic Anthropic stored
$ opencode run --model anthropic/claude-haiku-5-5 "Reply with exactly one word: pong"
> build · claude-haiku-5-5
pong
With opencode auth list --format json, you'll see "method": "key".
To see whether the credit is being used, look at Promotional credits under Settings > Billing in the Console and at the Cost page, before and after a request. On my machine, Promotional credits went down after I used OpenCode. Consumption through third-party clients isn't described officially, so it's worth confirming once on your own account. If it doesn't go down, first suspect that the key isn't from the linked organization. When the balance runs out, requests draw on any purchased credits or auto-reload you have; if there are none, API requests stop (your Claude plan isn't billed).
Move your Claude Code setup to OpenCode V2
Start with a prompt
I put the pitfalls from this section into a prompt for OpenCode. Start OpenCode and paste it as is.
Migrate my Claude Code setup to OpenCode V2.
- The source of truth is the OpenCode V2 docs (https://opencode.ai/v2/docs/). Don't use V1 syntax (`permission`, `bash`, `task`, `mcp.<name>`)
- Read: `~/.claude/CLAUDE.md`, `~/.claude/settings.json`, `~/.claude/agents/`, `~/.claude/skills/`, the enabled plugins (`enabledPlugins` in `settings.json`; their contents are under `~/.claude/plugins/cache/`), and the output of `claude mcp list`
- Treat `~/.claude` as read-only and don't change it. If `~/.config/opencode` already has files, back them up first
- Create:
1. `~/.config/opencode/AGENTS.md`: the contents of `CLAUDE.md`, plus one sentence saying "if a repository has a `CLAUDE.md`, read it before working"
2. `~/.config/opencode/agents/*.md`: give each agent `mode: subagent` and `model: provider/model#variant`, and rewrite `disallowedTools` as `permissions` deny rules. Don't write `name`
3. `~/.config/opencode/opencode.jsonc`: `model` (the variant goes in `agents.build.model`); in `skills`, list the plugins' skill folders first and `~/.claude/skills` after them (so personal skills win when IDs collide); MCP servers under `mcp.servers`; hooks only where they can be replaced by `permissions`
4. For each skill that takes arguments through `$ARGUMENTS`, a command in `~/.config/opencode/commands/` that does nothing but make the model load that skill
- Don't write API keys or tokens in config files (use `{env:NAME}` if needed). Tell me if skill IDs collide
- At the end, check with `opencode debug agents` and `opencode mcp list`, and report in a table what you migrated and what you couldn't (hooks, etc.)
If you'd rather not have it rewrite files right away, switch the agent to plan first (Shift+Tab or /agents) and have it produce only a plan. The plan agent doesn't edit ordinary files.
I tried this prompt as a dry run. In the plan agent on Sonnet 5.5, on my machine, it came back with a plan that covered rewriting 10 agents, the plugins' skill folders, the context7 MCP server and replacing the hooks, plus a table of what can't be moved (the statusLine, and the notification and usage-guard hooks). I did my own migration by hand, following the steps below, before this prompt existed. After a migration, compare the result against the sections below.
What maps to what
Copy a V1 config example and some names will be wrong. In V2, permission is permissions, bash is shell, task is subagent, and MCP servers live under mcp.servers.<name>, not mcp.<name> (Permissions, MCP servers).
| Item | Claude Code | OpenCode V2 |
|---|---|---|
| Instructions | CLAUDE.md |
AGENTS.md only |
| Subagents | ~/.claude/agents/*.md |
~/.config/opencode/agents/*.md (different frontmatter) |
| Skills |
~/.claude/skills, plugins |
~/.claude/skills is picked up automatically; plugin ones go in skills
|
| MCP | plugin (context7, in my case) | mcp.servers.<name> |
| Hooks and permissions |
hooks, permissions in settings.json
|
permissions; hooks are plugins |
| Slash commands | skills, commands/
|
commands/*.md ($ARGUMENTS is expanded here) |
CLAUDE.md isn't read
V2 reads only AGENTS.md; it doesn't fall back to CLAUDE.md (Instructions). In a throwaway git repository, I asked Haiku 5.5 to answer with a secret word from the instructions alone, without using tools. The word in CLAUDE.md didn't come back, and after I added an AGENTS.md, its word did.
# CLAUDE.md only (PINEAPPLE)
NONE
# AGENTS.md added too (MANGO)
MANGO
Putting CLAUDE.md in the instructions setting doesn't help: V2 accepts the entry but doesn't load it (Config). So I added one line to my global AGENTS.md. It's the model that reads it, so whether it follows the line is up to the model.
<!-- ~/.config/opencode/AGENTS.md -->
- Most of my repos were set up for Claude Code. When a repo has a `CLAUDE.md` and no `AGENTS.md` says otherwise, read that `CLAUDE.md` before working: it is the project's instructions, and its rules apply here.
You can also put an AGENTS.md in each repository that says only Read CLAUDE.md in this repository before working.
Subagents use different frontmatter
Compare the two using coder.
---
# ~/.claude/agents/coder.md
name: coder
description: Use for coding tasks delegated to a subagent: ...
model: sonnet
effort: max
---
---
# ~/.config/opencode/agents/coder.md
description: "Use for coding tasks delegated to a subagent: ..."
mode: subagent
model: "anthropic/claude-sonnet-5-5#max"
permissions:
- action: question
resource: "*"
effect: deny
---
- Don't write
name; the file name becomes the ID - Without
mode: subagent, the agent becomesprimary(Agents) -
modelisprovider/model#variant.sonnetandeffort: maxcollapse into it. Formodel: inherit, delete the line and the agent inherits the parent's model - I deny
questionbecause the built-ingeneralagent has the same setting
Copying a Claude Code agent as it is doesn't raise an error. I copied coder, reviewer, review-lead and Plan from ~/.claude/agents/ into .opencode/agents/ in a throwaway git repository, prefixing them with cc- so they wouldn't mix with global agents of the same name, and looked at them with opencode debug agents.
cc-coder primary (none)
cc-Plan primary (none)
cc-review-lead primary (none)
cc-reviewer primary (none)
All four are primary, and the model is empty. name, model and effort weren't applied. On top of that, cc-Plan has no edit deny at all, so an agent you meant to make read-only with disallowedTools can edit files. Rewrite disallowedTools as permissions denies.
# Claude Code (Plan.md)
disallowedTools: Edit, Write, NotebookEdit, Agent, ExitPlanMode, Artifact
# OpenCode (planner.md)
permissions:
- action: edit
resource: "*"
effect: deny
- action: subagent
resource: "*"
effect: deny
The main session's effort can't go in the root model. The root model keeps only the provider and model, and #variant doesn't survive (Models). Put it in agents.build.model.
// ~/.config/opencode/opencode.jsonc
"model": "anthropic/claude-opus-5-5",
"agents": {
"build": { "model": "anthropic/claude-opus-5-5#max" }
}
Check the agents you migrated by hand with opencode debug agents.
# Piping straight into `| jq` cut the JSON off partway (5 out of 5 times here), so go through a file
opencode debug agents > /tmp/agents.json
jq -r '.[] | select(.id | IN("build","coder","planner","review-lead")) | [.id, .mode, (.model | if . then "\(.providerID)/\(.id)#\(.variant // "")" else "(inherit)" end)] | @tsv' /tmp/agents.json | column -t -s$'\t'
build primary anthropic/claude-opus-5-5#max
coder subagent anthropic/claude-sonnet-5-5#max
planner subagent anthropic/claude-opus-5-5#max
review-lead subagent (inherit)
Skills: add only the plugin ones
~/.claude/skills and .claude/skills are read as they are (Skills). What isn't read is plugin skills. Add the skills directory inside the plugin's cache to the skills setting. The path contains the version, so rewrite it when the plugin updates.
// ~/.config/opencode/opencode.jsonc
"skills": [
"~/.claude/plugins/cache/<marketplace>/<plugin>/<version>/skills",
"~/.claude/skills", // on duplicate IDs the later entry wins, so put personal skills after plugins
"~/.config/opencode/skills" // skills rewritten for OpenCode go last (mine: delegate and implement-orchestrated)
]
A skill's ID comes from its path, without the plugin namespace (the name in frontmatter is a display name). On my machine, my personal code-review collided with the code-review from the mattpocock-skills plugin. Since the later entry wins, I kept the plugin's version under another name, as a directory containing only a symlink to its SKILL.md.
SRC=~/.claude/plugins/cache/claude-plugins-official/mattpocock-skills/1.2.3/skills/engineering/code-review/SKILL.md
mkdir -p ~/.config/opencode/skills/mattpocock-code-review
ln -s "$SRC" ~/.config/opencode/skills/mattpocock-code-review/SKILL.md
~/.claude/skills and the plugin cache are outside the working directory, so allow external_directory for them. Then skills can read their supporting files.
{ "action": "external_directory", "resource": "~/.claude/skills/*", "effect": "allow" },
{ "action": "external_directory", "resource": "~/.claude/plugins/cache/*", "effect": "allow" }
MCP goes under servers
// ~/.config/opencode/opencode.jsonc
"mcp": {
"servers": {
"context7": { "type": "remote", "url": "https://mcp.context7.com/mcp", "oauth": false }
}
}
Remote MCP servers use OAuth by default. context7 works without an account, so I set oauth: false. If opencode mcp list shows ✓ context7 connected, it's connected. Tool names are <server>_<tool>, not Claude Code's mcp__plugin_context7_context7__…. In the default Code Mode, tools are called through execute (set codemode: false to expose them as regular tools).
Hooks split into permissions and plugins
In Claude Code I had a PreToolUse hook (subagent-irreversible-guard.sh) that stopped only subagents from running git push and deploys. The main session was exempt.
In OpenCode V2 I replaced it with permissions. Rules are evaluated from the top, and the last match wins. Top-level rules apply to every agent, and a subagent doesn't inherit its parent's permissions but runs only on its own (Permissions). So I deny at the top level and re-open it only for the main build agent.
// ~/.config/opencode/opencode.jsonc
{
"permissions": [
// a deny that applies to every agent, subagents included
{ "action": "shell", "resource": "git push*", "effect": "deny" },
{ "action": "shell", "resource": "git -C * push", "effect": "deny" },
{ "action": "shell", "resource": "npm publish*", "effect": "deny" },
{ "action": "shell", "resource": "npm run *deploy*", "effect": "deny" }
],
"agents": {
"build": {
"permissions": [
// the last match wins: allow everything first, then set the commands that go outward back to ask
{ "action": "shell", "resource": "*", "effect": "allow" },
{ "action": "shell", "resource": "git push*", "effect": "ask" },
{ "action": "shell", "resource": "git -C * push", "effect": "ask" },
{ "action": "shell", "resource": "npm publish*", "effect": "ask" },
{ "action": "shell", "resource": "npm run *deploy*", "effect": "ask" }
]
}
}
}
- The default is allow-all. A V2 agent starts from an allow on
*; only reading.envand anything outside the working directory asks. So you add denies and asks rather than adding allows - A pattern is matched against the whole command string.
*matches anything, including spaces and quotes, so a broad pattern likegit * push*would even stopgit commit -m "fix push bug". I kept mine narrow:git push*andgit -C * push - The docs also say it's better to narrow down the commands you allow than to try to catch every dangerous command with patterns. This deny is a fence against accidents, not a sandbox
There's no setting that corresponds to the hooks I ran after edits and on stop (PostToolUse, Stop), so I rewrote them as plugins (~/.config/opencode/plugins/*.js, Plugins). I didn't migrate the usage-guard hooks, because an API key has no 5-hour or weekly plan window.
Slash commands are thin wrappers around skills
A skill is loaded through the skill tool, or by writing @skill-id in a prompt. It's the command that expands $ARGUMENTS (Commands). My delegate skill took its arguments by ending with ARGUMENTS: $ARGUMENTS. I checked how that behaves with opencode run --format json, using a throwaway skill called argtest: the input to the skill tool was only {"id": "argtest"}, and the body that reached the model still contained $ARGUMENTS as is. The model guesses the arguments from the conversation and fills them in, so it can look like it works.
So I add a thin command that only makes the model load the skill.
---
# ~/.config/opencode/commands/delegate.md
description: Hand a task to one background worker subagent (OpenCode version of /delegate)
---
Load the `delegate` skill and follow it. The task to hand off:
$ARGUMENTS
Claude Code-only frontmatter (context: fork, agent:, background:, and so on) isn't in the V2 docs. My /code-review skill had context: fork and agent: review-lead. I replaced them with the command's own agent and subagent: true (it runs in a background child session).
---
# ~/.config/opencode/commands/code-review.md
description: "Bug-hunting review in a background review-lead: [low|medium|high|xhigh|max] [--comment] [<pr#>|<branch>|<path>|<base>...<head>]"
agent: review-lead
subagent: true
---
Load the `code-review` skill and follow it. You are the review lead it describes; ...
Arguments:
$ARGUMENTS
Claude Code's own tools need translating
OpenCode has no Agent tool, SendMessage or isolation: worktree. So that skills written for Claude Code can be read as they are, I keep a translation table in my global AGENTS.md.
| Claude Code | OpenCode |
|---|---|
subagent_type: X in the Agent tool |
agent: X in the subagent tool |
run_in_background: true |
background: true |
SendMessage |
call subagent again with the same sessionID
|
isolation: worktree |
run git worktree add yourself and put the path in the instructions |
fork |
none (hand over a self-contained brief) |
git worktree add doesn't bring over .gitignored files. The .worktreeinclude copying that Claude Code did automatically is also yours to do.
What I checked, and what I didn't
- Credit consumption: I confirmed in the Console's Billing that Promotional credits went down after I used OpenCode. The official pages say nothing about third-party clients, so the treatment may change.
- On-screen wording: the claude.ai and Console steps follow what the official pages describe.
-
Permission patterns: that
git * push*would even stop a commit message containingpushfollows from the docs' matching rules. I didn't run it for this post. -
Aliased skill links: I link only
SKILL.md, so I haven't checked whether relative paths resolve for a skill that has supporting files. -
Slash commands:
$ARGUMENTSexpansion is from reading the docs only (opencode rundidn't expand/name). - Not tested: other operating systems, the Desktop app, the Team plan.
Wrap-up
The monthly API credit is for Max 5x, Max 20x and Team only. You get it by linking a Console organization, and interactive Claude Code can't spend it. In OpenCode, register a Console API key, not a Pro/Max login. Keep ANTHROPIC_API_KEY out of ~/.zshrc: Claude Code can pick it up and answer with Credit balance is too low. On my machine, OpenCode usage did draw from Promotional credits, but the official pages don't say so, so check your own balance.
To move your Claude Code setup, paste the prompt into OpenCode and check the result with opencode debug agents: agents and CLAUDE.md files copied over as they are get ignored. Split hooks between permissions (deny at the top level, re-open for build) and plugins.
It's one option for when Claude Code's limit stops you.
References
- Claude Help Center: Monthly API credits for Max and Team plans
- Claude Platform docs: API credits for Max and Team plans
- Claude Platform release notes (Oct 7, 2026)
- Claude Code: Legal and compliance (how credentials are handled)
- Claude Code: Authentication (authentication precedence)
- OpenCode V2: Providers (CLI)
- OpenCode V2: Agents
- OpenCode V2: Skills
- OpenCode V2: Permissions
This post is also on Zenn, in Japanese: zenn.dev/daydreamer/articles/opencode-claude-max-api-credits
Top comments (0)