feat: support remote mcp - #8
Conversation
There was a problem hiding this comment.
Pull request overview
This PR adds remote MCP server support alongside a broader set of packaging and skill-discovery changes for the OpenCode Lazy Loader plugin (now scoped/renamed), enabling skills to connect either via local stdio commands or via Streamable HTTP transport.
Changes:
- Add
RemoteMcpServerConfig+ Streamable HTTP transport support in the MCP manager (remote vs local). - Update skill discovery paths from
skill/toskills/and add a Playwright example skill under.opencode/skills/. - Rename/rebrand the npm package and update exports/docs accordingly.
Reviewed changes
Copilot reviewed 8 out of 10 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
| src/utils/env-vars.ts | Adjusts command/env normalization typing to local config (needs API/type alignment for union callers). |
| src/types.ts | Introduces local vs remote MCP config types and a unified union type. |
| src/skill-mcp-manager.ts | Adds Streamable HTTP transport support and selects transport based on config type. |
| src/skill-loader.ts | Updates discovery/loader logic and directory naming, plus minor typing changes. |
| src/index.ts | Re-exports newly added MCP config types. |
| README.md | Updates installation and examples for the renamed package and new skills/ paths. |
| package.json | Renames the package and updates metadata/scripts (publishing script needs attention). |
| package-lock.json | Updates lockfile content but still references the old package name (needs regeneration/aligning). |
| AGENTS.md | Updates documented skill discovery directories to skills/. |
| .opencode/skills/playwright-example/SKILL.md | Adds a new example skill embedding the Playwright MCP server. |
Suppressed comments (2)
src/utils/env-vars.ts:83
normalizeCommandcurrently only acceptsLocalMcpServerConfig, which makes passing aMcpServerConfigvalue (local-or-remote union) a type error even when the runtime value is local. Consider acceptingMcpServerConfigand explicitly rejectingtype: "remote"here to keep the helper usable across the codebase.
export function normalizeCommand(config: LocalMcpServerConfig): NormalizedCommand {
if (Array.isArray(config.command)) {
if (config.command.length === 0) {
throw new Error('Invalid MCP command configuration: command array must not be empty')
}
src/utils/env-vars.ts:102
- Same as
normalizeCommand:normalizeEnvbeing restricted toLocalMcpServerConfigmakes it awkward to call with variables typed as theMcpServerConfigunion. Widen the type and explicitly rejecttype: "remote"so misuse fails fast.
export function normalizeEnv(config: LocalMcpServerConfig): NormalizedEnv {
const envConfig = config.env ?? config.environment
if (!envConfig) {
return { env: {} }
}
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| scope: SkillScope | ||
| ): Promise<LoadedSkill[]> { | ||
| const entries = await fs.readdir(skillsDir, { withFileTypes: true }).catch(() => []) | ||
| const entries: Dirent<string>[] = await fs.readdir(skillsDir, { withFileTypes: true }).catch(() => []) |
| let url: URL | ||
| try { | ||
| url = new URL(config.url) | ||
| } catch { | ||
| throw new Error( | ||
| `MCP server "${info.serverName}" has an invalid URL: ${config.url}\n\n` + | ||
| `The URL must be a valid HTTP or HTTPS URL.` | ||
| ) | ||
| } |
| @@ -1,4 +1,4 @@ | |||
| import type { McpServerConfig, NormalizedCommand, NormalizedEnv } from '../types.js' | |||
| import type { LocalMcpServerConfig, NormalizedCommand, NormalizedEnv } from '../types.js' | |||
| url: string | ||
| /** Custom headers to send with requests */ | ||
| headers?: Record<string, string> | ||
| /** OAuth configuration, or false to disable OAuth */ |
| "scripts": { | ||
| "build": "npx tsc", | ||
| "watch": "npx tsc --watch", | ||
| "clean": "rm -rf dist", | ||
| "test": "vitest run", | ||
| "test:watch": "vitest", | ||
| "prepack": "npm run clean && npm run build" | ||
| "test:watch": "vitest" |
| ```json | ||
| { | ||
| "plugin": ["./path/to/opencode-lazy-loader"] | ||
| "plugin": ["./path/to/@orionpax/opencode-lazy-mcp"] |
|
Thanks @orionpax1997 — remote MCP support is a great addition! This PR couldn't be merged directly because it's your fork's I've ported the remote MCP feature itself to #14 with you credited as co-author, plus tests and docs. It also addresses the Copilot note here about |
No description provided.