Agent Support
OpenCode plugin that loads Claude Code plugins and Agent Plugins (agent-plugins.org) packages as native OpenCode skills, commands, agents, MCP servers, instructions, and hooks.
1
461
近 7 天 461
38.7
生态多维模型
8 天前
2026-10-12
快速安装与配置
opencode.json写入当前项目的 opencode.json,只对这个仓库生效。
opencode.json
{
"$schema": "https://opencode.ai/config.json",
"plugin": ["@harnesstap/opencode-agent-plugin-support@0.2.0"]
}写入 ~/.config/opencode/opencode.json,对所有项目生效。
~/.config/opencode/opencode.json
{
"$schema": "https://opencode.ai/config.json",
"plugin": ["@harnesstap/opencode-agent-plugin-support@0.2.0"]
}若你要在本地改造这个插件,先装到项目里再从本地路径引用。
shell
pnpm add -D @harnesstap/opencode-agent-plugin-supportOpenCode 启动时会通过内嵌运行时自动加载 npm 依赖并缓存至本地目录,无需手动在全局环境执行安装。
Loads Claude Code plugins and Agent Plugins packages into OpenCode as native skills, slash commands, subagents, MCP servers, instructions, and lifecycle hooks. Plugin files stay where they are; nothing is copied into .opencode/ or ~/.agents/skills.
Unrelated to the former unscoped npm package opencode-claude-plugins.
Quickstart
Tell it where your plugins are. Either:
a. Config file (recommended). Point straight at Claude's plugin directory, no symlink:
mkdir -p ~/.agents cat > ~/.agents/agent-plugin-support.json <<'JSON' { "$schema": "https://raw.githubusercontent.com/harnesstap/opencode-agent-plugin-support/main/schema/agent-plugin-support.schema.json", "sources": [ { "path": "~/.claude/plugins", "format": "claude" } ] } JSONb. Zero config. With no config file, plugins are read from
~/.agents/plugins, same layout as~/.claude/plugins. Symlink it:mkdir -p ~/.agents ln -s ~/.claude/plugins ~/.agents/pluginsCodex also uses
~/.agents/plugins/for its own plugin files; if you share that directory, prefer the config file and name each tool's directory explicitly.Add this package to
opencode.json(plugins, notplugin):{ "$schema": "https://opencode.ai/config.json", "plugins": ["@harnesstap/opencode-agent-plugin-support"] }Restart OpenCode (
opencode service restartif a background service is running).
Check what was found with npx @harnesstap/opencode-agent-plugin-support list (plugins) and ... sources (effective config).
From git (local directory)
v2 only loads index.js / index.ts at the folder root. It ignores package.json "main", and a path to a file is rejected.
git clone https://github.com/harnesstap/opencode-agent-plugin-support.git
cd opencode-agent-plugin-support
npm install
npm run build
{
"plugins": ["/absolute/path/to/opencode-agent-plugin-support"]
}
Restart OpenCode. Do not point plugins at dist/index.js or src/index.ts.
Configuration
~/.agents/agent-plugin-support.json (user) and <repo>/.agents/agent-plugin-support.json (project). Both are optional; a JSON schema is at schema/agent-plugin-support.schema.json.
{
"$schema": "https://raw.githubusercontent.com/harnesstap/opencode-agent-plugin-support/main/schema/agent-plugin-support.schema.json",
"sources": [
{ "path": "~/.claude/plugins", "format": "claude" },
{ "path": "~/.agents/plugins", "format": "agent-plugins" }
],
"enabledPlugins": { "oh-my-claudecode@omc": false }
}
sources: directories to load plugins from, in priority order.
| Field | |
|---|---|
path |
Directory. ~ is expanded; a relative path is relative to the config file's directory. |
format |
claude, agent-plugins, or auto (default). See below. |
label |
Suffix of Agent Plugins ids (<name>@<label>). Default: the directory name, or its parent's name when the directory is called plugins (~/.agents/plugins becomes agents). |
enabled |
false switches a source off, for example in a project to turn off a user source. |
A bare string is shorthand for { "path": "...", "format": "auto" }.
format |
What the directory is |
|---|---|
claude |
A Claude plugin tree: installed_plugins.json, known_marketplaces.json, cache/, marketplaces/; directory marketplaces are read in place. Exactly the 0.1.x behavior. |
agent-plugins |
A directory whose immediate children are Agent Plugins packages (a root plugin.json declaring an agent-plugins.org $schema). Children named cache, data, marketplaces, repos, or starting with . are skipped. |
auto |
Decides per plugin by its manifests: the registry in installed_plugins.json if there is one, plus every child directory with a .claude-plugin/plugin.json (Claude) or an Agent Plugins plugin.json. |
Merging. Project sources come first, then user sources; a project entry with the same resolved path as a user entry replaces it. If no config file declares sources, the default is one claude source at ~/.agents/plugins. If two enabled plugins from different sources have the same name, the first source wins and a warning is logged.
Plugin ids. claude plugins keep name@marketplace. Agent Plugins packages are <name>@<label>, with name from plugin.json: greeter@agents, or whatever label you set. list prints every id.
Enablement
Plugins are enabled unless set to false. Highest precedence first:
<repo>/.agents/agent-plugin-support.jsonenabledPlugins~/.agents/agent-plugin-support.jsonenabledPlugins<repo>/.agents/plugins.json(legacy)~/.agents/plugins.json(legacy)
Deprecated:
plugins.jsonstill works and is read at lower precedence, but new setups should useagent-plugin-support.json.extraKnownMarketplacesis still read fromplugins.jsononly.
Claude's ~/.claude/settings.json is not read.
Where data lives
${CLAUDE_PLUGIN_DATA} (Claude format) and ${PLUGIN_DATA} (Agent Plugins format) are both ~/.agents/plugins/data/<id with unsafe characters replaced by "-">/, created on first use, whichever sources you configure. Plugin updates and source changes do not move it.
Security
Hook commands (type: "command" in hooks.json) run as your user: full environment, project cwd, and a 30s default timeout (timeout in hooks.json is seconds). They can run any shell you would.
- PreToolUse timeout is fail-closed: if that hook hits the timeout, the tool call is blocked. A hung “deny this command” hook must not fail open.
- Other hook events still do not block on timeout (the process is killed; OpenCode continues). Exit
2/ JSONdenystill block where those events support it.
Malformed installed_plugins.json, plugin.json, hooks.json, .mcp.json, mcp.json, config files, or YAML frontmatter are skipped with a warning; other plugins keep loading. A repo can declare sources in <repo>/.agents/agent-plugin-support.json, so only open repositories you trust (the same is true of OpenCode's own project config).
See SECURITY.md to report a vulnerability.
Options and compatibility
Object form (npm package; local directory+options is dropped on OpenCode 2.0.24):
{
"plugins": [
{
"package": "@harnesstap/opencode-agent-plugin-support",
"options": {
"extraPluginDirs": { "my-plugin@local": "/path/to/claude-plugin" },
"skipInstalled": false,
"mcpDisabled": false
}
}
]
}
extraPluginDirs loads extra plugin directories (Claude or Agent Plugins, detected from the manifests) without writing a registry. skipInstalled skips discovery from every configured source. Prefer install-local (or that registry file) for Claude plugins if you need options on a local checkout.
OpenCode v1
{
"$schema": "https://opencode.ai/config.json",
"plugin": ["@harnesstap/opencode-agent-plugin-support"]
}
Needs OpenCode 1.18.29+ (object entrypoint with server()).
Compatibility
OpenCode v2 is the primary target. A v1 server() export remains for OpenCode 1.18.29+. v2 does not run v1 plugin implementations.
install-local refuses to write through a ~/.agents/plugins → ~/.claude/plugins symlink unless you pass --write-claude-registry.
Claude plugin trees
~/.agents/plugins/ (or any `claude` source)
installed_plugins.json
known_marketplaces.json
marketplaces/<name>/
cache/<marketplace>/<plugin>/<version>/
data/<plugin-id>/
Plugin roots are found the way Claude Code finds them: a relative-path plugin of a local (directory / file) marketplace is read in place from that marketplace; otherwise installPath from installed_plugins.json (~ / $HOME expanded, relative paths resolved from the source directory), then cache/<marketplace>/<plugin>/<version>/, then the marketplace clone's plugin source. Plugins that only exist in Claude's cache (github, git-subdir, npm, ... sources) cannot be rebuilt here; refresh them in Claude Code. Details in ARCHITECTURE.md.
Project-scoped installs for other repos are ignored. If several entries remain, the one whose directory exists wins.
Agent Plugins
Supports Agent Plugins 1.0.0 (the only published version): a root plugin.json with "$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json", skills/<dir>/SKILL.md, and mcp.json. Schemas are recognized locally and never fetched. A 1.1.0 (working draft) or unknown $schema rejects the plugin with a clear reason, as the spec requires for unsupported versions.
OpenCode-specific commands, agents, hooks, and instructions go in the client extension com.harnesstap.opencode/ (Claude-like layout) and/or extensions["com.harnesstap.opencode"] in plugin.json:
my-plugin/
plugin.json
skills/greet/SKILL.md
mcp.json
com.harnesstap.opencode/
commands/hello.md
agents/helper.md
hooks/hooks.json
instructions.md
Hook commands get PLUGIN_ROOT and PLUGIN_DATA next to the CLAUDE_* variables, and ${PLUGIN_ROOT} / ${PLUGIN_DATA} are expanded in hooks.json.
A plugin with both a .claude-plugin/plugin.json and an Agent Plugins plugin.json: from a claude or auto source, Claude is primary and the Agent Plugins mcp.json servers are added (a server name Claude already defines keeps the Claude definition; a differing name logs a warning and the Claude name stays the prefix). From an agent-plugins source, only the Agent Plugins side is read. An invalid Agent Plugins manifest on such a plugin falls back to Claude with a warning.
CLI
Bin name: opencode-agent-plugin-support.
npx @harnesstap/opencode-agent-plugin-support list
npx @harnesstap/opencode-agent-plugin-support sources
npx @harnesstap/opencode-agent-plugin-support enable name@marketplace
npx @harnesstap/opencode-agent-plugin-support disable name@marketplace --project
npx @harnesstap/opencode-agent-plugin-support install-local ./my-claude-plugin [name@local]
npx @harnesstap/opencode-agent-plugin-support install-local ./my-claude-plugin --write-claude-registry
npx @harnesstap/opencode-agent-plugin-support marketplace-add my-market github:org/repo
After a global install, the same commands work as opencode-agent-plugin-support ….
list— every plugin with effective on/off and where that was decided (source:default|user|project, plussourceFile), theformatit was loaded as (claude|agent-plugins), its configured source (sourcePath,sourceLabel,sourceFormat),dualManifest, the resolvedroot, how it was found (resolvedVia), every location tried (tried),reasonwhen it is off or unresolved, MCP servers left out (mcpSkipped), anddiagnostics.sources(aliasconfig) — the effective config: which config files exist, the merged sources with labels and origin, and everyenabledPluginskey with the file that decides it. Reads config only; it does not load plugins. SetOPENCODE_AGENT_PLUGIN_SUPPORT_DEBUG=1to log resolution to stderr.enable/disable— writeagent-plugin-support.jsonin the user directory (or the repo with--project) when that file exists, otherwise the legacyplugins.json. Other fields of the file are kept.install-local— register a local directory in~/.agents/plugins(must exist). Does not clone git marketplaces. Prints a note if~/.agents/pluginsis not one of your sources.marketplace-add— record an extra marketplace (github:org/repoor a path).
Support
| Component | OpenCode v2 | OpenCode v1 | Claude format | Agent Plugins format |
|---|---|---|---|---|
| Skills | ctx.skill.transform |
config.skills.paths |
skills/**/SKILL.md, manifest skills paths, root SKILL.md. Lenient frontmatter. Invocable as /plugin:skill; user-invocable: false skips the command, disable-model-invocation: true keeps the command but hides the skill from the model. |
Immediate children skills/<dir>/SKILL.md only, validated as Agent Skills (name equals the directory, description required); an invalid skill is skipped, siblings load. |
| MCP | ctx.mcp.transform (disabled) |
config.mcp (enabled) |
.mcp.json / manifest mcpServers. ${CLAUDE_PLUGIN_ROOT} / _DATA / _PROJECT_DIR / $ENV expanded. stdio, url / http / sse / ws (all mapped to local / remote). |
Root mcp.json, strict 1.0.0 rules. stdio and streamable-http run; sse is skipped with a report (OpenCode has no SSE client). Only ${PLUGIN_ROOT} / ${PLUGIN_DATA} expand; PLUGIN_ROOT / PLUGIN_DATA are set in the server's environment. An invalid entry skips that server, a bad file disables MCP for that plugin. |
| Commands | ctx.command.transform |
config.command |
commands/**/*.md and manifest commands, namespaced plugin:command. $ARGUMENTS works. |
From com.harnesstap.opencode/commands/ or extensions, namespaced with the plugin name. |
| Instructions | re-injected on every session.context |
config.instructions + system transform |
Plugin-root CLAUDE.md / AGENTS.md / INSTRUCTIONS.md. |
Only com.harnesstap.opencode/instructions.md. Root AGENTS.md / CLAUDE.md are not injected. |
| Agents | ctx.agent.transform update() (inserts if missing) |
config.agent |
agents/**/*.md, namespaced plugin:agent, mode: "subagent". |
From com.harnesstap.opencode/agents/ or extensions. |
| Hooks | tool / session / permission / event subscribe | v1 hook object | hooks/hooks.json, command hooks (type: "command") only. |
com.harnesstap.opencode/hooks/hooks.json or inline, same event support. PLUGIN_ROOT / PLUGIN_DATA set. |
bin/ on PATH |
shell.hook("create.before") |
shell.env |
Yes. | No. |
Every file an Agent Plugins package supplies must resolve (symlinks followed) inside the plugin root: plugin.json, skills/, each SKILL.md, MCP command and cwd, and extension files.
Hooks wired on v2: PreToolUse (block + updatedInput), PostToolUse / PostToolUseFailure (additionalContext), UserPromptSubmit, SessionStart (matcher = startup / clear / compact), SessionEnd, Stop (session.idle), PermissionRequest (permission.evaluate), PreCompact (session.compaction).
Not loaded: LSP, output styles, themes, monitors, workflows, in-process JS mods, .mcpb bundles, HTTP/prompt/MCP/agent hooks, and most other Claude hook events.
Skill ids stay kebab-case (OpenCode cannot namespace them as plugin:name). Invoke a plugin skill with /plugin:skill even if a user skill shares the name. Commands, agents, and MCP are namespaced as plugin:component.
v2 built-in tool ids shell, patch, and subagent map to Claude Bash, Edit, and Task for hook matchers.
This OpenCode plugin’s id is opencode-agent-plugin-support.
License
MIT
How injection works: ARCHITECTURE.md. Development: CONTRIBUTING.md.
同类生态推荐
Ocm
@wntic/ocm
Plugin marketplace for opencode: install skills, agents, commands, JS plugins and MCP servers from any git repo — once, globally, kept up to date
Navigator
opencode-navigator
Search, navigate, and manage OpenCode sessions from the TUI
@dodopayments/opencode-plugin
@dodopayments/opencode-plugin
Dodo Payments agent skills and MCP servers for OpenCode.