@suiramdev/opencode-with-claude
v2.0.0
Published
OpenCode v2 plugin to use your Claude Max/Pro subscription via the Meridian proxy
Maintainers
Readme
@suiramdev/opencode-with-claude
Use OpenCode with your Claude Max/Pro subscription.
[!IMPORTANT] This is a fork of
opencode-with-claudetargeting OpenCode v2 (theopencode2CLI). It will not load on v1: v2 requires a default-exported{ id, setup }plugin definition and dropped the v1config/chat.headers/experimental.chat.system.transformhooks. For OpenCode v1, use the upstream package.
What this is
An OpenCode plugin that runs Meridian (formerly opencode-claude-max-proxy) for you: start OpenCode once and the proxy comes up with it; quit OpenCode and the proxy stops. No separate proxy CLI or Docker container to manage.
Compared to running the proxy yourself:
- One process to think about — OpenCode owns the proxy lifecycle (start/stop) instead of you juggling two things.
- No provider config to maintain — the plugin points the
anthropicprovider at its own proxy through the v2 catalog, so the port never has to be written down. - Several OpenCode windows at once — each instance gets its own proxy on an OS-assigned port, so ports do not collide and you avoid session issues from sharing one proxy across instances.
- Explicit session headers — the plugin adds session tracking on outgoing API calls, so the proxy does not have to infer sessions from fingerprints alone.
How It Works
┌─────────────┐ ┌────────────────────┐ ┌─────────────────┐
│ OpenCode │─────────────▶│ Claude Max Proxy │──────▶│ Anthropic │
│ (TUI/Web) │ :3456 / auto │ (local server) │ SDK │ Claude Max │
│ │◀─────────────│ │◀──────│ │
└─────────────┘ └────────────────────┘ └─────────────────┘Quick Start
The plugin hooks into OpenCode's plugin system. When OpenCode launches, it starts the proxy, points the Anthropic provider at it, and cleans everything up on exit.
1. Authenticate with Claude (one-time)
npm install -g @anthropic-ai/claude-code
claude auth login2. Add to your opencode.jsonc
Global (~/.config/opencode/opencode.jsonc) or project-level:
{
"$schema": "https://opencode.ai/config.json",
"plugins": ["@suiramdev/opencode-with-claude"]
}[!WARNING] Use
plugins, and do not add a top-levelproviderkey. OpenCode v2 treats any config document containingprovideras a v1 document, and the v1 shape reads plugins fromplugin— apluginslist is then silently ignored, with no error and no log line. The plugin setsbaseURLitself, so the provider block the v1 plugin needed is obsolete.
3. Run OpenCode
opencode2Profiles and SDK features
The plugin now reads the same Meridian configuration files the meridian CLI
uses, so you can maintain multiple Claude accounts and tune SDK behavior
without leaving OpenCode.
Profiles (~/.config/meridian/profiles.json)
Define one or more named profiles (for example, a personal Claude Max account, a work account, or an OAuth-token profile). The plugin forwards them to Meridian at startup.
[
{
"id": "personal",
"claudeConfigDir": "/Users/me/.config/meridian/profiles/personal"
},
{
"id": "work",
"claudeConfigDir": "/Users/me/.config/meridian/profiles/work"
},
{
"id": "headless",
"type": "oauth-token",
"oauthToken": "<token from claude setup-token>"
}
]Active profile (~/.config/meridian/settings.json)
{ "activeProfile": "work" }activeProfile selects the default profile for any request that does not send
an explicit x-meridian-profile header. If the saved id is not in
profiles.json (or the file is missing), the plugin logs a warning and falls
back to the first configured profile.
SDK features (~/.config/meridian/sdk-features.json)
Meridian reads this file lazily on every request, so overrides take effect without restarting the proxy. The plugin does not need to do anything special for it to work — just edit the file and the next request picks it up. See Meridian's documentation for the full list of adapter keys.
This plugin does not edit Meridian's SDK feature file. When Meridian's default
client prompt pass-through is enabled, the plugin scrubs OpenCode-identifying
prompt fingerprints with @rynfar/meridian-plugin-opencode-scrub before
forwarding. User context such as AGENTS.md and configured instructions is
preserved, while cwd is forwarded to Meridian through the process environment.
{
"opencode": {
"memory": true,
"thinking": "enabled",
"maxBudgetUsd": 0.5
}
}Environment overrides
For parity with the meridian CLI:
MERIDIAN_PROFILES— JSON array of profile objects; wins overprofiles.json.MERIDIAN_DEFAULT_PROFILE— profile id; wins oversettings.activeProfile.
Because profiles.json lives at ~/.config/meridian regardless of OpenCode's
own config directory, these two variables are the way to give separate OpenCode
profiles separate Claude accounts.
The plugin also defaults CLAUDE_CODE_ENTRYPOINT to cli when it is unset.
The Claude Agent SDK otherwise stamps sdk-ts on the CLI it spawns, and
Anthropic bills that entrypoint as a third-party app: every request comes back
as 400 Third-party apps now draw from extra usage, not plan limits instead of
drawing on the subscription. Set the variable yourself to override.
Malformed or missing files never crash the plugin; all parse/IO failures are logged to OpenCode's plugin log and the plugin falls back to no-profile mode.
Switching profiles at runtime
Profile switching through Meridian's HTTP API continues to work — call
POST /profiles/active on the proxy URL the plugin prints at startup. The
selection is persisted back to settings.json and survives restarts.
Troubleshooting
"Claude Code CLI not found"
npm install -g @anthropic-ai/claude-code"Claude not authenticated"
claude auth login
# or (depends of your version)
claude loginThis opens a browser for OAuth. Your Claude Max subscription credentials are needed.
"Proxy failed to start"
- Check Claude auth:
claude auth status - Ensure your internet connection is working
- If using a manual port override, check if it's in use:
lsof -i :$CLAUDE_PROXY_PORT
Binding the proxy to a non-localhost interface
Meridian binds to 127.0.0.1 by default. If you need it to listen on another
interface, set CLAUDE_PROXY_HOST (or Meridian's MERIDIAN_HOST alias) before
starting OpenCode:
CLAUDE_PROXY_HOST=0.0.0.0 opencode2 serve --hostname 0.0.0.0 --port 4098The plugin still uses loopback internally when you bind to wildcard addresses
such as 0.0.0.0 or ::, so local health checks and provider requests remain
stable.
Warning
Exposing the proxy beyond localhost makes your authenticated Claude session reachable over the network. Only do this on trusted networks, and prefer firewall rules or other access controls if you open it up.
Development
Project Structure
opencode-with-claude/
├── src/
│ ├── index.ts # Plugin entry point (v2 `{ id, setup }` definition)
│ ├── proxy.ts # Proxy lifecycle management
│ ├── meridian-config.ts # Meridian profiles/settings loading
│ └── logger.ts # Plugin logger
├── test/
│ ├── run.sh # Interactive test runner
│ └── unit/ # `npm run test:unit`
├── package.json
└── tsconfig.jsonOpenCode v2 surface
| v1 | v2 |
|----|----|
| named ClaudeMaxPlugin export | export default { id, setup } (Plugin.define) |
| config hook rewriting provider.anthropic.options.baseURL | ctx.catalog.transform writing provider.settings.baseURL |
| experimental.chat.system.transform | ctx.session.hook("context") over system: SystemPart[] |
| chat.headers | ctx.session.hook("request") mutating headers in place |
| agent modes cached from the config hook | ctx.agent.get({ agentID }), cached per agent |
| implicit teardown | the cleanup function setup returns |
@opencode-ai/plugin is a dev dependency only: the entry imports define from
@opencode-ai/plugin/promise/plugin, an identity function that gets inlined at
build time. Nothing from the OpenCode runtime ends up in dist/, so the plugin
is not pinned to a single 0.0.0-next-* build.
One header is gone: x-opencode-request carried the OpenCode message id, which
the v2 request hook does not expose. Meridian never read it — it keys sessions
off x-opencode-session and tiers off x-opencode-agent-mode, both of which
are still sent.
Build
npm install
npm run buildTest locally
./test/run.sh # Build and launch OpenCode with the plugin
./test/run.sh --clean # Remove build artifactsFAQ
Do I need an Anthropic API key?
No. Claude Max/Pro is not authenticated with API keys here. Run claude login once; the proxy uses that session (Agent SDK via OAuth). The plugin fills in a placeholder apiKey for the provider itself, so there is nothing to configure.
What if my Claude Max subscription lapses?
The proxy will fail to authenticate. Run claude auth status. You need an active Claude Max plan; see claude.ai for current options and pricing.
Can I run several OpenCode instances at once?
Yes. The first instance uses port 3456 by default; others get a free OS-assigned port, so nothing extra to configure.
Is this the same as using the Anthropic API directly?
Not exactly. OpenCode speaks Anthropic-style HTTP to the local proxy; the proxy maps requests to the Claude Agent SDK and your Claude Max session. Usage limits follow your Max subscription, not Anthropic API billing tiers.
Disclaimer
This project is an unofficial wrapper around Anthropic's publicly available Claude Agent SDK and OpenCode. It is not affiliated with, endorsed by, or supported by Anthropic or OpenCode.
Use at your own risk. The authors make no claims regarding compliance with Anthropic's Terms of Service. It is your responsibility to review and comply with Anthropic's Terms of Service and Authorized Usage Policy. Terms may change at any time.
This project calls publicly available npm packages using your own authenticated account. No API keys are intercepted, no authentication is bypassed, and no proprietary systems are reverse-engineered.
Credits
Built on top of Meridian by @rynfar, which provides the core proxy that bridges the Anthropic Agent SDK to the standard API.
Powered by the Claude Agent SDK by Anthropic and OpenCode.
License
MIT
