opencode-mcp 1.0.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 +25 -0
- package/LICENSE +21 -0
- package/README.md +241 -0
- package/dist/client.d.ts +49 -0
- package/dist/client.js +197 -0
- package/dist/client.js.map +1 -0
- package/dist/helpers.d.ts +53 -0
- package/dist/helpers.js +132 -0
- package/dist/helpers.js.map +1 -0
- package/dist/index.d.ts +25 -0
- package/dist/index.js +86 -0
- package/dist/index.js.map +1 -0
- package/dist/prompts.d.ts +9 -0
- package/dist/prompts.js +144 -0
- package/dist/prompts.js.map +1 -0
- package/dist/resources.d.ts +10 -0
- package/dist/resources.js +197 -0
- package/dist/resources.js.map +1 -0
- package/dist/tools/config.d.ts +3 -0
- package/dist/tools/config.js +33 -0
- package/dist/tools/config.js.map +1 -0
- package/dist/tools/events.d.ts +6 -0
- package/dist/tools/events.js +59 -0
- package/dist/tools/events.js.map +1 -0
- package/dist/tools/file.d.ts +3 -0
- package/dist/tools/file.js +127 -0
- package/dist/tools/file.js.map +1 -0
- package/dist/tools/global.d.ts +3 -0
- package/dist/tools/global.js +12 -0
- package/dist/tools/global.js.map +1 -0
- package/dist/tools/message.d.ts +3 -0
- package/dist/tools/message.js +151 -0
- package/dist/tools/message.js.map +1 -0
- package/dist/tools/misc.d.ts +3 -0
- package/dist/tools/misc.js +143 -0
- package/dist/tools/misc.js.map +1 -0
- package/dist/tools/project.d.ts +3 -0
- package/dist/tools/project.js +20 -0
- package/dist/tools/project.js.map +1 -0
- package/dist/tools/provider.d.ts +3 -0
- package/dist/tools/provider.js +58 -0
- package/dist/tools/provider.js.map +1 -0
- package/dist/tools/session.d.ts +3 -0
- package/dist/tools/session.js +223 -0
- package/dist/tools/session.js.map +1 -0
- package/dist/tools/tui.d.ts +7 -0
- package/dist/tools/tui.js +106 -0
- package/dist/tools/tui.js.map +1 -0
- package/dist/tools/workflow.d.ts +7 -0
- package/dist/tools/workflow.js +215 -0
- package/dist/tools/workflow.js.map +1 -0
- package/package.json +57 -0
package/dist/helpers.js
ADDED
|
@@ -0,0 +1,132 @@
|
|
|
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
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
9
|
+
/**
|
|
10
|
+
* Extract a human-readable summary from a message response.
|
|
11
|
+
* Pulls text content from parts, summarizes tool calls, etc.
|
|
12
|
+
* Accepts any shape — casts internally for safety.
|
|
13
|
+
*/
|
|
14
|
+
export function formatMessageResponse(response) {
|
|
15
|
+
const r = response;
|
|
16
|
+
const sections = [];
|
|
17
|
+
if (r?.info) {
|
|
18
|
+
const { id, role, createdAt } = r.info;
|
|
19
|
+
sections.push(`[${role ?? "unknown"}] Message ${id ?? "?"}${createdAt ? ` at ${createdAt}` : ""}`);
|
|
20
|
+
}
|
|
21
|
+
if (r?.parts && Array.isArray(r.parts)) {
|
|
22
|
+
for (const part of r.parts) {
|
|
23
|
+
switch (part.type) {
|
|
24
|
+
case "text":
|
|
25
|
+
sections.push(part.text ?? part.content ?? "");
|
|
26
|
+
break;
|
|
27
|
+
case "tool-invocation":
|
|
28
|
+
case "tool-result":
|
|
29
|
+
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)}`);
|
|
30
|
+
break;
|
|
31
|
+
default:
|
|
32
|
+
sections.push(`[${part.type}] ${JSON.stringify(part, null, 2)}`);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
return sections.join("\n\n");
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Format a list of messages, extracting text content from each.
|
|
40
|
+
*/
|
|
41
|
+
export function formatMessageList(messages) {
|
|
42
|
+
if (!messages || messages.length === 0)
|
|
43
|
+
return "No messages found.";
|
|
44
|
+
return messages
|
|
45
|
+
.map((raw, i) => {
|
|
46
|
+
const msg = raw;
|
|
47
|
+
const role = msg?.info?.role ?? "unknown";
|
|
48
|
+
const id = msg?.info?.id ?? "?";
|
|
49
|
+
const parts = Array.isArray(msg?.parts) ? msg.parts : [];
|
|
50
|
+
const textParts = parts
|
|
51
|
+
.filter((p) => p.type === "text")
|
|
52
|
+
.map((p) => p.text ?? p.content ?? "")
|
|
53
|
+
.join("");
|
|
54
|
+
const toolParts = parts.filter((p) => p.type === "tool-invocation" || p.type === "tool-result");
|
|
55
|
+
let summary = `--- Message ${i + 1} [${role}] (${id}) ---\n`;
|
|
56
|
+
if (textParts)
|
|
57
|
+
summary += textParts;
|
|
58
|
+
if (toolParts.length > 0) {
|
|
59
|
+
summary += `\n[${toolParts.length} tool call(s)]`;
|
|
60
|
+
}
|
|
61
|
+
return summary;
|
|
62
|
+
})
|
|
63
|
+
.join("\n\n");
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Format a diff response into a readable summary.
|
|
67
|
+
*/
|
|
68
|
+
export function formatDiffResponse(diffs) {
|
|
69
|
+
if (!diffs || diffs.length === 0)
|
|
70
|
+
return "No changes found.";
|
|
71
|
+
return diffs
|
|
72
|
+
.map((d) => {
|
|
73
|
+
const diff = d;
|
|
74
|
+
const path = diff.path ?? diff.file ?? "unknown";
|
|
75
|
+
const status = diff.status ?? diff.type ?? "";
|
|
76
|
+
const additions = typeof diff.additions === "number" ? `+${diff.additions}` : "";
|
|
77
|
+
const deletions = typeof diff.deletions === "number" ? `-${diff.deletions}` : "";
|
|
78
|
+
const stats = [additions, deletions].filter(Boolean).join(" ");
|
|
79
|
+
let line = `${status} ${path}`;
|
|
80
|
+
if (stats)
|
|
81
|
+
line += ` (${stats})`;
|
|
82
|
+
if (typeof diff.diff === "string") {
|
|
83
|
+
line += `\n${diff.diff}`;
|
|
84
|
+
}
|
|
85
|
+
return line;
|
|
86
|
+
})
|
|
87
|
+
.join("\n");
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Format session objects for LLM-friendly display.
|
|
91
|
+
*/
|
|
92
|
+
export function formatSessionList(sessions) {
|
|
93
|
+
if (!sessions || sessions.length === 0)
|
|
94
|
+
return "No sessions found.";
|
|
95
|
+
return sessions
|
|
96
|
+
.map((raw) => {
|
|
97
|
+
const s = raw;
|
|
98
|
+
const id = s?.id ?? "?";
|
|
99
|
+
const title = s?.title ?? "(untitled)";
|
|
100
|
+
const createdAt = s?.createdAt ?? "";
|
|
101
|
+
const parentID = s?.parentID ? ` (child of ${s.parentID})` : "";
|
|
102
|
+
return `- ${title} [${id}]${parentID}${createdAt ? ` created ${createdAt}` : ""}`;
|
|
103
|
+
})
|
|
104
|
+
.join("\n");
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Generic safe JSON stringify with truncation for very large responses.
|
|
108
|
+
*/
|
|
109
|
+
export function safeStringify(value, maxLength = 50000) {
|
|
110
|
+
const json = JSON.stringify(value, null, 2);
|
|
111
|
+
if (json.length <= maxLength)
|
|
112
|
+
return json;
|
|
113
|
+
return (json.slice(0, maxLength) +
|
|
114
|
+
`\n\n... [truncated, ${json.length - maxLength} more characters]`);
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Standard tool response builder.
|
|
118
|
+
*/
|
|
119
|
+
export function toolResult(text, isError = false) {
|
|
120
|
+
return {
|
|
121
|
+
content: [{ type: "text", text }],
|
|
122
|
+
...(isError ? { isError: true } : {}),
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
export function toolError(e) {
|
|
126
|
+
const msg = e instanceof Error ? e.message : String(e);
|
|
127
|
+
return toolResult(`Error: ${msg}`, true);
|
|
128
|
+
}
|
|
129
|
+
export function toolJson(value) {
|
|
130
|
+
return toolResult(safeStringify(value));
|
|
131
|
+
}
|
|
132
|
+
//# sourceMappingURL=helpers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"helpers.js","sourceRoot":"","sources":["../src/helpers.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
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
|
+
* - 60+ 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
|
+
*
|
|
20
|
+
* Environment variables:
|
|
21
|
+
* OPENCODE_BASE_URL - Base URL of the OpenCode server (default: http://127.0.0.1:4096)
|
|
22
|
+
* OPENCODE_SERVER_USERNAME - Username for HTTP basic auth (default: opencode)
|
|
23
|
+
* OPENCODE_SERVER_PASSWORD - Password for HTTP basic auth (optional)
|
|
24
|
+
*/
|
|
25
|
+
export {};
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
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
|
+
* - 60+ 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
|
+
*
|
|
20
|
+
* Environment variables:
|
|
21
|
+
* OPENCODE_BASE_URL - Base URL of the OpenCode server (default: http://127.0.0.1:4096)
|
|
22
|
+
* OPENCODE_SERVER_USERNAME - Username for HTTP basic auth (default: opencode)
|
|
23
|
+
* OPENCODE_SERVER_PASSWORD - Password for HTTP basic auth (optional)
|
|
24
|
+
*/
|
|
25
|
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
26
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
27
|
+
import { OpenCodeClient } from "./client.js";
|
|
28
|
+
// Tool groups
|
|
29
|
+
import { registerGlobalTools } from "./tools/global.js";
|
|
30
|
+
import { registerConfigTools } from "./tools/config.js";
|
|
31
|
+
import { registerProjectTools } from "./tools/project.js";
|
|
32
|
+
import { registerSessionTools } from "./tools/session.js";
|
|
33
|
+
import { registerMessageTools } from "./tools/message.js";
|
|
34
|
+
import { registerFileTools } from "./tools/file.js";
|
|
35
|
+
import { registerProviderTools } from "./tools/provider.js";
|
|
36
|
+
import { registerMiscTools } from "./tools/misc.js";
|
|
37
|
+
import { registerWorkflowTools } from "./tools/workflow.js";
|
|
38
|
+
import { registerTuiTools } from "./tools/tui.js";
|
|
39
|
+
import { registerEventTools } from "./tools/events.js";
|
|
40
|
+
// Resources and prompts
|
|
41
|
+
import { registerResources } from "./resources.js";
|
|
42
|
+
import { registerPrompts } from "./prompts.js";
|
|
43
|
+
const baseUrl = process.env.OPENCODE_BASE_URL ?? "http://127.0.0.1:4096";
|
|
44
|
+
const username = process.env.OPENCODE_SERVER_USERNAME;
|
|
45
|
+
const password = process.env.OPENCODE_SERVER_PASSWORD;
|
|
46
|
+
const client = new OpenCodeClient({ baseUrl, username, password });
|
|
47
|
+
const server = new McpServer({
|
|
48
|
+
name: "opencode-mcp",
|
|
49
|
+
version: "1.0.0",
|
|
50
|
+
description: "Full-featured MCP server wrapping the OpenCode AI headless HTTP server. " +
|
|
51
|
+
"Provides 60+ tools, resources, and prompts to manage sessions, send " +
|
|
52
|
+
"prompts, search files, configure providers, control the TUI, monitor " +
|
|
53
|
+
"events, and interact with the full OpenCode API. " +
|
|
54
|
+
"Start with opencode_ask for one-shot questions, or opencode_context " +
|
|
55
|
+
"to understand the current project.",
|
|
56
|
+
});
|
|
57
|
+
// ── Low-level API tools ─────────────────────────────────────────────
|
|
58
|
+
registerGlobalTools(server, client);
|
|
59
|
+
registerConfigTools(server, client);
|
|
60
|
+
registerProjectTools(server, client);
|
|
61
|
+
registerSessionTools(server, client);
|
|
62
|
+
registerMessageTools(server, client);
|
|
63
|
+
registerFileTools(server, client);
|
|
64
|
+
registerProviderTools(server, client);
|
|
65
|
+
registerMiscTools(server, client);
|
|
66
|
+
// ── High-level workflow tools ───────────────────────────────────────
|
|
67
|
+
registerWorkflowTools(server, client);
|
|
68
|
+
// ── TUI control ─────────────────────────────────────────────────────
|
|
69
|
+
registerTuiTools(server, client);
|
|
70
|
+
// ── Event streaming ─────────────────────────────────────────────────
|
|
71
|
+
registerEventTools(server, client);
|
|
72
|
+
// ── Resources ───────────────────────────────────────────────────────
|
|
73
|
+
registerResources(server, client);
|
|
74
|
+
// ── Prompts ─────────────────────────────────────────────────────────
|
|
75
|
+
registerPrompts(server);
|
|
76
|
+
// ── Start ───────────────────────────────────────────────────────────
|
|
77
|
+
async function main() {
|
|
78
|
+
const transport = new StdioServerTransport();
|
|
79
|
+
await server.connect(transport);
|
|
80
|
+
console.error(`opencode-mcp v1.0.0 started (connecting to OpenCode at ${baseUrl})`);
|
|
81
|
+
}
|
|
82
|
+
main().catch((err) => {
|
|
83
|
+
console.error("Fatal error starting opencode-mcp:", err);
|
|
84
|
+
process.exit(1);
|
|
85
|
+
});
|
|
86
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP Prompts — reusable prompt templates for common workflows.
|
|
3
|
+
*
|
|
4
|
+
* These are pre-built prompts that LLMs and MCP clients can discover
|
|
5
|
+
* and invoke, pre-filling arguments from the user. They guide the LLM
|
|
6
|
+
* through complex multi-step OpenCode interactions.
|
|
7
|
+
*/
|
|
8
|
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
9
|
+
export declare function registerPrompts(server: McpServer): void;
|
package/dist/prompts.js
ADDED
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP Prompts — reusable prompt templates for common workflows.
|
|
3
|
+
*
|
|
4
|
+
* These are pre-built prompts that LLMs and MCP clients can discover
|
|
5
|
+
* and invoke, pre-filling arguments from the user. They guide the LLM
|
|
6
|
+
* through complex multi-step OpenCode interactions.
|
|
7
|
+
*/
|
|
8
|
+
import { z } from "zod";
|
|
9
|
+
export function registerPrompts(server) {
|
|
10
|
+
// ─── Code Review ──────────────────────────────────────────────────
|
|
11
|
+
server.prompt("opencode-code-review", "Review code changes in an OpenCode session. Fetches the diff and provides a structured review.", {
|
|
12
|
+
sessionId: z
|
|
13
|
+
.string()
|
|
14
|
+
.describe("Session ID to review changes from"),
|
|
15
|
+
}, async ({ sessionId }) => ({
|
|
16
|
+
messages: [
|
|
17
|
+
{
|
|
18
|
+
role: "user",
|
|
19
|
+
content: {
|
|
20
|
+
type: "text",
|
|
21
|
+
text: `Please review the code changes in OpenCode session "${sessionId}".
|
|
22
|
+
|
|
23
|
+
Steps:
|
|
24
|
+
1. Use opencode_review_changes with sessionId "${sessionId}" to get the diff
|
|
25
|
+
2. Analyze the changes for:
|
|
26
|
+
- Correctness and potential bugs
|
|
27
|
+
- Code style and best practices
|
|
28
|
+
- Performance implications
|
|
29
|
+
- Security concerns
|
|
30
|
+
3. Provide a structured review with specific line-level feedback
|
|
31
|
+
4. Suggest improvements where applicable`,
|
|
32
|
+
},
|
|
33
|
+
},
|
|
34
|
+
],
|
|
35
|
+
}));
|
|
36
|
+
// ─── Debug Session ────────────────────────────────────────────────
|
|
37
|
+
server.prompt("opencode-debug", "Start a debugging session with OpenCode", {
|
|
38
|
+
issue: z.string().describe("Description of the bug or issue"),
|
|
39
|
+
context: z
|
|
40
|
+
.string()
|
|
41
|
+
.optional()
|
|
42
|
+
.describe("Additional context (file paths, error messages, etc.)"),
|
|
43
|
+
}, async ({ issue, context }) => ({
|
|
44
|
+
messages: [
|
|
45
|
+
{
|
|
46
|
+
role: "user",
|
|
47
|
+
content: {
|
|
48
|
+
type: "text",
|
|
49
|
+
text: `I need to debug an issue. Here's what's happening:
|
|
50
|
+
|
|
51
|
+
Issue: ${issue}
|
|
52
|
+
${context ? `\nContext: ${context}` : ""}
|
|
53
|
+
|
|
54
|
+
Steps:
|
|
55
|
+
1. Use opencode_context to understand the project setup
|
|
56
|
+
2. Use opencode_ask with the agent "build" to investigate the issue:
|
|
57
|
+
- Search for relevant files with opencode_find_text and opencode_find_file
|
|
58
|
+
- Read the relevant source code with opencode_file_read
|
|
59
|
+
- Analyze the code and identify the root cause
|
|
60
|
+
3. Suggest a fix and optionally have OpenCode implement it`,
|
|
61
|
+
},
|
|
62
|
+
},
|
|
63
|
+
],
|
|
64
|
+
}));
|
|
65
|
+
// ─── Project Setup ────────────────────────────────────────────────
|
|
66
|
+
server.prompt("opencode-project-setup", "Get oriented in a new project using OpenCode", {}, async () => ({
|
|
67
|
+
messages: [
|
|
68
|
+
{
|
|
69
|
+
role: "user",
|
|
70
|
+
content: {
|
|
71
|
+
type: "text",
|
|
72
|
+
text: `Help me understand this project.
|
|
73
|
+
|
|
74
|
+
Steps:
|
|
75
|
+
1. Use opencode_context to get project info, VCS status, and available agents
|
|
76
|
+
2. Use opencode_file_list to see the project structure
|
|
77
|
+
3. Look for key files: README, package.json, config files, entry points
|
|
78
|
+
4. Use opencode_file_read on the most important files
|
|
79
|
+
5. Provide a summary of:
|
|
80
|
+
- What the project does
|
|
81
|
+
- Tech stack and dependencies
|
|
82
|
+
- Project structure
|
|
83
|
+
- How to build and run it
|
|
84
|
+
- Key areas of the codebase`,
|
|
85
|
+
},
|
|
86
|
+
},
|
|
87
|
+
],
|
|
88
|
+
}));
|
|
89
|
+
// ─── Implement Feature ────────────────────────────────────────────
|
|
90
|
+
server.prompt("opencode-implement", "Have OpenCode implement a feature or make changes", {
|
|
91
|
+
description: z
|
|
92
|
+
.string()
|
|
93
|
+
.describe("Description of what to implement"),
|
|
94
|
+
requirements: z
|
|
95
|
+
.string()
|
|
96
|
+
.optional()
|
|
97
|
+
.describe("Specific requirements or constraints"),
|
|
98
|
+
}, async ({ description, requirements }) => ({
|
|
99
|
+
messages: [
|
|
100
|
+
{
|
|
101
|
+
role: "user",
|
|
102
|
+
content: {
|
|
103
|
+
type: "text",
|
|
104
|
+
text: `I want OpenCode to implement the following:
|
|
105
|
+
|
|
106
|
+
${description}
|
|
107
|
+
${requirements ? `\nRequirements: ${requirements}` : ""}
|
|
108
|
+
|
|
109
|
+
Steps:
|
|
110
|
+
1. Use opencode_context to understand the project
|
|
111
|
+
2. Use opencode_ask with the "build" agent to implement the feature:
|
|
112
|
+
"Please implement: ${description}${requirements ? `. Requirements: ${requirements}` : ""}"
|
|
113
|
+
3. Use opencode_review_changes to see what was changed
|
|
114
|
+
4. Report back what was implemented and any follow-up items`,
|
|
115
|
+
},
|
|
116
|
+
},
|
|
117
|
+
],
|
|
118
|
+
}));
|
|
119
|
+
// ─── Session Summary ──────────────────────────────────────────────
|
|
120
|
+
server.prompt("opencode-session-summary", "Summarize what happened in an OpenCode session", {
|
|
121
|
+
sessionId: z.string().describe("Session ID to summarize"),
|
|
122
|
+
}, async ({ sessionId }) => ({
|
|
123
|
+
messages: [
|
|
124
|
+
{
|
|
125
|
+
role: "user",
|
|
126
|
+
content: {
|
|
127
|
+
type: "text",
|
|
128
|
+
text: `Please summarize OpenCode session "${sessionId}".
|
|
129
|
+
|
|
130
|
+
Steps:
|
|
131
|
+
1. Use opencode_session_get to get session metadata
|
|
132
|
+
2. Use opencode_conversation with sessionId "${sessionId}" to read the full history
|
|
133
|
+
3. Use opencode_review_changes with sessionId "${sessionId}" to see file changes
|
|
134
|
+
4. Provide a summary including:
|
|
135
|
+
- What was discussed/requested
|
|
136
|
+
- What actions were taken
|
|
137
|
+
- What files were modified
|
|
138
|
+
- Current status and any remaining work`,
|
|
139
|
+
},
|
|
140
|
+
},
|
|
141
|
+
],
|
|
142
|
+
}));
|
|
143
|
+
}
|
|
144
|
+
//# sourceMappingURL=prompts.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompts.js","sourceRoot":"","sources":["../src/prompts.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP Resources — expose OpenCode data as browseable resources.
|
|
3
|
+
*
|
|
4
|
+
* Resources let MCP clients (and LLMs) discover and read structured data
|
|
5
|
+
* without needing to know the exact tool calls. They're perfect for
|
|
6
|
+
* things like "show me the current project" or "list available sessions".
|
|
7
|
+
*/
|
|
8
|
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
9
|
+
import { OpenCodeClient } from "./client.js";
|
|
10
|
+
export declare function registerResources(server: McpServer, client: OpenCodeClient): void;
|
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP Resources — expose OpenCode data as browseable resources.
|
|
3
|
+
*
|
|
4
|
+
* Resources let MCP clients (and LLMs) discover and read structured data
|
|
5
|
+
* without needing to know the exact tool calls. They're perfect for
|
|
6
|
+
* things like "show me the current project" or "list available sessions".
|
|
7
|
+
*/
|
|
8
|
+
import { safeStringify } from "./helpers.js";
|
|
9
|
+
export function registerResources(server, client) {
|
|
10
|
+
// ─── Current Project ──────────────────────────────────────────────
|
|
11
|
+
server.resource("project-current", "opencode://project/current", {
|
|
12
|
+
description: "The currently active OpenCode project",
|
|
13
|
+
mimeType: "application/json",
|
|
14
|
+
}, async () => {
|
|
15
|
+
try {
|
|
16
|
+
const project = await client.get("/project/current");
|
|
17
|
+
return {
|
|
18
|
+
contents: [
|
|
19
|
+
{
|
|
20
|
+
uri: "opencode://project/current",
|
|
21
|
+
mimeType: "application/json",
|
|
22
|
+
text: safeStringify(project),
|
|
23
|
+
},
|
|
24
|
+
],
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
catch {
|
|
28
|
+
return {
|
|
29
|
+
contents: [
|
|
30
|
+
{
|
|
31
|
+
uri: "opencode://project/current",
|
|
32
|
+
mimeType: "text/plain",
|
|
33
|
+
text: "No project currently active.",
|
|
34
|
+
},
|
|
35
|
+
],
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
});
|
|
39
|
+
// ─── Config ───────────────────────────────────────────────────────
|
|
40
|
+
server.resource("config", "opencode://config", {
|
|
41
|
+
description: "Current OpenCode configuration",
|
|
42
|
+
mimeType: "application/json",
|
|
43
|
+
}, async () => {
|
|
44
|
+
const config = await client.get("/config");
|
|
45
|
+
return {
|
|
46
|
+
contents: [
|
|
47
|
+
{
|
|
48
|
+
uri: "opencode://config",
|
|
49
|
+
mimeType: "application/json",
|
|
50
|
+
text: safeStringify(config),
|
|
51
|
+
},
|
|
52
|
+
],
|
|
53
|
+
};
|
|
54
|
+
});
|
|
55
|
+
// ─── Providers ────────────────────────────────────────────────────
|
|
56
|
+
server.resource("providers", "opencode://providers", {
|
|
57
|
+
description: "All available LLM providers, their models, and connection status",
|
|
58
|
+
mimeType: "application/json",
|
|
59
|
+
}, async () => {
|
|
60
|
+
const providers = await client.get("/provider");
|
|
61
|
+
return {
|
|
62
|
+
contents: [
|
|
63
|
+
{
|
|
64
|
+
uri: "opencode://providers",
|
|
65
|
+
mimeType: "application/json",
|
|
66
|
+
text: safeStringify(providers),
|
|
67
|
+
},
|
|
68
|
+
],
|
|
69
|
+
};
|
|
70
|
+
});
|
|
71
|
+
// ─── Agents ───────────────────────────────────────────────────────
|
|
72
|
+
server.resource("agents", "opencode://agents", {
|
|
73
|
+
description: "All available agents and their configurations",
|
|
74
|
+
mimeType: "application/json",
|
|
75
|
+
}, async () => {
|
|
76
|
+
const agents = await client.get("/agent");
|
|
77
|
+
return {
|
|
78
|
+
contents: [
|
|
79
|
+
{
|
|
80
|
+
uri: "opencode://agents",
|
|
81
|
+
mimeType: "application/json",
|
|
82
|
+
text: safeStringify(agents),
|
|
83
|
+
},
|
|
84
|
+
],
|
|
85
|
+
};
|
|
86
|
+
});
|
|
87
|
+
// ─── Commands ─────────────────────────────────────────────────────
|
|
88
|
+
server.resource("commands", "opencode://commands", {
|
|
89
|
+
description: "All available commands (built-in and custom)",
|
|
90
|
+
mimeType: "application/json",
|
|
91
|
+
}, async () => {
|
|
92
|
+
const commands = await client.get("/command");
|
|
93
|
+
return {
|
|
94
|
+
contents: [
|
|
95
|
+
{
|
|
96
|
+
uri: "opencode://commands",
|
|
97
|
+
mimeType: "application/json",
|
|
98
|
+
text: safeStringify(commands),
|
|
99
|
+
},
|
|
100
|
+
],
|
|
101
|
+
};
|
|
102
|
+
});
|
|
103
|
+
// ─── Server Health ────────────────────────────────────────────────
|
|
104
|
+
server.resource("health", "opencode://health", {
|
|
105
|
+
description: "OpenCode server health and version",
|
|
106
|
+
mimeType: "application/json",
|
|
107
|
+
}, async () => {
|
|
108
|
+
const health = await client.get("/global/health");
|
|
109
|
+
return {
|
|
110
|
+
contents: [
|
|
111
|
+
{
|
|
112
|
+
uri: "opencode://health",
|
|
113
|
+
mimeType: "application/json",
|
|
114
|
+
text: safeStringify(health),
|
|
115
|
+
},
|
|
116
|
+
],
|
|
117
|
+
};
|
|
118
|
+
});
|
|
119
|
+
// ─── VCS Info ─────────────────────────────────────────────────────
|
|
120
|
+
server.resource("vcs", "opencode://vcs", {
|
|
121
|
+
description: "Version control system info for the current project",
|
|
122
|
+
mimeType: "application/json",
|
|
123
|
+
}, async () => {
|
|
124
|
+
try {
|
|
125
|
+
const vcs = await client.get("/vcs");
|
|
126
|
+
return {
|
|
127
|
+
contents: [
|
|
128
|
+
{
|
|
129
|
+
uri: "opencode://vcs",
|
|
130
|
+
mimeType: "application/json",
|
|
131
|
+
text: safeStringify(vcs),
|
|
132
|
+
},
|
|
133
|
+
],
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
catch {
|
|
137
|
+
return {
|
|
138
|
+
contents: [
|
|
139
|
+
{
|
|
140
|
+
uri: "opencode://vcs",
|
|
141
|
+
mimeType: "text/plain",
|
|
142
|
+
text: "No VCS information available.",
|
|
143
|
+
},
|
|
144
|
+
],
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
});
|
|
148
|
+
// ─── Session list (resource template) ─────────────────────────────
|
|
149
|
+
server.resource("sessions", "opencode://sessions", {
|
|
150
|
+
description: "All sessions",
|
|
151
|
+
mimeType: "application/json",
|
|
152
|
+
}, async () => {
|
|
153
|
+
const sessions = await client.get("/session");
|
|
154
|
+
return {
|
|
155
|
+
contents: [
|
|
156
|
+
{
|
|
157
|
+
uri: "opencode://sessions",
|
|
158
|
+
mimeType: "application/json",
|
|
159
|
+
text: safeStringify(sessions),
|
|
160
|
+
},
|
|
161
|
+
],
|
|
162
|
+
};
|
|
163
|
+
});
|
|
164
|
+
// ─── MCP Servers ──────────────────────────────────────────────────
|
|
165
|
+
server.resource("mcp-servers", "opencode://mcp-servers", {
|
|
166
|
+
description: "Status of all configured MCP servers in OpenCode",
|
|
167
|
+
mimeType: "application/json",
|
|
168
|
+
}, async () => {
|
|
169
|
+
const mcp = await client.get("/mcp");
|
|
170
|
+
return {
|
|
171
|
+
contents: [
|
|
172
|
+
{
|
|
173
|
+
uri: "opencode://mcp-servers",
|
|
174
|
+
mimeType: "application/json",
|
|
175
|
+
text: safeStringify(mcp),
|
|
176
|
+
},
|
|
177
|
+
],
|
|
178
|
+
};
|
|
179
|
+
});
|
|
180
|
+
// ─── File Status ──────────────────────────────────────────────────
|
|
181
|
+
server.resource("file-status", "opencode://file-status", {
|
|
182
|
+
description: "VCS status of all tracked files",
|
|
183
|
+
mimeType: "application/json",
|
|
184
|
+
}, async () => {
|
|
185
|
+
const status = await client.get("/file/status");
|
|
186
|
+
return {
|
|
187
|
+
contents: [
|
|
188
|
+
{
|
|
189
|
+
uri: "opencode://file-status",
|
|
190
|
+
mimeType: "application/json",
|
|
191
|
+
text: safeStringify(status),
|
|
192
|
+
},
|
|
193
|
+
],
|
|
194
|
+
};
|
|
195
|
+
});
|
|
196
|
+
}
|
|
197
|
+
//# sourceMappingURL=resources.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resources.js","sourceRoot":"","sources":["../src/resources.ts"],"names":[],"mappings":"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"}
|