@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
package/dist/index.js ADDED
@@ -0,0 +1,198 @@
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
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
31
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
32
+ import { OpenCodeClient } from "./client.js";
33
+ import { ensureServer } from "./server-manager.js";
34
+ import { setModelDefaults } from "./helpers.js";
35
+ // Tool groups
36
+ import { registerGlobalTools } from "./tools/global.js";
37
+ import { registerConfigTools } from "./tools/config.js";
38
+ import { registerProjectTools } from "./tools/project.js";
39
+ import { registerSessionTools } from "./tools/session.js";
40
+ import { registerMessageTools } from "./tools/message.js";
41
+ import { registerFileTools } from "./tools/file.js";
42
+ import { registerProviderTools } from "./tools/provider.js";
43
+ import { registerMiscTools } from "./tools/misc.js";
44
+ import { registerWorkflowTools } from "./tools/workflow.js";
45
+ import { registerTuiTools } from "./tools/tui.js";
46
+ import { registerEventTools } from "./tools/events.js";
47
+ // Resources and prompts
48
+ import { registerResources } from "./resources.js";
49
+ import { registerPrompts } from "./prompts.js";
50
+ const baseUrl = process.env.OPENCODE_BASE_URL ?? "http://127.0.0.1:4096";
51
+ const username = process.env.OPENCODE_SERVER_USERNAME;
52
+ const password = process.env.OPENCODE_SERVER_PASSWORD;
53
+ const autoServe = process.env.OPENCODE_AUTO_SERVE !== "false";
54
+ const defaultProvider = process.env.OPENCODE_DEFAULT_PROVIDER;
55
+ const defaultModel = process.env.OPENCODE_DEFAULT_MODEL;
56
+ // Set global model defaults from env vars (used by applyModelDefaults() in tools)
57
+ setModelDefaults(defaultProvider, defaultModel);
58
+ // Use env-var defaults in instruction examples; fall back to generic placeholders
59
+ const exProvider = defaultProvider || "<your-provider>";
60
+ const exModel = defaultModel || "<your-model>";
61
+ const client = new OpenCodeClient({ baseUrl, username, password, autoServe });
62
+ const server = new McpServer({
63
+ name: "opencode-mcp",
64
+ version: "1.10.1",
65
+ description: "MCP server wrapping the OpenCode AI coding agent. " +
66
+ "Delegates complex coding tasks (build apps, refactor, debug) to an autonomous AI agent. " +
67
+ "Start with opencode_setup, then use opencode_ask for simple tasks, opencode_run for complex tasks, or opencode_fire for long-running background work.",
68
+ }, {
69
+ instructions: [
70
+ "# OpenCode MCP — Guide for LLM Clients",
71
+ "",
72
+ "You are connected to OpenCode, an autonomous AI coding agent that can build, edit, and debug software projects.",
73
+ "This server exposes ~79 tools organized into tiers. Use high-level tools first; drop to low-level only when needed.",
74
+ "",
75
+ "## Getting Started (First Time)",
76
+ "1. Call `opencode_setup` — checks server health, shows configured providers, and suggests next steps.",
77
+ "2. Pick a provider from the **Ready to use** list returned by `opencode_setup`, then call `opencode_provider_models` to see its models.",
78
+ "3. IMPORTANT: Always pass `providerID` and `modelID` from the discovered providers when sending prompts, or you may get empty responses. Do NOT assume any specific provider is available — always discover first.",
79
+ "",
80
+ "## Tool Tiers (prefer higher tiers)",
81
+ "",
82
+ "### Tier 1 — Essential (use these first)",
83
+ "- `opencode_setup` — first-time onboarding, health check (read-only)",
84
+ "- `opencode_ask` — one-shot question/task, creates session + gets response in one call. Simplest way to use OpenCode.",
85
+ "- `opencode_reply` — continue a conversation in an existing session",
86
+ "- `opencode_context` — get project info (path, git branch, config, agents) (read-only)",
87
+ "",
88
+ "### Tier 2 — Async Tasks (for complex/long work)",
89
+ "- `opencode_run` — RECOMMENDED: send a task and wait for completion in one call. Creates session, sends prompt, polls until done. Best for tasks under 10 minutes.",
90
+ "- `opencode_fire` — fire-and-forget: send a task and return immediately. Use `opencode_check` to monitor progress. Best for long tasks (10+ min).",
91
+ "- `opencode_check` — cheap progress report: status, todos, file counts. Use to monitor sessions from `opencode_fire`. (read-only)",
92
+ "- `opencode_wait` — block until a session finishes processing. Use after `opencode_message_send_async`. Has timeout.",
93
+ "- `opencode_session_todo` — see the agent's internal task list for a session (read-only)",
94
+ "",
95
+ "### Tier 3 — Monitoring & Review",
96
+ "- `opencode_review_changes` — see all file diffs from a session (read-only)",
97
+ "- `opencode_conversation` — get full message history (read-only)",
98
+ "- `opencode_sessions_overview` — list all sessions with status (read-only)",
99
+ "- `opencode_provider_models` — list models for a specific provider (read-only)",
100
+ "- `opencode_status` — quick server health dashboard (read-only)",
101
+ "",
102
+ "### Tier 4 — Fine-Grained Control",
103
+ "- `opencode_session_*` — create, delete, fork, abort, share sessions",
104
+ "- `opencode_message_*` — send messages, list history, execute commands",
105
+ "- `opencode_permission_list` / `opencode_session_permission` — check and respond to permission requests",
106
+ "- `opencode_file_*` / `opencode_find_*` — search files, read content, check VCS status",
107
+ "- `opencode_provider_*` — manage providers, auth, OAuth flows",
108
+ "",
109
+ "### Tier 5 — Specialist (rarely needed)",
110
+ "- `opencode_tui_*` — control the terminal UI (only if a TUI is running)",
111
+ "- `opencode_events_poll` — poll raw SSE events",
112
+ "- `opencode_mcp_*` — manage MCP servers inside OpenCode",
113
+ "- `opencode_instance_dispose` — shut down the server (DESTRUCTIVE!)",
114
+ "",
115
+ "## Recommended Workflows",
116
+ "",
117
+ "### Quick question or small task:",
118
+ "```",
119
+ `opencode_ask({prompt: "How does auth work in this project?", providerID: "${exProvider}", modelID: "${exModel}"})`,
120
+ "```",
121
+ "",
122
+ "### Complex multi-step task (build an app, refactor code, etc.):",
123
+ "```",
124
+ "// Option A: One-call (recommended for tasks under 10 min)",
125
+ `opencode_run({prompt: "Build a React login form with validation...", providerID: "${exProvider}", modelID: "${exModel}", maxDurationSeconds: 600})`,
126
+ "",
127
+ "// Option B: Fire-and-forget (for longer tasks)",
128
+ `opencode_fire({prompt: "Build a full React app with auth, dashboard...", providerID: "${exProvider}", modelID: "${exModel}"})`,
129
+ "// ... do other work ...",
130
+ 'opencode_check({sessionId: "ses_xxx"}) // quick progress check',
131
+ 'opencode_review_changes({sessionId: "ses_xxx"}) // see changes after completion',
132
+ "```",
133
+ "",
134
+ "### Continue working on an existing session:",
135
+ "```",
136
+ `opencode_reply({sessionId: "ses_xxx", prompt: "Now add form validation", providerID: "${exProvider}", modelID: "${exModel}"})`,
137
+ "```",
138
+ "",
139
+ "## Permissions",
140
+ "OpenCode may pause a session to ask for permission (e.g. to run a shell command or access files outside the project).",
141
+ "- **Recommended for headless/automation:** Set `\"permission\": \"allow\"` in `opencode.json` to auto-approve all operations. Without this, sessions can block waiting for approval.",
142
+ "- **If a session seems stuck:** Call `opencode_permission_list` to check for pending permission requests, then respond with `opencode_session_permission`.",
143
+ "- You can also set permissions at runtime: `opencode_config_update({config: {permission: \"allow\"}})`",
144
+ "",
145
+ "## Important Notes",
146
+ "- ALWAYS specify `providerID` and `modelID` when using `opencode_ask`, `opencode_reply`, `opencode_message_send`, or `opencode_message_send_async`. Without these, the agent may return empty responses. Use providers and models discovered via `opencode_setup` — do NOT hardcode any specific provider. If `OPENCODE_DEFAULT_PROVIDER` and `OPENCODE_DEFAULT_MODEL` env vars are set, they will be used as fallbacks when you don't specify them.",
147
+ "- The `directory` parameter on every tool targets a specific project. Omit it to use the server's default project. Must be an absolute path to an existing directory — relative paths and non-existent paths are rejected with a helpful error.",
148
+ "- Tools marked with `readOnlyHint: true` in their annotations are safe and don't modify state.",
149
+ "- Tools marked with `destructiveHint: true` (`opencode_instance_dispose`, `opencode_session_delete`) permanently delete data — confirm with the user before calling.",
150
+ "- `opencode_wait` sends `notifications/message` progress updates while blocking. If it times out, it returns a progress report instead of failing.",
151
+ "- For tasks under 10 minutes, prefer `opencode_run` (one call, handles everything). For longer tasks, use `opencode_fire` + `opencode_check`.",
152
+ "- For very long tasks, use `opencode_fire` + periodically call `opencode_check` or `opencode_session_todo` to monitor progress.",
153
+ ].join("\n"),
154
+ });
155
+ // ── Low-level API tools ─────────────────────────────────────────────
156
+ registerGlobalTools(server, client);
157
+ registerConfigTools(server, client);
158
+ registerProjectTools(server, client);
159
+ registerSessionTools(server, client);
160
+ registerMessageTools(server, client);
161
+ registerFileTools(server, client);
162
+ registerProviderTools(server, client);
163
+ registerMiscTools(server, client);
164
+ // ── High-level workflow tools ───────────────────────────────────────
165
+ registerWorkflowTools(server, client);
166
+ // ── TUI control ─────────────────────────────────────────────────────
167
+ registerTuiTools(server, client);
168
+ // ── Event streaming ─────────────────────────────────────────────────
169
+ registerEventTools(server, client);
170
+ // ── Resources ───────────────────────────────────────────────────────
171
+ registerResources(server, client);
172
+ // ── Prompts ─────────────────────────────────────────────────────────
173
+ registerPrompts(server);
174
+ // ── Start ───────────────────────────────────────────────────────────
175
+ async function main() {
176
+ // Step 1: Ensure OpenCode server is available (auto-start if needed).
177
+ try {
178
+ await ensureServer({ baseUrl, autoServe, username, password });
179
+ }
180
+ catch (err) {
181
+ // Log the error but don't prevent MCP from starting — tools will
182
+ // report connection errors individually, and the server may come
183
+ // up later.
184
+ console.error(`Warning: ${err instanceof Error ? err.message : String(err)}`);
185
+ }
186
+ // Step 2: Connect the MCP transport.
187
+ const transport = new StdioServerTransport();
188
+ await server.connect(transport);
189
+ const defaultsInfo = defaultProvider && defaultModel
190
+ ? ` | defaults: ${defaultProvider}/${defaultModel}`
191
+ : "";
192
+ console.error(`opencode-mcp v1.10.1 started (OpenCode server at ${baseUrl}${defaultsInfo})`);
193
+ }
194
+ main().catch((err) => {
195
+ console.error("Fatal error starting opencode-mcp:", err);
196
+ process.exit(1);
197
+ });
198
+ //# 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;
@@ -0,0 +1,210 @@
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
+ // ─── Best Practices ─────────────────────────────────────────────────
120
+ server.prompt("opencode-best-practices", "Get best practices for using OpenCode MCP tools effectively. Covers tool selection, async workflows, provider configuration, and common pitfalls.", {}, async () => ({
121
+ messages: [
122
+ {
123
+ role: "user",
124
+ content: {
125
+ type: "text",
126
+ text: `# OpenCode MCP Best Practices
127
+
128
+ ## 1. First-Time Setup
129
+ - Always start with \`opencode_setup\` to check server health and see available providers.
130
+ - Pick a provider from the **Ready to use** list, then call \`opencode_provider_models\` to see its models.
131
+ - Test a provider with \`opencode_provider_test\` if you're unsure it's working.
132
+
133
+ ## 2. Always Specify Provider and Model
134
+ CRITICAL: When calling \`opencode_ask\`, \`opencode_reply\`, \`opencode_message_send\`, or \`opencode_message_send_async\`, ALWAYS pass \`providerID\` and \`modelID\`. Without these, the agent may select a default model that returns empty responses. Use providers discovered via \`opencode_setup\` — do NOT hardcode any specific provider.
135
+
136
+ Good: \`opencode_ask({prompt: "...", providerID: "<your-provider>", modelID: "<your-model>"})\`
137
+ Bad: \`opencode_ask({prompt: "..."})\`
138
+
139
+ ## 3. Choosing the Right Tool
140
+
141
+ | Task | Tool | Why |
142
+ |------|------|-----|
143
+ | Quick question | \`opencode_ask\` | One call, creates session + gets response |
144
+ | Multi-turn conversation | \`opencode_ask\` then \`opencode_reply\` | Builds on existing session |
145
+ | Complex build task (< 10 min) | \`opencode_run\` | One call, creates session + polls until done |
146
+ | Very long task (10+ min) | \`opencode_fire\` + \`opencode_check\` | Fire-and-forget with cheap progress checks |
147
+ | Monitor a running session | \`opencode_check\` | Status, todos, file counts in one call |
148
+
149
+ ## 4. Writing Good Prompts for OpenCode
150
+ The agent works best with structured, specific prompts:
151
+ - Specify the tech stack explicitly
152
+ - List all features/requirements as bullet points
153
+ - Define the project structure you want
154
+ - State what tests you expect
155
+ - Say "Run npm run build and fix any errors" at the end
156
+
157
+ ## 5. Monitoring Long-Running Tasks
158
+ - \`opencode_check\` — quick progress report: status, todos, file counts (cheapest)
159
+ - \`opencode_session_todo\` — see the agent's internal checklist
160
+ - \`opencode_wait\` — block until done, but has a timeout
161
+ - \`opencode_conversation\` — see full message history (expensive, lots of tokens)
162
+ - \`opencode_review_changes\` — see all file diffs (use after task completes)
163
+
164
+ ## 6. Error Recovery
165
+ - If a session fails, use \`opencode_reply\` to give the agent the error and ask it to fix
166
+ - If the server is unreachable, call \`opencode_setup\` to diagnose
167
+ - If auth fails, use \`opencode_auth_set\` to update API keys
168
+ - If a session is stuck, use \`opencode_session_abort\` then retry
169
+
170
+ ## 7. Tool Annotations
171
+ Tools are annotated with behavior hints:
172
+ - \`readOnlyHint: true\` — safe, doesn't change anything (setup, status, find, review)
173
+ - \`destructiveHint: true\` — permanently deletes data (session_delete, instance_dispose)
174
+ - No annotation — has side effects but is not destructive (ask, reply, send messages)
175
+
176
+ ## 8. Common Pitfalls
177
+ - Don't call \`opencode_conversation\` on active sessions — it's expensive and the response is still being generated
178
+ - Don't create new sessions for each message — use \`opencode_reply\` to continue existing ones
179
+ - Don't forget the \`directory\` parameter when working with multiple projects
180
+ - Don't call \`opencode_instance_dispose\` unless you really want to shut down the server`,
181
+ },
182
+ },
183
+ ],
184
+ }));
185
+ // ─── Session Summary ──────────────────────────────────────────────
186
+ server.prompt("opencode-session-summary", "Summarize what happened in an OpenCode session", {
187
+ sessionId: z.string().describe("Session ID to summarize"),
188
+ }, async ({ sessionId }) => ({
189
+ messages: [
190
+ {
191
+ role: "user",
192
+ content: {
193
+ type: "text",
194
+ text: `Please summarize OpenCode session "${sessionId}".
195
+
196
+ Steps:
197
+ 1. Use opencode_session_get to get session metadata
198
+ 2. Use opencode_conversation with sessionId "${sessionId}" to read the full history
199
+ 3. Use opencode_review_changes with sessionId "${sessionId}" to see file changes
200
+ 4. Provide a summary including:
201
+ - What was discussed/requested
202
+ - What actions were taken
203
+ - What files were modified
204
+ - Current status and any remaining work`,
205
+ },
206
+ },
207
+ ],
208
+ }));
209
+ }
210
+ //# 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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"}