Releases: AlaeddineMessadi/opencode-mcp
Release list
v1.11.0 — SDK migration, parallel projects tool, security hardening
Architectural release. Migrates server lifecycle to the official @opencode-ai/sdk, adds a tool for parallel project initialization, and lands a substantial security/correctness pass on the HTTP and SSE layers.
Added
opencode_project_inittool — initialize or open a project directory to host an independent OpenCode session. Designed for MCP clients orchestrating parallel multi-project workloads. Creates the directory (mkdir -p, idempotent on existing dirs), then pings the OpenCode server at that path to register it as a project. Returns the canonical (realpath'd) absolute path so downstream calls can rely on it.
Changed
- Server lifecycle now uses
@opencode-ai/sdk'screateOpencodeServerinstead ofspawn("opencode serve"). The HTTP server still runs on a port (default127.0.0.1:4096), but it's hosted in-process rather than as a child process. Eliminates zombie processes, port-binding races, and the binary-discovery code path.OPENCODE_SERVE_ARGSis now silently ignored (the SDK manages config in-process). - Reconnect logic rebinds
baseUrlfromensureServer()result — when the managed server comes up on a different URL than expected, the client rebuilds its SDK instance against the new endpoint before retrying. reconnectAttemptsbudget now resets on successful requests — previously the counter grew monotonically, so a long-lived client permanently exhausted its auto-heal capacity after three reconnects.- Startup serialization keyed by
baseUrl— concurrentensureServer()calls targeting different URLs each get their own startup promise.
Security
- Symlink escape in
opencode_project_initclosed —path.resolveonly canonicalizes../.lexically. A symlink at e.g./tmp/safe → /etcwould have passed the forbidden-roots check, then OpenCode would scope its session into/etc. The tool now callsrealpathaftermkdirand re-runs the deny-list against the canonical path. Forbidden roots are also realpath'd at module load so macOS-style symlinks (/etc → /private/etc) match in either form. /varremoved from the project_init forbidden-roots list — macOS user-temp directories live under/var/foldersand many/varsubtrees are legitimately user-writable. The original deny-list rejectedos.tmpdir()paths on macOS; a latent bug uncovered while writing the new regression tests.- CRLF/NUL guard in
normalizeDirectory— Node'sundicialready rejects CRLF in header values, so this isn't currently exploitable, butnormalizeDirectorynow explicitly rejects NUL and CR/LF so the contract is independent of the runtime. - Basic auth header now propagated to
/global/healthprobe — whenOPENCODE_SERVER_PASSWORDwas set, the probe was rejected with 401,isServerRunningreported unhealthy, andensureServerlooped trying to auto-start an already-running server. x-opencode-directoryheader sent raw, no longer URI-encoded — the OpenCode server treats the header as a literal absolute filesystem path; URI-encoding turned/tmp/projinto%2Ftmp%2Fprojand broke project scoping for every multi-project tool call.opencode_project_initvalidatesisAbsolute, rejects NUL bytes, rejects\r/\n, denies system roots (/,/etc,/usr,/bin,/sbin,/sys,/proc,/dev).
Fixed
- SSE event parser dropped events when the server used CRLF line endings — the parser split on
\"\\n\"only, leaving\\ron every line. Event names came out as\"message\\r\"and the blank-line dispatcher never fired, silently corruptingopencode_events_polland any downstream SSE consumers. - Per-call timeouts now propagated to the HTTP dispatcher via
AbortSignal.
Install
```bash
npx -y opencode-mcp@1.11.0
```
Or pin in your MCP client config:
```json
{
"command": "npx",
"args": ["-y", "opencode-mcp@1.11.0"]
}
```
Stats
- 80 tools (up from 79)
- 328 tests passing
Full Changelog: v1.10.2...v1.11.0
v1.10.2 — Windows path fix, OPENCODE_SERVE_ARGS, model variant
User-facing bugfix release. Three commits sat unreleased on main since v1.10.1; cutting v1.10.2 unblocks Windows clients without dragging the larger SDK migration (PR #11) along.
Fixed
-
normalizeDirectoryrejected valid Windows absolute paths (#5, #6, #13) — the resolved-path check usedstartsWith("/"), which only matches POSIX. On Windows hosts (includingnpx-spawned MCPs talking to a WSL OpenCode),path.resolve("/mnt/d/Projects/foo")returns"\\mnt\\d\\Projects\\foo", failing the check and rendering every tool'sdirectoryparameter unusable for Windows clients.Switched to the platform-aware
path.isAbsolutefromnode:path, which accepts both POSIX (/home/user/project) and Windows (C:\Users\me\project,\\server\share) absolute paths. Updated the error message to show both forms.
Added
OPENCODE_SERVE_ARGSenvironment variable (#7, #9) — pass custom arguments to theopencode servesubprocess at auto-start. Useful for advanced server configuration. Thanks @xpufx for the issue.- Model variant parameter on all model-accepting tools (#8, #10) —
opencode_ask,opencode_run,opencode_fire,opencode_reply,opencode_message_send*now accept an optional `variant` to target a specific model variant. Thanks @iamabigartist for the issue.
Install
```bash
npx -y opencode-mcp@1.10.2
```
Or pin in your MCP client config:
```json
{
"command": "npx",
"args": ["-y", "opencode-mcp@1.10.2"]
}
```
Stats
- 79 tools
- 321 tests passing
Full Changelog: v1.10.1...v1.10.2
v1.10.1
[1.10.1] - 2026-04-10
Changed
- Instruction examples now use discovered/default provider and model values instead of hardcoded Anthropic examples. This avoids steering MCP clients toward unavailable providers and aligns the startup guidance with
opencode_setup.
Fixed
- Health checks for authenticated OpenCode servers now propagate HTTP basic auth through the full auto-start path, including startup polling and reconnection flows.
ensureServer()now forwards configured server credentials during startup so remote protected servers no longer fail the health probe while coming online.
Stats
- Tool count: 79
- Tests: 320