-
Notifications
You must be signed in to change notification settings - Fork 2.5k
Description
Prerequisites
- I will write this issue in English (see our Language Policy)
- I have searched existing issues and discussions to avoid duplicates
- This feature request is specific to oh-my-opencode (not OpenCode core)
- I have read the documentation or asked an AI coding agent with this project's GitHub URL loaded and couldn't find the answer
Problem Description
Background
oh-my-opencode currently has its own MCP client implementation via skill-mcp-manager and claude-code-mcp-loader features. These work well for the current use case (skill-embedded MCPs and Claude Code MCP configs), but they require:
- Manual MCP server management — users must configure MCP servers in Claude Code config files (
~/.claude.json,.mcp.json) or skill frontmatter/mcp.jsonfiles - No unified discovery — MCP servers are scattered across multiple config scopes (user, project, local, skill-embedded) with different loading logic
- No auto-install — if an MCP server requires installation (e.g.,
npx -y @some/mcp-server), users must set it up manually - No CLI generation — users cannot generate standalone CLIs from their MCP servers
- No daemon/keep-alive — stdio MCP servers are spawned per-session with idle timeout cleanup, no persistent connection pooling
mcporter (MIT license, npm: [email protected]) is a mature TypeScript runtime, CLI, and code-generation toolkit for MCP that already solves all of these problems:
- Zero-config discovery — merges
~/.mcporter/mcporter.json,config/mcporter.json, plus imports from Cursor/Claude/Codex/Windsurf/OpenCode/VS Code - CLI generation —
mcporter generate-cliturns any MCP server into a standalone CLI - TypeScript codegen —
mcporter emit-tsgenerates typed client wrappers - OAuth handling — built-in OAuth caching, step-up auth
- Daemon —
mcporter daemon start/stop/restartkeeps MCP servers warm across sessions - Ad-hoc connections —
--http-url/--stdioflags for trying MCP servers without config - Config management —
mcporter config add/remove/import/login/logout
Proposed Solution
Phase 1: mcporter as the unified MCP backend
Replace skill-mcp-manager's direct @modelcontextprotocol/sdk usage with mcporter as the underlying MCP client runtime.
Architecture Mapping
| Current (skill-mcp-manager) | Proposed (mcporter) |
|---|---|
SkillMcpManager.getOrCreateClient() → direct Client from @modelcontextprotocol/sdk |
mcporter.createRuntime() → connection-pooled runtime with auto-discovery |
StdioClientTransport / StreamableHTTPClientTransport manual setup |
mcporter handles stdio/HTTP/SSE transport selection automatically |
Manual env expansion via expandEnvVarsInObject() |
mcporter's ${ENV} placeholder expansion built-in |
Custom OAuth via McpOAuthProvider + step-up handling |
mcporter's built-in OAuth caching + mcporter auth CLI |
| Idle timeout cleanup (5min default) | mcporter daemon with configurable lifecycle: keep-alive/ephemeral |
Skill frontmatter mcp: block or mcp.json per skill |
Skill MCPs auto-registered into mcporter config at skill load time |
Key Integration Points
1. Config Unification
mcporter already supports OpenCode config import paths:
opencode.jsonc / opencode.json (project root)
~/.config/opencode/opencode.jsonc / opencode.json (global)
The skill-embedded MCP configs (from mcp.json or YAML frontmatter in SKILL.md) would be dynamically registered into mcporter's runtime at skill load time:
// In opencode-skill-loader, after loading skill MCPs:
for (const [serverName, config] of Object.entries(skill.mcpConfig)) {
await mcporterRuntime.addServer(serverName, config)
}2. Tool Compatibility — Full Backward Compatibility
The skill_mcp tool interface remains unchanged:
skill_mcp(mcp_name="sqlite", tool_name="query", arguments='{"sql": "SELECT * FROM users"}')
skill_mcp(mcp_name="memory", resource_name="memory://notes")
Internally, instead of manager.callTool(info, context, name, args) creating a raw MCP SDK client, it delegates to mcporter:
const result = await mcporterRuntime.call(`${serverName}.${toolName}`, args)3. Claude Code MCP Loader Compatibility
claude-code-mcp-loader reads MCP configs from 4 paths:
~/.claude.json~/.claude/.mcp.json{cwd}/.mcp.json{cwd}/.claude/.mcp.json
mcporter's config import claude-code already reads these same paths. The loader can be simplified to delegate to mcporter's discovery.
4. Builtin MCPs
Current builtin MCPs (websearch, context7, grep_app) are remote HTTP MCPs. These would be registered as mcporter configs:
{
"websearch": { "url": "https://...", "headers": { "Authorization": "Bearer ${OPENCODE_WEBSEARCH_KEY}" } },
"context7": { "url": "https://mcp.context7.com/mcp" },
"grep_app": { "url": "https://mcp.grep.app/mcp" }
}Phase 2: Auto-install and MCP Discovery
MCP Auto-Install in Skills
Extend the skill mcp.json or SKILL.md frontmatter to support install directives:
---
name: my-skill
mcp:
sqlite:
command: npx
args: [-y, "@anthropic/mcp-server-sqlite", "--db", "${SKILL_DIR}/data.db"]
auto_install: true # mcporter handles installation
---Or in mcp.json:
{
"mcpServers": {
"sqlite": {
"command": "npx",
"args": ["-y", "@anthropic/mcp-server-sqlite"],
"autoInstall": true
}
}
}When auto_install: true, the skill loader invokes mcporter config add <name> --stdio "<command>" to persist it, and mcporter's runtime handles the first-run installation.
MCP Discovery from mcporter
Add a new tool or extend skill_mcp to discover MCP servers that mcporter knows about but aren't skill-embedded:
skill_mcp(mcp_name="__discover__")
# Returns all available MCP servers from mcporter's merged config
This gives agents access to MCPs configured via Cursor, Claude Desktop, Codex, etc. without any oh-my-opencode-specific setup.
Phase 3: Advanced Features
CLI Generation for Custom Tools
Agents can use mcporter's CLI generation to create project-specific tool CLIs:
mcporter generate-cli --server my-project-mcp --compile ./tools/my-cliThis could be exposed as a skill or command:
/mcporter-generate --server <name> --output <path>
Daemon Integration
For long-running agents (sisyphus, hephaestus), mcporter daemon keeps MCP servers warm:
- Agent starts →
mcporter daemon start(if not running) - Agent uses MCP tools → connection reuse via daemon
- Agent ends → daemon stays alive for next agent
Playwright-Style HTTP MCP Servers
mcporter already supports HTTP MCP servers. A Playwright MCP server running locally (e.g., @anthropic/mcp-server-playwright) can be configured as:
{
"playwright": {
"command": "npx",
"args": ["-y", "@anthropic/mcp-server-playwright"],
"lifecycle": "keep-alive"
}
}The daemon keeps the Playwright server (and its browser instance) alive across multiple tool calls.
Detailed Implementation Plan
Files to Modify
| File | Change |
|---|---|
src/features/skill-mcp-manager/manager.ts |
Replace raw SDK client creation with mcporter runtime |
src/features/skill-mcp-manager/connection.ts |
Delegate to mcporter's connection management |
src/features/skill-mcp-manager/stdio-client.ts |
Remove (mcporter handles stdio) |
src/features/skill-mcp-manager/http-client.ts |
Remove (mcporter handles HTTP) |
src/features/skill-mcp-manager/oauth-handler.ts |
Remove (mcporter handles OAuth) |
src/features/skill-mcp-manager/cleanup.ts |
Simplify — mcporter handles cleanup via daemon |
src/features/skill-mcp-manager/env-cleaner.ts |
Remove (mcporter handles env expansion) |
src/features/opencode-skill-loader/skill-mcp-config.ts |
Add auto-install directive parsing |
src/features/claude-code-mcp-loader/loader.ts |
Optionally delegate to mcporter import |
src/mcp/index.ts |
Register builtins via mcporter config |
src/tools/skill-mcp/tools.ts |
Add __discover__ mode for MCP discovery |
package.json |
Add mcporter as dependency |
New Files
| File | Purpose |
|---|---|
src/features/mcporter-runtime/index.ts |
mcporter runtime initialization and config management |
src/features/mcporter-runtime/skill-bridge.ts |
Bridge between skill MCP configs and mcporter |
src/features/mcporter-runtime/discovery.ts |
MCP discovery from mcporter's merged configs |
Migration Path
- Add mcporter as dependency —
bun add mcporter - Create mcporter-runtime wrapper — Wraps mcporter's
createRuntime()with oh-my-opencode's session management - Refactor SkillMcpManager — Delegate to mcporter runtime instead of raw SDK
- Backward-compatible — All existing
skill_mcpcalls work unchanged - Add discovery — New
__discover__mode in skill_mcp tool - Add auto-install — Parse
autoInstallin skill MCP configs - Daemon integration — Optional, for long-running agent sessions
Config Compatibility
Current skill MCP config (no change needed):
mcp:
my-server:
command: npx
args: [-y, some-mcp-server]
env:
API_KEY: ${MY_API_KEY}Current mcp.json (no change needed):
{
"mcpServers": {
"my-server": {
"command": "npx",
"args": ["-y", "some-mcp-server"]
}
}
}Both formats are already compatible with mcporter's config schema (ClaudeCodeMcpServer type matches mcporter's entry schema exactly — command, args, env, url, headers, type, oauth).
Feasibility Assessment
Why This Works
- Config format compatibility — oh-my-opencode's
ClaudeCodeMcpServertype and mcporter's entry schema are nearly identical (both supportcommand/args/envfor stdio,url/headersfor HTTP,typefield for explicit transport) - mcporter already imports OpenCode configs — The
pathsForImport('opencode', rootDir)function in mcporter readsopencode.jsonc/opencode.jsonfrom project root and~/.config/opencode/ - MIT license — No licensing issues
- Active maintenance — [email protected], actively developed by steipete
- Programmatic API —
createRuntime()andcreateServerProxy()are designed for embedding
Potential Risks
- Dependency weight — mcporter adds a dependency, but replaces
@modelcontextprotocol/sdkdirect usage - Breaking changes — mcporter is pre-1.0; pin version and test thoroughly
- Daemon lifecycle — Need to handle daemon startup/shutdown gracefully in oh-my-opencode's process lifecycle
Alternatives Considered
No response
Doctor Output (Optional)
Additional Context
Related existing code:
src/features/skill-mcp-manager/— Current MCP client management (12 files)src/features/claude-code-mcp-loader/— Claude Code MCP config loading (5 files)src/features/mcp-oauth/— MCP OAuth handling (8 files)src/tools/skill-mcp/— skill_mcp tool (5 files)src/mcp/— Builtin MCP definitions (6 files)
mcporter source: https://github.com/steipete/mcporter
Feature Type
New Tool
Contribution
- I'm willing to submit a PR for this feature
- I can help with testing
- I can help with documentation