- Added 'MCP LOADER (claude-code-mcp-loader)' section to src/features/AGENTS.md - Documented .mcp.json file locations with priority order (user, project, local) - Specified .mcp.json format with complete structure and examples - Documented server types (stdio, http, sse) with required fields - Added environment variable expansion syntax documentation - Provided practical examples for stdio, http, and disabled servers - Added transformation reference table for Claude Code → OpenCode format - Improved discoverability for users setting up MCP servers via Claude Code configuration 🤖 GENERATED WITH ASSISTANCE OF [OhMyOpenCode](https://github.com/code-yeongyu/oh-my-opencode)
5.9 KiB
5.9 KiB
FEATURES KNOWLEDGE BASE
OVERVIEW
Claude Code compatibility layer and core feature modules. Enables Claude Code configs/commands/skills/MCPs/hooks to work seamlessly in OpenCode.
STRUCTURE
features/
├── background-agent/ # Background task management
│ ├── manager.ts # Task lifecycle, notifications
│ ├── manager.test.ts
│ └── types.ts
├── builtin-commands/ # Built-in slash command definitions
├── builtin-skills/ # Built-in skills (playwright, etc.)
│ └── */SKILL.md # Each skill in own directory
├── claude-code-agent-loader/ # Load agents from ~/.claude/agents/*.md
├── claude-code-command-loader/ # Load commands from ~/.claude/commands/*.md
├── claude-code-mcp-loader/ # Load MCPs from .mcp.json
│ └── env-expander.ts # ${VAR} expansion
├── claude-code-plugin-loader/ # Load external plugins from installed_plugins.json
├── claude-code-session-state/ # Session state persistence
├── opencode-skill-loader/ # Load skills from OpenCode and Claude paths
├── skill-mcp-manager/ # MCP servers embedded in skills
│ ├── manager.ts # Lazy-loading MCP client lifecycle
│ └── types.ts
└── hook-message-injector/ # Inject messages into conversation
LOADER PRIORITY
Each loader reads from multiple directories (highest priority first):
| Loader | Priority Order |
|---|---|
| Commands | .opencode/command/ > ~/.config/opencode/command/ > .claude/commands/ > ~/.claude/commands/ |
| Skills | .opencode/skill/ > ~/.config/opencode/skill/ > .claude/skills/ > ~/.claude/skills/ |
| Agents | .claude/agents/ > ~/.claude/agents/ |
| MCPs | .claude/.mcp.json > .mcp.json > ~/.claude/.mcp.json |
HOW TO ADD A LOADER
- Create directory:
src/features/claude-code-my-loader/ - Create files:
loader.ts: Main loader logic withload()functiontypes.ts: TypeScript interfacesindex.ts: Barrel export
- Pattern: Read from multiple dirs, merge with priority, return normalized config
BACKGROUND AGENT SPECIFICS
- Task lifecycle: pending → running → completed/failed
- Notifications: OS notification on task complete (configurable)
- Result retrieval:
background_outputtool with task_id - Cancellation:
background_cancelwith task_id or all=true
CONFIG TOGGLES
Disable features in oh-my-opencode.json:
{
"claude_code": {
"mcp": false, // Skip .mcp.json loading
"commands": false, // Skip commands/*.md loading
"skills": false, // Skip skills/*/SKILL.md loading
"agents": false, // Skip agents/*.md loading
"hooks": false // Skip settings.json hooks
}
}
HOOK MESSAGE INJECTOR
- Purpose: Inject system messages into conversation at specific points
- Timing: PreToolUse, PostToolUse, UserPromptSubmit, Stop
- Format: Returns
{ messages: [{ role: "user", content: "..." }] }
MCP LOADER (claude-code-mcp-loader)
Loads MCP server configs from .mcp.json files. Full Claude Code compatibility.
File Locations (Priority Order)
| Path | Scope | Description |
|---|---|---|
~/.claude/.mcp.json |
user | User-global MCP servers |
./.mcp.json |
project | Project-specific MCP servers |
./.claude/.mcp.json |
local | Local overrides (git-ignored) |
.mcp.json Format
{
"mcpServers": {
"server-name": {
"type": "stdio|http|sse",
"command": "npx",
"args": ["-y", "@anthropics/mcp-server-example"],
"env": {
"API_KEY": "${MY_API_KEY}"
},
"disabled": false
}
}
}
Server Types
| Type | Required Fields | Description |
|---|---|---|
stdio (default) |
command, args?, env? |
Local subprocess MCP |
http |
url, headers? |
HTTP-based remote MCP |
sse |
url, headers? |
SSE-based remote MCP |
Environment Variable Expansion
Supports ${VAR} syntax in all string fields:
{
"mcpServers": {
"my-server": {
"command": "node",
"args": ["${HOME}/mcp-server/index.js"],
"env": {
"API_KEY": "${MY_API_KEY}",
"DEBUG": "${DEBUG:-false}"
}
}
}
}
Examples
stdio (Local subprocess):
{
"mcpServers": {
"filesystem": {
"command": "npx",
"args": ["-y", "@anthropics/mcp-server-filesystem", "/path/to/dir"]
}
}
}
http (Remote):
{
"mcpServers": {
"remote-api": {
"type": "http",
"url": "https://mcp.example.com/api",
"headers": {
"Authorization": "Bearer ${API_TOKEN}"
}
}
}
}
Disable a server:
{
"mcpServers": {
"expensive-server": {
"command": "...",
"disabled": true
}
}
}
Transformation
Claude Code format → OpenCode format:
| Claude Code | OpenCode |
|---|---|
type: "stdio" |
type: "local" |
type: "http|sse" |
type: "remote" |
command + args |
command: [cmd, ...args] |
env |
environment |
headers |
headers |
SKILL MCP MANAGER
- Purpose: Manage MCP servers embedded in skill YAML frontmatter
- Lifecycle: Lazy client loading, session-scoped cleanup
- Config:
mcpfield in skill's YAML frontmatter defines server config - Tool:
skill_mcpexposes MCP capabilities (tools, resources, prompts)
BUILTIN SKILLS
- Location:
src/features/builtin-skills/*/SKILL.md - Available:
playwright(browser automation) - Disable:
disabled_skills: ["playwright"]in config
ANTI-PATTERNS (FEATURES)
- Blocking on load: Loaders run at startup, keep them fast
- No error handling: Always try/catch, log failures, return empty on error
- Ignoring priority: Higher priority dirs must override lower
- Modifying user files: Loaders read-only, never write to ~/.claude/