opencode-mcp 1.9.0 → 1.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +30 -0
- package/README.md +94 -275
- package/dist/client.d.ts +6 -0
- package/dist/client.js +43 -2
- package/dist/client.js.map +1 -1
- package/dist/helpers.d.ts +26 -0
- package/dist/helpers.js +88 -2
- package/dist/helpers.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.js +23 -6
- package/dist/index.js.map +1 -1
- package/dist/tools/message.js +13 -13
- package/dist/tools/message.js.map +1 -1
- package/dist/tools/session.js +49 -9
- package/dist/tools/session.js.map +1 -1
- package/dist/tools/workflow.js +37 -18
- package/dist/tools/workflow.js.map +1 -1
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,36 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [1.10.0] - 2026-02-10
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- **`opencode_permission_list` tool** — lists all pending permission requests across sessions, showing permission type, session ID, patterns, and tool name. Helps detect and unblock sessions stuck waiting for approval in headless mode.
|
|
13
|
+
- **`OPENCODE_DEFAULT_PROVIDER` / `OPENCODE_DEFAULT_MODEL` env vars** — set default provider and model for all tool calls. Three-tier resolution: explicit params → env defaults → server fallback. Implemented via `applyModelDefaults()` across all 8 model-accepting tools.
|
|
14
|
+
- **`normalizeDirectory()` path validation** — resolves paths to absolute, strips trailing slashes, resolves `..`, and rejects non-existent directories with descriptive errors.
|
|
15
|
+
- **Lazy server reconnection** — on `ECONNREFUSED`/`ENOTFOUND` after all retries, auto-restarts the OpenCode server (max 3 reconnection attempts per MCP session).
|
|
16
|
+
- **Enhanced `diagnoseError()`** — 6 new error patterns with contextual suggestions (empty response, model errors, permission issues, config problems).
|
|
17
|
+
- **Directory display in workflow responses** — `opencode_run`, `opencode_fire`, `opencode_check`, `opencode_status` now show the active project directory.
|
|
18
|
+
- **Session-directory consistency warnings** — warns when a session was created for a different directory than the current request.
|
|
19
|
+
- **Permissions guidance in instructions** — recommends `"permission": "allow"` in `opencode.json` for headless use, documents permission tools.
|
|
20
|
+
|
|
21
|
+
### Changed
|
|
22
|
+
|
|
23
|
+
- **`opencode_session_permission` updated** — now uses the new API (`POST /permission/{requestID}/reply`) with automatic fallback to the deprecated endpoint. `reply` parameter changed from free string to enum: `"once"` | `"always"` | `"reject"`. Removed the old `remember` parameter.
|
|
24
|
+
|
|
25
|
+
### Fixed
|
|
26
|
+
|
|
27
|
+
- **Directory validation errors swallowed by `.catch(() => null)`** — `opencode_status`, `opencode_context`, and `opencode_check` used `Promise.all` with `.catch(() => null)` which silently ate validation errors (showing "UNREACHABLE" instead of "directory not found"). Fixed by adding early `normalizeDirectory()` before `Promise.all` in all 3 tools.
|
|
28
|
+
|
|
29
|
+
### Removed
|
|
30
|
+
|
|
31
|
+
- Demo projects (`projects/snake-game/`, `projects/nextjs-todo-app/`) — these were test artifacts.
|
|
32
|
+
|
|
33
|
+
### Stats
|
|
34
|
+
|
|
35
|
+
- Tool count: 79 (up from 78)
|
|
36
|
+
- Tests: 316 (up from 275)
|
|
37
|
+
|
|
8
38
|
## [1.9.0] - 2026-02-10
|
|
9
39
|
|
|
10
40
|
### Added
|
package/README.md
CHANGED
|
@@ -5,31 +5,23 @@
|
|
|
5
5
|
[](https://nodejs.org/)
|
|
6
6
|
[](https://www.npmjs.com/package/opencode-mcp)
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
**Give any MCP client the power of [OpenCode](https://opencode.ai/).**
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
opencode-mcp is an MCP server that bridges your AI tools (Claude, Cursor, Windsurf, VS Code, etc.) to OpenCode's headless API. It lets your AI delegate real coding work — building features, debugging, refactoring, running tests — to OpenCode sessions that autonomously read, write, and execute code in your project.
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
**79 tools** | **10 resources** | **6 prompts** | **Multi-project** | **Auto-start**
|
|
13
13
|
|
|
14
|
-
|
|
14
|
+
## Why Use This?
|
|
15
15
|
|
|
16
|
-
|
|
17
|
-
|
|
16
|
+
- **Delegate coding tasks** — Tell Claude "build me a REST API" and it delegates to OpenCode, which creates files, installs packages, writes tests, and reports back.
|
|
17
|
+
- **Parallel work** — Fire off multiple tasks to OpenCode while your primary AI keeps working on something else.
|
|
18
|
+
- **Any MCP client** — Works with Claude Desktop, Claude Code, Cursor, Windsurf, VS Code Copilot, Cline, Continue, Zed, Amazon Q, and any other MCP-compatible tool.
|
|
19
|
+
- **Zero setup** — The server auto-starts `opencode serve` if it's not already running. No manual steps.
|
|
18
20
|
|
|
19
|
-
|
|
21
|
+
## Quick Start
|
|
20
22
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
```json
|
|
24
|
-
{
|
|
25
|
-
"mcpServers": {
|
|
26
|
-
"opencode": {
|
|
27
|
-
"command": "npx",
|
|
28
|
-
"args": ["-y", "opencode-mcp"]
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
```
|
|
23
|
+
> **Prerequisite:** [OpenCode](https://opencode.ai/) must be installed.
|
|
24
|
+
> `curl -fsSL https://opencode.ai/install | bash` or `npm i -g opencode-ai` or `brew install sst/tap/opencode`
|
|
33
25
|
|
|
34
26
|
**Claude Code:**
|
|
35
27
|
|
|
@@ -37,20 +29,7 @@ Pick your client below. No authentication is needed by default — just add the
|
|
|
37
29
|
claude mcp add opencode -- npx -y opencode-mcp
|
|
38
30
|
```
|
|
39
31
|
|
|
40
|
-
**Cursor** (
|
|
41
|
-
|
|
42
|
-
```json
|
|
43
|
-
{
|
|
44
|
-
"mcpServers": {
|
|
45
|
-
"opencode": {
|
|
46
|
-
"command": "npx",
|
|
47
|
-
"args": ["-y", "opencode-mcp"]
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
```
|
|
52
|
-
|
|
53
|
-
**Windsurf** (`~/.windsurf/mcp.json`):
|
|
32
|
+
**Claude Desktop / Cursor / Windsurf / Cline / Continue** (add to your MCP config):
|
|
54
33
|
|
|
55
34
|
```json
|
|
56
35
|
{
|
|
@@ -63,161 +42,79 @@ claude mcp add opencode -- npx -y opencode-mcp
|
|
|
63
42
|
}
|
|
64
43
|
```
|
|
65
44
|
|
|
66
|
-
|
|
45
|
+
That's it. Restart your client and OpenCode's tools will be available.
|
|
67
46
|
|
|
68
|
-
|
|
69
|
-
{
|
|
70
|
-
"github.copilot.chat.mcp.servers": [
|
|
71
|
-
{
|
|
72
|
-
"name": "opencode",
|
|
73
|
-
"type": "stdio",
|
|
74
|
-
"command": "npx",
|
|
75
|
-
"args": ["-y", "opencode-mcp"]
|
|
76
|
-
}
|
|
77
|
-
]
|
|
78
|
-
}
|
|
79
|
-
```
|
|
47
|
+
> See [Configuration](docs/configuration.md) for all client configs (VS Code Copilot, Zed, Amazon Q, etc.) and environment variables.
|
|
80
48
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
```json
|
|
84
|
-
{
|
|
85
|
-
"mcpServers": {
|
|
86
|
-
"opencode": {
|
|
87
|
-
"command": "npx",
|
|
88
|
-
"args": ["-y", "opencode-mcp"]
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
```
|
|
93
|
-
|
|
94
|
-
**Continue** (`.continue/config.json`):
|
|
95
|
-
|
|
96
|
-
```json
|
|
97
|
-
{
|
|
98
|
-
"mcpServers": {
|
|
99
|
-
"opencode": {
|
|
100
|
-
"command": "npx",
|
|
101
|
-
"args": ["-y", "opencode-mcp"]
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
```
|
|
106
|
-
|
|
107
|
-
**Zed** (`settings.json`):
|
|
49
|
+
## How It Works
|
|
108
50
|
|
|
109
|
-
```json
|
|
110
|
-
{
|
|
111
|
-
"context_servers": {
|
|
112
|
-
"opencode": {
|
|
113
|
-
"command": {
|
|
114
|
-
"path": "npx",
|
|
115
|
-
"args": ["-y", "opencode-mcp"]
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
51
|
```
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
```json
|
|
125
|
-
{
|
|
126
|
-
"amazon-q.mcp.servers": [
|
|
127
|
-
{
|
|
128
|
-
"name": "opencode",
|
|
129
|
-
"type": "stdio",
|
|
130
|
-
"command": "npx",
|
|
131
|
-
"args": ["-y", "opencode-mcp"]
|
|
132
|
-
}
|
|
133
|
-
]
|
|
134
|
-
}
|
|
135
|
-
```
|
|
136
|
-
|
|
137
|
-
That's it. Your MCP client now has access to the entire OpenCode API. The MCP server will auto-start `opencode serve` if it's not already running.
|
|
138
|
-
|
|
139
|
-
### Custom server URL or authentication (optional)
|
|
140
|
-
|
|
141
|
-
By default, the MCP server connects to `http://127.0.0.1:4096` with no authentication. Both username and password are **optional** — auth is only needed if you've enabled it on the OpenCode server side.
|
|
142
|
-
|
|
143
|
-
If the OpenCode server is on a different host/port or has auth enabled, pass environment variables:
|
|
144
|
-
|
|
145
|
-
```json
|
|
146
|
-
{
|
|
147
|
-
"mcpServers": {
|
|
148
|
-
"opencode": {
|
|
149
|
-
"command": "npx",
|
|
150
|
-
"args": ["-y", "opencode-mcp"],
|
|
151
|
-
"env": {
|
|
152
|
-
"OPENCODE_BASE_URL": "http://192.168.1.10:4096",
|
|
153
|
-
"OPENCODE_SERVER_USERNAME": "myuser",
|
|
154
|
-
"OPENCODE_SERVER_PASSWORD": "mypass"
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
}
|
|
52
|
+
MCP Client <--stdio--> opencode-mcp <--HTTP--> OpenCode Server
|
|
53
|
+
(Claude, Cursor, etc.) (this package) (opencode serve)
|
|
159
54
|
```
|
|
160
55
|
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
```json
|
|
164
|
-
{
|
|
165
|
-
"env": {
|
|
166
|
-
"OPENCODE_AUTO_SERVE": "false"
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
```
|
|
56
|
+
Your MCP client calls tools over stdio. This server translates them into HTTP requests to the OpenCode headless API. If the OpenCode server isn't running, it's started automatically.
|
|
170
57
|
|
|
171
|
-
##
|
|
58
|
+
## Key Tools
|
|
172
59
|
|
|
173
|
-
|
|
60
|
+
The 79 tools are organized into tiers. Start with the workflow tools — they handle the common patterns in a single call.
|
|
174
61
|
|
|
175
|
-
|
|
62
|
+
### Workflow Tools (13) — Start Here
|
|
176
63
|
|
|
177
64
|
| Tool | What it does |
|
|
178
65
|
|---|---|
|
|
179
|
-
| `opencode_setup` | Check server health,
|
|
180
|
-
| `opencode_ask` | Create session + send prompt + get answer
|
|
66
|
+
| `opencode_setup` | Check server health, providers, and project status. Use first. |
|
|
67
|
+
| `opencode_ask` | Create session + send prompt + get answer. One call. |
|
|
181
68
|
| `opencode_reply` | Follow-up message in an existing session |
|
|
182
|
-
| `
|
|
69
|
+
| `opencode_run` | Send a task and wait for completion (session + async send + polling) |
|
|
70
|
+
| `opencode_fire` | Fire-and-forget: dispatch a task, return immediately |
|
|
71
|
+
| `opencode_check` | Compact progress report for a running session (status, todos, files changed) |
|
|
72
|
+
| `opencode_conversation` | Get formatted conversation history |
|
|
183
73
|
| `opencode_sessions_overview` | Quick overview of all sessions |
|
|
184
|
-
| `opencode_context` | Project +
|
|
185
|
-
| `opencode_wait` | Poll an async session until it finishes |
|
|
74
|
+
| `opencode_context` | Project + VCS + config + agents in one call |
|
|
186
75
|
| `opencode_review_changes` | Formatted diff summary for a session |
|
|
187
|
-
| `
|
|
188
|
-
| `
|
|
189
|
-
|
|
190
|
-
### Session Tools (19)
|
|
191
|
-
|
|
192
|
-
Create, list, get, delete, update, fork, share, abort, revert sessions. Get diffs, todos, summaries, child sessions, and respond to permission requests.
|
|
193
|
-
|
|
194
|
-
### Message Tools (6)
|
|
195
|
-
|
|
196
|
-
Send prompts (sync or async), list/get messages, execute slash commands, run shell commands.
|
|
197
|
-
|
|
198
|
-
### File & Search Tools (6)
|
|
199
|
-
|
|
200
|
-
Search text/regex across the project, find files by name, find workspace symbols, list directories, read files, check VCS file status.
|
|
201
|
-
|
|
202
|
-
### Project Tools (2)
|
|
203
|
-
|
|
204
|
-
List known projects and inspect the current active project.
|
|
76
|
+
| `opencode_wait` | Poll an async session until it finishes |
|
|
77
|
+
| `opencode_provider_test` | Quick-test whether a provider is working |
|
|
78
|
+
| `opencode_status` | Health + providers + sessions + VCS dashboard |
|
|
205
79
|
|
|
206
|
-
###
|
|
80
|
+
### Recommended Patterns
|
|
207
81
|
|
|
208
|
-
|
|
82
|
+
**Quick question:**
|
|
83
|
+
```
|
|
84
|
+
opencode_ask({ prompt: "Explain the auth flow in this project" })
|
|
85
|
+
```
|
|
209
86
|
|
|
210
|
-
|
|
87
|
+
**Build something and wait:**
|
|
88
|
+
```
|
|
89
|
+
opencode_run({ prompt: "Add input validation to POST /api/users", maxDurationSeconds: 300 })
|
|
90
|
+
```
|
|
211
91
|
|
|
212
|
-
|
|
92
|
+
**Parallel background tasks:**
|
|
93
|
+
```
|
|
94
|
+
opencode_fire({ prompt: "Refactor the auth module to use JWT" })
|
|
95
|
+
→ returns sessionId immediately
|
|
96
|
+
opencode_check({ sessionId: "..." })
|
|
97
|
+
→ check progress anytime
|
|
98
|
+
```
|
|
213
99
|
|
|
214
|
-
###
|
|
100
|
+
### All Tool Categories
|
|
215
101
|
|
|
216
|
-
|
|
102
|
+
| Category | Count | Description |
|
|
103
|
+
|---|---|---|
|
|
104
|
+
| [Workflow](docs/tools.md#workflow-tools) | 13 | High-level composite operations |
|
|
105
|
+
| [Session](docs/tools.md#session-tools) | 20 | Create, list, fork, share, abort, revert, permissions |
|
|
106
|
+
| [Message](docs/tools.md#message-tools) | 6 | Send prompts, execute commands, run shell |
|
|
107
|
+
| [File & Search](docs/tools.md#file--search-tools) | 6 | Search text/regex, find files/symbols, read files |
|
|
108
|
+
| [System](docs/tools.md#system--monitoring-tools) | 13 | Health, VCS, LSP, MCP servers, agents, logging |
|
|
109
|
+
| [TUI Control](docs/tools.md#tui-control-tools) | 9 | Remote-control the OpenCode terminal UI |
|
|
110
|
+
| [Provider & Auth](docs/tools.md#provider--auth-tools) | 6 | List providers/models, set API keys, OAuth |
|
|
111
|
+
| [Config](docs/tools.md#config-tools) | 3 | Get/update configuration |
|
|
112
|
+
| [Project](docs/tools.md#project-tools) | 2 | List and inspect projects |
|
|
113
|
+
| [Events](docs/tools.md#event-tools) | 1 | Poll real-time SSE events |
|
|
217
114
|
|
|
218
115
|
### Resources (10)
|
|
219
116
|
|
|
220
|
-
Browseable data endpoints:
|
|
117
|
+
Browseable data endpoints — your client can read these without tool calls:
|
|
221
118
|
|
|
222
119
|
| URI | Description |
|
|
223
120
|
|---|---|
|
|
@@ -232,100 +129,40 @@ Browseable data endpoints:
|
|
|
232
129
|
| `opencode://mcp-servers` | MCP server status |
|
|
233
130
|
| `opencode://file-status` | VCS file status |
|
|
234
131
|
|
|
235
|
-
### Prompts (
|
|
132
|
+
### Prompts (6)
|
|
236
133
|
|
|
237
|
-
Guided workflow templates:
|
|
134
|
+
Guided workflow templates your client can offer as selectable actions:
|
|
238
135
|
|
|
239
136
|
| Prompt | Description |
|
|
240
137
|
|---|---|
|
|
241
|
-
| `opencode-code-review` |
|
|
242
|
-
| `opencode-debug` |
|
|
138
|
+
| `opencode-code-review` | Review diffs from a session |
|
|
139
|
+
| `opencode-debug` | Step-by-step debugging workflow |
|
|
243
140
|
| `opencode-project-setup` | Get oriented in a new project |
|
|
244
|
-
| `opencode-implement` | Have OpenCode
|
|
245
|
-
| `opencode-
|
|
141
|
+
| `opencode-implement` | Have OpenCode build a feature |
|
|
142
|
+
| `opencode-best-practices` | Setup, tool selection, monitoring, and pitfalls |
|
|
143
|
+
| `opencode-session-summary` | Summarize what happened in a session |
|
|
246
144
|
|
|
247
|
-
##
|
|
248
|
-
|
|
249
|
-
All environment variables are **optional**. You only need to set them if you've changed the defaults on the OpenCode server side.
|
|
250
|
-
|
|
251
|
-
| Variable | Description | Default | Required |
|
|
252
|
-
|---|---|---|---|
|
|
253
|
-
| `OPENCODE_BASE_URL` | URL of the OpenCode server | `http://127.0.0.1:4096` | No |
|
|
254
|
-
| `OPENCODE_SERVER_USERNAME` | HTTP basic auth username | `opencode` | No |
|
|
255
|
-
| `OPENCODE_SERVER_PASSWORD` | HTTP basic auth password | *(none — auth disabled)* | No |
|
|
256
|
-
| `OPENCODE_AUTO_SERVE` | Auto-start `opencode serve` if not running | `true` | No |
|
|
257
|
-
|
|
258
|
-
> **Note:** Authentication is disabled by default. It only activates when `OPENCODE_SERVER_PASSWORD` is set on both the OpenCode server and the MCP server.
|
|
145
|
+
## Multi-Project Support
|
|
259
146
|
|
|
260
|
-
|
|
147
|
+
Every tool accepts an optional `directory` parameter to target a different project. No restarts needed.
|
|
261
148
|
|
|
262
149
|
```
|
|
263
|
-
|
|
264
|
-
(
|
|
150
|
+
opencode_ask({ directory: "/home/user/mobile-app", prompt: "Add navigation" })
|
|
151
|
+
opencode_ask({ directory: "/home/user/web-app", prompt: "Add auth" })
|
|
265
152
|
```
|
|
266
153
|
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
**Auto-start flow:** On startup, the MCP server checks if the OpenCode server is already running (via the `/global/health` endpoint). If not, it finds the `opencode` binary on your system and spawns `opencode serve` as a child process. The child is automatically cleaned up when the MCP server exits.
|
|
270
|
-
|
|
271
|
-
## Working with Multiple Projects
|
|
272
|
-
|
|
273
|
-
Every tool accepts an optional `directory` parameter that targets a specific project directory. This lets you work on multiple projects from a single OpenCode server without restarting anything.
|
|
274
|
-
|
|
275
|
-
```
|
|
276
|
-
# First-time setup: check server status and configure providers
|
|
277
|
-
opencode_setup()
|
|
278
|
-
|
|
279
|
-
# Set an API key (one-time, global — shared across all projects)
|
|
280
|
-
opencode_auth_set({ providerId: "anthropic", type: "api", key: "sk-ant-..." })
|
|
281
|
-
|
|
282
|
-
# Work on a mobile app
|
|
283
|
-
opencode_ask({
|
|
284
|
-
directory: "/home/user/projects/mobile-app",
|
|
285
|
-
prompt: "Set up navigation with React Navigation"
|
|
286
|
-
})
|
|
287
|
-
|
|
288
|
-
# Switch to a web app — same server, different directory
|
|
289
|
-
opencode_ask({
|
|
290
|
-
directory: "/home/user/projects/web-app",
|
|
291
|
-
prompt: "Add authentication to the Next.js app"
|
|
292
|
-
})
|
|
293
|
-
|
|
294
|
-
# Go back to the mobile app — no restart needed
|
|
295
|
-
opencode_reply({
|
|
296
|
-
directory: "/home/user/projects/mobile-app",
|
|
297
|
-
sessionId: "sess_abc123",
|
|
298
|
-
prompt: "Now add a login screen"
|
|
299
|
-
})
|
|
300
|
-
```
|
|
301
|
-
|
|
302
|
-
When `directory` is omitted, the OpenCode server uses its own working directory (where `opencode serve` was started).
|
|
303
|
-
|
|
304
|
-
**How it works internally:** The `directory` parameter is sent as the `x-opencode-directory` HTTP header. The OpenCode server lazily initializes a separate instance per directory (with its own LSP, VCS, MCP servers, sessions, etc.) and caches them in memory.
|
|
154
|
+
## Environment Variables
|
|
305
155
|
|
|
306
|
-
|
|
156
|
+
All optional. Only needed if you've changed defaults on the OpenCode server.
|
|
307
157
|
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
tools/
|
|
317
|
-
workflow.ts High-level workflow tools (10)
|
|
318
|
-
session.ts Session management tools (19)
|
|
319
|
-
message.ts Message/prompt tools (6)
|
|
320
|
-
file.ts File and search tools (6)
|
|
321
|
-
tui.ts TUI remote control tools (9)
|
|
322
|
-
config.ts Config tools (3)
|
|
323
|
-
provider.ts Provider/auth tools (6)
|
|
324
|
-
misc.ts System, agents, LSP, MCP, logging tools (12)
|
|
325
|
-
events.ts SSE event polling (1)
|
|
326
|
-
global.ts Health check (1)
|
|
327
|
-
project.ts Project tools (2)
|
|
328
|
-
```
|
|
158
|
+
| Variable | Default | Description |
|
|
159
|
+
|---|---|---|
|
|
160
|
+
| `OPENCODE_BASE_URL` | `http://127.0.0.1:4096` | OpenCode server URL |
|
|
161
|
+
| `OPENCODE_SERVER_USERNAME` | `opencode` | HTTP basic auth username |
|
|
162
|
+
| `OPENCODE_SERVER_PASSWORD` | *(none)* | HTTP basic auth password (enables auth when set) |
|
|
163
|
+
| `OPENCODE_AUTO_SERVE` | `true` | Auto-start `opencode serve` if not running |
|
|
164
|
+
| `OPENCODE_DEFAULT_PROVIDER` | *(none)* | Default provider ID when not specified per-tool (e.g. `anthropic`) |
|
|
165
|
+
| `OPENCODE_DEFAULT_MODEL` | *(none)* | Default model ID when not specified per-tool (e.g. `claude-sonnet-4-5`) |
|
|
329
166
|
|
|
330
167
|
## Development
|
|
331
168
|
|
|
@@ -333,51 +170,33 @@ src/
|
|
|
333
170
|
git clone https://github.com/AlaeddineMessadi/opencode-mcp.git
|
|
334
171
|
cd opencode-mcp
|
|
335
172
|
npm install
|
|
336
|
-
npm run build
|
|
337
|
-
npm start #
|
|
173
|
+
npm run build
|
|
174
|
+
npm start # run the MCP server
|
|
338
175
|
npm run dev # watch mode
|
|
176
|
+
npm test # 316 tests
|
|
339
177
|
```
|
|
340
178
|
|
|
341
179
|
### Smoke Testing
|
|
342
180
|
|
|
343
|
-
|
|
181
|
+
End-to-end test against a running OpenCode server:
|
|
344
182
|
|
|
345
183
|
```bash
|
|
346
|
-
npm run build
|
|
347
|
-
node scripts/mcp-smoke-test.mjs
|
|
184
|
+
npm run build && node scripts/mcp-smoke-test.mjs
|
|
348
185
|
```
|
|
349
186
|
|
|
350
|
-
By default it **skips tools that are destructive or require special environment state** (OAuth flows, TUI control, `config_update`, `instance_dispose`, long-running `session_init`/`session_summarize`).
|
|
351
|
-
|
|
352
187
|
## Documentation
|
|
353
188
|
|
|
354
|
-
- [Getting Started](docs/getting-started.md) — step-by-step setup
|
|
355
|
-
- [Configuration](docs/configuration.md) —
|
|
356
|
-
- [Tools Reference](docs/tools.md) —
|
|
357
|
-
- [Resources
|
|
358
|
-
- [Prompts
|
|
359
|
-
- [
|
|
189
|
+
- [Getting Started](docs/getting-started.md) — step-by-step setup
|
|
190
|
+
- [Configuration](docs/configuration.md) — env vars and all client configs
|
|
191
|
+
- [Tools Reference](docs/tools.md) — all 79 tools in detail
|
|
192
|
+
- [Resources](docs/resources.md) — 10 MCP resources
|
|
193
|
+
- [Prompts](docs/prompts.md) — 6 guided workflow templates
|
|
194
|
+
- [Examples](docs/examples.md) — real workflow examples
|
|
360
195
|
- [Architecture](docs/architecture.md) — system design and data flow
|
|
361
196
|
|
|
362
|
-
## Compatible MCP Clients
|
|
363
|
-
|
|
364
|
-
Works with any MCP-compatible client, including:
|
|
365
|
-
|
|
366
|
-
- [Claude Desktop](https://claude.ai/download)
|
|
367
|
-
- [Claude Code](https://docs.anthropic.com/en/docs/claude-code)
|
|
368
|
-
- [Cursor](https://cursor.sh/)
|
|
369
|
-
- [Windsurf](https://codeium.com/windsurf)
|
|
370
|
-
- [VS Code (GitHub Copilot)](https://code.visualstudio.com/)
|
|
371
|
-
- [Cline](https://github.com/cline/cline)
|
|
372
|
-
- [Continue](https://continue.dev/)
|
|
373
|
-
- [Zed](https://zed.dev/)
|
|
374
|
-
- [Amazon Q](https://aws.amazon.com/q/developer/)
|
|
375
|
-
|
|
376
197
|
## References
|
|
377
198
|
|
|
378
|
-
- [OpenCode
|
|
379
|
-
- [OpenCode Server API](https://opencode.ai/docs/server/)
|
|
380
|
-
- [OpenCode SDK](https://opencode.ai/docs/sdk/)
|
|
199
|
+
- [OpenCode](https://opencode.ai/) | [OpenCode Docs](https://opencode.ai/docs/) | [OpenCode Server API](https://opencode.ai/docs/server/)
|
|
381
200
|
- [Model Context Protocol](https://modelcontextprotocol.io/)
|
|
382
201
|
|
|
383
202
|
## License
|
package/dist/client.d.ts
CHANGED
|
@@ -7,11 +7,15 @@
|
|
|
7
7
|
* - Proper 204 No Content handling on all methods
|
|
8
8
|
* - SSE streaming support
|
|
9
9
|
* - Error categorization (transient vs permanent)
|
|
10
|
+
* - Directory path normalization and validation
|
|
11
|
+
* - Lazy server reconnection on connection failure
|
|
10
12
|
*/
|
|
11
13
|
export interface OpenCodeClientOptions {
|
|
12
14
|
baseUrl: string;
|
|
13
15
|
username?: string;
|
|
14
16
|
password?: string;
|
|
17
|
+
/** Enable lazy server reconnection when connection fails. */
|
|
18
|
+
autoServe?: boolean;
|
|
15
19
|
}
|
|
16
20
|
export declare class OpenCodeError extends Error {
|
|
17
21
|
readonly status: number;
|
|
@@ -26,6 +30,8 @@ export declare class OpenCodeError extends Error {
|
|
|
26
30
|
export declare class OpenCodeClient {
|
|
27
31
|
private baseUrl;
|
|
28
32
|
private authHeader?;
|
|
33
|
+
private autoServe;
|
|
34
|
+
private reconnectAttempts;
|
|
29
35
|
constructor(options: OpenCodeClientOptions);
|
|
30
36
|
getBaseUrl(): string;
|
|
31
37
|
private buildUrl;
|
package/dist/client.js
CHANGED
|
@@ -7,7 +7,11 @@
|
|
|
7
7
|
* - Proper 204 No Content handling on all methods
|
|
8
8
|
* - SSE streaming support
|
|
9
9
|
* - Error categorization (transient vs permanent)
|
|
10
|
+
* - Directory path normalization and validation
|
|
11
|
+
* - Lazy server reconnection on connection failure
|
|
10
12
|
*/
|
|
13
|
+
import { normalizeDirectory } from "./helpers.js";
|
|
14
|
+
import { ensureServer, isServerRunning } from "./server-manager.js";
|
|
11
15
|
export class OpenCodeError extends Error {
|
|
12
16
|
status;
|
|
13
17
|
method;
|
|
@@ -36,11 +40,26 @@ export class OpenCodeError extends Error {
|
|
|
36
40
|
}
|
|
37
41
|
const MAX_RETRIES = 2;
|
|
38
42
|
const BASE_DELAY_MS = 500;
|
|
43
|
+
/** Max reconnection attempts per MCP session lifetime. */
|
|
44
|
+
const MAX_RECONNECT_ATTEMPTS = 3;
|
|
45
|
+
/** Check if an error looks like a connection failure (server unreachable). */
|
|
46
|
+
function isConnectionError(err) {
|
|
47
|
+
const msg = err.message.toLowerCase();
|
|
48
|
+
return (msg.includes("econnrefused") ||
|
|
49
|
+
msg.includes("enotfound") ||
|
|
50
|
+
msg.includes("ehostunreach") ||
|
|
51
|
+
msg.includes("fetch failed") ||
|
|
52
|
+
msg.includes("network error") ||
|
|
53
|
+
msg.includes("socket hang up"));
|
|
54
|
+
}
|
|
39
55
|
export class OpenCodeClient {
|
|
40
56
|
baseUrl;
|
|
41
57
|
authHeader;
|
|
58
|
+
autoServe;
|
|
59
|
+
reconnectAttempts = 0;
|
|
42
60
|
constructor(options) {
|
|
43
61
|
this.baseUrl = options.baseUrl.replace(/\/$/, "");
|
|
62
|
+
this.autoServe = options.autoServe ?? false;
|
|
44
63
|
if (options.password) {
|
|
45
64
|
const username = options.username ?? "opencode";
|
|
46
65
|
this.authHeader =
|
|
@@ -70,8 +89,10 @@ export class OpenCodeClient {
|
|
|
70
89
|
if (this.authHeader) {
|
|
71
90
|
h["Authorization"] = this.authHeader;
|
|
72
91
|
}
|
|
73
|
-
|
|
74
|
-
|
|
92
|
+
// Normalize and validate the directory path before sending as header
|
|
93
|
+
const normalized = normalizeDirectory(directory);
|
|
94
|
+
if (normalized) {
|
|
95
|
+
h["x-opencode-directory"] = normalized;
|
|
75
96
|
}
|
|
76
97
|
return h;
|
|
77
98
|
}
|
|
@@ -124,6 +145,26 @@ export class OpenCodeClient {
|
|
|
124
145
|
break;
|
|
125
146
|
}
|
|
126
147
|
}
|
|
148
|
+
// Lazy reconnection: if all retries exhausted and error looks like a
|
|
149
|
+
// connection failure, try restarting the server and retry once.
|
|
150
|
+
if (this.autoServe &&
|
|
151
|
+
this.reconnectAttempts < MAX_RECONNECT_ATTEMPTS &&
|
|
152
|
+
lastError &&
|
|
153
|
+
isConnectionError(lastError)) {
|
|
154
|
+
this.reconnectAttempts++;
|
|
155
|
+
console.error(`Connection failed (attempt ${this.reconnectAttempts}/${MAX_RECONNECT_ATTEMPTS}), attempting server reconnection...`);
|
|
156
|
+
try {
|
|
157
|
+
const status = await isServerRunning(this.baseUrl);
|
|
158
|
+
if (!status.healthy) {
|
|
159
|
+
await ensureServer({ baseUrl: this.baseUrl, autoServe: true });
|
|
160
|
+
}
|
|
161
|
+
// Retry the original request once after reconnection
|
|
162
|
+
return this.request(method, path, opts);
|
|
163
|
+
}
|
|
164
|
+
catch (reconnectErr) {
|
|
165
|
+
console.error(`Server reconnection failed: ${reconnectErr instanceof Error ? reconnectErr.message : String(reconnectErr)}`);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
127
168
|
throw lastError ?? new Error(`${method} ${path} failed after retries`);
|
|
128
169
|
}
|
|
129
170
|
async get(path, query, directory) {
|
package/dist/client.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
|