With Claude
OpenCode plugin to use your Claude Max subscription via Meridian proxy
599
近 30 天 +45
5,627
近 7 天 1.7k
74.0
生态多维模型
4 天前
2026-09-30
快速安装与配置
opencode.json写入当前项目的 opencode.json,只对这个仓库生效。
opencode.json
{
"$schema": "https://opencode.ai/config.json",
"plugin": ["opencode-with-claude@1.11.1"]
}写入 ~/.config/opencode/opencode.json,对所有项目生效。
~/.config/opencode/opencode.json
{
"$schema": "https://opencode.ai/config.json",
"plugin": ["opencode-with-claude@1.11.1"]
}若你要在本地改造这个插件,先装到项目里再从本地路径引用。
shell
pnpm add -D opencode-with-claudeOpenCode 启动时会通过内嵌运行时自动加载 npm 依赖并缓存至本地目录,无需手动在全局环境执行安装。
Use OpenCode with your Claude Max subscription.
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.
Works with both OpenCode generations: the 1.x line (opencode) and OpenCode 2 (@opencode/cli), from the same package.
Compared to running the proxy yourself:
- One process to think about — OpenCode owns the proxy lifecycle (start/stop) instead of you juggling two things.
- Several OpenCode windows at once — each process gets its own proxy (port 3456 when available, otherwise an OS-assigned port). Project instances within the same process share that proxy, including concurrent plugin initialization.
- Explicit session headers — the plugin adds session tracking on outgoing API calls, so the proxy does not have to infer sessions from fingerprints alone. OpenCode's hidden title and summary requests are kept off the session's turn lease, so the first message of a fresh session does not race them.
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, configures the Anthropic provider, and cleans everything up on exit.
1. Install the plugin
With npm:
npm install -g opencode-with-claude
Or with Homebrew (macOS/Linux), which keeps the plugin
updated through brew upgrade instead of npm update -g:
brew install ianjwhite99/tap/opencode-with-claude
2. Authenticate with Claude (one-time)
npm install -g @anthropic-ai/claude-code # or: brew install --cask claude-code
claude auth login
3. Add to your opencode.json
Global (~/.config/opencode/opencode.json) or project-level. The keys differ
between OpenCode generations; a block written for the other generation is
silently ignored, so make sure you use the right one.
OpenCode 1.x:
{
"$schema": "https://opencode.ai/config.json",
"plugin": ["opencode-with-claude"],
"provider": {
"anthropic": {
"options": {
"baseURL": "http://127.0.0.1:3456",
"apiKey": "dummy"
}
}
}
}
OpenCode 2 (plugins and providers.<id>.settings instead of plugin and
provider.<id>.options):
{
"$schema": "https://opencode.ai/config.json",
"plugins": ["opencode-with-claude"],
"providers": {
"anthropic": {
"settings": {
"baseURL": "http://127.0.0.1:3456/v1",
"apiKey": "dummy"
}
}
}
}
In both cases the baseURL is only a placeholder: the plugin rewrites every
Anthropic request to whatever port its own proxy actually got, so several
OpenCode instances can run side by side.
If you installed with Homebrew, point the plugin entry at the installed
file instead of the package name (the path is stable across upgrades, and
brew info opencode-with-claude prints it):
"plugin": ["file:///opt/homebrew/opt/opencode-with-claude/libexec/lib/node_modules/opencode-with-claude/dist/index.js"]
("plugins": [...] on OpenCode 2.) On Linux or Intel macOS replace
/opt/homebrew with your Homebrew prefix (brew --prefix, usually
/home/linuxbrew/.linuxbrew or /usr/local).
4. Run OpenCode
opencode
Updating
- Homebrew:
brew upgrade opencode-with-claude. The release workflow bumps the formula inianjwhite99/homebrew-tapafter every npm publish, sobrew update && brew upgradetracks new releases. - npm:
npm update -g opencode-with-claude. Note that OpenCode caches plugins it installs by package name; if a new version is not picked up, clear~/.cache/opencode/node_modules/opencode-with-claudeand restart.
Profiles 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.MERIDIAN_PATH— run your own Meridian build instead of the bundled one (see Using your own Meridian build).
Malformed or missing files never crash the plugin; all parse/IO failures are logged via OpenCode's plugin log and the plugin falls back to no-profile mode.
Using your own Meridian build
Each plugin release pins one exact @rynfar/meridian version, and Meridian
ships faster than this plugin does. Set MERIDIAN_PATH to follow Meridian's
releases without waiting for a plugin release:
npm install -g @rynfar/meridian
MERIDIAN_PATH="$(npm root -g)" opencode
MERIDIAN_PATH accepts any of:
- the Meridian package root —
.../node_modules/@rynfar/meridian - any directory Node can resolve
@rynfar/meridianfrom — a globalnode_modules, or a project that depends on it - the entry file itself —
.../@rynfar/meridian/dist/server.js
Auth, profiles, and the session cache already live on disk
(~/.config/meridian, ~/.cache/meridian), so an external build shares all of
them with the meridian CLI; only the code version changes.
The bundled copy stays the fallback. A path that does not exist, is not a
Meridian install, or exposes no startProxyServer logs a warning and changes
nothing else. Either way the plugin logs which build it is running, so a bug
report can name it:
meridian 1.79.0 (bundled)
meridian 1.80.0 (external: /opt/homebrew/lib/node_modules/@rynfar/meridian)
A swapped build has to keep the surface the plugin uses: startProxyServer
returning { server, config.port, close() }, and a /health response carrying
status, error, version, and auth.{daysUntilRenewal,renewalRequiredSoon}.
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 login
This 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 opencode serve --hostname 0.0.0.0 --port 4098
The 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: v1 server() + v2 setup()
│ ├── headers.ts # Meridian request-identity headers (shared)
│ ├── proxy.ts # Proxy lifecycle management
│ ├── meridian-source.ts # Picks the Meridian build (bundled or MERIDIAN_PATH)
│ ├── meridian-config.ts # Reads Meridian's profiles/settings files
│ └── logger.ts # Plugin loggers
├── test/
│ ├── run.sh # Launches OpenCode 1.x with the built plugin
│ ├── opencode.json # Test config
│ └── unit/ # node:test suites (npm run test:unit)
├── scripts/
│ └── update-homebrew-formula.sh # Bumps the Homebrew formula (in ianjwhite99/homebrew-tap) after an npm release
├── package.json
└── tsconfig.json
Build
npm install
npm run build
Test locally
npm run test:unit # Build, then run the unit suites (v1 hooks and v2 setup)
./test/run.sh # Build and launch OpenCode 1.x with the plugin
./test/run.sh --clean # Remove build artifacts
To try the build in OpenCode 2, point a plugins entry at the dist
directory, for example "plugins": ["/path/to/opencode-with-claude/dist"].
How the two OpenCode generations are served
dist/index.js has a single default export with id, server() and
setup(). OpenCode 1.x calls server() and uses the returned hooks
(config, chat.headers, ...). OpenCode 2 calls setup(ctx) and the plugin
registers session.hook("model.request") (base URL and Meridian headers),
session.hook("http.request") (drops the anthropic-beta header OpenCode's
Anthropic transport re-adds after model.request — Meridian talks to the
Claude Agent SDK, which refuses custom betas on subscription auth), and the
system-prompt hooks on the context. The module deliberately has no other
exports: OpenCode 1.17 and 1.18 load every export as a plugin, so a second one
would start a second proxy.
FAQ
Do I need an Anthropic API key?
No. Claude Max is not authenticated with API keys here. Run claude login once; the proxy uses that session (Agent SDK via OAuth). OpenCode still expects an apiKey field in the Anthropic provider config, so set a placeholder such as "dummy" in opencode.json — it is not used for real auth.
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.
Does this work with OpenCode 2?
Yes. The same package loads on OpenCode 1.x and OpenCode 2; only the
opencode.json keys differ (see Quick Start). OpenCode 2 gives plugins no log
API, so on that generation the plugin's startup and health messages go to the
server's stderr instead of the OpenCode log (visible with --print-logs).
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
同类生态推荐
With Claude
@suiramdev/opencode-with-claude
OpenCode v2 plugin to use your Claude Max/Pro subscription via the Meridian proxy
Claude Subscription
opencode-claude-subscription
OpenCode v2 plugin: use your Claude Pro/Max subscription with OpenCode's built-in Anthropic provider.
Compaction Guard
opencode-compaction-guard
OpenCode plugin that prevents and auto-recovers from the 'tool_use ids were found without tool_result blocks' error that makes sessions unrecoverable after auto-compaction or interrupted tool calls.