opencode-mcp 1.2.0 → 1.3.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 +19 -0
- package/README.md +21 -10
- package/dist/index.d.ts +3 -1
- package/dist/index.js +19 -3
- package/dist/index.js.map +1 -1
- package/dist/server-manager.d.ts +68 -0
- package/dist/server-manager.js +251 -0
- package/dist/server-manager.js.map +1 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,25 @@ 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.3.0] - 2025-02-08
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- **Auto-serve** — the MCP server now automatically detects whether `opencode serve` is running and starts it as a child process if not. No more manual "start opencode serve" step before using the MCP server.
|
|
13
|
+
- Checks the `/global/health` endpoint on startup
|
|
14
|
+
- Finds the `opencode` binary via `which`/`where`
|
|
15
|
+
- Spawns `opencode serve --port <port>` and polls until healthy
|
|
16
|
+
- Graceful shutdown: kills the managed child process on SIGINT/SIGTERM/exit
|
|
17
|
+
- Clear error messages with install instructions if the binary is not found
|
|
18
|
+
- **`OPENCODE_AUTO_SERVE` env var** — set to `"false"` to disable auto-start for users who prefer manual control
|
|
19
|
+
- **`src/server-manager.ts` module** — new module with `findBinary()`, `isServerRunning()`, `startServer()`, `stopServer()`, `ensureServer()`
|
|
20
|
+
- **140 tests** (up from 117) — 23 new tests for the server manager covering health checks, binary detection, auto-start, error cases, and shutdown
|
|
21
|
+
|
|
22
|
+
### Changed
|
|
23
|
+
|
|
24
|
+
- Startup flow in `src/index.ts` now calls `ensureServer()` before connecting the MCP transport
|
|
25
|
+
- Updated README: removed manual "start opencode serve" step, added auto-serve documentation, updated env vars table and architecture section
|
|
26
|
+
|
|
8
27
|
## [1.2.0] - 2025-02-08
|
|
9
28
|
|
|
10
29
|
### Added
|
package/README.md
CHANGED
|
@@ -5,19 +5,16 @@
|
|
|
5
5
|
[](https://nodejs.org/)
|
|
6
6
|
[](https://www.npmjs.com/package/opencode-mcp)
|
|
7
7
|
|
|
8
|
-
An [MCP](https://modelcontextprotocol.io/) server that gives any MCP-compatible client full access to
|
|
8
|
+
An [MCP](https://modelcontextprotocol.io/) server that gives any MCP-compatible client full access to [OpenCode](https://opencode.ai/). Manage sessions, send prompts, search files, review diffs, configure providers, control the TUI, and more.
|
|
9
9
|
|
|
10
|
-
**71 tools** | **10 resources** | **5 prompts** | **Multi-project support**
|
|
10
|
+
**71 tools** | **10 resources** | **5 prompts** | **Multi-project support** | **Auto-start**
|
|
11
11
|
|
|
12
12
|
## Quick Start
|
|
13
13
|
|
|
14
|
-
|
|
14
|
+
Add to your MCP client and go. The server **automatically detects and starts** the OpenCode server if it's not already running — no manual `opencode serve` step needed.
|
|
15
15
|
|
|
16
|
-
|
|
17
|
-
opencode
|
|
18
|
-
```
|
|
19
|
-
|
|
20
|
-
### 2. Add to your MCP client
|
|
16
|
+
> **Prerequisite:** [OpenCode](https://opencode.ai/) must be installed on your system.
|
|
17
|
+
> Install: `curl -fsSL https://opencode.ai/install | bash` or `npm i -g opencode-ai` or `brew install sst/tap/opencode`
|
|
21
18
|
|
|
22
19
|
Pick your client below. No authentication is needed by default — just add the config and restart your client.
|
|
23
20
|
|
|
@@ -137,7 +134,7 @@ claude mcp add opencode -- npx -y opencode-mcp
|
|
|
137
134
|
}
|
|
138
135
|
```
|
|
139
136
|
|
|
140
|
-
That's it. Your MCP client now has access to the entire OpenCode API.
|
|
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.
|
|
141
138
|
|
|
142
139
|
### Custom server URL or authentication (optional)
|
|
143
140
|
|
|
@@ -161,6 +158,16 @@ If the OpenCode server is on a different host/port or has auth enabled, pass env
|
|
|
161
158
|
}
|
|
162
159
|
```
|
|
163
160
|
|
|
161
|
+
To **disable** auto-start (if you prefer to manage the OpenCode server yourself):
|
|
162
|
+
|
|
163
|
+
```json
|
|
164
|
+
{
|
|
165
|
+
"env": {
|
|
166
|
+
"OPENCODE_AUTO_SERVE": "false"
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
```
|
|
170
|
+
|
|
164
171
|
## What Can It Do?
|
|
165
172
|
|
|
166
173
|
### Workflow Tools (start here)
|
|
@@ -240,6 +247,7 @@ All environment variables are **optional**. You only need to set them if you've
|
|
|
240
247
|
| `OPENCODE_BASE_URL` | URL of the OpenCode server | `http://127.0.0.1:4096` | No |
|
|
241
248
|
| `OPENCODE_SERVER_USERNAME` | HTTP basic auth username | `opencode` | No |
|
|
242
249
|
| `OPENCODE_SERVER_PASSWORD` | HTTP basic auth password | *(none — auth disabled)* | No |
|
|
250
|
+
| `OPENCODE_AUTO_SERVE` | Auto-start `opencode serve` if not running | `true` | No |
|
|
243
251
|
|
|
244
252
|
> **Note:** Authentication is disabled by default. It only activates when `OPENCODE_SERVER_PASSWORD` is set on both the OpenCode server and the MCP server.
|
|
245
253
|
|
|
@@ -250,7 +258,9 @@ MCP Client <--stdio--> opencode-mcp <--HTTP--> OpenCode Server
|
|
|
250
258
|
(Claude, Cursor, etc.) (this package) (opencode serve)
|
|
251
259
|
```
|
|
252
260
|
|
|
253
|
-
The MCP server communicates over **stdio** using the Model Context Protocol. When a client invokes a tool, the server translates it into HTTP calls against the OpenCode headless API.
|
|
261
|
+
The MCP server communicates over **stdio** using the Model Context Protocol. When a client invokes a tool, the server translates it into HTTP calls against the OpenCode headless API.
|
|
262
|
+
|
|
263
|
+
**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.
|
|
254
264
|
|
|
255
265
|
## Working with Multiple Projects
|
|
256
266
|
|
|
@@ -292,6 +302,7 @@ When `directory` is omitted, the OpenCode server uses its own working directory
|
|
|
292
302
|
```
|
|
293
303
|
src/
|
|
294
304
|
index.ts Entry point — wires everything together
|
|
305
|
+
server-manager.ts Auto-detect, find, and start OpenCode server
|
|
295
306
|
client.ts HTTP client with retry, SSE, error categorization
|
|
296
307
|
helpers.ts Smart response formatting for LLM-friendly output
|
|
297
308
|
resources.ts MCP Resources (10 browseable data endpoints)
|
package/dist/index.d.ts
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
* providers, and more.
|
|
9
9
|
*
|
|
10
10
|
* Features:
|
|
11
|
-
* -
|
|
11
|
+
* - 70+ tools covering the entire OpenCode API surface
|
|
12
12
|
* - High-level workflow tools (opencode_ask, opencode_reply, etc.)
|
|
13
13
|
* - Smart response formatting for LLM-friendly output
|
|
14
14
|
* - MCP Resources for browseable project data
|
|
@@ -16,10 +16,12 @@
|
|
|
16
16
|
* - SSE event polling
|
|
17
17
|
* - TUI control tools
|
|
18
18
|
* - Retry logic with exponential backoff
|
|
19
|
+
* - Auto-detection and auto-start of the OpenCode server
|
|
19
20
|
*
|
|
20
21
|
* Environment variables:
|
|
21
22
|
* OPENCODE_BASE_URL - Base URL of the OpenCode server (default: http://127.0.0.1:4096)
|
|
22
23
|
* OPENCODE_SERVER_USERNAME - Username for HTTP basic auth (default: opencode)
|
|
23
24
|
* OPENCODE_SERVER_PASSWORD - Password for HTTP basic auth (optional)
|
|
25
|
+
* OPENCODE_AUTO_SERVE - Set to "false" to disable auto-start (default: true)
|
|
24
26
|
*/
|
|
25
27
|
export {};
|
package/dist/index.js
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
* providers, and more.
|
|
9
9
|
*
|
|
10
10
|
* Features:
|
|
11
|
-
* -
|
|
11
|
+
* - 70+ tools covering the entire OpenCode API surface
|
|
12
12
|
* - High-level workflow tools (opencode_ask, opencode_reply, etc.)
|
|
13
13
|
* - Smart response formatting for LLM-friendly output
|
|
14
14
|
* - MCP Resources for browseable project data
|
|
@@ -16,15 +16,18 @@
|
|
|
16
16
|
* - SSE event polling
|
|
17
17
|
* - TUI control tools
|
|
18
18
|
* - Retry logic with exponential backoff
|
|
19
|
+
* - Auto-detection and auto-start of the OpenCode server
|
|
19
20
|
*
|
|
20
21
|
* Environment variables:
|
|
21
22
|
* OPENCODE_BASE_URL - Base URL of the OpenCode server (default: http://127.0.0.1:4096)
|
|
22
23
|
* OPENCODE_SERVER_USERNAME - Username for HTTP basic auth (default: opencode)
|
|
23
24
|
* OPENCODE_SERVER_PASSWORD - Password for HTTP basic auth (optional)
|
|
25
|
+
* OPENCODE_AUTO_SERVE - Set to "false" to disable auto-start (default: true)
|
|
24
26
|
*/
|
|
25
27
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
26
28
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
27
29
|
import { OpenCodeClient } from "./client.js";
|
|
30
|
+
import { ensureServer } from "./server-manager.js";
|
|
28
31
|
// Tool groups
|
|
29
32
|
import { registerGlobalTools } from "./tools/global.js";
|
|
30
33
|
import { registerConfigTools } from "./tools/config.js";
|
|
@@ -43,15 +46,17 @@ import { registerPrompts } from "./prompts.js";
|
|
|
43
46
|
const baseUrl = process.env.OPENCODE_BASE_URL ?? "http://127.0.0.1:4096";
|
|
44
47
|
const username = process.env.OPENCODE_SERVER_USERNAME;
|
|
45
48
|
const password = process.env.OPENCODE_SERVER_PASSWORD;
|
|
49
|
+
const autoServe = process.env.OPENCODE_AUTO_SERVE !== "false";
|
|
46
50
|
const client = new OpenCodeClient({ baseUrl, username, password });
|
|
47
51
|
const server = new McpServer({
|
|
48
52
|
name: "opencode-mcp",
|
|
49
|
-
version: "1.
|
|
53
|
+
version: "1.3.0",
|
|
50
54
|
description: "Full-featured MCP server wrapping the OpenCode AI headless HTTP server. " +
|
|
51
55
|
"Provides 70+ tools, resources, and prompts to manage sessions, send " +
|
|
52
56
|
"prompts, search files, configure providers, control the TUI, monitor " +
|
|
53
57
|
"events, and interact with the full OpenCode API. " +
|
|
54
58
|
"All tools support a directory parameter for multi-project workflows. " +
|
|
59
|
+
"Auto-detects and starts the OpenCode server if not already running. " +
|
|
55
60
|
"Start with opencode_setup for onboarding, opencode_ask for one-shot " +
|
|
56
61
|
"questions, or opencode_context to understand the current project.",
|
|
57
62
|
});
|
|
@@ -76,9 +81,20 @@ registerResources(server, client);
|
|
|
76
81
|
registerPrompts(server);
|
|
77
82
|
// ── Start ───────────────────────────────────────────────────────────
|
|
78
83
|
async function main() {
|
|
84
|
+
// Step 1: Ensure OpenCode server is available (auto-start if needed).
|
|
85
|
+
try {
|
|
86
|
+
await ensureServer({ baseUrl, autoServe });
|
|
87
|
+
}
|
|
88
|
+
catch (err) {
|
|
89
|
+
// Log the error but don't prevent MCP from starting — tools will
|
|
90
|
+
// report connection errors individually, and the server may come
|
|
91
|
+
// up later.
|
|
92
|
+
console.error(`Warning: ${err instanceof Error ? err.message : String(err)}`);
|
|
93
|
+
}
|
|
94
|
+
// Step 2: Connect the MCP transport.
|
|
79
95
|
const transport = new StdioServerTransport();
|
|
80
96
|
await server.connect(transport);
|
|
81
|
-
console.error(`opencode-mcp v1.
|
|
97
|
+
console.error(`opencode-mcp v1.3.0 started (OpenCode server at ${baseUrl})`);
|
|
82
98
|
}
|
|
83
99
|
main().catch((err) => {
|
|
84
100
|
console.error("Fatal error starting opencode-mcp:", err);
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Auto-detection and auto-start of the OpenCode headless server.
|
|
3
|
+
*
|
|
4
|
+
* This module handles:
|
|
5
|
+
* 1. Checking if `opencode serve` is already running (health check)
|
|
6
|
+
* 2. Finding the `opencode` binary on the system
|
|
7
|
+
* 3. Spawning `opencode serve` as a child process if needed
|
|
8
|
+
* 4. Graceful shutdown of the child process on exit
|
|
9
|
+
*
|
|
10
|
+
* Controlled via environment variables:
|
|
11
|
+
* OPENCODE_AUTO_SERVE - Set to "false" to disable auto-start (default: true)
|
|
12
|
+
* OPENCODE_BASE_URL - Base URL of the server (default: http://127.0.0.1:4096)
|
|
13
|
+
*/
|
|
14
|
+
export interface ServerManagerOptions {
|
|
15
|
+
baseUrl: string;
|
|
16
|
+
/** Disable auto-start entirely. */
|
|
17
|
+
autoServe?: boolean;
|
|
18
|
+
/** Max time (ms) to wait for the server to become healthy after spawning. */
|
|
19
|
+
startupTimeoutMs?: number;
|
|
20
|
+
}
|
|
21
|
+
export interface ServerStatus {
|
|
22
|
+
running: boolean;
|
|
23
|
+
version?: string;
|
|
24
|
+
managedByUs: boolean;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Check if the OpenCode server is already running by hitting the health endpoint.
|
|
28
|
+
* Returns `{ healthy: true, version }` or `{ healthy: false }`.
|
|
29
|
+
*/
|
|
30
|
+
export declare function isServerRunning(baseUrl: string): Promise<{
|
|
31
|
+
healthy: boolean;
|
|
32
|
+
version?: string;
|
|
33
|
+
}>;
|
|
34
|
+
/**
|
|
35
|
+
* Attempt to find the `opencode` binary on the system.
|
|
36
|
+
* Returns the full path or null if not found.
|
|
37
|
+
*/
|
|
38
|
+
export declare function findBinary(): Promise<string | null>;
|
|
39
|
+
/**
|
|
40
|
+
* Get the installed OpenCode version. Returns null if not installed.
|
|
41
|
+
*/
|
|
42
|
+
export declare function getInstalledVersion(binaryPath: string): Promise<string | null>;
|
|
43
|
+
/**
|
|
44
|
+
* Build installation instructions for when the binary is not found.
|
|
45
|
+
*/
|
|
46
|
+
export declare function getInstallInstructions(): string;
|
|
47
|
+
/**
|
|
48
|
+
* Spawn `opencode serve` as a background child process.
|
|
49
|
+
* Waits until the health endpoint responds or the timeout elapses.
|
|
50
|
+
*
|
|
51
|
+
* @throws Error if the binary is not found or the server fails to start.
|
|
52
|
+
*/
|
|
53
|
+
export declare function startServer(binaryPath: string, baseUrl: string, timeoutMs?: number): Promise<{
|
|
54
|
+
version?: string;
|
|
55
|
+
}>;
|
|
56
|
+
/**
|
|
57
|
+
* Stop the managed child process (if we started one).
|
|
58
|
+
*/
|
|
59
|
+
export declare function stopServer(): void;
|
|
60
|
+
/**
|
|
61
|
+
* Main entry point: ensure the OpenCode server is available.
|
|
62
|
+
*
|
|
63
|
+
* Returns a status object describing the result.
|
|
64
|
+
* Logs progress to stderr (MCP servers use stdout for the transport).
|
|
65
|
+
*
|
|
66
|
+
* @throws Error if the server cannot be reached and auto-start fails.
|
|
67
|
+
*/
|
|
68
|
+
export declare function ensureServer(opts: ServerManagerOptions): Promise<ServerStatus>;
|
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Auto-detection and auto-start of the OpenCode headless server.
|
|
3
|
+
*
|
|
4
|
+
* This module handles:
|
|
5
|
+
* 1. Checking if `opencode serve` is already running (health check)
|
|
6
|
+
* 2. Finding the `opencode` binary on the system
|
|
7
|
+
* 3. Spawning `opencode serve` as a child process if needed
|
|
8
|
+
* 4. Graceful shutdown of the child process on exit
|
|
9
|
+
*
|
|
10
|
+
* Controlled via environment variables:
|
|
11
|
+
* OPENCODE_AUTO_SERVE - Set to "false" to disable auto-start (default: true)
|
|
12
|
+
* OPENCODE_BASE_URL - Base URL of the server (default: http://127.0.0.1:4096)
|
|
13
|
+
*/
|
|
14
|
+
import { execFile, spawn } from "node:child_process";
|
|
15
|
+
import { promisify } from "node:util";
|
|
16
|
+
const execFileAsync = promisify(execFile);
|
|
17
|
+
const DEFAULT_STARTUP_TIMEOUT_MS = 30_000;
|
|
18
|
+
const HEALTH_POLL_INTERVAL_MS = 500;
|
|
19
|
+
/** Singleton child process reference so we can clean up on exit. */
|
|
20
|
+
let managedProcess = null;
|
|
21
|
+
let shutdownRegistered = false;
|
|
22
|
+
/**
|
|
23
|
+
* Check if the OpenCode server is already running by hitting the health endpoint.
|
|
24
|
+
* Returns `{ healthy: true, version }` or `{ healthy: false }`.
|
|
25
|
+
*/
|
|
26
|
+
export async function isServerRunning(baseUrl) {
|
|
27
|
+
try {
|
|
28
|
+
const url = `${baseUrl.replace(/\/$/, "")}/global/health`;
|
|
29
|
+
const controller = new AbortController();
|
|
30
|
+
const timeout = setTimeout(() => controller.abort(), 3_000);
|
|
31
|
+
const res = await fetch(url, {
|
|
32
|
+
method: "GET",
|
|
33
|
+
signal: controller.signal,
|
|
34
|
+
});
|
|
35
|
+
clearTimeout(timeout);
|
|
36
|
+
if (res.ok) {
|
|
37
|
+
const body = (await res.json());
|
|
38
|
+
return {
|
|
39
|
+
healthy: body.healthy === true,
|
|
40
|
+
version: typeof body.version === "string" ? body.version : undefined,
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
return { healthy: false };
|
|
44
|
+
}
|
|
45
|
+
catch {
|
|
46
|
+
return { healthy: false };
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Attempt to find the `opencode` binary on the system.
|
|
51
|
+
* Returns the full path or null if not found.
|
|
52
|
+
*/
|
|
53
|
+
export async function findBinary() {
|
|
54
|
+
const cmd = process.platform === "win32" ? "where" : "which";
|
|
55
|
+
try {
|
|
56
|
+
const { stdout } = await execFileAsync(cmd, ["opencode"]);
|
|
57
|
+
const path = stdout.trim().split("\n")[0]?.trim();
|
|
58
|
+
return path || null;
|
|
59
|
+
}
|
|
60
|
+
catch {
|
|
61
|
+
return null;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Get the installed OpenCode version. Returns null if not installed.
|
|
66
|
+
*/
|
|
67
|
+
export async function getInstalledVersion(binaryPath) {
|
|
68
|
+
try {
|
|
69
|
+
const { stdout } = await execFileAsync(binaryPath, ["--version"]);
|
|
70
|
+
return stdout.trim() || null;
|
|
71
|
+
}
|
|
72
|
+
catch {
|
|
73
|
+
return null;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Build installation instructions for when the binary is not found.
|
|
78
|
+
*/
|
|
79
|
+
export function getInstallInstructions() {
|
|
80
|
+
return [
|
|
81
|
+
"OpenCode is not installed on this system.",
|
|
82
|
+
"",
|
|
83
|
+
"Install it using one of these methods:",
|
|
84
|
+
" curl -fsSL https://opencode.ai/install | bash",
|
|
85
|
+
" npm i -g opencode-ai",
|
|
86
|
+
" brew install sst/tap/opencode",
|
|
87
|
+
"",
|
|
88
|
+
"For more options: https://opencode.ai",
|
|
89
|
+
"",
|
|
90
|
+
"After installing, restart the MCP server.",
|
|
91
|
+
"To disable auto-start: set OPENCODE_AUTO_SERVE=false",
|
|
92
|
+
].join("\n");
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Parse host and port from a base URL.
|
|
96
|
+
*/
|
|
97
|
+
function parseBaseUrl(baseUrl) {
|
|
98
|
+
const url = new URL(baseUrl);
|
|
99
|
+
return {
|
|
100
|
+
hostname: url.hostname,
|
|
101
|
+
port: url.port ? parseInt(url.port, 10) : 4096,
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Poll the health endpoint until the server responds or timeout elapses.
|
|
106
|
+
*/
|
|
107
|
+
async function waitForHealthy(baseUrl, timeoutMs) {
|
|
108
|
+
const deadline = Date.now() + timeoutMs;
|
|
109
|
+
while (Date.now() < deadline) {
|
|
110
|
+
const { healthy } = await isServerRunning(baseUrl);
|
|
111
|
+
if (healthy)
|
|
112
|
+
return true;
|
|
113
|
+
await new Promise((r) => setTimeout(r, HEALTH_POLL_INTERVAL_MS));
|
|
114
|
+
}
|
|
115
|
+
return false;
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Register process-exit handlers to kill the managed child process.
|
|
119
|
+
* Only registers once even if called multiple times.
|
|
120
|
+
*/
|
|
121
|
+
function registerShutdownHandlers() {
|
|
122
|
+
if (shutdownRegistered)
|
|
123
|
+
return;
|
|
124
|
+
shutdownRegistered = true;
|
|
125
|
+
const cleanup = () => {
|
|
126
|
+
if (managedProcess && !managedProcess.killed) {
|
|
127
|
+
managedProcess.kill("SIGTERM");
|
|
128
|
+
managedProcess = null;
|
|
129
|
+
}
|
|
130
|
+
};
|
|
131
|
+
process.on("exit", cleanup);
|
|
132
|
+
process.on("SIGINT", () => {
|
|
133
|
+
cleanup();
|
|
134
|
+
process.exit(0);
|
|
135
|
+
});
|
|
136
|
+
process.on("SIGTERM", () => {
|
|
137
|
+
cleanup();
|
|
138
|
+
process.exit(0);
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Spawn `opencode serve` as a background child process.
|
|
143
|
+
* Waits until the health endpoint responds or the timeout elapses.
|
|
144
|
+
*
|
|
145
|
+
* @throws Error if the binary is not found or the server fails to start.
|
|
146
|
+
*/
|
|
147
|
+
export async function startServer(binaryPath, baseUrl, timeoutMs = DEFAULT_STARTUP_TIMEOUT_MS) {
|
|
148
|
+
const { hostname, port } = parseBaseUrl(baseUrl);
|
|
149
|
+
const args = ["serve", "--port", String(port)];
|
|
150
|
+
if (hostname !== "127.0.0.1" && hostname !== "localhost") {
|
|
151
|
+
args.push("--hostname", hostname);
|
|
152
|
+
}
|
|
153
|
+
const child = spawn(binaryPath, args, {
|
|
154
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
155
|
+
detached: false,
|
|
156
|
+
});
|
|
157
|
+
managedProcess = child;
|
|
158
|
+
registerShutdownHandlers();
|
|
159
|
+
// Collect stderr for diagnostics if the process exits early.
|
|
160
|
+
let stderrOutput = "";
|
|
161
|
+
child.stderr?.on("data", (chunk) => {
|
|
162
|
+
stderrOutput += chunk.toString();
|
|
163
|
+
});
|
|
164
|
+
// Also watch stdout for the "listening" line (informational).
|
|
165
|
+
let stdoutOutput = "";
|
|
166
|
+
child.stdout?.on("data", (chunk) => {
|
|
167
|
+
stdoutOutput += chunk.toString();
|
|
168
|
+
});
|
|
169
|
+
// Reject early if the child process exits before becoming healthy.
|
|
170
|
+
const earlyExit = new Promise((_, reject) => {
|
|
171
|
+
child.on("error", (err) => {
|
|
172
|
+
reject(new Error(`Failed to start opencode serve: ${err.message}`));
|
|
173
|
+
});
|
|
174
|
+
child.on("exit", (code) => {
|
|
175
|
+
if (code !== null && code !== 0) {
|
|
176
|
+
reject(new Error(`opencode serve exited with code ${code}.\n${stderrOutput || stdoutOutput}`));
|
|
177
|
+
}
|
|
178
|
+
});
|
|
179
|
+
});
|
|
180
|
+
// Race: either the server becomes healthy or the child crashes.
|
|
181
|
+
const healthy = await Promise.race([
|
|
182
|
+
waitForHealthy(baseUrl, timeoutMs),
|
|
183
|
+
earlyExit.catch(() => false),
|
|
184
|
+
]);
|
|
185
|
+
if (!healthy) {
|
|
186
|
+
// Kill the child if it's still around.
|
|
187
|
+
if (!child.killed)
|
|
188
|
+
child.kill("SIGTERM");
|
|
189
|
+
managedProcess = null;
|
|
190
|
+
throw new Error(`opencode serve did not become healthy within ${timeoutMs / 1000}s.\n` +
|
|
191
|
+
`stderr: ${stderrOutput}\nstdout: ${stdoutOutput}`);
|
|
192
|
+
}
|
|
193
|
+
// Grab the version from the now-running server.
|
|
194
|
+
const status = await isServerRunning(baseUrl);
|
|
195
|
+
return { version: status.version };
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* Stop the managed child process (if we started one).
|
|
199
|
+
*/
|
|
200
|
+
export function stopServer() {
|
|
201
|
+
if (managedProcess && !managedProcess.killed) {
|
|
202
|
+
managedProcess.kill("SIGTERM");
|
|
203
|
+
managedProcess = null;
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
/**
|
|
207
|
+
* Main entry point: ensure the OpenCode server is available.
|
|
208
|
+
*
|
|
209
|
+
* Returns a status object describing the result.
|
|
210
|
+
* Logs progress to stderr (MCP servers use stdout for the transport).
|
|
211
|
+
*
|
|
212
|
+
* @throws Error if the server cannot be reached and auto-start fails.
|
|
213
|
+
*/
|
|
214
|
+
export async function ensureServer(opts) {
|
|
215
|
+
const baseUrl = opts.baseUrl;
|
|
216
|
+
const autoServe = opts.autoServe !== false;
|
|
217
|
+
const timeoutMs = opts.startupTimeoutMs ?? DEFAULT_STARTUP_TIMEOUT_MS;
|
|
218
|
+
// Step 1: Check if server is already running.
|
|
219
|
+
const existing = await isServerRunning(baseUrl);
|
|
220
|
+
if (existing.healthy) {
|
|
221
|
+
console.error(`OpenCode server already running at ${baseUrl} (v${existing.version ?? "unknown"})`);
|
|
222
|
+
return {
|
|
223
|
+
running: true,
|
|
224
|
+
version: existing.version,
|
|
225
|
+
managedByUs: false,
|
|
226
|
+
};
|
|
227
|
+
}
|
|
228
|
+
// If auto-serve is disabled, just report that the server isn't running.
|
|
229
|
+
if (!autoServe) {
|
|
230
|
+
throw new Error(`OpenCode server is not running at ${baseUrl} and OPENCODE_AUTO_SERVE=false.\n` +
|
|
231
|
+
`Start it manually: opencode serve`);
|
|
232
|
+
}
|
|
233
|
+
// Step 2: Find the opencode binary.
|
|
234
|
+
console.error("OpenCode server not detected, attempting auto-start...");
|
|
235
|
+
const binaryPath = await findBinary();
|
|
236
|
+
if (!binaryPath) {
|
|
237
|
+
throw new Error(getInstallInstructions());
|
|
238
|
+
}
|
|
239
|
+
const version = await getInstalledVersion(binaryPath);
|
|
240
|
+
console.error(`Found opencode binary at ${binaryPath}${version ? ` (${version})` : ""}`);
|
|
241
|
+
// Step 3: Start the server.
|
|
242
|
+
console.error(`Starting: opencode serve --port ${parseBaseUrl(baseUrl).port}`);
|
|
243
|
+
const result = await startServer(binaryPath, baseUrl, timeoutMs);
|
|
244
|
+
console.error(`OpenCode server started successfully (v${result.version ?? "unknown"})`);
|
|
245
|
+
return {
|
|
246
|
+
running: true,
|
|
247
|
+
version: result.version,
|
|
248
|
+
managedByUs: true,
|
|
249
|
+
};
|
|
250
|
+
}
|
|
251
|
+
//# sourceMappingURL=server-manager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server-manager.js","sourceRoot":"","sources":["../src/server-manager.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "opencode-mcp",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.0",
|
|
4
4
|
"description": "MCP server that wraps the OpenCode AI headless server API — 71 tools, 10 resources, 5 prompts with multi-project support for any MCP client",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|