OpenCode plugin for Morph Fast Apply - 10x faster code editing with lazy edit markers.
// ... existing code ...) - no exact string matching neededMorph: src/file.ts +15/-3 (450ms)edit tool on API failureNote: This is an OpenCode plugin that wraps Morph's Fast Apply API. For the official Morph MCP server (which includes WarpGrep search), see @morphllm/morphmcp. This plugin uses
morph_editas the tool name to avoid conflicts if you have both installed.
Preferred when your setup syncs packaged instructions into ~/.config/opencode/instructions/:
Add to your global config (~/.config/opencode/opencode.json):
{
"instructions": ["~/.config/opencode/instructions/morph-tools.md"],
"plugin": ["github:JRedeker/opencode-morph-fast-apply"]
}
Or pin to a specific version:
{
"instructions": ["~/.config/opencode/instructions/morph-tools.md"],
"plugin": ["github:JRedeker/opencode-morph-fast-apply#v1.11.0"]
}
Recommended setup summary:
~/.config/opencode/instructions/morph-tools.mdnode_modules/.../morph-tools.md path only when your setup does not sync instructionsinstructions array, not a skillIf you are installing the plugin directly and do not sync packaged instructions into
~/.config/opencode/instructions/, you can point OpenCode at the packaged file
instead:
{
"instructions": [
"~/.config/opencode/node_modules/opencode-morph-fast-apply/instructions/morph-tools.md"
],
"plugin": ["github:JRedeker/opencode-morph-fast-apply"]
}
The morph_edit tool description remains self-contained, but for more reliable
tool selection you should also load the packaged always-on instruction file
shown above. This avoids agents defaulting to native edit when morph_edit
is the better fit for large, scattered, or whitespace-sensitive edits.
Important: the active agent must also expose morph_edit in its tool manifest.
If an agent profile marks morph_edit: false, the model cannot choose Morph
even when the plugin is installed and the always-on instruction is present.
Get an API key at morphllm.com/dashboard, then add it to the environment that starts OpenCode:
export MORPH_API_KEY="sk-your-key-here"
The plugin reads MORPH_API_KEY from the OpenCode process environment when it
loads. Setting the variable in an unrelated shell does not update
already-running OpenCode sessions.
The morph_edit tool will now be available.
The LLM uses morph_edit for efficient partial file edits:
morph_edit({
target_filepath: "src/auth.ts",
instructions: "I am adding error handling for invalid tokens",
code_edit: `// ... existing code ...
function validateToken(token) {
if (!token) {
throw new Error("Token is required");
}
// ... existing code ...
}
// ... existing code ...`
})
morph_edit vs edit| Situation | Tool | Reason |
|---|---|---|
| Small, exact replacement | edit | Fast, no API call |
| Large file (500+ lines) | morph_edit | Handles partial snippets |
| Multiple scattered changes | morph_edit | Batch efficiently |
| Whitespace-sensitive | morph_edit | Forgiving with formatting |
| Variable | Default | Description |
|---|---|---|
MORPH_API_KEY | (required) | Your Morph API key |
MORPH_API_URL | https://api.morphllm.com | API endpoint |
MORPH_MODEL | morph-v3-fast | Model to use (see below) |
MORPH_TIMEOUT | 30000 | Request timeout in ms |
| Model | Speed | Accuracy | Best For |
|---|---|---|---|
morph-v3-fast | 10,500+ tok/sec | 96% | Real-time applications, quick edits |
morph-v3-large | 5,000+ tok/sec | 98% | Complex changes, highest accuracy |
auto | 5,000-10,500 tok/sec | ~98% | Recommended - automatically selects optimal model |
<instruction> - Your intent description<code> - The complete original file<update> - Your partial edit with markersEnsure the environment variable is set and exported in the shell or service that starts OpenCode:
echo $MORPH_API_KEY # Should show your key
After changing MORPH_API_KEY, restart OpenCode so the plugin reloads with the
updated OpenCode process environment.
Increase the timeout for large files:
export MORPH_TIMEOUT=60000 # 60 seconds
If code is being deleted unexpectedly, ensure your code_edit includes // ... existing code ... markers at the start and end. Omitting these markers tells Morph to replace the entire file.
The plugin blocks unsafe Morph responses before writing files:
// ... existing code ... but the original file did not, the write is aborted.MORPH_API_KEY or Bearer tokens in tool output.In all guard cases, morph_edit returns a detailed error with recovery options (retry with tighter anchors, use native edit, or split into smaller edits).
code_edit inputIf an AI agent wraps code_edit in markdown fences (for example, ```typescript ... ```), morph_edit strips the outer fence before sending content to Morph.
If edits are applied to the wrong location, add more unique context around your changes and make your instructions more specific about which function/section you're modifying.
When a native edit reports an unmatched or ambiguous exact target:
edit input.edit only when the re-read proves the change is still small and exact.morph_edit for the contextual repair — multi-line, scattered, whitespace-sensitive, or broader anchoring.write only for new-file or intentional full-file replacement.This recovery sequence is separate from the Morph API-error/timeout fallback, which still recovers to native edit.
The morph_edit tool is disabled in readonly agent modes (plan, explore). Switch to a build/code mode to make edits.
morph_edit description, the packaged always-on instruction, and the README now share the same bounded recovery sequence for a failed native exact edit: re-read the target, do not repeat unchanged input, allow at most one corrected native edit only when still small and exact, otherwise hand off to morph_edit for contextual repair. The existing Morph API-error/timeout → native edit fallback is preserved.instructions/morph-tools.md now documents that agent profiles must expose morph_edit: true in their tool manifest for the routing policy to take effect~/.config/opencode/instructions/morph-tools.md and keeps the packaged node_modules/... path as a fallback for direct installsinstructions/morph-tools.md now explicitly says morph routing belongs in always-on instructions, not a skillinstructions/morph-tools.md now ships with the plugin so OpenCode can load reliable morph_edit selection guidance through the instructions arrayinstructions/ directory, and tests verify that the shipped instruction path is documentedmorph_edit selectionmorph_edit guidance still lives in the tool description so the tool is usable even without extra setup.instructions/morph-tools.md can be added to your OpenCode instructions array so agents choose morph_edit more reliably.skills/morph/SKILL.md and MORPH_INSTRUCTIONS.md. The skill added a round-trip and split-brain problem where guidance lived in multiple places.MORPH_SKILL_LOAD_HINT — Agents no longer need to load a skill before using morph_edit.// ... existing code ... as literal textcode_edit to prevent merge confusionMorph: blocked (marker leakage) or Morph: blocked (truncation) on guard failuresMorph: src/file.ts +15/-3 (450ms)console.log/console.warn with client.app.log() SDK methodmorph_edit in plan and explore modes to prevent accidental editscode_edit is missing markers for files >10 lines, preventing catastrophic code lossMORPH_INSTRUCTIONS.md now includes all key examples (adding functions, modifying code, deletions)MORPH_INSTRUCTIONS.md reduced by 72% (237→67 lines) while keeping critical guidancecode_edit is missing markers (helps debug unexpected deletions)Contributions welcome! This plugin could potentially be integrated into OpenCode core.
This project uses Bun. The bun.lock lockfile is tracked in git; pnpm-lock.yaml and package-lock.json are ignored.
64 commits
TypeScript
99.5%
OpenCode plugin for Morph Fast Apply - 10x faster code editing with lazy edit markers.
// ... existing code ...) - no exact string matching neededMorph: src/file.ts +15/-3 (450ms)edit tool on API failureNote: This is an OpenCode plugin that wraps Morph's Fast Apply API. For the official Morph MCP server (which includes WarpGrep search), see @morphllm/morphmcp. This plugin uses
morph_editas the tool name to avoid conflicts if you have both installed.
Preferred when your setup syncs packaged instructions into ~/.config/opencode/instructions/:
Add to your global config (~/.config/opencode/opencode.json):
{
"instructions": ["~/.config/opencode/instructions/morph-tools.md"],
"plugin": ["github:JRedeker/opencode-morph-fast-apply"]
}
Or pin to a specific version:
{
"instructions": ["~/.config/opencode/instructions/morph-tools.md"],
"plugin": ["github:JRedeker/opencode-morph-fast-apply#v1.11.0"]
}
Recommended setup summary:
~/.config/opencode/instructions/morph-tools.mdnode_modules/.../morph-tools.md path only when your setup does not sync instructionsinstructions array, not a skillIf you are installing the plugin directly and do not sync packaged instructions into
~/.config/opencode/instructions/, you can point OpenCode at the packaged file
instead:
{
"instructions": [
"~/.config/opencode/node_modules/opencode-morph-fast-apply/instructions/morph-tools.md"
],
"plugin": ["github:JRedeker/opencode-morph-fast-apply"]
}
The morph_edit tool description remains self-contained, but for more reliable
tool selection you should also load the packaged always-on instruction file
shown above. This avoids agents defaulting to native edit when morph_edit
is the better fit for large, scattered, or whitespace-sensitive edits.
Important: the active agent must also expose morph_edit in its tool manifest.
If an agent profile marks morph_edit: false, the model cannot choose Morph
even when the plugin is installed and the always-on instruction is present.
Get an API key at morphllm.com/dashboard, then add it to the environment that starts OpenCode:
export MORPH_API_KEY="sk-your-key-here"
The plugin reads MORPH_API_KEY from the OpenCode process environment when it
loads. Setting the variable in an unrelated shell does not update
already-running OpenCode sessions.
The morph_edit tool will now be available.
The LLM uses morph_edit for efficient partial file edits:
morph_edit({
target_filepath: "src/auth.ts",
instructions: "I am adding error handling for invalid tokens",
code_edit: `// ... existing code ...
function validateToken(token) {
if (!token) {
throw new Error("Token is required");
}
// ... existing code ...
}
// ... existing code ...`
})
morph_edit vs edit| Situation | Tool | Reason |
|---|---|---|
| Small, exact replacement | edit | Fast, no API call |
| Large file (500+ lines) | morph_edit | Handles partial snippets |
| Multiple scattered changes | morph_edit | Batch efficiently |
| Whitespace-sensitive | morph_edit | Forgiving with formatting |
| Variable | Default | Description |
|---|---|---|
MORPH_API_KEY | (required) | Your Morph API key |
MORPH_API_URL | https://api.morphllm.com | API endpoint |
MORPH_MODEL | morph-v3-fast | Model to use (see below) |
MORPH_TIMEOUT | 30000 | Request timeout in ms |
| Model | Speed | Accuracy | Best For |
|---|---|---|---|
morph-v3-fast | 10,500+ tok/sec | 96% | Real-time applications, quick edits |
morph-v3-large | 5,000+ tok/sec | 98% | Complex changes, highest accuracy |
auto | 5,000-10,500 tok/sec | ~98% | Recommended - automatically selects optimal model |
<instruction> - Your intent description<code> - The complete original file<update> - Your partial edit with markersEnsure the environment variable is set and exported in the shell or service that starts OpenCode:
echo $MORPH_API_KEY # Should show your key
After changing MORPH_API_KEY, restart OpenCode so the plugin reloads with the
updated OpenCode process environment.
Increase the timeout for large files:
export MORPH_TIMEOUT=60000 # 60 seconds
If code is being deleted unexpectedly, ensure your code_edit includes // ... existing code ... markers at the start and end. Omitting these markers tells Morph to replace the entire file.
The plugin blocks unsafe Morph responses before writing files:
// ... existing code ... but the original file did not, the write is aborted.MORPH_API_KEY or Bearer tokens in tool output.In all guard cases, morph_edit returns a detailed error with recovery options (retry with tighter anchors, use native edit, or split into smaller edits).
code_edit inputIf an AI agent wraps code_edit in markdown fences (for example, ```typescript ... ```), morph_edit strips the outer fence before sending content to Morph.
If edits are applied to the wrong location, add more unique context around your changes and make your instructions more specific about which function/section you're modifying.
When a native edit reports an unmatched or ambiguous exact target:
edit input.edit only when the re-read proves the change is still small and exact.morph_edit for the contextual repair — multi-line, scattered, whitespace-sensitive, or broader anchoring.write only for new-file or intentional full-file replacement.This recovery sequence is separate from the Morph API-error/timeout fallback, which still recovers to native edit.
The morph_edit tool is disabled in readonly agent modes (plan, explore). Switch to a build/code mode to make edits.
morph_edit description, the packaged always-on instruction, and the README now share the same bounded recovery sequence for a failed native exact edit: re-read the target, do not repeat unchanged input, allow at most one corrected native edit only when still small and exact, otherwise hand off to morph_edit for contextual repair. The existing Morph API-error/timeout → native edit fallback is preserved.instructions/morph-tools.md now documents that agent profiles must expose morph_edit: true in their tool manifest for the routing policy to take effect~/.config/opencode/instructions/morph-tools.md and keeps the packaged node_modules/... path as a fallback for direct installsinstructions/morph-tools.md now explicitly says morph routing belongs in always-on instructions, not a skillinstructions/morph-tools.md now ships with the plugin so OpenCode can load reliable morph_edit selection guidance through the instructions arrayinstructions/ directory, and tests verify that the shipped instruction path is documentedmorph_edit selectionmorph_edit guidance still lives in the tool description so the tool is usable even without extra setup.instructions/morph-tools.md can be added to your OpenCode instructions array so agents choose morph_edit more reliably.skills/morph/SKILL.md and MORPH_INSTRUCTIONS.md. The skill added a round-trip and split-brain problem where guidance lived in multiple places.MORPH_SKILL_LOAD_HINT — Agents no longer need to load a skill before using morph_edit.// ... existing code ... as literal textcode_edit to prevent merge confusionMorph: blocked (marker leakage) or Morph: blocked (truncation) on guard failuresMorph: src/file.ts +15/-3 (450ms)console.log/console.warn with client.app.log() SDK methodmorph_edit in plan and explore modes to prevent accidental editscode_edit is missing markers for files >10 lines, preventing catastrophic code lossMORPH_INSTRUCTIONS.md now includes all key examples (adding functions, modifying code, deletions)MORPH_INSTRUCTIONS.md reduced by 72% (237→67 lines) while keeping critical guidancecode_edit is missing markers (helps debug unexpected deletions)Contributions welcome! This plugin could potentially be integrated into OpenCode core.
This project uses Bun. The bun.lock lockfile is tracked in git; pnpm-lock.yaml and package-lock.json are ignored.
64 commits
TypeScript
99.5%