@mekareteriker/opencode-mcp 1.10.2-mekareteriker.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.
Files changed (55) hide show
  1. package/CHANGELOG.md +204 -0
  2. package/LICENSE +22 -0
  3. package/README.md +174 -0
  4. package/dist/client.d.ts +60 -0
  5. package/dist/client.js +282 -0
  6. package/dist/client.js.map +1 -0
  7. package/dist/helpers.d.ts +150 -0
  8. package/dist/helpers.js +575 -0
  9. package/dist/helpers.js.map +1 -0
  10. package/dist/index.d.ts +30 -0
  11. package/dist/index.js +198 -0
  12. package/dist/index.js.map +1 -0
  13. package/dist/prompts.d.ts +9 -0
  14. package/dist/prompts.js +210 -0
  15. package/dist/prompts.js.map +1 -0
  16. package/dist/resources.d.ts +10 -0
  17. package/dist/resources.js +197 -0
  18. package/dist/resources.js.map +1 -0
  19. package/dist/server-manager.d.ts +72 -0
  20. package/dist/server-manager.js +264 -0
  21. package/dist/server-manager.js.map +1 -0
  22. package/dist/tools/config.d.ts +3 -0
  23. package/dist/tools/config.js +105 -0
  24. package/dist/tools/config.js.map +1 -0
  25. package/dist/tools/events.d.ts +6 -0
  26. package/dist/tools/events.js +63 -0
  27. package/dist/tools/events.js.map +1 -0
  28. package/dist/tools/file.d.ts +3 -0
  29. package/dist/tools/file.js +153 -0
  30. package/dist/tools/file.js.map +1 -0
  31. package/dist/tools/global.d.ts +3 -0
  32. package/dist/tools/global.js +17 -0
  33. package/dist/tools/global.js.map +1 -0
  34. package/dist/tools/message.d.ts +3 -0
  35. package/dist/tools/message.js +169 -0
  36. package/dist/tools/message.js.map +1 -0
  37. package/dist/tools/misc.d.ts +3 -0
  38. package/dist/tools/misc.js +298 -0
  39. package/dist/tools/misc.js.map +1 -0
  40. package/dist/tools/project.d.ts +3 -0
  41. package/dist/tools/project.js +62 -0
  42. package/dist/tools/project.js.map +1 -0
  43. package/dist/tools/provider.d.ts +3 -0
  44. package/dist/tools/provider.js +175 -0
  45. package/dist/tools/provider.js.map +1 -0
  46. package/dist/tools/session.d.ts +3 -0
  47. package/dist/tools/session.js +392 -0
  48. package/dist/tools/session.js.map +1 -0
  49. package/dist/tools/tui.d.ts +7 -0
  50. package/dist/tools/tui.js +121 -0
  51. package/dist/tools/tui.js.map +1 -0
  52. package/dist/tools/workflow.d.ts +7 -0
  53. package/dist/tools/workflow.js +775 -0
  54. package/dist/tools/workflow.js.map +1 -0
  55. package/package.json +68 -0
@@ -0,0 +1,575 @@
1
+ /**
2
+ * Smart response formatting helpers.
3
+ *
4
+ * Instead of dumping raw JSON to the LLM, these helpers extract the
5
+ * meaningful content from OpenCode API responses so the LLM can reason
6
+ * about them efficiently.
7
+ */
8
+ import { z } from "zod";
9
+ import { existsSync } from "node:fs";
10
+ import { isAbsolute, resolve } from "node:path";
11
+ /* eslint-disable @typescript-eslint/no-explicit-any */
12
+ // ── Tool Annotations ─────────────────────────────────────────────────
13
+ // MCP spec tool annotations help clients understand tool behavior.
14
+ /** Read-only tool: does not modify state. */
15
+ export const readOnly = { readOnlyHint: true, destructiveHint: false };
16
+ /** Destructive tool: permanently deletes data or shuts down services. */
17
+ export const destructive = { readOnlyHint: false, destructiveHint: true };
18
+ /**
19
+ * Shared Zod parameter for project directory targeting.
20
+ * When provided, sent as the x-opencode-directory header so the
21
+ * OpenCode server scopes the request to that project.
22
+ */
23
+ export const directoryParam = z
24
+ .string()
25
+ .optional()
26
+ .describe("Absolute path to the project directory. " +
27
+ "When provided, the request targets that project. " +
28
+ "If omitted, the OpenCode server uses its own working directory.");
29
+ // ── Default Provider/Model ────────────────────────────────────────────
30
+ /**
31
+ * Module-level defaults for provider and model.
32
+ * Set via `setModelDefaults()` during startup from env vars.
33
+ * If not set, tools fall back to whatever the OpenCode server decides.
34
+ */
35
+ let _defaultProviderID;
36
+ let _defaultModelID;
37
+ /**
38
+ * Set the global default provider and model.
39
+ * Called once from index.ts during startup.
40
+ */
41
+ export function setModelDefaults(providerID, modelID) {
42
+ _defaultProviderID = providerID;
43
+ _defaultModelID = modelID;
44
+ }
45
+ /**
46
+ * Apply model defaults: use explicit params if both are provided,
47
+ * otherwise fall back to env-var defaults if both are set,
48
+ * otherwise return undefined (let the server decide).
49
+ *
50
+ * Returns `{ providerID, modelID }` or `undefined`.
51
+ */
52
+ export function applyModelDefaults(providerID, modelID, variant) {
53
+ // Explicit params take priority
54
+ if (providerID && modelID) {
55
+ return { providerID, modelID, ...(variant ? { variant } : {}) };
56
+ }
57
+ // Fall back to env-var defaults
58
+ if (_defaultProviderID && _defaultModelID) {
59
+ return { providerID: _defaultProviderID, modelID: _defaultModelID, ...(variant ? { variant } : {}) };
60
+ }
61
+ // No defaults available — let the server decide
62
+ return undefined;
63
+ }
64
+ // ── Directory Validation ─────────────────────────────────────────────
65
+ /**
66
+ * Normalize and validate a directory path:
67
+ * - Resolves to absolute (handles "..", ".", trailing slashes, and
68
+ * converts relative inputs against `process.cwd()`)
69
+ * - Confirms the resolved path is absolute for the current platform
70
+ * - Validates that the path exists on disk
71
+ *
72
+ * Accepts both POSIX ("/home/user/my-project") and Windows
73
+ * ("C:\\Users\\me\\my-project", "\\\\server\\share") absolute paths via
74
+ * the platform-aware `resolve` + `isAbsolute` from `node:path`.
75
+ *
76
+ * Returns the normalized path, or undefined if input was undefined.
77
+ * Throws a descriptive Error on validation failure.
78
+ */
79
+ export function normalizeDirectory(directory) {
80
+ if (!directory)
81
+ return undefined;
82
+ // Resolve to an absolute, platform-appropriate form. `resolve` handles
83
+ // "..", ".", trailing slashes, and will convert a relative input against
84
+ // `process.cwd()`.
85
+ const normalized = resolve(directory);
86
+ // Defensive check: `resolve` guarantees an absolute path on every
87
+ // supported platform, but we verify via the platform-aware `isAbsolute`
88
+ // so callers get a clear error if that assumption is ever violated.
89
+ if (!isAbsolute(normalized)) {
90
+ throw new Error(`Invalid directory: "${directory}" is not an absolute path. ` +
91
+ `Provide a full path like "/home/user/my-project" (POSIX) or ` +
92
+ `"C:\\\\Users\\\\me\\\\my-project" (Windows).`);
93
+ }
94
+ // Must exist on disk
95
+ if (!existsSync(normalized)) {
96
+ throw new Error(`Directory not found: "${normalized}" does not exist. ` +
97
+ `Check the path and try again.`);
98
+ }
99
+ return normalized;
100
+ }
101
+ /**
102
+ * Extract a human-readable summary from a message response.
103
+ * Pulls text content from parts, summarizes tool calls, etc.
104
+ * Accepts any shape — casts internally for safety.
105
+ */
106
+ export function formatMessageResponse(response) {
107
+ const r = response;
108
+ const sections = [];
109
+ // Omit verbose message header for cleaner output; the caller (opencode_ask etc.)
110
+ // already provides session context. Keep a minimal role tag only when it adds info.
111
+ if (r?.parts && Array.isArray(r.parts)) {
112
+ for (const part of r.parts) {
113
+ switch (part.type) {
114
+ case "text":
115
+ sections.push(part.text ?? part.content ?? "");
116
+ break;
117
+ case "tool-invocation":
118
+ case "tool-result":
119
+ sections.push(`[Tool: ${part.toolName ?? "unknown"}] ${part.error ? `ERROR: ${part.error}` : typeof part.output === "string" ? part.output : JSON.stringify(part.output ?? part.input, null, 2)}`);
120
+ break;
121
+ case "step-start":
122
+ case "step-finish":
123
+ // Internal lifecycle events — omit from user-facing output.
124
+ // Optionally surface cost/token info from step-finish.
125
+ if (part.type === "step-finish" && (part.cost != null || part.tokens)) {
126
+ const meta = [];
127
+ if (part.cost != null)
128
+ meta.push(`cost: $${Number(part.cost).toFixed(4)}`);
129
+ if (part.tokens) {
130
+ const t = part.tokens;
131
+ const tokParts = [];
132
+ if (t.input)
133
+ tokParts.push(`${t.input} in`);
134
+ if (t.output)
135
+ tokParts.push(`${t.output} out`);
136
+ if (t.reasoning)
137
+ tokParts.push(`${t.reasoning} reasoning`);
138
+ if (tokParts.length > 0)
139
+ meta.push(`tokens: ${tokParts.join(", ")}`);
140
+ }
141
+ if (meta.length > 0)
142
+ sections.push(`_${meta.join(" | ")}_`);
143
+ }
144
+ break;
145
+ default:
146
+ // Skip unknown internal part types to keep output clean
147
+ if (part.text || part.content) {
148
+ sections.push(part.text ?? part.content);
149
+ }
150
+ // Only dump JSON for truly unknown parts that have meaningful data
151
+ else if (part.type && !["source"].includes(part.type)) {
152
+ sections.push(`[${part.type}] ${JSON.stringify(part, null, 2)}`);
153
+ }
154
+ }
155
+ }
156
+ }
157
+ return sections.join("\n\n");
158
+ }
159
+ /**
160
+ * Format a list of messages, extracting text content from each.
161
+ *
162
+ * When the assistant message has no text content (common with some providers
163
+ * that only emit tool calls), we show a concise summary of tool actions
164
+ * instead of blank output. Cost/token metadata from step-finish parts is
165
+ * appended when available.
166
+ */
167
+ export function formatMessageList(messages) {
168
+ if (!messages || messages.length === 0)
169
+ return "No messages found.";
170
+ return messages
171
+ .map((raw, i) => {
172
+ const msg = raw;
173
+ const role = msg?.info?.role ?? "unknown";
174
+ const id = msg?.info?.id ?? "?";
175
+ const parts = Array.isArray(msg?.parts) ? msg.parts : [];
176
+ const textParts = parts
177
+ .filter((p) => p.type === "text")
178
+ .map((p) => (p.text ?? p.content ?? "").trim())
179
+ .filter(Boolean)
180
+ .join("\n");
181
+ const toolParts = parts.filter((p) => p.type === "tool-invocation" || p.type === "tool-result");
182
+ // Extract cost/token metadata from step-finish parts
183
+ const costMeta = extractCostMeta(parts);
184
+ let summary = `--- Message ${i + 1} [${role}] (${id}) ---\n`;
185
+ if (textParts) {
186
+ summary += textParts;
187
+ if (toolParts.length > 0) {
188
+ summary += `\n[${toolParts.length} tool call(s)]`;
189
+ }
190
+ }
191
+ else if (toolParts.length > 0) {
192
+ // No text but agent performed actions — show concise tool summaries
193
+ const toolSummaries = toolParts.slice(0, 10).map((p) => {
194
+ const name = p.toolName ?? "unknown";
195
+ // Extract the most useful arg (file path, command, etc.)
196
+ const hint = summarizeToolInput(p.input);
197
+ const errTag = p.error ? " ERROR" : "";
198
+ return ` ${name}${hint ? `: ${hint}` : ""}${errTag}`;
199
+ });
200
+ summary += `Agent performed ${toolParts.length} action(s):\n${toolSummaries.join("\n")}`;
201
+ if (toolParts.length > 10) {
202
+ summary += `\n ... and ${toolParts.length - 10} more`;
203
+ }
204
+ }
205
+ else {
206
+ summary += "(no content)";
207
+ }
208
+ if (costMeta)
209
+ summary += `\n${costMeta}`;
210
+ return summary;
211
+ })
212
+ .join("\n\n");
213
+ }
214
+ /**
215
+ * Extract a short hint from a tool-call input object.
216
+ * Prefers path, command, file, query — the most informative single arg.
217
+ */
218
+ function summarizeToolInput(input) {
219
+ if (!input || typeof input !== "object")
220
+ return "";
221
+ const obj = input;
222
+ // Ordered by likely usefulness
223
+ for (const key of ["path", "filePath", "file", "command", "query", "url", "pattern", "text"]) {
224
+ const val = obj[key];
225
+ if (typeof val === "string" && val.length > 0) {
226
+ return val.length > 80 ? val.slice(0, 77) + "..." : val;
227
+ }
228
+ }
229
+ return "";
230
+ }
231
+ /**
232
+ * Extract cost/token metadata from step-finish parts and return a
233
+ * compact line, or empty string if none found.
234
+ */
235
+ function extractCostMeta(parts) {
236
+ const stepFinish = parts.find((p) => p.type === "step-finish" && (p.cost != null || p.tokens));
237
+ if (!stepFinish)
238
+ return "";
239
+ const meta = [];
240
+ if (stepFinish.cost != null)
241
+ meta.push(`cost: $${Number(stepFinish.cost).toFixed(4)}`);
242
+ if (stepFinish.tokens) {
243
+ const t = stepFinish.tokens;
244
+ const tokParts = [];
245
+ if (t.input)
246
+ tokParts.push(`${t.input} in`);
247
+ if (t.output)
248
+ tokParts.push(`${t.output} out`);
249
+ if (t.reasoning)
250
+ tokParts.push(`${t.reasoning} reasoning`);
251
+ if (tokParts.length > 0)
252
+ meta.push(`tokens: ${tokParts.join(", ")}`);
253
+ }
254
+ return meta.length > 0 ? `_${meta.join(" | ")}_` : "";
255
+ }
256
+ /**
257
+ * Format a diff response into a readable summary.
258
+ */
259
+ export function formatDiffResponse(diffs) {
260
+ if (!diffs || diffs.length === 0)
261
+ return "No changes found.";
262
+ return diffs
263
+ .map((d) => {
264
+ const diff = d;
265
+ const path = diff.path ?? diff.file ?? "unknown";
266
+ const status = diff.status ?? diff.type ?? "";
267
+ const additions = typeof diff.additions === "number" ? `+${diff.additions}` : "";
268
+ const deletions = typeof diff.deletions === "number" ? `-${diff.deletions}` : "";
269
+ const stats = [additions, deletions].filter(Boolean).join(" ");
270
+ let line = `${status} ${path}`;
271
+ if (stats)
272
+ line += ` (${stats})`;
273
+ if (typeof diff.diff === "string") {
274
+ line += `\n${diff.diff}`;
275
+ }
276
+ return line;
277
+ })
278
+ .join("\n");
279
+ }
280
+ /**
281
+ * Format session objects for LLM-friendly display.
282
+ */
283
+ export function formatSessionList(sessions) {
284
+ if (!sessions || sessions.length === 0)
285
+ return "No sessions found.";
286
+ return sessions
287
+ .map((raw) => {
288
+ const s = raw;
289
+ const id = s?.id ?? "?";
290
+ const title = s?.title ?? "(untitled)";
291
+ const createdAt = s?.createdAt ?? "";
292
+ const parentID = s?.parentID ? ` (child of ${s.parentID})` : "";
293
+ return `- ${title} [${id}]${parentID}${createdAt ? ` created ${createdAt}` : ""}`;
294
+ })
295
+ .join("\n");
296
+ }
297
+ /**
298
+ * Generic safe JSON stringify with truncation for very large responses.
299
+ */
300
+ export function safeStringify(value, maxLength = 50000) {
301
+ const json = JSON.stringify(value, null, 2);
302
+ if (json.length <= maxLength)
303
+ return json;
304
+ return (json.slice(0, maxLength) +
305
+ `\n\n... [truncated, ${json.length - maxLength} more characters]`);
306
+ }
307
+ /**
308
+ * Analyze an AI message response for signs of failure:
309
+ * - Completely empty (null/undefined)
310
+ * - Has parts but no text content (provider returned nothing)
311
+ * - Contains error indicators in parts
312
+ *
313
+ * Returns a diagnostic object with `isEmpty`, `hasError`, and `warning` text.
314
+ */
315
+ export function analyzeMessageResponse(response) {
316
+ if (response === null || response === undefined) {
317
+ return {
318
+ isEmpty: true,
319
+ hasError: false,
320
+ warning: "The AI returned an empty response. This usually means the provider " +
321
+ "is not configured or the API key is missing/invalid. " +
322
+ "Use `opencode_setup` to check provider status, or " +
323
+ "`opencode_auth_set` to configure an API key.",
324
+ };
325
+ }
326
+ const r = response;
327
+ const parts = Array.isArray(r?.parts) ? r.parts : [];
328
+ // Check for error parts
329
+ const errorParts = parts.filter((p) => p.error ||
330
+ (p.type === "tool-result" && p.error) ||
331
+ (typeof p.text === "string" && /\b(error|unauthorized|forbidden|invalid.?key)\b/i.test(p.text)));
332
+ if (errorParts.length > 0) {
333
+ const firstError = errorParts[0].error ??
334
+ errorParts[0].text ??
335
+ JSON.stringify(errorParts[0]);
336
+ return {
337
+ isEmpty: false,
338
+ hasError: true,
339
+ warning: `The response contains an error: ${typeof firstError === "string" ? firstError : JSON.stringify(firstError)}. ` +
340
+ "This may indicate an authentication issue. " +
341
+ "Use `opencode_auth_set` to verify your API key.",
342
+ };
343
+ }
344
+ // Check if there's any actual text content
345
+ const textContent = parts
346
+ .filter((p) => p.type === "text")
347
+ .map((p) => (p.text ?? p.content ?? "").trim())
348
+ .join("");
349
+ if (parts.length === 0 || textContent === "") {
350
+ return {
351
+ isEmpty: true,
352
+ hasError: false,
353
+ warning: "The AI returned a response with no text content. This usually means " +
354
+ "the provider API key is missing or the model is unavailable. " +
355
+ "Try a different provider/model, or use `opencode_auth_set` to configure credentials.",
356
+ };
357
+ }
358
+ return { isEmpty: false, hasError: false, warning: null };
359
+ }
360
+ /**
361
+ * Detect if a string value looks like an API key or secret token,
362
+ * regardless of the key name it's stored under.
363
+ */
364
+ const SECRET_VALUE_PREFIXES = /^(?:sk-|tvly-|ctx7sk-|pplx-|hf_|ghp_|gho_|ghu_|ghs_|ghr_|xoxb-|xoxp-|xapp-|whsec_|rk-|pk_live_|sk_live_|sk_test_|pk_test_|FLWSECK_|access_|bearer\s)/i;
365
+ const LONG_HEX_OR_BASE64 = /^[A-Za-z0-9+/=_-]{32,}$/;
366
+ function looksLikeSecret(val) {
367
+ if (val.length < 16)
368
+ return false;
369
+ if (SECRET_VALUE_PREFIXES.test(val))
370
+ return true;
371
+ // Long alphanumeric strings without spaces (probable tokens)
372
+ if (LONG_HEX_OR_BASE64.test(val) && !val.includes(" "))
373
+ return true;
374
+ return false;
375
+ }
376
+ /**
377
+ * Redact query-parameter values in a URL string that look like secrets.
378
+ */
379
+ function redactUrlSecrets(url) {
380
+ try {
381
+ const parsed = new URL(url);
382
+ let changed = false;
383
+ const sensitiveParamPattern = /(?:key|token|secret|password|credential|auth)/i;
384
+ for (const [name, val] of parsed.searchParams.entries()) {
385
+ if ((sensitiveParamPattern.test(name) && val.length > 8) || looksLikeSecret(val)) {
386
+ parsed.searchParams.set(name, val.slice(0, 4) + "***REDACTED***");
387
+ changed = true;
388
+ }
389
+ }
390
+ return changed ? parsed.toString() : url;
391
+ }
392
+ catch {
393
+ return url;
394
+ }
395
+ }
396
+ /**
397
+ * Redact values that look like API keys, tokens, or secrets.
398
+ * Replaces the value with the first 4 characters + "***REDACTED***".
399
+ * Works recursively on objects and arrays.
400
+ *
401
+ * Three layers of detection:
402
+ * 1. Key-name based: key names matching sensitive patterns (KEY, TOKEN, SECRET, etc.)
403
+ * 2. Value-based: string values matching known API key prefixes or long hex/base64 tokens
404
+ * 3. URL-based: query parameters in URL strings that contain secrets
405
+ */
406
+ export function redactSecrets(value) {
407
+ if (value === null || value === undefined)
408
+ return value;
409
+ if (typeof value === "string")
410
+ return value;
411
+ if (Array.isArray(value)) {
412
+ return value.map((item) => {
413
+ // Redact string items in arrays that look like secrets (e.g. command args)
414
+ if (typeof item === "string" && looksLikeSecret(item)) {
415
+ return item.slice(0, 4) + "***REDACTED***";
416
+ }
417
+ return redactSecrets(item);
418
+ });
419
+ }
420
+ if (typeof value === "object") {
421
+ const result = {};
422
+ const sensitiveKeyPattern = /(?:key|token|secret|password|credential|api_key|apikey|auth)/i;
423
+ for (const [k, v] of Object.entries(value)) {
424
+ if (typeof v === "string") {
425
+ if (v.length > 8 && sensitiveKeyPattern.test(k)) {
426
+ // Layer 1: key-name match
427
+ result[k] = v.slice(0, 4) + "***REDACTED***";
428
+ }
429
+ else if (looksLikeSecret(v)) {
430
+ // Layer 2: value looks like a secret
431
+ result[k] = v.slice(0, 4) + "***REDACTED***";
432
+ }
433
+ else if (v.includes("://") && v.includes("?")) {
434
+ // Layer 3: URL with query params — redact secret params
435
+ result[k] = redactUrlSecrets(v);
436
+ }
437
+ else {
438
+ result[k] = v;
439
+ }
440
+ }
441
+ else if (typeof v === "object" && v !== null) {
442
+ result[k] = redactSecrets(v);
443
+ }
444
+ else {
445
+ result[k] = v;
446
+ }
447
+ }
448
+ return result;
449
+ }
450
+ return value;
451
+ }
452
+ /**
453
+ * Determine whether a provider object from the OpenCode API is truly configured
454
+ * (i.e. has usable credentials), as opposed to being a built-in default.
455
+ *
456
+ * Detection layers:
457
+ * - source "env" / "config" / "api" → always configured
458
+ * - source "custom" with a non-empty apiKey → configured
459
+ * - source "custom" for "anthropic" with extra option keys (OAuth sets headers) → configured
460
+ * - Everything else → not configured
461
+ */
462
+ export function isProviderConfigured(p) {
463
+ const source = p.source;
464
+ if (source === "env" || source === "config" || source === "api")
465
+ return true;
466
+ if (source === "custom") {
467
+ const opts = p.options;
468
+ if (typeof opts?.apiKey === "string" && opts.apiKey !== "")
469
+ return true;
470
+ // Anthropic heuristic: OAuth sets headers but no apiKey
471
+ if (p.id === "anthropic" && opts && Object.keys(opts).some((k) => k !== "apiKey"))
472
+ return true;
473
+ }
474
+ return false;
475
+ }
476
+ /**
477
+ * Resolve a session status value from the OpenCode API.
478
+ *
479
+ * The API may return status as a plain string ("idle", "running") or as an
480
+ * object like `{ state: "running", ... }`. This helper normalises both forms
481
+ * into a human-readable string.
482
+ */
483
+ export function resolveSessionStatus(raw) {
484
+ if (raw === null || raw === undefined)
485
+ return "idle";
486
+ if (typeof raw === "string")
487
+ return raw;
488
+ if (typeof raw === "object") {
489
+ const obj = raw;
490
+ // Try common property names the API might use
491
+ for (const key of ["state", "status", "type"]) {
492
+ if (typeof obj[key] === "string")
493
+ return obj[key];
494
+ }
495
+ // Last resort: check for a meaningful boolean flag
496
+ if (obj.running === true)
497
+ return "running";
498
+ if (obj.done === true)
499
+ return "completed";
500
+ if (obj.error === true)
501
+ return "error";
502
+ }
503
+ return "unknown";
504
+ }
505
+ /**
506
+ * Standard tool response builder.
507
+ */
508
+ export function toolResult(text, isError = false) {
509
+ return {
510
+ content: [{ type: "text", text }],
511
+ ...(isError ? { isError: true } : {}),
512
+ };
513
+ }
514
+ export function toolError(e) {
515
+ const msg = e instanceof Error ? e.message : String(e);
516
+ const suggestions = diagnoseError(msg);
517
+ const text = suggestions
518
+ ? `Error: ${msg}\n\n**Suggestions:**\n${suggestions}`
519
+ : `Error: ${msg}`;
520
+ return toolResult(text, true);
521
+ }
522
+ /**
523
+ * Analyze an error message and return contextual suggestions, or empty
524
+ * string if no specific advice applies. Keeps suggestions concise to
525
+ * minimise token overhead.
526
+ */
527
+ function diagnoseError(msg) {
528
+ const lower = msg.toLowerCase();
529
+ const tips = [];
530
+ if (lower.includes("api key") || lower.includes("401") || lower.includes("403") || lower.includes("unauthorized") || lower.includes("forbidden")) {
531
+ tips.push("- Check credentials with `opencode_provider_test`");
532
+ tips.push("- Set a key with `opencode_auth_set`");
533
+ }
534
+ else if (lower.includes("timeout") || lower.includes("timed out") || lower.includes("aborted")) {
535
+ tips.push("- Use `opencode_run` for complex tasks (handles polling automatically)");
536
+ tips.push("- Or use `opencode_message_send_async` + `opencode_wait` for manual control");
537
+ tips.push("- Check session progress with `opencode_conversation`");
538
+ }
539
+ else if (lower.includes("not found") && lower.includes("session")) {
540
+ tips.push("- List active sessions with `opencode_sessions_overview`");
541
+ }
542
+ else if (lower.includes("rate limit") || lower.includes("429")) {
543
+ tips.push("- Wait a moment and retry, or switch provider");
544
+ tips.push("- Try a free model: `opencode_ask` with providerID `opencode`, modelID `minimax-m2.1-free`");
545
+ }
546
+ else if (lower.includes("econnrefused")) {
547
+ tips.push("- The OpenCode server is not accepting connections");
548
+ tips.push("- Is `opencode serve` running? Check with `opencode_setup`");
549
+ tips.push("- Verify OPENCODE_BASE_URL is correct (default: http://127.0.0.1:4096)");
550
+ tips.push("- The server will auto-reconnect on the next request if OPENCODE_AUTO_SERVE is enabled");
551
+ }
552
+ else if (lower.includes("enotfound") || lower.includes("ehostunreach")) {
553
+ tips.push("- Cannot reach the OpenCode server host");
554
+ tips.push("- Check that OPENCODE_BASE_URL points to a reachable address");
555
+ tips.push("- If running remotely, verify network connectivity");
556
+ }
557
+ else if (lower.includes("etimedout")) {
558
+ tips.push("- The server is not responding (connection timed out)");
559
+ tips.push("- The server may be overloaded or starting up — retry in a few seconds");
560
+ tips.push("- Check with `opencode_setup` to verify server health");
561
+ }
562
+ else if (lower.includes("unreachable") || lower.includes("fetch failed")) {
563
+ tips.push("- Is `opencode serve` running? Check with `opencode_setup`");
564
+ tips.push("- Verify OPENCODE_BASE_URL is correct (default: http://127.0.0.1:4096)");
565
+ }
566
+ else if (lower.includes("directory not found") || lower.includes("not an absolute path")) {
567
+ tips.push("- The `directory` parameter must be an absolute path to an existing directory");
568
+ tips.push("- Example: `/home/user/my-project` (not `./my-project` or `~/my-project`)");
569
+ }
570
+ return tips.join("\n");
571
+ }
572
+ export function toolJson(value) {
573
+ return toolResult(safeStringify(value));
574
+ }
575
+ //# sourceMappingURL=helpers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"helpers.js","sourceRoot":"","sources":["../src/helpers.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,30 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * OpenCode MCP Server
4
+ *
5
+ * An MCP (Model Context Protocol) server that wraps the OpenCode AI headless
6
+ * server HTTP API. This allows any MCP client to interact with a running
7
+ * OpenCode instance — manage sessions, send prompts, search files, configure
8
+ * providers, and more.
9
+ *
10
+ * Features:
11
+ * - 79 tools covering the entire OpenCode API surface
12
+ * - High-level workflow tools (opencode_ask, opencode_reply, etc.)
13
+ * - Smart response formatting for LLM-friendly output
14
+ * - MCP Resources for browseable project data
15
+ * - MCP Prompts for guided workflows
16
+ * - SSE event polling
17
+ * - TUI control tools
18
+ * - Retry logic with exponential backoff
19
+ * - Auto-detection and auto-start of the OpenCode server
20
+ *
21
+ * Environment variables:
22
+ * OPENCODE_BASE_URL - Base URL of the OpenCode server (default: http://127.0.0.1:4096)
23
+ * OPENCODE_SERVER_USERNAME - Username for HTTP basic auth (default: opencode)
24
+ * OPENCODE_SERVER_PASSWORD - Password for HTTP basic auth (optional)
25
+ * OPENCODE_AUTO_SERVE - Set to "false" to disable auto-start (default: true)
26
+ * OPENCODE_DEFAULT_PROVIDER - Default provider ID when not specified per-tool (optional)
27
+ * OPENCODE_DEFAULT_MODEL - Default model ID when not specified per-tool (optional)
28
+ * OPENCODE_SERVE_ARGS - Extra arguments for the `opencode serve` auto-start (optional)
29
+ */
30
+ export {};